[BUG] Java inner classes aren't working properly

I tried to go for the Skynet the Virus challenge using a Builder-Pattern approach and leaving the heavy lifting to a small inner class I quickly kicked up.

Unfortunately that’s already where the problems started. As I can’t upload a screenshot here goes: This is the output I get from the Console.

Standard Error Stream:
error: non-static variable this cannot be referenced from a static context
Builder builder = new Builder();
----------------------^

The code shouldn’t really be anywhere near a problem:

public static void main(String args[]) {
        Scanner in = new Scanner(System.in);
        Builder builder = new Builder();
        int nodeCount = in.nextInt(); // the total number of nodes in the level, including the gateways
        int linkCount = in.nextInt(); // the number of links
        int exitCount = in.nextInt(); // the number of exit gateways
        in.nextLine();
        
        builder.setNodeCount(nodeCount);
        
        for (int i = 0; i < L; i++) {
            int N1 = in.nextInt(); // N1 and N2 defines a link between these nodes
            int N2 = in.nextInt();
            in.nextLine();
            builder.addLink(N1, N2);
        }
        for (int i = 0; i < E; i++) {
            int EI = in.nextInt(); // the index of a gateway node
            in.nextLine();
            builder.addExit(EI);
        }

        Network network = builder.build();
        // game loop
        while (true) {
            int SI = in.nextInt(); // The index of the node on which the Skynet agent is positioned this turn
            in.nextLine();

            // Write an action using System.out.println()
            // To debug: System.err.println("Debug messages...");

            System.out.println(network.linkToSevere(SI)); // Example: 0 1 are the indices of the nodes you wish to sever the link between
        }
    }
    
    public class Builder {
        private int nodeCount;
        private Set<Integer> gatewayNumbers = new HashSet<>();
        private Map<Integer, List<Integer>> links = new HashMap<Integer, List<Integer>>();
        
        public void setNodeCount(int nodeCount) {
            this.nodeCount = nodeCount;
        }
        
        public void addLink(int nodeNumber1, int nodeNumber2) {
            if (links.get(nodeNumber1) != null) {
                links.put(nodeNumber1, links.get(nodeNumber1).add(nodeNumber2));
            } else {
                links.put(nodeNumber1, Arrays.asList(new int[]{nodeNumber2}));
            }
            if (links.get(nodeNumber2) != null) {
                links.put(nodeNumber2, links.get(nodeNumber2).add(nodeNumber1));
            } else {
                links.put(nodeNumber2, Arrays.asList(new int[]{nodeNumber1}));
            }
        }
        
        public void addExit (int gatewayIndex) {
            gatewayNumbers.add(gatewayIndex);
        }
        
        public Network build() {
            //Build the network from the nodes...
            Node[] nodes = new Node[nodeCount];
            
            for (int i = 0; i < nodeCount; i++) {
                nodes[i] = new Node(gatewayNumbers.contains(i), i);
            }
            
            for (Node n : nodes) {
                n.linkTo(links.get(n.number));
            }
            return new Network(Arrays.asList(nodes));
        }
    }
    //following definitions for Network and Node left out for brevity
}

Why isn’t it possible to use a OOP approach? Java 1.7 can handle this :wink:

Maybe I’m wrong, but it seems that you declare your class Builder inside the standard class Solution. You need to put it outside the solution class and also you need to remove “public” from your builder-class declaration. It should just be :

class Solution { 
     blablabla
}

class Builder {
     blablabla
}

This works fine for me :slight_smile:

That actually fixed it… Still interesting would be why the nesting doesn’t work…

Maybe I’m wrong, but as your Builder class is a non-static member of your Player class, I think you can’t call its constructor from a static method. There are 2 solutions, depending on what you exactly want to do:

// create a new player p then call p.new instead of new
class Player {
    public static void main(String args[]) {
        Player p = new Player();
        Builder t = p.new Builder();
    }
    
    public class Builder {}
}

// make the Builder class static
class Player {
    public static void main(String args[]) {
        Builder t = new Builder();
    }
    
    public static class Builder {}
}

Both will compile without error.

Interesting… I didn’t think the latter approach would work. I have tried doing this, but I got an error about “this modifier is not allowed in this position” for the static class…

Seems that this was a problem on my side. I apologize for the inconvenience…