Skip to content
Browse files

add game, human and machine players, and illustrator. machine player …

…doesn't work yet
  • Loading branch information...
1 parent 45acc09 commit f2eaa2a90bd86cbd39777ed43905948d7abeb264 Kevin Liddle committed Dec 7, 2011
Showing with 612 additions and 156 deletions.
  1. +39 −37 lib/board.ik
  2. +74 −0 lib/game.ik
  3. +27 −0 lib/human_player.ik
  4. +16 −0 lib/illustrator.ik
  5. +56 −0 lib/machine_player.ik
  6. +3 −0 lib/play_game.ik
  7. +43 −27 lib/rules.ik
  8. +59 −51 spec/board_spec.ik
  9. +76 −0 spec/game_spec.ik
  10. +29 −0 spec/human_player_spec.ik
  11. +31 −0 spec/illustrator_spec.ik
  12. +79 −0 spec/machine_player_spec.ik
  13. +80 −41 spec/rules_spec.ik
View
76 lib/board.ik
@@ -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)
View
74 lib/game.ik
@@ -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..."
+ )
+ )
View
27 lib/human_player.ik
@@ -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)
View
16 lib/illustrator.ik
@@ -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, " ",
+ "?"))
View
56 lib/machine_player.ik
@@ -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
+ )
+ )
View
3 lib/play_game.ik
@@ -0,0 +1,3 @@
+use("lib/game")
+
+Game mimic(3) play
View
70 lib/rules.ik
@@ -1,29 +1,45 @@
Rules = Origin mimic
-Rules 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?)
-
-Rules 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?)
-
-Rules diagonal_winner? = method(board,
- back_diagonal_winner?(board) or forward_diagonal_winner?(board))
-
-Rules back_diagonal_winner? = method(board,
- winning_group?(board dimension, board get_back_diagonal))
-
-Rules forward_diagonal_winner? = method(board,
- winning_group?(board dimension, board get_forward_diagonal))
-
-Rules winning_group? = method(board_dimension, group,
- group select(n, n == group first and n != 0) length == board_dimension)
+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))
View
110 spec/board_spec.ik
@@ -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
+ )
)
-)
View
76 spec/game_spec.ik
@@ -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"
+ )
+ )
View
29 spec/human_player_spec.ik
@@ -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
+ )
+ )
View
31 spec/illustrator_spec.ik
@@ -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"
+ )
+
+ )
View
79 spec/machine_player_spec.ik
@@ -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]
+ ; )
+ )
View
121 spec/rules_spec.ik
@@ -4,45 +4,84 @@ use("lib/board")
describe("Rules",
- it("detects a horizontal win",
- board = Board mimic(3)
- board dimension times(column,
- board reset!
- Rules horizontal_winner?(board) should be false
- board set_space(column,0,1)
- board set_space(column,1,1)
- board set_space(column,2,1)
- Rules horizontal_winner?(board) should be true
- )
- )
-
- it("detects a vertical win",
- board = Board mimic(3)
- board dimension times(row,
- board reset!
- Rules vertical_winner?(board) should be false
- board set_space(0,row,-1)
- board set_space(1,row,-1)
- board set_space(2,row,-1)
- Rules vertical_winner?(board) should be true
+ 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
+ )
)
- )
-
- it("detects a back diagonal win",
- board = Board mimic(3)
- Rules diagonal_winner?(board) should be false
- board set_space(0,0,-1)
- board set_space(1,1,-1)
- board set_space(2,2,-1)
- Rules diagonal_winner?(board) should be true
- )
-
- it("detects a back diagonal win",
- board = Board mimic(3)
- Rules diagonal_winner?(board) should be false
- board set_space(2,0,-1)
- board set_space(1,1,-1)
- board set_space(0,2,-1)
- Rules diagonal_winner?(board) should be true
- )
-)

0 comments on commit f2eaa2a

Please sign in to comment.
Something went wrong with that request. Please try again.