Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: KevinLiddle/Ioke_TTT
base: dfcc8b286f
...
head fork: KevinLiddle/Ioke_TTT
compare: f2eaa2a90b
  • 2 commits
  • 15 files changed
  • 0 commit comments
  • 1 contributor
Commits on Dec 05, 2011
Kevin Liddle rename game state to rules 45acc09
Commits on Dec 07, 2011
Kevin Liddle add game, human and machine players, and illustrator. machine player …
…doesn't work yet
f2eaa2a
76 lib/board.ik
View
@@ -1,58 +1,60 @@
Board = Origin mimic
Board initialize = method(dimension,
- self dimension = dimension
- self spaces = self initialize_spaces)
+ self dimension = dimension
+ self spaces = self initialize_spaces)
Board initialize_spaces = method(
- row = []
- board_spaces = []
- self dimension times(row << 0)
- self dimension times(board_spaces << deep_list_copy(row))
- board_spaces
- )
-
-Board deep_list_copy = method(template_list,
- target_list = []
- template_list each(elem,
- target_list << elem)
- target_list)
+ row = []
+ board_spaces = []
+ self dimension times(row << 0)
+ self dimension times(board_spaces << row mimic)
+ board_spaces
+ )
Board get_space = method(row, column,
- self spaces[row][column])
+ self spaces[row][column])
Board set_space = method(row, column, player_value,
- self spaces[row][column] = player_value
-)
+ self spaces[row][column] = player_value
+ )
Board blank? = method(
- blank = true
- dimension times(row,
- dimension times(column,
- unless(get_space(row, column) == 0,
- blank = false)))
- blank)
+ blank = true
+ dimension times(row,
+ dimension times(column,
+ unless(get_space(row, column) == 0,
+ blank = false)))
+ blank)
+
+Board full? = method(
+ full = true
+ dimension times(row,
+ dimension times(column,
+ if(get_space(row, column) == 0,
+ full = false)))
+ full)
Board reset! = method(
- self spaces = initialize_spaces)
+ self spaces = initialize_spaces)
Board get_row = method(row_index,
- self spaces[row_index])
+ self spaces[row_index])
Board get_column = method(column_index,
- column = []
- self dimension times(row_index,
- column << get_space(row_index, column_index))
- column)
+ column = []
+ self dimension times(row_index,
+ column << get_space(row_index, column_index))
+ column)
Board get_back_diagonal = method(
- diagonal = []
- self dimension times(index,
- diagonal << get_space(index, index))
- diagonal)
+ diagonal = []
+ self dimension times(index,
+ diagonal << get_space(index, index))
+ diagonal)
Board get_forward_diagonal = method(
- diagonal = []
- self dimension times(index,
- diagonal << get_space(self dimension - 1 - index, index))
- diagonal)
+ diagonal = []
+ self dimension times(index,
+ diagonal << get_space(self dimension - 1 - index, index))
+ diagonal)
74 lib/game.ik
View
@@ -0,0 +1,74 @@
+use("lib/board")
+use("lib/illustrator")
+use("lib/rules")
+use("lib/human_player")
+use("lib/machine_player")
+
+Game = Origin mimic
+
+Game initialize = method(game_type,
+ self board = Board mimic(3)
+ self player1 = nil
+ self player2 = nil
+ cond(
+ game_type == 1, human_vs_human,
+ game_type == 2, machine_vs_human,
+ game_type == 3, human_vs_machine,
+ human_vs_human
+ )
+ )
+
+Game human_vs_human = method(
+ self player1 = HumanPlayer mimic(1)
+ self player2 = HumanPlayer mimic(-1)
+ )
+
+Game machine_vs_human = method(
+ self player1 = MachinePlayer mimic(1)
+ self player2 = HumanPlayer mimic(-1)
+ )
+
+Game human_vs_machine = method(
+ self player1 = HumanPlayer mimic(1)
+ self player2 = MachinePlayer mimic(-1)
+ )
+
+Game play = method(
+ until(Rules game_over?(board),
+ take_turn
+ )
+ display_board
+ game_over_message println
+ )
+
+Game take_turn = method(
+ display_board
+ move = player_by_turn get_move(board)
+ make_move(move[0], move[1])
+ )
+
+Game player_by_turn = method(
+ total_moves = 0
+ self board dimension times(row,
+ self board dimension times(column,
+ if(self board get_space(row, column) != 0,
+ total_moves++)))
+ if(total_moves % 2 == 0,
+ player1,
+ player2)
+ )
+
+Game make_move = method(row, column,
+ if(self board get_space(row, column) == 0,
+ self board set_space(row, column, player_by_turn marker_value)))
+
+Game display_board = method(
+ Illustrator draw(self board) print)
+
+Game game_over_message = method(
+ cond(
+ Rules winner(self board) == 1, "Player 1 wins!",
+ Rules winner(self board) == -1, "Player 2 wins!",
+ Rules winner(self board) == 0, "Cat's Game..."
+ )
+ )
29 lib/game_state.ik
View
@@ -1,29 +0,0 @@
-GameState = Origin mimic
-
-GameState horizontal_winner? = method(board,
- winning_row? = false
- board dimension times(row_index,
- row = board get_row(row_index)
- if(winning_group?(board dimension, row),
- winning_row? = true))
- winning_row?)
-
-GameState vertical_winner? = method(board,
- winning_column? = false
- board dimension times(column_index,
- column = board get_column(column_index)
- if(winning_group?(board dimension, column),
- winning_column? = true))
- winning_column?)
-
-GameState diagonal_winner? = method(board,
- back_diagonal_winner?(board) or forward_diagonal_winner?(board))
-
-GameState back_diagonal_winner? = method(board,
- winning_group?(board dimension, board get_back_diagonal))
-
-GameState forward_diagonal_winner? = method(board,
- winning_group?(board dimension, board get_forward_diagonal))
-
-GameState winning_group? = method(board_dimension, group,
- group select(n, n == group first and n != 0) length == board_dimension)
27 lib/human_player.ik
View
@@ -0,0 +1,27 @@
+HumanPlayer = Origin mimic
+
+HumanPlayer initialize = method(marker_value,
+ self marker_value = marker_value)
+
+HumanPlayer get_move = method(board,
+ move = []
+ bind(
+ handle(Condition Error Arithmetic NotParseable, fn(c, "Please enter a real number...jerk." println))
+ )
+ ["row", "column"] each(position,
+ input = -1
+ until(valid_input?(input, board),
+ prompt_for_move(position, board)
+ input = System in read asText toRational - 1
+ move << input
+ )
+ )
+ move
+ )
+
+HumanPlayer prompt_for_move = method(position, board,
+ "Enter a #{position} (1-#{board dimension}): " print
+ )
+
+HumanPlayer valid_input? = method(input, board,
+ input >= 0 and input < board dimension)
16 lib/illustrator.ik
View
@@ -0,0 +1,16 @@
+Illustrator = Origin mimic
+
+Illustrator draw = method(board,
+ illustration = ""
+ board spaces each(row,
+ row each(space,
+ illustration += "[" + space_marker(space) + "]")
+ illustration += "\n")
+ illustration)
+
+Illustrator space_marker = method(space_value,
+ cond(
+ space_value == 1, "X",
+ space_value == -1, "O",
+ space_value == 0, " ",
+ "?"))
56 lib/machine_player.ik
View
@@ -0,0 +1,56 @@
+use("lib/board")
+
+MachinePlayer = Origin mimic
+
+MachinePlayer initialize = method(marker_value,
+ self marker_value = marker_value
+ )
+
+MachinePlayer get_move = method(board,
+ if(board get_space(middle_of_board(board), middle_of_board(board)) == 0,
+ [middle_of_board(board), middle_of_board(board)],
+ minimax(board, marker_value, 1) keys first
+ )
+ )
+; DOES NOT WORK YET. need to compare weights based on player value
+MachinePlayer minimax = method(board, turn, depth,
+ best_move = {}
+ board dimension times(row,
+ board dimension times(column,
+ if(board get_space(row, column) == 0,
+ board set_space(row, column, turn)
+ if(Rules game_over?(board),
+ if(best_move == {} or better_than_best?(inverse(Rules winner(board) * (depth + 1)), best_move[best_move keys first]),
+ best_move = { [row, column] => inverse( Rules winner(board) * (depth + 1) ) }
+ )
+ ,
+ next_level_best_move = minimax(board, turn negation, depth + 1)
+ next_move = { [row, column] => next_level_best_move[next_level_best_move keys first] }
+ if( best_move == {} or better_than_best?(next_move[next_move keys first], best_move[best_move keys first]),
+ best_move = next_move
+ )
+ )
+ board set_space(row, column, 0)
+ )
+ )
+ )
+ best_move
+ )
+
+MachinePlayer better_than_best? = method(score, best_move_score,
+ if(marker_value > 0,
+ score > best_move_score,
+ score < best_move_score
+ )
+ )
+
+MachinePlayer middle_of_board = method(board,
+ (board dimension - (board dimension % 2)) / 2 ; Ioke doesn't have Integer divsion or rounding. performing (3/2) will yield a "Ratio" of 3/2, which you can't do much with
+ )
+
+MachinePlayer inverse = method(value,
+ if(value != 0,
+ 1 / value,
+ 0
+ )
+ )
3  lib/play_game.ik
View
@@ -0,0 +1,3 @@
+use("lib/game")
+
+Game mimic(3) play
45 lib/rules.ik
View
@@ -0,0 +1,45 @@
+Rules = Origin mimic
+
+Rules winner_of_group = method(board_dimension, group,
+ common_group = group select(n, n == group first and n != 0)
+ if(common_group length == board_dimension,
+ common_group first,
+ 0
+ ))
+
+Rules horizontal_winner = method(board,
+ winning_marker = 0
+ board dimension times(row_index,
+ row = board get_row(row_index)
+ if(winner_of_group(board dimension, row) != 0,
+ winning_marker = winner_of_group(board dimension, row)))
+ winning_marker)
+
+Rules vertical_winner = method(board,
+ winning_marker = 0
+ board dimension times(column_index,
+ column = board get_column(column_index)
+ if(winner_of_group(board dimension, column) != 0,
+ winning_marker = winner_of_group(board dimension, column)))
+ winning_marker)
+
+Rules diagonal_winner = method(board,
+ back_diagonal_winner(board) | forward_diagonal_winner(board))
+
+Rules back_diagonal_winner = method(board,
+ winner_of_group(board dimension, board get_back_diagonal))
+
+Rules forward_diagonal_winner = method(board,
+ winner_of_group(board dimension, board get_forward_diagonal))
+
+Rules winner = method(board,
+ horizontal_winner(board) | vertical_winner(board) | diagonal_winner(board))
+
+Rules winner? = method(board,
+ winner(board) != 0)
+
+Rules cats_game? = method(board,
+ board full? and winner?(board) not)
+
+Rules game_over? = method(board,
+ cats_game?(board) or winner?(board))
110 spec/board_spec.ik
View
@@ -3,62 +3,70 @@ use("lib/board")
describe("Board",
- it("can be initialized",
- board = Board mimic(3)
- board dimension should == 3
- )
+ before(board = Board mimic(3))
- it("initializes board with values of 0",
- board = Board mimic(3)
- 3 times(row,
- 3 times(column,
- board get_space(row, column) should == 0))
- )
+ it("can be initialized",
+ board dimension should == 3
+ )
- it("can set board spaces",
- board = Board mimic(3)
- board get_space(0,0) should == 0
- board set_space(0,0,1)
- board get_space(0,0) should == 1
- board get_space(1,0) should == 0
- )
+ it("initializes board with values of 0",
+ 3 times(row,
+ 3 times(column,
+ board get_space(row, column) should == 0))
+ )
- it("resets the board",
- board = Board mimic(3)
- board blank? should be true
- board set_space(0,0,1)
- board blank? should be false
- board reset!
- board blank? should be true
- )
+ it("can set board spaces",
+ board get_space(0,0) should == 0
+ board set_space(0,0,1)
+ board get_space(0,0) should == 1
+ board get_space(1,0) should == 0
+ )
- it("grabs a given row",
- board = Board mimic(3)
- board set_space(0,0,1)
- board set_space(0,1,-1)
- board get_row(0) should == [1, -1, 0]
- )
+ it("resets the board",
+ board blank? should be true
+ board set_space(0,0,1)
+ board blank? should be false
+ board reset!
+ board blank? should be true
+ )
- it("grabs a given column",
- board = Board mimic(3)
- board set_space(0,0,1)
- board set_space(1,0,-1)
- board get_column(0) should == [1, -1, 0]
- )
+ it("grabs a given row",
+ board set_space(0,0,1)
+ board set_space(0,1,-1)
+ board get_row(0) should == [1, -1, 0]
+ )
- it("grabs a back diagonal",
- board = Board mimic(3)
- board set_space(0,0,1)
- board set_space(1,1,-1)
- board get_back_diagonal should == [1, -1, 0]
- )
+ it("grabs a given column",
+ board set_space(0,0,1)
+ board set_space(1,0,-1)
+ board get_column(0) should == [1, -1, 0]
+ )
+
+ it("grabs a back diagonal",
+ board set_space(0,0,1)
+ board set_space(1,1,-1)
+ board get_back_diagonal should == [1, -1, 0]
+ )
+
+ it("grabs a forward diagonal",
+ board set_space(0,2,1)
+ board set_space(1,1,-1)
+ board set_space(2,0,-1)
+ board get_back_diagonal should == [0, -1, 0]
+ board get_forward_diagonal should == [-1, -1, 1]
+ )
- it("grabs a forward diagonal",
- board = Board mimic(3)
- board set_space(0,2,1)
- board set_space(1,1,-1)
- board set_space(2,0,-1)
- board get_back_diagonal should == [0, -1, 0]
- board get_forward_diagonal should == [-1, -1, 1]
+ it("detects a full board",
+ board full? should be false
+ board set_space(0,0,1)
+ board set_space(0,1,-1)
+ board set_space(0,2,-1)
+ board set_space(1,0,1)
+ board set_space(1,1,-1)
+ board set_space(1,2,-1)
+ board set_space(2,0,1)
+ board set_space(2,1,-1)
+ board set_space(2,2,-1)
+ board full? should be true
+ )
)
-)
76 spec/game_spec.ik
View
@@ -0,0 +1,76 @@
+use("ispec")
+use("lib/game")
+
+describe("Game",
+
+ before(game = Game mimic(1))
+
+ it("initializes a game with a board",
+ game board should not be nil
+ )
+
+ it("initializes a human vs. human game with game type 1",
+ game player1 kind should == "HumanPlayer"
+ )
+
+ it("draws the board when game is started",
+ Game should receive display_board
+ game player1 should receive get_move(game board) andReturn([2,1])
+ game take_turn
+ )
+
+ it("knows whose turn it is",
+ game player_by_turn should == game player1
+ game board set_space(0,0,1)
+ game player_by_turn should == game player2
+ )
+
+ it("makes a move",
+ game make_move(2, 1)
+ game board get_space(2, 1) should == 1
+ )
+
+ it("creates a game over message for player 1 win",
+ game board set_space(0,0,1)
+ game board set_space(0,1,1)
+ game board set_space(0,2,1)
+ game game_over_message should == "Player 1 wins!"
+ )
+
+ it("creates a game over message for player 2 win",
+ game board set_space(0,0,-1)
+ game board set_space(0,1,-1)
+ game board set_space(0,2,-1)
+ game game_over_message should == "Player 2 wins!"
+ )
+
+ it("creates a game over message for a Cat's game",
+ game board set_space(0,0,1)
+ game board set_space(0,1,1)
+ game board set_space(0,2,-1)
+ game board set_space(1,0,-1)
+ game board set_space(1,1,-1)
+ game board set_space(1,2,1)
+ game board set_space(2,0,1)
+ game board set_space(2,1,-1)
+ game board set_space(2,2,1)
+ game game_over_message should == "Cat's Game..."
+ )
+
+ it("creates 2 human players for game type 1",
+ game player1 kind should == "HumanPlayer"
+ game player2 kind should == "HumanPlayer"
+ )
+
+ it("creates 1 machine player and 1 human player for game type 2",
+ game1 = Game mimic(2)
+ game1 player1 kind should == "MachinePlayer"
+ game1 player2 kind should == "HumanPlayer"
+ )
+
+ it("creates 1 human player and 1 machine player for game type 3",
+ game2 = Game mimic(3)
+ game2 player1 kind should == "HumanPlayer"
+ game2 player2 kind should == "MachinePlayer"
+ )
+ )
48 spec/game_state_spec.ik
View
@@ -1,48 +0,0 @@
-use("ispec")
-use("lib/game_state")
-use("lib/board")
-
-describe("GameState",
-
- it("detects a horizontal win",
- board = Board mimic(3)
- board dimension times(column,
- board reset!
- GameState horizontal_winner?(board) should be false
- board set_space(column,0,1)
- board set_space(column,1,1)
- board set_space(column,2,1)
- GameState horizontal_winner?(board) should be true
- )
- )
-
- it("detects a vertical win",
- board = Board mimic(3)
- board dimension times(row,
- board reset!
- GameState vertical_winner?(board) should be false
- board set_space(0,row,-1)
- board set_space(1,row,-1)
- board set_space(2,row,-1)
- GameState vertical_winner?(board) should be true
- )
- )
-
- it("detects a back diagonal win",
- board = Board mimic(3)
- GameState diagonal_winner?(board) should be false
- board set_space(0,0,-1)
- board set_space(1,1,-1)
- board set_space(2,2,-1)
- GameState diagonal_winner?(board) should be true
- )
-
- it("detects a back diagonal win",
- board = Board mimic(3)
- GameState diagonal_winner?(board) should be false
- board set_space(2,0,-1)
- board set_space(1,1,-1)
- board set_space(0,2,-1)
- GameState diagonal_winner?(board) should be true
- )
-)
29 spec/human_player_spec.ik
View
@@ -0,0 +1,29 @@
+use("ispec")
+use("lib/human_player")
+
+describe("HumanPlayer",
+
+ before(
+ player = HumanPlayer mimic(1)
+ board = Board mimic(3)
+ )
+
+ it("can be initialized with a marker value",
+ player marker_value should == 1
+ )
+
+ it("gets input from user for a move",
+ player should receive prompt_for_move("row", board)
+ player should receive prompt_for_move("column", board)
+ System in should receive read andReturn("2") twice
+ player get_move(board) should == [1, 1]
+ )
+
+ it("knows what moves are valid",
+ player valid_input?(2, board) should be true
+ player valid_input?(1, board) should be true
+ player valid_input?(0, board) should be true
+ player valid_input?(3, board) should be false
+ player valid_input?(-1, board) should be false
+ )
+ )
31 spec/illustrator_spec.ik
View
@@ -0,0 +1,31 @@
+use("ispec")
+use("lib/illustrator")
+
+describe("Illustrator",
+
+ before(board = Board mimic(3))
+
+ it("can draw a blank board",
+ Illustrator draw(board) should == "[ ][ ][ ]\n[ ][ ][ ]\n[ ][ ][ ]\n"
+ )
+
+ it("draws an X for player value 1",
+ board set_space(0,0,1)
+ Illustrator draw(board) should == "[X][ ][ ]\n[ ][ ][ ]\n[ ][ ][ ]\n"
+ )
+
+ it("draws an O for player value -1",
+ board set_space(0,0,-1)
+ Illustrator draw(board) should == "[O][ ][ ]\n[ ][ ][ ]\n[ ][ ][ ]\n"
+ )
+
+ it("draws a partially filled in board",
+ board set_space(0,0,-1)
+ board set_space(1,0,1)
+ board set_space(2,1,-1)
+ board set_space(2,2,1)
+ board set_space(0,1,-1)
+ Illustrator draw(board) should == "[O][O][ ]\n[X][ ][ ]\n[ ][O][X]\n"
+ )
+
+ )
79 spec/machine_player_spec.ik
View
@@ -0,0 +1,79 @@
+use("ispec")
+use("lib/machine_player")
+
+describe("MachinePlayer",
+
+ before(
+ player = MachinePlayer mimic(1)
+ board = Board mimic(3)
+ )
+
+ it("can be initialized with a marker value",
+ player marker_value should == 1
+ )
+
+ it("calculates the inverse of a number",
+ MachinePlayer inverse(4) should == 1/4
+ MachinePlayer inverse(-4) should == -1/4
+ MachinePlayer inverse(0) should == 0
+ )
+
+ it("compares scores based on the player's marker value",
+ player better_than_best?(1/3, -1/8) should be true
+ MachinePlayer mimic(-1) better_than_best?(1/3, -1/8) should be false
+ )
+
+ it("returns the index of the middle of the board",
+ MachinePlayer middle_of_board(board) should == 1
+ MachinePlayer middle_of_board(Board mimic(10)) should == 5
+ MachinePlayer middle_of_board(Board mimic(17)) should == 8
+ )
+
+ ; it("will pick the middle if available",
+ ; player get_move(board) should == [1,1]
+ ; )
+
+ ; it("will win if it can",
+ ; board set_space(0,0,1)
+ ; board set_space(0,1,-1)
+ ; board set_space(1,1,1)
+ ; board set_space(0,2,-1)
+ ; player get_move(board) should == [2,2]
+ ; )
+
+ it("blocks when it should",
+ board set_space(0,0,-1)
+ board set_space(1,1,1)
+ board set_space(1,0,-1)
+ player get_move(board) should == [2,0]
+ )
+
+ ; it("*********************",
+ ; board set_space(0,0,-1)
+ ; board set_space(1,1,1)
+ ; board set_space(1,0,-1)
+ ; player get_move(board) should == [2,0]
+ ; )
+
+ ; it("wins an easy one",
+ ; board set_space(0,0,-1)
+ ; board set_space(0,1,1)
+ ; board set_space(0,2,-1)
+ ; board set_space(1,0,-1)
+ ; board set_space(1,1,1)
+ ; board set_space(1,2,-1)
+ ; board set_space(2,0,1)
+ ; player get_move(board) should == [2,1]
+ ; )
+
+ ; it("blocks an easy one",
+ ; board set_space(0,0,1)
+ ; board set_space(0,1,-1)
+ ; board set_space(0,2,1)
+ ; board set_space(1,0,-1)
+ ; board set_space(1,1,-1)
+ ; board set_space(2,0,-1)
+ ; board set_space(2,1,1)
+ ; player get_move(board) should == [1,2]
+ ; )
+ )
87 spec/rules_spec.ik
View
@@ -0,0 +1,87 @@
+use("ispec")
+use("lib/rules")
+use("lib/board")
+
+describe("Rules",
+
+ before(board = Board mimic(3))
+
+ it("detects a horizontal win",
+ board dimension times(column,
+ board reset!
+ Rules winner?(board) should be false
+ board set_space(column,0,1)
+ board set_space(column,1,1)
+ board set_space(column,2,1)
+ Rules winner?(board) should be true
+ Rules winner(board) should == 1
+ )
+ )
+
+ it("detects a vertical win",
+ board dimension times(row,
+ board reset!
+ Rules winner?(board) should be false
+ board set_space(0,row,-1)
+ board set_space(1,row,-1)
+ board set_space(2,row,-1)
+ Rules winner?(board) should be true
+ Rules winner(board) should == -1
+ )
+ )
+
+ it("detects a back diagonal win",
+ Rules winner?(board) should be false
+ board set_space(0,0,-1)
+ board set_space(1,1,-1)
+ board set_space(2,2,-1)
+ Rules winner?(board) should be true
+ Rules winner(board) should == -1
+ )
+
+ it("detects a back diagonal win",
+ Rules winner?(board) should be false
+ board set_space(2,0,-1)
+ board set_space(1,1,-1)
+ board set_space(0,2,-1)
+ Rules winner?(board) should be true
+ Rules winner(board) should == -1
+ )
+
+ it("detects a cat's game",
+ Rules cats_game?(board) should be false
+ board set_space(0,0,1)
+ board set_space(0,1,1)
+ board set_space(0,2,-1)
+ board set_space(1,0,-1)
+ board set_space(1,1,-1)
+ board set_space(1,2,1)
+ board set_space(2,0,1)
+ board set_space(2,1,-1)
+ board set_space(2,2,1)
+ Rules cats_game?(board) should be true
+ Rules winner(board) should == 0
+ )
+
+ it("detects a game over by cats game or a winner",
+ Rules game_over?(board) should be false
+ board set_space(0,0,1)
+ board set_space(0,1,1)
+ board set_space(0,2,-1)
+ board set_space(1,0,-1)
+ board set_space(1,1,-1)
+ board set_space(1,2,1)
+ board set_space(2,0,1)
+ board set_space(2,1,-1)
+ board set_space(2,2,1)
+ Rules game_over?(board) should be true
+ Rules winner(board) should == 0
+ board reset!
+ Rules game_over?(board) should be false
+ board set_space(0,0,1)
+ board set_space(0,1,1)
+ board set_space(0,2,1)
+ Rules game_over?(board) should be true
+ Rules winner(board) should == 1
+ )
+ )

No commit comments for this range

Something went wrong with that request. Please try again.