From 046ce9445f826f4a23eeabf5f3b9ba19bafa75d1 Mon Sep 17 00:00:00 2001 From: "Giannis (Ioannis) Pantidis" <40605232+AttackingOrDefending@users.noreply.github.com> Date: Sun, 29 Sep 2024 15:26:38 +0200 Subject: [PATCH] Fix ambiguous moves (#43) * Add files via upload * Add files via upload --- draughts/core/variant.py | 42 ++++++++++++++----------- test_pydraughts/test_ambiguous_moves.py | 16 ++++++++++ 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/draughts/core/variant.py b/draughts/core/variant.py index e90512d9..8133d5c1 100644 --- a/draughts/core/variant.py +++ b/draughts/core/variant.py @@ -209,7 +209,8 @@ def _from_board(self, hub_move: Optional[str] = None, hub_position_move: Optiona possible_steps_move = [possible_move[0][0]] for semi_move in possible_move: possible_steps_move.append(semi_move[1]) - moves_with_same_start_end_and_captures.append(possible_steps_move) + if possible_captures == self.captures: + moves_with_same_start_end_and_captures.append(possible_steps_move) self.ambiguous = same_start_ends >= 2 if self.ambiguous: # From FMJD (https://pdn.fmjd.org/grammar.html#pdn-3-0-grammar): @@ -223,23 +224,28 @@ def _from_board(self, hub_move: Optional[str] = None, hub_position_move: Optiona # pydraughts supports providing a square not immediately behind the captured piece, but when we # convert it to a PDN move, we have to change it to the square immediately behind the captured piece. correct_start_ends = [] - for index in range(1, len(steps_move) - 1): - closest_distance = 1000 - - for steps_move in moves_with_same_start_end_and_captures: - distance = abs(steps_move[index - 1] - steps_move[index]) - - # New closest square - if distance < closest_distance: - closest_distance = distance - correct_start_ends = [steps_move] - # The same intermediate square. - # This means that the difference is in a later intermediate square. - elif distance == closest_distance: - correct_start_ends.append(steps_move) - moves_with_same_start_end_and_captures = correct_start_ends - - correct_move = correct_start_ends[0] + # If it is equal to 1 then there are other moves with the same start and end, but not the same captures. + # This can happen in russian draughts. + if len(moves_with_same_start_end_and_captures) > 1: + for index in range(1, len(steps_move) - 1): + closest_distance = 1000 + + for possible_steps_move in moves_with_same_start_end_and_captures: + distance = abs(possible_steps_move[index - 1] - possible_steps_move[index]) + + # New closest square + if distance < closest_distance: + closest_distance = distance + correct_start_ends = [possible_steps_move] + # The same intermediate square. + # This means that the difference is in a later intermediate square. + elif distance == closest_distance: + correct_start_ends.append(possible_steps_move) + moves_with_same_start_end_and_captures = correct_start_ends + + correct_move = correct_start_ends[0] + else: + correct_move = steps_move pdn_position_move = "".join(list(map(self._make_len_2, correct_move))) else: diff --git a/test_pydraughts/test_ambiguous_moves.py b/test_pydraughts/test_ambiguous_moves.py index d833a248..1cac3658 100644 --- a/test_pydraughts/test_ambiguous_moves.py +++ b/test_pydraughts/test_ambiguous_moves.py @@ -6,3 +6,19 @@ def test_ambiguous_move(): big_move = [[47, 33], [33, 24], [24, 13], [13, 36]] move_move = Move(game, big_move) assert move_move.pdn_move == "47x38x24x13x36" # Not "47x33x24x13x36" + + board = Board("russian", fen="W:WKd2:Bf6,c5,e5,e3:H0:F1") + legal_moves = list(map(lambda m: m.pdn_move, board.legal_moves())) + assert legal_moves == ['6x15x22x13', '6x15x22x9', '6x20x27x13', '6x20x27x9'] + + board = Board("russian", fen="W:We3,g3,h4,a5,b2,h2,a3,Kf8:Bc5,e5,g5,g7,h8") + legal_moves = list(map(lambda m: m.pdn_move, board.legal_moves())) + assert legal_moves == ['31x13', '31x24x15x22x13', '16x21'] + + board = Board("russian", fen="W:WKd2:Bc5,e5,c3,e3:H0:F1") + legal_moves = list(map(lambda m: m.pdn_move, board.legal_moves())) + assert legal_moves == ['6x13x22x15x6', '6x2', '6x15x22x13x6', '6x3'] + + board = Board(fen="W:WK38:B18,19,32,33:H0:F1") + legal_moves = list(map(lambda m: m.pdn_move, board.legal_moves())) + assert legal_moves == ['38x27x13x24x38', '38x42', '38x47', '38x24x13x27x38', '38x43', '38x49']