Skip to content

Commit

Permalink
Fix ambiguous moves (#43)
Browse files Browse the repository at this point in the history
* Add files via upload

* Add files via upload
  • Loading branch information
AttackingOrDefending authored Sep 29, 2024
1 parent 29bd429 commit 046ce94
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 18 deletions.
42 changes: 24 additions & 18 deletions draughts/core/variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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:
Expand Down
16 changes: 16 additions & 0 deletions test_pydraughts/test_ambiguous_moves.py
Original file line number Diff line number Diff line change
Expand Up @@ -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']

0 comments on commit 046ce94

Please # to comment.