Permalink
Browse files

implemented Game

  • Loading branch information...
1 parent b6c120c commit 2846cfd1fc2df10754a20bdaa501a1e33bf3a5e3 @sl4m committed Nov 25, 2010
Showing with 169 additions and 9 deletions.
  1. +95 −0 TicTacToe-Core/Game.st
  2. +65 −0 TicTacToe-Core/GameTest.st
  3. +5 −5 TicTacToe-Core/Negamax.st
  4. +4 −4 TicTacToe-Core/NegamaxTest.st
View
@@ -0,0 +1,95 @@
+Object subclass: Game [
+ | board ui playerX playerO |
+
+ Game class >> create: newBoard ui: newUi playerX: newPlayerX playerO: newPlayerO [
+ ^self new
+ board: newBoard;
+ ui: newUi;
+ playerX: newPlayerX board: newBoard ui: newUi;
+ playerO: newPlayerO board: newBoard ui: newUi
+ ]
+
+ board [
+ ^board
+ ]
+
+ board: newBoard [
+ board := newBoard.
+ ]
+
+ ui [
+ ^ui
+ ]
+
+ ui: newUi [
+ ui := newUi.
+ ]
+
+ playerX [
+ ^playerX
+ ]
+
+ playerX: newPlayerX board: newBoard ui: newUi [
+ playerX := newPlayerX.
+ playerX board: newBoard;
+ ui: newUi.
+ ]
+
+ playerO [
+ ^playerO
+ ]
+
+ playerO: newPlayerO board: newBoard ui: newUi [
+ playerO := newPlayerO.
+ playerO board: newBoard;
+ ui: newUi.
+ ]
+
+ moveFrom: player [
+ | move |
+ [true]
+ whileTrue: [
+ move := player makeMove.
+ (board isValidMove: move)
+ ifTrue: [^move].
+ ].
+ ]
+
+ makeMove: player [
+ (self board isGameOver)
+ ifFalse: [
+ | playerMove |
+ playerMove := self moveFrom: player.
+ self board move: playerMove piece: player piece.
+ self ui displayBoard: self board list.
+ ].
+ ]
+
+ currentPlayer [
+ (self board movesMade \\ 2 = 0)
+ ifTrue: [^self playerX]
+ ifFalse: [^self playerO].
+ ]
+
+ play [
+ self ui displayBoard: self board list.
+ [self board isGameOver]
+ whileFalse: [
+ self makeMove: self currentPlayer.
+ ].
+ self endOfPlay.
+ ]
+
+ endOfPlay [
+ self displayEndMessage.
+ self ui displayTryAgain.
+ ]
+
+ displayEndMessage [
+ | winner |
+ winner := board winner.
+ (winner = board noWinner)
+ ifTrue: [self ui displayDrawMessage]
+ ifFalse: [self ui displayWinner: winner].
+ ]
+]
View
@@ -1,2 +1,67 @@
TicTacToeTestCase subclass: GameTestCase [
+ | board human negamax game console fakeStdIn fakeStdOut |
+ setUp [
+ fakeStdIn := FakeStdIn new.
+ fakeStdOut := FakeStdOut new.
+ console := Console new.
+ console stdInput: fakeStdIn.
+ console stdOutput: fakeStdOut.
+ board := ThreeByThree new.
+ human := Player create: 'Human' piece: 'X'.
+ negamax := Player create: 'Negamax' piece: 'O'.
+ game := Game create: board ui: console playerX: human playerO: negamax
+ ]
+
+ testPlayersInGame [
+ self assert: (game playerX = human).
+ self assert: (game playerO = negamax).
+ ]
+
+ testBoardInGame [
+ self assert: (game board = board).
+ ]
+
+ testUiInGame [
+ self assert: (game ui = console).
+ ]
+
+ testPlayersHoldBoard [
+ self assert: (game playerX board = board).
+ self assert: (game playerO board = board).
+ ]
+
+ testPlayersHoldUi [
+ self assert: (game playerX ui = console).
+ self assert: (game playerO ui = console).
+ ]
+
+ testMoveForHumanPlayer [
+ | move |
+ move := '1'.
+ fakeStdIn nextLine: move.
+ self assert: ((game moveFrom: human) = 1).
+ ]
+
+ testMoveForNegamaxPlayer [
+ | move |
+ board move: 1 piece: 'X'.
+ move := game moveFrom: negamax.
+ self assert: (negamax bestMoves includes: move).
+ ]
+
+ testMoveForNegamaxPlayer2 [
+ | move |
+ board move: 1 piece: 'O'.
+ board move: 4 piece: 'X'.
+ board move: 5 piece: 'X'.
+
+ self assert: ((game moveFrom: negamax) = 6).
+ ]
+
+ testCurrentPlayer [
+ self assert: ((game currentPlayer) = human).
+ fakeStdIn nextLine: '4'.
+ game makeMove: human.
+ self assert: ((game currentPlayer) = negamax).
+ ]
]
View
@@ -70,13 +70,13 @@ Player subclass: Negamax [
]
bestRandomMove [
- | bestScores randomIndex |
- bestScores := self bestScores.
- randomIndex := (((bestScores size - 1) * (Random new next)) + 1) asInteger.
- ^bestScores at: randomIndex
+ | bestMoves randomIndex |
+ bestMoves := self bestMoves.
+ randomIndex := (((bestMoves size - 1) * (Random new next)) + 1) asInteger.
+ ^bestMoves at: randomIndex
]
- bestScores [
+ bestMoves [
| max indexes counter |
max := self highestScore.
indexes := Array new: (self highestScoreCount).
@@ -112,11 +112,11 @@ TicTacToeTestCase subclass: NegamaxTestCase [
self assert: (player highestScoreCount = 3).
]
- testBestScores [
+ testBestMoves [
| scores |
scores := {2 . 1 . 0 . 1 . 2 . 1 . 2 . 0 . 1}.
player scores: scores.
- self assert: (player bestScores = #(1 5 7)).
+ self assert: (player bestMoves = #(1 5 7)).
]
testBestRandomMove [
@@ -136,7 +136,7 @@ TicTacToeTestCase subclass: NegamaxTestCase [
board move: 4 piece: 'X'.
player makeMove.
- self assert: (#(5 9) = player bestScores).
+ self assert: (#(5 9) = player bestMoves).
]
testMaxMakesWinningMoveScenario2 [
@@ -197,6 +197,6 @@ TicTacToeTestCase subclass: NegamaxTestCase [
board move: 9 piece: 'X'.
player makeMove.
- self assert: (#(3 7) = player bestScores).
+ self assert: (#(3 7) = player bestMoves).
]
]

0 comments on commit 2846cfd

Please sign in to comment.