From b6524b4fe271174522ada900790d5647eacfc3a7 Mon Sep 17 00:00:00 2001 From: Rory Heim Date: Mon, 6 May 2019 18:54:01 -0700 Subject: [PATCH 1/2] Fix issue with slow boards ko violation --- code/dlgo/goboard_slow.py | 21 +++++++++++++- code/dlgo/goboard_test.py | 61 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/code/dlgo/goboard_slow.py b/code/dlgo/goboard_slow.py index fb7f9cac..549aa85e 100644 --- a/code/dlgo/goboard_slow.py +++ b/code/dlgo/goboard_slow.py @@ -213,10 +213,29 @@ def does_move_violate_ko(self, player, move): next_board.place_stone(player, move.point) next_situation = (player.other, next_board) past_state = self.previous_state + + # Assume ko is violated. + ko_violated = True + while past_state is not None: - if past_state.situation == next_situation: + past_board = past_state.situation[1] + next_board = next_situation[1] + + for row in range(self.board.num_rows, 0, -1): + for col in range(1, self.board.num_cols + 1): + past_stone = past_board.get(Point(row=row, col=col)) + next_stone = next_board.get(Point(row=row, col=col)) + + # If a point/player between the boards don't match, ko is + # not violated. + if past_stone != next_stone: + ko_violated = False + + if ko_violated: return True + past_state = past_state.previous_state + return False # end::is_ko[] diff --git a/code/dlgo/goboard_test.py b/code/dlgo/goboard_test.py index feb4f2b0..2bcfada5 100644 --- a/code/dlgo/goboard_test.py +++ b/code/dlgo/goboard_test.py @@ -76,6 +76,67 @@ def test_empty_triangle(self): [Point(3, 2), Point(2, 3), Point(1, 3)], black_string.liberties) + def test_GameState_does_move_violate_ko(self): + # Testing Figures 3.5-3.7. + game = GameState.new_game(6) + board = game.board + board.place_stone(Player.black, Point(1, 2)) + board.place_stone(Player.black, Point(1, 3)) + board.place_stone(Player.white, Point(1, 4)) + board.place_stone(Player.white, Point(1, 6)) + board.place_stone(Player.black, Point(2, 2)) + board.place_stone(Player.white, Point(2, 3)) + board.place_stone(Player.black, Point(2, 4)) + board.place_stone(Player.black, Point(2, 5)) + board.place_stone(Player.white, Point(2, 6)) + board.place_stone(Player.black, Point(3, 2)) + board.place_stone(Player.white, Point(3, 3)) + board.place_stone(Player.white, Point(3, 4)) + board.place_stone(Player.white, Point(3, 5)) + + next_player, _ = game.situation + self.assertTrue(next_player, Player.black) + + move = Move(Point(1, 5), is_pass=False, is_resign=False) + self.assertFalse(game.does_move_violate_ko(Player.black, move)) + move = move.play(Point(1, 5)) + game = game.apply_move(move) + + next_player, _ = game.situation + self.assertTrue(next_player, Player.white) + + # Verify white can play at 1,4. + move = Move(Point(1, 4), is_pass=False, is_resign=False) + self.assertFalse(game.does_move_violate_ko(Player.white, move)) + move = move.play(Point(1, 4)) + game = game.apply_move(move) + + # Testing a real Ko. Figure 2.5 + game = GameState.new_game(5) + board = game.board + board.place_stone(Player.black, Point(2, 2)) + board.place_stone(Player.black, Point(3, 1)) + board.place_stone(Player.white, Point(3, 2)) + board.place_stone(Player.black, Point(3, 3)) + board.place_stone(Player.white, Point(4, 1)) + board.place_stone(Player.white, Point(4, 3)) + board.place_stone(Player.white, Point(5, 2)) + + # Have black capture 4,2. + next_player, _ = game.situation + self.assertTrue(next_player, Player.black) + + move = Move(Point(4, 2), is_pass=False, is_resign=False) + self.assertFalse(game.does_move_violate_ko(Player.black, move)) + move = move.play(Point(4, 2)) + game = game.apply_move(move) + + # Have white break Ko rule. + next_player, _ = game.situation + self.assertTrue(next_player, Player.white) + move = Move(Point(3, 2), is_pass=False, is_resign=False) + move = move.play(Point(3, 2)) + self.assertTrue(game.does_move_violate_ko(Player.white, move)) class GameTest(unittest.TestCase): def test_new_game(self): From 5d0fde79b5f1b52d458a5f63463c4737e9e18bb1 Mon Sep 17 00:00:00 2001 From: Rory Heim Date: Mon, 6 May 2019 19:01:41 -0700 Subject: [PATCH 2/2] Clean up --- code/dlgo/goboard_slow.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/dlgo/goboard_slow.py b/code/dlgo/goboard_slow.py index 549aa85e..13417122 100644 --- a/code/dlgo/goboard_slow.py +++ b/code/dlgo/goboard_slow.py @@ -214,10 +214,10 @@ def does_move_violate_ko(self, player, move): next_situation = (player.other, next_board) past_state = self.previous_state - # Assume ko is violated. - ko_violated = True - while past_state is not None: + # Assume ko is violated. + ko_violated = True + past_board = past_state.situation[1] next_board = next_situation[1] @@ -226,7 +226,7 @@ def does_move_violate_ko(self, player, move): past_stone = past_board.get(Point(row=row, col=col)) next_stone = next_board.get(Point(row=row, col=col)) - # If a point/player between the boards don't match, ko is + # If a point/player between the boards does not match, ko is # not violated. if past_stone != next_stone: ko_violated = False