๐Ÿ“ฆ AlistairKeiller / UNIT1

๐Ÿ“„ custompawn.py ยท 111 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111import dataclasses
from dataclasses import dataclass
from enum import Enum
from typing import Iterable, Type

from chessmaker.chess.base.game import AfterTurnChangeEvent
from chessmaker.chess.base.move_option import MoveOption
from chessmaker.chess.base.piece import (
    Piece,
    BeforeMoveEvent,
    AfterMoveEvent,
    BeforeCapturedEvent,
    AfterCapturedEvent,
)
from chessmaker.chess.base.player import Player
from chessmaker.chess.base.position import Position
from chessmaker.chess.piece_utils import iterate_until_blocked, is_in_board
from chessmaker.events import EventPriority, Event, event_publisher
from chessmaker.chess.pieces import Pawn


class CustomPawn(Pawn):
    def _get_move_options(self):
        move_options = []
        non_capture_positions_sideways = list(
            iterate_until_blocked(self, (0, self._direction.value))
        )[:1]
        if (
            len(non_capture_positions_sideways) != 0
            and self.board[non_capture_positions_sideways[-1]].piece is not None
        ):
            non_capture_positions_sideways.pop()
        move_options += [
            MoveOption(position) for position in non_capture_positions_sideways
        ]

        non_capture_positions_sideways = list(
            iterate_until_blocked(self, (-self._direction.value, 0))
        )[:1]
        if (
            len(non_capture_positions_sideways) != 0
            and self.board[non_capture_positions_sideways[-1]].piece is not None
        ):
            non_capture_positions_sideways.pop()
        move_options += [
            MoveOption(position) for position in non_capture_positions_sideways
        ]

        capture_positions = [
            self.position.offset(1, self._direction.value),
            self.position.offset(-1, self._direction.value),
            self.position.offset(-self._direction.value, -self._direction.value),
        ]
        capture_positions = filter(
            lambda position: is_in_board(self.board, position), capture_positions
        )

        for position in capture_positions:
            position_piece = self.board[position].piece
            if position_piece is None:
                above_position, below_position = (
                    Position(position.x, position.y + 1),
                    Position(position.x, position.y - 1),
                )
                if not is_in_board(self.board, above_position) or not is_in_board(
                    self.board, below_position
                ):
                    continue
                squares = self.board[above_position], self.board[below_position]

                for i, square in enumerate(squares):
                    if (
                        square is not None
                        and isinstance(square.piece, Pawn)
                        and square.piece.player != self.player
                        and square.piece._last_position == squares[1 - i].position
                        and 0 <= square.piece._moved_turns_ago <= 1
                    ):
                        move_options.append(
                            MoveOption(
                                position,
                                extra=dict(en_passant=True),
                                captures={square.position},
                            )
                        )
                continue
            elif position_piece.player == self.player:
                continue
            move_options.append(MoveOption(position, captures={position}))

        for move_option in list(move_options):
            position = move_option.position
            last_position_in_column = max(
                filter(lambda square: square.position.x == position.x, self.board),
                key=lambda square: square.position.y * self._direction.value,
            ).position
            last_position_in_row = max(
                filter(lambda square: square.position.y == position.y, self.board),
                key=lambda square: -square.position.x * self._direction.value,
            ).position
            if position == last_position_in_column or position == last_position_in_row:
                move_options.remove(move_option)
                for promotion_name in self.promotions:
                    move_options.append(
                        dataclasses.replace(
                            move_option, extra=dict(promote=promotion_name)
                        )
                    )

        return move_options