Skip to content

Can't run in local if the agent has an inner class in it #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Butanium opened this issue Aug 25, 2022 · 5 comments
Open

Can't run in local if the agent has an inner class in it #68

Butanium opened this issue Aug 25, 2022 · 5 comments
Labels

Comments

@Butanium
Copy link
Contributor

Having this runner :

package Runners.tests;

import agents.moveDumb;
import com.codingame.gameengine.runner.MultiplayerGameRunner;

public class crashTestMove {
    public static void main(String[] args) {
        /* Multiplayer Game */
        MultiplayerGameRunner gameRunner = new MultiplayerGameRunner();
        gameRunner.addAgent(moveDumb.class);
        gameRunner.addAgent(moveDumb.class);
        gameRunner.setLeagueLevel(3);
        gameRunner.setSeed(3794553746263553451L);
        gameRunner.start();
  

    }
}

I get this erro :
image

java.lang.IllegalAccessError: tried to access class agents.moveDumb$Empty from class Agent41436
    at Agent41436.main(moveDumb.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.codingame.gameengine.runner.JavaPlayerAgent$JavaAgentThread.run(JavaPlayerAgent.java:191)

The agent that provok this is

package agents;

import java.util.Scanner;

/**
 * Control your bots in order to destroy the enemy team !
 **/
@SuppressWarnings("InfiniteLoopStatement")
public
class moveDumb {
    static class Empty {
        public int x;
        public int y;
        public Empty(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int botPerPlayer = in.nextInt(); // the amount of bot you control
        int mapSize = in.nextInt();
        // game loop
        while (true) {
            StringBuilder result = new StringBuilder();
            new Empty(1,2);
            int allyBotAlive = in.nextInt(); // the amount of your bot which are still alive
            int totalEntities = in.nextInt(); // the amount of entities in the arena
            System.err.printf("%d allybots, %d entities", allyBotAlive, totalEntities);
            in.nextLine();
            for (int i = 0; i < totalEntities; i++) {
               in.nextLine();
            }
            for (int i = 0; i < allyBotAlive; i++) {
                int accRank = totalEntities;
                int accId = 0;
                int accDist = 0;
                int selfId = 0;
                for (int j = 0; j < totalEntities; j++) {
                    int entId = in.nextInt(); // the unique entity id
                    String entType = in.next(); // the entity type in a string. It can be ON_AIR | ALLY | ENEMY
                    int distMe = in.nextInt(); // approximate distance between the target and the current bot. Can be 0 to 3 for short, medium, long and out of range
                    int distMeRank = in.nextInt(); // entities are sorted by ascending order based on their distance to the current bot
                    int shieldComp = in.nextInt(); // -1 if the entity has more shield than the current bot, 0 if it's equal, 1 if your bot as more shield
                    int healthComp = in.nextInt(); // same as shieldComp but for the health
                    int totComp = in.nextInt(); // same as shieldComp but based on the sum of health+shield
                    if(entType.equals("ENEMY") && distMeRank<accRank) {
                        accId = entId;
                        accRank = distMeRank;
                        accDist = distMe;
                    }
                    if (entType.equals("ON_AIR")) {
                        selfId = entId;
                    }
                }
                result.append(selfId).append(" MOVE ").append(accId).append(";");
            }
            System.out.println(result);
        }
    }
}

The cause is the use of the Empty class. However, online, this player works perfectly. How can I make it work locally ?

@CGjupoulton
Copy link
Contributor

CGjupoulton commented Aug 25, 2022 via email

@Butanium
Copy link
Contributor Author

Butanium commented Aug 25, 2022

What do you mean by inner class ? Empty is already declared in the moveDumb class, which is the one used by the agent.
I tried to move the class declaration inside the main :

public static void main(String[] args) {
        class Empty {
            public int x;
            public int y;
            public Empty(int x, int y) {
                this.x = x;
                this.y = y;
            }
        }
        ...

which throw this error :

java.lang.IllegalAccessError: tried to access class agents.moveDumb$1Empty from class Agent582577
	at Agent582577.main(moveDumb.java:27)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.codingame.gameengine.runner.JavaPlayerAgent$JavaAgentThread.run(JavaPlayerAgent.java:191)

I guess I'll have to do it with the command line.

I tried multiple command but none works :

String path = " C:\\Users\\Clement\\Documents\\coding\\codinGame\\clash-of-bits\\src\\test\\java\\"
gameRunner.addAgent(new String[]{"javac " + path + "agents\\moveDumb.java",
                "java -cp "+path+" agents.moveDumb"});
// or
gameRunner.addAgent(new String[]{"javac " + path + "agents\\moveDumb.java",
                        "java -cp "+path+"; agents.moveDumb"});
// or
gameRunner.addAgent("javac " + path + "agents\\moveDumb.java" + " & " +
                "java -cp "+path+"; agents.moveDumb");
// or
gameRunner.addAgent("javac " + path + "agents\\moveDumb.java" + " ; " +
                "java -cp "+path+" agents.moveDumb");

The 2 first fail at compilation and the 2 last fail at runtime.

What command do you use to run .java with the SDK ? Because in CMD the first serie works and in powershell the second works :

PS C:\Users\Clement\Documents\coding\codinGame\clash-of-bits> javac C:\Users\Clement\Documents\coding\codinGame\clash-of-bits\src\test\java\agents\moveD
umb.java
PS C:\Users\Clement\Documents\coding\codinGame\clash-of-bits> java -cp C:\Users\Clement\Documents\coding\codinGame\clash-of-bits\src\test\java\ agents.m
oveDumb 
2 3 23 23
23 allybots, 23 entities

@CGjupoulton
Copy link
Contributor

CGjupoulton commented Aug 26, 2022 via email

@Butanium
Copy link
Contributor Author

With the same runner as in the first comment it fails :

package agents;

import java.util.Scanner;

/**
 * Control your bots in order to destroy the enemy team !
 **/
class Empty {
    public int x;
    public int y;
    public Empty(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
public
class moveDumb {
    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        int botPerPlayer = in.nextInt(); // the amount of bot you control
        int mapSize = in.nextInt();
        // game loop
        while (true) {
            StringBuilder result = new StringBuilder();
            new Empty(1,2);
            int allyBotAlive = in.nextInt(); // the amount of your bot which are still alive
            int totalEntities = in.nextInt(); // the amount of entities in the arena
            System.err.printf("%d allybots, %d entities", allyBotAlive, totalEntities);
            in.nextLine();
            for (int i = 0; i < totalEntities; i++) {
               in.nextLine();
            }
            for (int i = 0; i < allyBotAlive; i++) {
                int accRank = totalEntities;
                int accId = 0;
                int accDist = 0;
                int selfId = 0;
                for (int j = 0; j < totalEntities; j++) {
                    int entId = in.nextInt(); // the unique entity id
                    String entType = in.next(); // the entity type in a string. It can be ON_AIR | ALLY | ENEMY
                    int distMe = in.nextInt(); // approximate distance between the target and the current bot. Can be 0 to 3 for short, medium, long and out of range
                    int distMeRank = in.nextInt(); // entities are sorted by ascending order based on their distance to the current bot
                    int shieldComp = in.nextInt(); // -1 if the entity has more shield than the current bot, 0 if it's equal, 1 if your bot as more shield
                    int healthComp = in.nextInt(); // same as shieldComp but for the health
                    int totComp = in.nextInt(); // same as shieldComp but based on the sum of health+shield
                    if(entType.equals("ENEMY") && distMeRank<accRank) {
                        accId = entId;
                        accRank = distMeRank;
                        accDist = distMe;
                    }
                    if (entType.equals("ON_AIR")) {
                        selfId = entId;
                    }
                }
                result.append(selfId).append(" MOVE ").append(accId).append(";");
            }
            System.out.println(result);
        }
    }
}
java.lang.IllegalAccessError: tried to access class agents.Empty from class Agent991903
	at Agent991903.main(moveDumb.java:27)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.codingame.gameengine.runner.JavaPlayerAgent$JavaAgentThread.run(JavaPlayerAgent.java:191)

No hurry for the command line agent, I did all my testing with the uploaded contrib

@CGjupoulton
Copy link
Contributor

Here use this:

    private static String compile(String botFile) throws IOException, InterruptedException {
        File outFolder = Files.createTempDir();

        System.out.println("Compiling " + botFile);
        Process compileProcess = Runtime.getRuntime()
            .exec(new String[] { "bash", "-c", "javac " + botFile + " -d " + outFolder.getAbsolutePath() });
        compileProcess.waitFor();
        return "java -cp " + outFolder + " Player";
    }

and use like this

   gameRunner.addAgent(compile("bots/Player.java"), "JavaBot");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants