Enums in Karel

Our enum type ServerState has an underlying int type.

The possible values for ServerState are defined as constants. Using enum in Java, we can define these states with specific internal representation.

By implementing the toString method, values of ServerState can be printed out or converted to strings.

Here’s how you can do it in Java:

public enum ServerState {
    IDLE("idle"),
    CONNECTED("connected"),
    ERROR("error"),
    RETRYING("retrying");

    private String stateName;

    ServerState(String stateName) {
        this.stateName = stateName;
    }

    @Override
    public String toString() {
        return this.stateName;
    }
}

If we have a value of type int, we cannot directly manipulate it as a ServerState. This provides some degree of compile-time type safety for enums.

For example:

public class Main {
    public static void main(String[] args) {
        ServerState ns = transition(ServerState.IDLE);
        System.out.println(ns);
      
        ServerState ns2 = transition(ns);
        System.out.println(ns2);
    }

    public static ServerState transition(ServerState s) {
        switch (s) {
            case IDLE:
                return ServerState.CONNECTED;
            case CONNECTED:
            case RETRYING:
                // Suppose we check some predicates here to determine the next state…
                return ServerState.IDLE;
            case ERROR:
                return ServerState.ERROR;
            default:
                throw new IllegalStateException("Unknown state: " + s);
        }
    }
}

To run this program, save the code in Main.java and use the javac compiler and java runtime:

$ javac Main.java
$ java Main
connected
idle

This demonstrates how enums can be used to represent a set of named constants in Java, with the ability to add custom behavior and ensure type safety.