WE CAN FINALLY PLAY THE GAME. Made controller
Some checks failed
pre-release / Pre Release (push) Waiting to run
tagged-release / Tagged Release (push) Has been cancelled

working
This commit is contained in:
Karma Riuk 2025-01-31 11:39:23 +01:00
parent ac85f3e6d3
commit c14a8c83b3
7 changed files with 86 additions and 25 deletions

View File

@ -1,4 +1,7 @@
from logic.board import Board from logic.board import Board
from logic.move import Move
from logic.pieces.piece import Piece
from logic.position import Position
from view.view import View from view.view import View
@ -8,6 +11,47 @@ class Controller:
self._view = view self._view = view
self._view.set_controller(self) self._view.set_controller(self)
self._reset_selection()
self._selected_piece: Piece = None
self._legal_moves: list[Move] = []
def _reset_selection(self):
self._selected_piece = None
self._legal_moves = []
self._view.update_board(self._board, self._selected_piece, self._legal_moves)
def _show_legal_moves(self, pos: Position):
piece = self._board.piece_at(pos.x, pos.y)
if piece:
if piece.colour != self._board._turn:
return
self._selected_piece = piece
self._legal_moves = piece.legal_moves(self._board)
self._view.update_board(self._board, self._selected_piece, self._legal_moves)
else:
self._reset_selection()
def _make_move(self, move: Move) -> None:
self._board = self._board.make_move(move)
self._reset_selection()
def on_tile_selected(self, x: int, y: int) -> None: def on_tile_selected(self, x: int, y: int) -> None:
raise NotImplementedError(f"Cannot handle tile selected event, {type(self).__name__} did not implement it") pos = Position(x, y)
print(f"Clicked on {pos.to_algebraic()}")
piece = self._board.piece_at(x, y)
if self._selected_piece is None or (piece is not None and piece != self._selected_piece):
self._show_legal_moves(pos)
else:
legal_moves_positions = [move for move in self._legal_moves if move.pos == pos]
assert len(legal_moves_positions) <= 1, f"Apparently we can make multiple moves towards {pos.to_algebraic()} with {type(self._selected_piece)}, which doesn't make sense..."
if len(legal_moves_positions) == 0: # click on a square outside of the possible moves
self._reset_selection()
else:
move = legal_moves_positions[0]
self._make_move(move)

View File

@ -1,20 +0,0 @@
from logic.board import Board
from view.view import View
from .controller import Controller
class GuiController(Controller):
def __init__(self, board: Board, view: View) -> None:
super().__init__(board, view)
self._view.update_board(self._board, None, [])
def on_tile_selected(self, x: int, y: int) -> None:
piece = self._board.piece_at(x, y)
print(f"Clicked on {x, y}, {piece = }")
if piece:
self._view.update_board(self._board, piece, piece.legal_moves(self._board))
else:
self._view.update_board(self._board, None, [])

View File

@ -1,3 +1,4 @@
from logic.move import Move
from logic.pieces.bishop import Bishop from logic.pieces.bishop import Bishop
from logic.pieces.king import King from logic.pieces.king import King
from logic.pieces.knight import Knight from logic.pieces.knight import Knight
@ -111,3 +112,32 @@ class Board:
if white_piece != None: if white_piece != None:
return white_piece return white_piece
return black_piece return black_piece
def make_move(self, move: Move) -> "Board":
dest_piece = self.piece_at(move.pos.x, move.pos.y)
if dest_piece:
assert dest_piece.colour != move.piece.colour, "A piece cannot cannot eat another piece of the same colour"
ret = Board()
ret._white = self._white.copy()
ret._black = self._black.copy()
ret._turn = Colour.WHITE if self._turn == Colour.BLACK else Colour.BLACK
ret._white_castling_write = self._white_castling_write.copy()
ret._black_castling_write = self._black_castling_write.copy()
ret._en_passant_target = self._en_passant_target
piece = move.piece
if piece.colour == Colour.WHITE:
del ret._white[piece.pos]
ret._white[move.pos] = piece.move_to(move.pos)
if move.pos in ret._black:
del ret._black[move.pos]
else:
del ret._black[piece.pos]
ret._black[move.pos] = piece.move_to(move.pos)
if move.pos in ret._white:
del ret._white[move.pos]
return ret

View File

@ -37,6 +37,4 @@ class Pawn(Piece):
pos = Position(self.pos.x, self.pos.y - dy) pos = Position(self.pos.x, self.pos.y - dy)
ret.append(PieceMove(self, pos)) ret.append(PieceMove(self, pos))
print(ret)
return ret return ret

View File

@ -43,5 +43,9 @@ class Piece:
def position(self) -> Position: def position(self) -> Position:
return self.pos return self.pos
def move_to(self, pos: Position) -> "Piece":
ret = type(self)(pos, self.colour)
return ret
def legal_moves(self, board: "Board") -> list["Move"]: def legal_moves(self, board: "Board") -> list["Move"]:
raise NotImplementedError(f"Can't say what the legal moves are for {type(self).__name__}, the method hasn't been implemented yet") raise NotImplementedError(f"Can't say what the legal moves are for {type(self).__name__}, the method hasn't been implemented yet")

View File

@ -1,4 +1,7 @@
class Position: class Position:
_RANKS = range(1, 9)
_FILES = "abcdefgh"
_MIN_POS = 0 _MIN_POS = 0
_MAX_POS = 7 _MAX_POS = 7
@ -14,6 +17,8 @@ class Position:
return x >= Position._MIN_POS and x <= Position._MAX_POS \ return x >= Position._MIN_POS and x <= Position._MAX_POS \
and y >= Position._MIN_POS and y <= Position._MAX_POS and y >= Position._MIN_POS and y <= Position._MAX_POS
def to_algebraic(self) -> str:
return f"{Position._FILES[self.x]}{Position._RANKS[self.y]}"
def __eq__(self, value: object, /) -> bool: def __eq__(self, value: object, /) -> bool:
if type(value) != type(self): if type(value) != type(self):

View File

@ -1,4 +1,4 @@
from controller.gui_controller import GuiController from controller.controller import Controller
from logic.board import Board from logic.board import Board
from view.gui import GUI from view.gui import GUI
from view.tui import TUI from view.tui import TUI
@ -9,6 +9,6 @@ if __name__ == "__main__":
view = GUI() view = GUI()
controller = GuiController(board, view) controller = Controller(board, view)
view.show() view.show()