Exemplo n.º 1
0
    def possible_moves(self):
        x, y = self.square
        # typical one hop moves
        moves = list(
            map(
                lambda square: Move.typical(
                    self.board, piece=self, new_square=square),
                filter(
                    # Either no piece or enemy piece to capture
                    lambda square: square and (not self.board[
                        square] or self.board[square].player != self.player),
                    (Square(x + 1, y), Square(x, y + 1), Square(x + 1, y + 1),
                     Square(x - 1, y + 1), Square(x - 1, y), Square(x, y - 1),
                     Square(x + 1, y - 1), Square(x - 1, y - 1)))))

        # castling moves
        king_side_castle = self.king_side_castle()
        if king_side_castle:
            moves.append(king_side_castle)

        queen_side_castle = self.queen_side_castle()
        if queen_side_castle:
            moves.append(queen_side_castle)

        return moves
Exemplo n.º 2
0
 def attack_squares(self):
     x, y = self.square
     right_square = Square(x + 1, y -
                           1) if self.player == Player.WHITE else Square(
                               x + 1, y + 1)
     left_square = Square(x - 1, y -
                          1) if self.player == Player.WHITE else Square(
                              x - 1, y + 1)
     return list(
         filter(
             # Either no piece or enemy piece to capture
             lambda square: square and (not self.board[
                 square] or self.board[square].player != self.player),
             [left_square, right_square]))
Exemplo n.º 3
0
    def develop(self,
                min_percent: Optional[float] = None,
                max_percent: Optional[float] = None) -> None:
        starting_square = Square(self.starting_point.x, self.starting_point.y,
                                 self.current_generation)
        self.squares[starting_square.x][starting_square.y] = starting_square
        self.__not_reproduced_squares.append([starting_square])

        minp_exists = min_percent is not None
        maxp_exists = max_percent is not None
        pass_once = True

        while minp_exists or maxp_exists or pass_once:

            while self.__not_reproduced_squares != deque(
                [[]]) and self.count <= self.max_count:
                self.__develop_one_generation()
                if maxp_exists:
                    if self.count / self.max_count >= max_percent:
                        break

            pass_once = False
            print()

            if maxp_exists:
                if self.count / self.max_count >= max_percent:
                    break
                else:
                    self.__destroy()

            if minp_exists:
                if self.count / self.max_count >= min_percent:
                    break
                else:
                    self.__destroy()
