import java.util.*; class Game { private final Painter painter; private final int cols; private final int rows; private final int n; private final Board board; private final List players = new ArrayList(); private int currentPlayerIndex; protected final static int DEFAULT_COLS = 8; protected final static int DEFAULT_ROWS = 8; protected final static int DEFAULT_N = 4; Game(Painter painter, int cols, int rows, int n) { this.painter = painter; this.cols = cols; this.rows = rows; this.n = n; this.board = new Board(this); } public void go() { boolean first = true; painter.init(this); while (true) { painter.paint(this); if (board.isWinner()) { showWinner(); break; } if (!first) nextPlayer(); first = false; while (true) { int move = currentPlayer().nextMove(this); if (board.isValidMove(move)) { board.placeMove(move,currentPlayer()); break; } else { note("Invalid move: " + move); } } } } public int getN () { return n; } public Player nextPlayer(Player p) { int nextIndex = (players.indexOf(p)+1)%players.size(); return players.get(nextIndex); } public Board getBoard() { return board; } public Player getSlot(int row, int col) { return board.getSlot(row,col); } public int getNumRows() { return rows; } public int getNumCols() { return cols; } private Player board(int row, int col) { return board.getSlot(row,col); } public Player currentPlayer() { return players.get(currentPlayerIndex); } public void addPlayer(Player p) { players.add(p); } public void removePlayer(Player p) { players.remove(p); } protected void err(Throwable t) { t.printStackTrace(); } protected void note(Object msg) { System.err.println("*** " + msg); } private Player nextPlayer() { currentPlayerIndex = (currentPlayerIndex+1)%players.size(); return currentPlayer(); } private void showWinner() { note("Winner: " + currentPlayer()); painter.showWinner(currentPlayer()); } }