import java.io.*; import java.util.*; public class TurnManager extends Thread { public static enum Status { Waiting ( "waiting" ), RoleSelect ( "selecting roles" ), Playing ( "playing turn" ), Done ( "game over" ); private String statustext; Status( String s ) { statustext = s; } public String toString() { return statustext; } } public static final int MsgErr = -1; public static final int MsgQuit = 0; public static final int MsgTalk = 1; public Status status; private Vector observers; private Player[] players; private int numplayers; private int numplaying; private Random rnd = null; private boolean gamestarted; private int crown = Roles.unassigned; private int turn; private int[] roles; private String[] rolenames; private void processTurn() { switch (status) { case Waiting: for (Player p : observers) { if (p.connected() && (!p.playing())) { numplaying++; p.setPlaying( true ); players[ firstFreePlayer() ] = p; break; } } if (numplaying == numplayers) { status = Status.Playing; System.out.println( "Players connected. Starting game." ); if (!gamestarted) { gamestarted = true; crown = getRandomPlayer(); turn = crown; System.out.println( getPlayerName( crown ) + " has been crowned " + (rolenames[ Roles.monarch ]).toLowerCase() + "." ); } } break; case RoleSelect: case Playing: processQueue( turn ); break; default: // NOP } } public int getRandomPlayer() { return rnd.nextInt( numplayers ); } public String getPlayerName( int i ) { return players[ i ].getName(); } public int getPlayerIndex( String name ) { int id = -1; for (int i = 0; i < numplayers; i++) { if (name.equals( players[ i ].getName() )) { id = i; break; } } return id; } public int getIndex( Player p ) { int id = -1; for (int i = 0; i < numplayers; i++) { if (p == players[ i ]) { // Yes, in this case, I do actually want ==, not .equals() id = i; break; } } return id; } public boolean playerExists( int idx ) { return (idx <= players.length); } public Player getPlayer( int idx ) { return players[ idx ]; } public TurnManager( Vector obs, int nplayers ) { observers = obs; numplayers = nplayers; numplaying = 0; gamestarted = false; rnd = new Random(); initRoles( "roles.dat" ); players = new Player[ numplayers ]; for (int i = 0; i < numplayers; i++) { players[ i ] = null; } } private void waitForInterrupt( long millis ) { if (! Thread.interrupted() ) { try { sleep( millis ); } catch (InterruptedException e) { // NOP, just exit } } } private int firstFreePlayer() { for (int i = 0; i < numplayers; i++) { if (players[ i ] == null) { return i; } } return -1; } private void initRoles( String filename ) { BufferedReader rfile; String instr; int numroles = Roles.numRoles( numplayers ); roles = new int[ numroles ]; rolenames = new String[ numroles ]; for (int i = 0; i < numroles; i++) { roles[ i ] = Roles.unassigned; } try { rfile = new BufferedReader( new FileReader( filename ) ); int i = 0; while (i < numroles) { instr = rfile.readLine(); if (instr == null) { System.out.println( "End of roles file reached." ); rolenames[ i ] = "role " + i; } else if ((instr.trim()).equals( "" ) || instr.startsWith( "#" )) { continue; } else { rolenames[ i ] = instr.trim(); } i++; } rfile.close(); System.out.println( numroles + " roles initialized." ); } catch (IOException e) { System.out.println( "Error reading roles file." ); for (int i = 0; i < numroles; i++) { if (rolenames[ i ] == null) { rolenames[ i ] = "role " + i; } } } } public String playerFlags( int player ) { StringBuilder s = new StringBuilder(); int numroles = Roles.numRoles( numplayers ); if (player == crown) { s.append( "Player is currently crowned " + (rolenames[ Roles.monarch ]).toLowerCase() + ".\n" ); } for (int i = 0; i < numroles; i++) { if (roles[ i ] == player) { s.append( "Player currently holds role: " + rolenames[ i ] + "\n" ); } } return s.toString(); } private void processQueue( int player ) { // TODO: fill this in! } public void run() { status = Status.Waiting; while (status != Status.Done) { waitForInterrupt( 50 ); processTurn(); } } }