Exemplo n.º 4
0
    def handle_click(self, pos):
        if self._promotion_move:  # Handle promotion
            piece_cls = get_promotion_selection(pos)
            if piece_cls:
                self._promotion_move.new_piece = piece_cls(
                    self._promotion_move.player, self._board)
                self.make_move(self._promotion_move)
                self._promotion_move = None
                self._selected_piece = None
            return

        pos = pos[0] - BOARD_LEFT, pos[1] - BOARD_TOP
        if 0 <= pos[0] < BOARD_WIDTH and 0 <= pos[1] < BOARD_HEIGHT:
            clicked_square = Square(pos[0] // SQUARE, pos[1] // SQUARE)
            if self._selected_piece:  # if piece already selected
                if self._board[clicked_square] and self._board[
                        clicked_square].player == self._turn:
                    self._selected_piece = self._board[
                        clicked_square]  # if player's on own piece, change selection
                else:
                    move = self.get_move(self._selected_piece, clicked_square)
                    if move:
                        if move.pawn_promoted:  # Wait for user to make a choice
                            self._promotion_move = move
                        else:  # Make a move if not for promotion
                            self.make_move(move)
                        self._selected_piece = None
            else:  # if no piece was selected, select the piece on the square (if any) if belongs to (turn's) player
                if self._board[clicked_square] and self._board[
                        clicked_square].player == self._turn:
                    self._selected_piece = self._board[clicked_square]
Exemplo n.º 5
0
	def attack_squares(self):
		x, y = self.square
		squares = []
		for direction in [
			[Square(x - i, y - i) for i in range(1, min(x + 1, y + 1))],
			[Square(x + i, y + i) for i in range(1, min(8 - x, 8 - y))],
			[Square(x + i, y - i) for i in range(1, min(8 - x, y + 1))],
			[Square(x - i, y + i) for i in range(1, min(x + 1, 8 - y))],
		]:
			for square in direction:
				if not self.board[square]:  # if nothing in pathway
					squares.append(square)
					continue
				if self.board[square].player != self.player:  # if enemy in pathway
					squares.append(square)
				break
		return squares
Exemplo n.º 6
0
 def attack_squares(self):
     x, y = self.square
     squares = []
     for direction in [
         [Square(i, y) for i in reversed(range(0, x))],
         [Square(i, y) for i in range(x + 1, 8)],
         [Square(x, j) for j in reversed(range(0, y))],
         [Square(x, j) for j in range(y + 1, 8)],
     ]:
         for square in direction:
             if not self.board[square]:  # if nothing in pathway
                 squares.append(square)
                 continue
             if self.board[
                     square].player != self.player:  # if enemy in pathway
                 squares.append(square)
             break
     return squares
Exemplo n.º 7
0
 def attack_squares(self):
     x, y = self.square
     # typical one hop moves
     return list(
         filter(
             # Either no piece or enemy piece to capture
             lambda square: square and (not self.board[
                 square] or self.board[square].player != self.player),
             (Square(x + 1, y), Square(x, y + 1), Square(x + 1, y + 1),
              Square(x - 1, y + 1), Square(x - 1, y), Square(
                  x, y - 1), Square(x + 1, y - 1), Square(x - 1, y - 1))))
Exemplo n.º 8
0
    def __destroy(self) -> None:
        self.squares = [[None for y in range(self.size.y + 1)]
                        for x in range(self.size.x + 1)]
        self.count = 1
        self.current_generation = 1
        self.__not_reproduced_squares = deque()

        starting_square = Square(self.starting_point.x, self.starting_point.y,
                                 self.current_generation)
        self.squares[starting_square.x][starting_square.y] = starting_square
        self.__not_reproduced_squares.append([starting_square])
Exemplo n.º 9
0
def test_move_equal_operator(move):
    assert move == Move(Square(1, 1), value=1)
    assert not move == Move(Square(1, 1), value=0)
    assert not move == Move(Square(1, 1), value=2)
    assert not move == Move(Square(0, 1), value=1)
    assert not move == Move(Square(0, 0), value=1)
    assert not move == Move(Square(0, 0), value=0)
Exemplo n.º 10
0
 def _get_square() -> Square:
     """Ask human player for square coordinates."""
     while True:
         try:
             pos = input("  Give disk position (x,y): ")
             coordinates = [
                 int(x.strip()) for x in pos.split(",") if x.strip()
             ]
             if len(coordinates) != 2:
                 raise ValueError
             return Square(coordinates[0], coordinates[1])
         except ValueError:
             print_error("give coordinates in the form 'x,y'!", indent=2)
Exemplo n.º 11
0
 def attack_squares(self):
     x, y = self.square
     return list(
         filter(
             lambda square: square and (not self.board[
                 square] or self.board[square].player != self.player), [
                     Square(x - 1, y - 2),
                     Square(x + 1, y - 2),
                     Square(x - 2, y - 1),
                     Square(x + 2, y - 1),
                     Square(x - 1, y + 2),
                     Square(x + 1, y + 2),
                     Square(x - 2, y + 1),
                     Square(x + 2, y + 1)
                 ]))
Exemplo n.º 12
0
 def en_passant(self):
     x, y = self.square
     if self.board.last_move:
         last_move = self.board.last_move
         enemy_piece, from_square, to_square = last_move.piece, last_move.old_square, last_move.new_square
         if isinstance(enemy_piece, Pawn) and \
           ((enemy_piece.player == Player.WHITE and from_square.y == 6 and to_square.y == 4) or
            (enemy_piece.player == Player.BLACK and from_square.y == 1 and to_square.y == 3)) \
           and y == to_square.y and abs(to_square.x - x) == 1:
             # checking the condition for en-passant
             en_passant_square = Square(
                 to_square.x,
                 y - 1 if self.player == Player.WHITE else y + 1)
             return Move.en_passant(self.board, self, en_passant_square,
                                    enemy_piece)
Exemplo n.º 13
0
    def __init__(self, size=8):
        self._size = size
        # init game board with empty disks
        self._board = [[Disk.EMPTY for _ in range(self._size)] for _ in range(self._size)]

        # set starting positions
        row = (self._size - 1) // 2 if self._size % 2 == 0 else (self._size - 1) // 2 - 1
        col = self._size // 2
        self._board[row][row] = Disk.BLACK
        self._board[row][col] = Disk.WHITE
        self._board[col][row] = Disk.WHITE
        self._board[col][col] = Disk.BLACK

        # keep track of empty squares on board to avoid checking already filled positions
        self._empty_squares = set(
            Square(x, y) for x in range(self._size) for y in range(self._size) if self._board[y][x] == Disk.EMPTY
        )
Exemplo n.º 14
0
 def queen_side_castle(self):
     x, y = self.square
     if not self.moved:  # King must not have moved
         if not self.board[Square(3, y)] and not self.board[Square(2, y)] and not self.board[Square(1, y)] and \
           self.board[Square(0, y)]:
             # no pieces between rook and king and rook must not have moved
             piece: Piece = self.board[Square(0, y)]
             if piece.player == self.player and isinstance(
                     piece, Rook) and not piece.moved:
                 if not self.under_check():  # NOTE: No castling under check
                     return Move.castle(self.board,
                                        king=self,
                                        new_king_square=Square(2, y),
                                        rook=piece,
                                        new_rook_square=Square(3, y))
Exemplo n.º 15
0
 def attack_squares(self):
     x, y = self.square
     squares = []
     for direction in [
             # Bishop moves
         [Square(x - i, y - i) for i in range(1, min(x + 1, y + 1))],
         [Square(x + i, y + i) for i in range(1, min(8 - x, 8 - y))],
         [Square(x + i, y - i) for i in range(1, min(8 - x, y + 1))],
         [Square(x - i, y + i) for i in range(1, min(x + 1, 8 - y))],
             # Rook moves
         [Square(i, y) for i in reversed(range(0, x))],
         [Square(i, y) for i in range(x + 1, 8)],
         [Square(x, j) for j in reversed(range(0, y))],
         [Square(x, j) for j in range(y + 1, 8)],
     ]:
         for square in direction:
             if not self.board[square]:  # if nothing in pathway
                 squares.append(square)
                 continue
             if self.board[
                     square].player != self.player:  # if enemy in pathway
                 squares.append(square)
             break
     return squares
Exemplo n.º 16
0
    def __square_reproduce(self, square: Square, generation: int) -> list:
        self.count += 1

        x = square.x
        y = square.y

        neighboring_coordinates = None

        right = Vector(x + 1, y)
        up = Vector(x, y + 1)
        left = Vector(x - 1, y)
        bottom = Vector(x, y - 1)

        if self.quadratic:
            right_up = Vector(x + 1, y + 1)
            right_down = Vector(x + 1, y - 1)
            left_up = Vector(x - 1, y + 1)
            left_down = Vector(x - 1, y - 1)

            neighboring_coordinates = [
                right, up, left, bottom, right_up, right_down, left_up,
                left_down
            ]
        else:
            neighboring_coordinates = [right, up, left, bottom]

        neighboring_squares = []
        # 'nc' stands for 'neighboring coordinate'
        for nc in neighboring_coordinates:
            if (nc.x <= self.size.x and nc.x >= 0 and nc.y <= self.size.y
                    and nc.y >= 0 and self.__able_to_reproduce()):
                if self.squares[nc.x][nc.y] is None:
                    self.squares[nc.x][nc.y] = Square(nc.x, nc.y, generation)
                    neighboring_squares.append(self.squares[nc.x][nc.y])

        return neighboring_squares
Exemplo n.º 17
0
def square():
    return Square(1, 1)
Exemplo n.º 18
0
    def possible_moves(self):
        x, y = self.square
        forward_square = Square(
            x, y - 1) if self.player == Player.WHITE else Square(x, y + 1)
        forward_two_square = Square(
            x, y - 2) if self.player == Player.WHITE else Square(x, y + 2)
        right_square = Square(x + 1, y -
                              1) if self.player == Player.WHITE else Square(
                                  x + 1, y + 1)
        left_square = Square(x - 1, y -
                             1) if self.player == Player.WHITE else Square(
                                 x - 1, y + 1)

        moves = []
        if not self.moved:  # if not yet moved
            if not self.board[forward_square] and not self.board[
                    forward_two_square]:
                # if nothing in first two squares, can move two squares
                moves.append(
                    Move.typical(self.board,
                                 piece=self,
                                 new_square=forward_two_square))

        # promotion occurs if pawn reaches last rank
        promotion = (y - 1) == 0 if self.player == Player.WHITE else (y +
                                                                      1) == 7
        if promotion:
            # note: promoted piece is determined by the player.
            if forward_square and not self.board[
                    forward_square]:  # if nothing forward, can move one square forward
                moves.append(
                    Move.pawn_promotion(self.board,
                                        self,
                                        forward_square,
                                        new_piece=None))
            if right_square and self.board[right_square] and self.board[
                    right_square].player != self.player:
                moves.append(
                    Move.pawn_promotion(self.board,
                                        self,
                                        right_square,
                                        new_piece=None))
            if left_square and self.board[left_square] and self.board[
                    left_square].player != self.player:
                moves.append(
                    Move.pawn_promotion(self.board,
                                        self,
                                        left_square,
                                        new_piece=None))

        else:  # if no promotion possible (typical)
            if forward_square and not self.board[
                    forward_square]:  # if nothing forward, can move one square forward
                moves.append(Move.typical(self.board, self, forward_square))
            if right_square and self.board[right_square] and self.board[
                    right_square].player != self.player:
                moves.append(Move.typical(self.board, self, right_square))
            if left_square and self.board[left_square] and self.board[
                    left_square].player != self.player:
                moves.append(Move.typical(self.board, self, left_square))

        en_passant = self.en_passant()
        if en_passant:
            moves.append(en_passant)

        return moves
Exemplo n.º 19
0
from __future__ import annotations

from board import Board
from chess import Chess
from pieces import King, Queen, Rook, Bishop, Knight, Pawn
from utils import Player, Square, History

WHITE, BLACK = Player.WHITE, Player.BLACK

INITIAL_POSITIONS = [
	# White pieces
	(Pawn, Player.WHITE, Square(0, 6)),
	(Pawn, Player.WHITE, Square(1, 6)),
	(Pawn, Player.WHITE, Square(2, 6)),
	(Pawn, Player.WHITE, Square(3, 6)),
	(Pawn, Player.WHITE, Square(4, 6)),
	(Pawn, Player.WHITE, Square(5, 6)),
	(Pawn, Player.WHITE, Square(6, 6)),
	(Pawn, Player.WHITE, Square(7, 6)),
	(Rook, Player.WHITE, Square(0, 7)),
	(Knight, Player.WHITE, Square(1, 7)),
	(Bishop, Player.WHITE, Square(2, 7)),
	(Queen, Player.WHITE, Square(3, 7)),
	(King, Player.WHITE, Square(4, 7)),
	(Bishop, Player.WHITE, Square(5, 7)),
	(Knight, Player.WHITE, Square(6, 7)),
	(Rook, Player.WHITE, Square(7, 7)),
	# Black pieces
	(Pawn, Player.BLACK, Square(0, 1)),
	(Pawn, Player.BLACK, Square(1, 1)),
	(Pawn, Player.BLACK, Square(2, 1)),
Exemplo n.º 20
0
def test_square_not_equal_operator(square):
    assert square != Square(0, 0)
    assert square != Square(0, 1)
    assert square != Square(1, 0)
    assert not square != Square(1, 1)
Exemplo n.º 21
0
def move():
    return Move(Square(1, 1), disk=Disk.WHITE, value=1)