Class: Spinner Responsibilities: getSpin() Collaborations: none Class: Board Responsibilities: getCellAt() checkWinningPosition() Collaborations: Cell Class: Player Responsibilities: takeATurn() checkWon() X getPosition() Collaborations: Spinner Board Cell Class: Cell Responsibilities: getDestination() Collaborations: none Class: Game Responsibilities: X checkEnd() ?? X getCurrentPlayer() startPlaying(); Collaborations: Player
public class Board { private Cell cells[]; public Board() { cells = new Cell[101]; for (int i=1;i < =100;i++) cells[i] = new Cell(i); cells[1].setDestination(38); cells[4].setDestination(14); ... } public Cell getCellAt(int i) { if ((i < 1) || (i > 100) ) return null; return cells[i]; } public boolean checkWinningPosition(int i) { return (i==100); } }Need to add the following responsibility to Cell: setDestination();
public class Game { private Board board; private Player players[]; private int numPlayers; private int currentPlayerIndex; private int moveCount; public Game(int numPlayers) { this.numPlayers = numPlayers; board = new Board(); players = new Player[numPlayers]; for (int i=0;i < numPlayers;i++) players[i] = new Player(board,"Player "+i); } public void startPlaying() { currentPlayerIndex = numPlayers; moveCount = 0; while( ! players[currentPlayerIndex].checkWinningPosition() ) { moveCount++; currentPlayerIndex = (currentPlayerIndex + 1) % numPlayers; players[currentPlayerIndex].takeATurn(); } System.out.println("Player "+currentPlayerIndex+" won on "+ moveCount+" moves"); } }
public class Player { private int currentPosition; private String name; private Cell newCell; private Board board; public Player(Board board, String name) { this.board = board; this.name = name; currentPosition = 0; } public void takeATurn() { newCell = board.getCellAt(currentPosition + Spinner.getSpin()); if (newCell == null) return; currentPosition = newCell.getDestination(); } public boolean checkWon() { return board.checkWon(currentPosition); } }Note: getSpin is a static method of the class Spinner.
Revisions to CRC cards after implementation:
Class: Spinner no change (getSpin made static) Responsibilities: getSpin() Collaborations: none Class: Board no change Responsibilities: getCellAt() checkWinningPosition() Collaborations: Cell Class: Player Added responsibility: getName() Responsibilities: takeATurn() checkWon() X getPosition() Collaborations: Spinner Board Cell Class: Cell Added responsibility: setDestination() Responsibilities: getDestination() Collaborations: none Class: Game Added responsibilities: getMoves(), getWinner() Responsibilities: Added Collaboration: Board X checkEnd() ?? X getCurrentPlayer() startPlaying(); Collaborations: Player
Test Program 1:
class Tester { public static void main(String args[]) { Game g; g = new Game(2); g.startPlaying(); System.out.println("Player "+g.getWinner() + " won in "+ g.getMoves()+" moves."); } }Example output:
Player Player 1 won in 32 moves.
Test Program 2:
class TestMany { public static void main(String args[]) { Game g; int numGames; double sumMoves; double averageMoves; int numMoves; int minMoves; int maxMoves; long startTime; long endTime; long totalTime; if (args.length != 1) { System.out.println("Usage: TestMany n\n"); return; } numGames = Integer.parseInt(args[0]); sumMoves = 0; numMoves = 0; minMoves = Integer.MAX_VALUE; maxMoves = 0; System.out.println("Starting simulation of "+numGames+" games:"); startTime = System.currentTimeMillis(); for (int i=0;i < numGames;i++) { g = new Game(2); g.startPlaying(); numMoves = g.getMoves(); if (minMoves > numMoves) minMoves = numMoves; if (maxMoves < numMoves) maxMoves = numMoves; sumMoves += numMoves; } endTime = System.currentTimeMillis(); totalTime = endTime - startTime; averageMoves = sumMoves/numGames; System.out.println("Statistics generated after "+numGames+ " games:"); System.out.println("Time for simulation: "+(totalTime/1000.0)+" seconds"); System.out.println("Minimum number of moves is "+minMoves); System.out.println("Maximum number of moves is "+maxMoves); System.out.println("Average number of moves is "+averageMoves); } }Sample output:
java -version java version "1.2.1" Solaris VM (build Solaris_JDK_1.2.1_04, native threads, sunwjit) java TestMany 1000000 Starting simulation of 1000000 games: Statistics generated after 1000000 games: Time for simulation: 143.602 seconds Minimum number of moves is 13 Maximum number of moves is 411 Average number of moves is 52.460248
Here is what happens if you turn off the just-in-time compiler:
setenv JAVA_COMPILER NONE java -version java version "1.2.1" Solaris VM (build Solaris_JDK_1.2.1_04, native threads, nojit) java TestMany 1000000 Starting simulation of 1000000 games: Statistics generated after 1000000 games: Time for simulation: 1587.89 seconds Minimum number of moves is 13 Maximum number of moves is 335 Average number of moves is 52.371593This takes 11 times as long.