Final code version before submitting

This commit is contained in:
2023-09-18 20:11:39 +01:00
parent e34df3a166
commit 5b253369ee
20 changed files with 1663 additions and 1495 deletions
+121 -16
View File
@@ -1,3 +1,5 @@
from __future__ import annotations
import pygame
from copy import deepcopy
from .constants import BLACK, ROWS, GREEN, SQUARE_SIZE, COLS, WHITE
@@ -5,20 +7,32 @@ from .piece import Piece
class Board:
def __init__(self):
def __init__(self) -> None:
"""
Constructor for the Board class
:return: None
"""
self.board = []
self.greenLeft = self.whiteLeft = 12
self.greenKings = self.whiteKings = 0
self.green = (144, 184, 59)
self._createBoard()
def _drawSquares(self, win):
def _drawSquares(self, win: pygame.display) -> None:
"""
Draws the squares on the board
:param win: The window
"""
win.fill(BLACK)
for row in range(ROWS):
for col in range(row % 2, ROWS, 2):
pygame.draw.rect(win, self.green, (row * SQUARE_SIZE, col * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
def _createBoard(self):
def _createBoard(self) -> None:
"""
Creates a board representation of the game
:return: None
"""
for row in range(ROWS):
self.board.append([])
for col in range(COLS):
@@ -36,7 +50,12 @@ class Board:
self.board[row].append(0)
def draw(self, win):
def draw(self, win: pygame.display) -> None:
"""
Draws the pieces on the board
:param win: The window
:return: None
"""
self._drawSquares(win)
for row in range(ROWS):
for col in range(COLS):
@@ -44,7 +63,14 @@ class Board:
if piece != 0:
piece.draw(win)
def move(self, piece, row, col):
def move(self, piece: Piece, row: int, col: int) -> None:
"""
Moves a piece and make it a king if it reaches the end of the board
:param piece: Piece to move
:param row: Row to move to
:param col: Column to move to
:return: None
"""
self.board[piece.row][piece.col], self.board[row][col] = self.board[row][col], self.board[piece.row][piece.col]
piece.move(row, col)
@@ -57,7 +83,11 @@ class Board:
if piece.colour == GREEN:
self.greenKings += 1
def remove(self, skipped):
def remove(self, skipped: tuple) -> None:
"""
Removes a piece from the board
:param skipped: A tuple of the piece to remove
"""
for piece in skipped:
self.board[piece.row][piece.col] = 0
if piece != 0:
@@ -66,7 +96,12 @@ class Board:
continue
self.whiteLeft -= 1
def getAllMoves(self, colour):
def getAllMoves(self, colour: int) -> list:
"""
Gets all the possible moves for a player
:param colour: colour of the player
:return:
"""
moves = []
possibleMoves = []
possiblePieces = []
@@ -103,14 +138,28 @@ class Board:
return moves
def _simulateMove(self, piece, move, board, skip):
def _simulateMove(self, piece: Piece, move: list, board: Board, skip: tuple) -> Board:
"""
Simulates a move on the board
:param piece: Piece to move
:param move: Move to make
:param board: Board to make the move on
:param skip: Tuple of pieces to skip
:return: Board after the move
"""
board.move(piece, move[0], move[1])
if skip:
board.remove(skip)
return board
def getPiece(self, row, col):
def getPiece(self, row: int, col: int) -> Piece:
"""
Gets a piece from the board
:param row: Row of the piece
:param col: Column of the piece
:return: Piece
"""
return self.board[row][col]
def winner(self):
@@ -122,7 +171,12 @@ class Board:
return None
def getValidMoves(self, piece):
def getValidMoves(self, piece: Piece) -> dict:
"""
Gets all the valid moves for a piece
:param piece: Piece to get the moves for
:return: dictionary of moves
"""
moves = {}
forcedCapture = {}
left = piece.col - 1
@@ -162,10 +216,19 @@ class Board:
return forcedCapture
def scoreOfTheBoard(self):
def scoreOfTheBoard(self) -> int:
"""
Calculates the score of the board
:return: score of the board
"""
return self.whiteLeft - self.greenLeft
def getAllPieces(self, colour):
"""
Gets all the pieces of a player
:param colour: Piece colour
:return: Pieces of the player
"""
pieces = []
for row in self.board:
for piece in row:
@@ -173,7 +236,17 @@ class Board:
pieces.append(piece)
return pieces
def _traverseLeft(self, start, stop, step, colour, left, skipped=[]):
def _traverseLeft(self, start: int, stop: int, step: int, colour: int, left: int, skipped: list = []) -> dict:
"""
Traverses the left side of the board
:param start: Start position
:param stop: Stop position
:param step: Step size
:param colour: colour of the player
:param left: Left position
:param skipped: List of pieces to skip
:return: dictionary of moves
"""
moves = {}
last = []
for row in range(start, stop, step):
@@ -189,7 +262,17 @@ class Board:
left -= 1
return moves
def _traverseRight(self, start, stop, step, colour, right, skipped=[]):
def _traverseRight(self, start: int, stop: int, step: int, colour: int, right: int, skipped: list = []) -> dict:
"""
Traverses the left side of the board
:param start: Start position
:param stop: Stop position
:param step: Step size
:param colour: colour of the player
:param right: Right position
:param skipped: List of pieces to skip
:return: dictionary of moves
"""
moves = {}
last = []
for row in range(start, stop, step):
@@ -207,7 +290,18 @@ class Board:
right += 1
return moves
def _traverse(self, row, col, skipped, moves, step, last, colour):
def _traverse(self, row: int, col: int, skipped: list, moves: dict, step: int, last: list, colour: int) -> list or None:
"""
Traverses the board
:param row: Row to traverse
:param col: Column to traverse
:param skipped: List of pieces to jump
:param moves: Dictionary of moves
:param step: Step size
:param last: List of last pieces
:param colour: Colour of the player
:return: list of last pieces or None
"""
current = self.board[row][col]
if current == 0:
if skipped and not last:
@@ -231,7 +325,13 @@ class Board:
last = [current]
return last
def step(self, move, colour):
def step(self, move: int, colour: int) -> None:
"""
Takes a move and executes it
:param move: The move to execute
:param colour: The colour of the player
:return: None
"""
start, end = self._decode(move)
start[0] = start[0] - 1
start[1] = start[1] - 1
@@ -264,7 +364,12 @@ class Board:
return reward, self, done
def _decode(self, move):
def _decode(self, move: int) -> tuple:
"""
Decodes the move from a integer to a start and end tuple
:param move: The move to decode
:return: Start and end tuple
"""
# Split digits back out
str_code = str(move)
# print(str_code)
+1 -1
View File
@@ -4,7 +4,7 @@ WIDTH, HEIGHT = 800, 800
ROWS, COLS = 8, 8
SQUARE_SIZE = WIDTH // COLS
# RGB color
# RGB colour
GREEN = 1
WHITE = 2
+59 -10
View File
@@ -1,29 +1,54 @@
from __future__ import annotations
import pygame
from utilities.Board import Board
from utilities.constants import GREEN, WHITE, BLUE, SQUARE_SIZE
class GameManager:
def __init__(self, win, colour):
def __init__(self, win: pygame.display, colour: int) -> None:
"""
Constructor for the GameManager class
:param win: The window
:param colour: The colour of the player
"""
self._init(colour)
self.win = win
def _init(self, colour):
def _init(self, colour: int) -> None:
"""
Initializes the game
:param colour: the colour of the player
"""
self.selected = None
self.board = Board()
self.turn = colour
self.validMoves = {}
self.legCount = 0
def update(self):
def update(self) -> None:
"""
Updates the GUI
return: None
"""
self.board.draw(self.win)
self.drawValidMoves(self.validMoves)
pygame.display.update()
def reset(self):
def reset(self) -> None:
"""
Resets the game
:return: None
"""
self._init(self.turn)
def select(self, row, col):
def select(self, row: int, col: int) -> bool:
"""
Selects a piece
:param row: Row of the piece
:param col: Column of the piece
:return: True
"""
if self.selected:
result = self._move(row, col)
if not result:
@@ -35,7 +60,13 @@ class GameManager:
self.validMoves = self.board.getValidMoves(piece)
return True
def _move(self, row, col):
def _move(self, row: int, col: int) -> bool:
"""
Moves a piece
:param row: Row of the piece
:param col: Column of the piece
:return: True if the move was successful, False otherwise
"""
piece = self.board.getPiece(row, col)
if self.selected and piece == 0 and (row, col) in self.validMoves:
self.board.move(self.selected, row, col)
@@ -62,18 +93,36 @@ class GameManager:
return
self.turn = GREEN
def drawValidMoves(self, moves):
def drawValidMoves(self, moves: list) -> None:
"""
Draws the valid moves
:param moves: list of valid moves
:return: None
"""
for row, col in moves:
pygame.draw.circle(self.win, BLUE,
(col * SQUARE_SIZE + SQUARE_SIZE // 2, row * SQUARE_SIZE + SQUARE_SIZE // 2), 15)
def winner(self):
def winner(self) -> int or None:
"""
Gets the winner
:return: The winner
"""
return self.board.winner()
def getBoard(self):
def getBoard(self) -> Board:
"""
Gets the board
:return: The board
"""
return self.board
def aiMove(self, board):
def aiMove(self, board: Board) -> None:
"""
Makes a move for the AI
:param board: The new board
:return: None
"""
if board is None:
# colour = "green" if self.turn == GREEN else "white"
# print("no move left for " + colour + " to make")
+35 -6
View File
@@ -4,7 +4,13 @@ from utilities.constants import SQUARE_SIZE, GREY, CROWN, GREEN
class Piece:
def __init__(self, row, col, colour):
def __init__(self, row: int, col: int, colour: int) -> None:
"""
Initialises the piece class, which represents a piece on the board. Constructor for the piece class
:param row: Row of the piece
:param col: Column of the piece
:param colour: Colour of the piece
"""
self.row = row
self.col = col
self.colour = colour
@@ -17,24 +23,47 @@ class Piece:
self.green = (144, 184, 59)
self.white = (255, 255, 255)
def calcPosition(self):
def calcPosition(self) -> None:
"""
Calculates the position of the piece
:return: None
"""
self.x = SQUARE_SIZE * self.col + SQUARE_SIZE // 2
self.y = SQUARE_SIZE * self.row + SQUARE_SIZE // 2
def makeKing(self):
def makeKing(self) -> None:
"""
Makes the piece a king
:return: None
"""
self.king = True
def draw(self, win):
def draw(self, win) -> None:
"""
Draws the piece
:param win: The window to draw the piece on
:return: None
"""
radius = SQUARE_SIZE // 2 - self.padding
pygame.draw.circle(win, GREY, (self.x, self.y), radius + self.border)
pygame.draw.circle(win, self.green if self.colour == GREEN else self.white, (self.x, self.y), radius)
if self.king:
win.blit(CROWN, (self.x - CROWN.get_width() // 2, self.y - CROWN.get_height() // 2))
def move(self, row, col):
def move(self, row: int, col: int) -> None:
"""
Moves the piece to a new position
:param row: Row to move to
:param col: Column to move to
:return: None
"""
self.row = row
self.col = col
self.calcPosition()
def __repr__(self):
def __repr__(self) -> str:
"""
String representation of the piece
:return: String representation of the colour
"""
return str(self.colour)