Make pieces move
This commit is contained in:
parent
d630115cce
commit
23adf99347
|
@ -1,20 +1,20 @@
|
||||||
from typing import Callable, Iterable
|
from typing import Callable, Iterable, Union
|
||||||
from os import system
|
from os import system
|
||||||
from shutil import get_terminal_size as getTerminalSize
|
|
||||||
|
|
||||||
from piece import Piece
|
from piece import Piece
|
||||||
|
from util import centerText, centerBlockText, boxCharsToBoldBoxCharsMap, determineMove
|
||||||
|
|
||||||
|
|
||||||
class Board:
|
class Board:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, boardState=None):
|
||||||
self.boardArray = [
|
self.boardArray = [
|
||||||
[Piece(type, 'black') for type in ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']],
|
[Piece(type, 'black') for type in ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']],
|
||||||
[Piece('p', 'black') for _ in range(8)],
|
[Piece('p', 'black') for _ in range(8)],
|
||||||
*[[None for _ in range(8)] for _ in range(4)],
|
*[[None for _ in range(8)] for _ in range(4)],
|
||||||
[Piece('p', 'white') for _ in range(8)],
|
[Piece('p', 'white') for _ in range(8)],
|
||||||
[Piece(type, 'white') for type in ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']],
|
[Piece(type, 'white') for type in ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']],
|
||||||
]
|
] if boardState == None else boardState
|
||||||
|
|
||||||
def draw(
|
def draw(
|
||||||
self,
|
self,
|
||||||
|
@ -43,7 +43,7 @@ class Board:
|
||||||
# Draw general outline
|
# Draw general outline
|
||||||
stringArray = [list('┼' + '───┼' * 8)] + [[None] for _ in range(8 * 2)]
|
stringArray = [list('┼' + '───┼' * 8)] + [[None] for _ in range(8 * 2)]
|
||||||
for y, row in enumerate(self.boardArray):
|
for y, row in enumerate(self.boardArray):
|
||||||
for x, column in enumerate(row):
|
for x, _ in enumerate(row):
|
||||||
stringArray[2 * y + 1][4 * x] = '│'
|
stringArray[2 * y + 1][4 * x] = '│'
|
||||||
stringArray[2 * y + 2][4 * x] = '┼'
|
stringArray[2 * y + 2][4 * x] = '┼'
|
||||||
|
|
||||||
|
@ -65,30 +65,15 @@ class Board:
|
||||||
stringArray[i * 2 + 2][0] = '├'
|
stringArray[i * 2 + 2][0] = '├'
|
||||||
stringArray[i * 2 + 2][-1] = '┤'
|
stringArray[i * 2 + 2][-1] = '┤'
|
||||||
|
|
||||||
def highlightContent(x, y):
|
def highlightContent(x, y, escapeCodes=config['highlightEscapeCodes']):
|
||||||
"""highlight contents of a piece with xterm-256colors modifiers"""
|
"""highlight contents of a piece with xterm-256colors modifiers"""
|
||||||
stringArray[y * 2 +
|
stringArray[y * 2 + 1][x * 4 + 1] = \
|
||||||
1][x * 4 +
|
escapeCodes[0] + stringArray[y * 2 + 1][x * 4 + 1]
|
||||||
1] = config['highlightEscapeCodes'][0] + stringArray[y * 2 + 1][x * 4 + 1]
|
stringArray[y * 2 + 1][x * 4 + 3] += escapeCodes[1]
|
||||||
stringArray[y * 2 + 1][x * 4 + 3] += config['highlightEscapeCodes'][1]
|
|
||||||
|
|
||||||
def highlightBox(x, y):
|
def highlightBox(x, y):
|
||||||
"""Make box around a piece bold"""
|
"""Make box around a piece bold"""
|
||||||
|
|
||||||
characterMap = {
|
|
||||||
'─': '═',
|
|
||||||
'│': '║',
|
|
||||||
'┼': '╬',
|
|
||||||
'╰': '╚',
|
|
||||||
'╯': '╝',
|
|
||||||
'╭': '╔',
|
|
||||||
'╮': '╗',
|
|
||||||
'├': '╠',
|
|
||||||
'┴': '╩',
|
|
||||||
'┤': '╣',
|
|
||||||
'┬': '╦',
|
|
||||||
}
|
|
||||||
|
|
||||||
pointsToChange = \
|
pointsToChange = \
|
||||||
[(x * 4 + 0, y * 2 + i) for i in range(3)] + \
|
[(x * 4 + 0, y * 2 + i) for i in range(3)] + \
|
||||||
[(x * 4 + 4, y * 2 + i) for i in range(3)] + \
|
[(x * 4 + 4, y * 2 + i) for i in range(3)] + \
|
||||||
|
@ -96,13 +81,18 @@ class Board:
|
||||||
[(x * 4 + i, y * 2 + 2) for i in range(1,4)]
|
[(x * 4 + i, y * 2 + 2) for i in range(1,4)]
|
||||||
|
|
||||||
for x, y in pointsToChange:
|
for x, y in pointsToChange:
|
||||||
stringArray[y][x] = characterMap[
|
stringArray[y][x] = boxCharsToBoldBoxCharsMap[
|
||||||
stringArray[y][x]] if stringArray[y][x] in characterMap else stringArray[y][x]
|
stringArray[y]
|
||||||
|
[x]] if stringArray[y][x] in boxCharsToBoldBoxCharsMap else stringArray[y][x]
|
||||||
|
|
||||||
for x, y in config['highlightedBoxes']:
|
# Color white pieces
|
||||||
highlightBox(x, y)
|
for piece in self.getPositionsWhere(lambda piece: piece.color == 'white'):
|
||||||
for x, y in config['highlightedContent']:
|
highlightContent(*piece, ('\033[7m', '\033[0m'))
|
||||||
highlightContent(x, y)
|
|
||||||
|
for box in config['highlightedBoxes']:
|
||||||
|
highlightBox(*box)
|
||||||
|
for piece in config['highlightedContent']:
|
||||||
|
highlightContent(*piece)
|
||||||
|
|
||||||
return '\n'.join([''.join(line) for line in stringArray])
|
return '\n'.join([''.join(line) for line in stringArray])
|
||||||
|
|
||||||
|
@ -111,35 +101,68 @@ class Board:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
system('clear')
|
system('clear')
|
||||||
menuString = '\n' + player.name + '\n\n'
|
playerString = '\n' + player.name + '\n\n'
|
||||||
menuString += self.draw({'highlightedBoxes': [(x, y)]}) + '\n'
|
menuString = self.draw({'highlightedBoxes': [(x, y)]}) + '\n'
|
||||||
inputString = f" W E\nA S D <- Enter : "
|
inputString = f" W E\nA S D <- Enter : "
|
||||||
|
|
||||||
def centerText(text):
|
|
||||||
terminalWidth = getTerminalSize((60, 0))[0] # Column size 60 as fallback
|
|
||||||
return "\n".join(line.center(terminalWidth) for line in text.split('\n'))
|
|
||||||
|
|
||||||
def centerBlockText(text):
|
|
||||||
terminalWidth = getTerminalSize((60, 0))[0] # Column size 60 as fallback
|
|
||||||
textArray = text.split('\n')
|
|
||||||
offset = int((terminalWidth - len(textArray[0])) / 2)
|
|
||||||
return "\n".join(offset * ' ' + line for line in textArray)
|
|
||||||
|
|
||||||
if centering:
|
if centering:
|
||||||
menuString = centerText(menuString)
|
playerString = centerText(playerString)
|
||||||
|
menuString = centerBlockText(menuString)
|
||||||
inputString = centerBlockText(inputString)
|
inputString = centerBlockText(inputString)
|
||||||
|
|
||||||
|
print(playerString)
|
||||||
print(menuString)
|
print(menuString)
|
||||||
|
|
||||||
|
try:
|
||||||
key = input(inputString)[0]
|
key = input(inputString)[0]
|
||||||
if key in ['s', 'j'] and y != 7: y += 1
|
except IndexError:
|
||||||
elif key in ['w', 'k'] and y != 0: y -= 1
|
key = ''
|
||||||
elif key in ['d', 'l'] and x != 7: x += 1
|
try:
|
||||||
elif key in ['a', 'h'] and x != 0: x -= 1
|
if move := determineMove(key, x, y, (0, 7)):
|
||||||
elif key == 'e': return (x, y)
|
x += move[0]
|
||||||
|
y += move[1]
|
||||||
|
elif key == 'e' and self.getPieceAt(x, y).color==player.color:
|
||||||
|
return (x, y)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def selectMove(self, player, x, y, legalMoves, centering=True) -> Union[tuple, bool]:
|
||||||
|
"""Lets the user select a move to make from a graphic board"""
|
||||||
|
|
||||||
|
while True:
|
||||||
|
system('clear')
|
||||||
|
playerString = '\n' + player.name + '\n\n'
|
||||||
|
menuString = self.draw({
|
||||||
|
'highlightedBoxes': [(x, y)],
|
||||||
|
'highlightedContent': legalMoves
|
||||||
|
}) + '\n'
|
||||||
|
inputString = f"Q W E\nA S D <- Enter : "
|
||||||
|
|
||||||
|
if centering:
|
||||||
|
playerString = centerText(playerString)
|
||||||
|
menuString = centerBlockText(menuString)
|
||||||
|
inputString = centerBlockText(inputString)
|
||||||
|
|
||||||
|
print(playerString)
|
||||||
|
print(menuString)
|
||||||
|
|
||||||
|
try:
|
||||||
|
key = input(inputString)[0]
|
||||||
|
except IndexError:
|
||||||
|
key = ''
|
||||||
|
if move := determineMove(key, x, y, (0, 7)):
|
||||||
|
x += move[0]
|
||||||
|
y += move[1]
|
||||||
|
elif key == 'q':
|
||||||
|
return False
|
||||||
|
elif key == 'e' and (x, y) in legalMoves:
|
||||||
|
return (x, y)
|
||||||
|
|
||||||
def getPieceAt(self, x, y) -> Piece:
|
def getPieceAt(self, x, y) -> Piece:
|
||||||
|
try:
|
||||||
return self.boardArray[y][x]
|
return self.boardArray[y][x]
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
def getPositionsWhere(self, condition: Callable[[Piece], bool]) -> Iterable[tuple]:
|
def getPositionsWhere(self, condition: Callable[[Piece], bool]) -> Iterable[tuple]:
|
||||||
""" Returns a list of xy pairs of the pieces where a condition is met """
|
""" Returns a list of xy pairs of the pieces where a condition is met """
|
||||||
|
@ -147,19 +170,22 @@ class Board:
|
||||||
result = []
|
result = []
|
||||||
for y, row in enumerate(self.boardArray):
|
for y, row in enumerate(self.boardArray):
|
||||||
for x, piece in enumerate(row):
|
for x, piece in enumerate(row):
|
||||||
|
try:
|
||||||
if condition(piece):
|
if condition(piece):
|
||||||
result.append((x, y))
|
result.append((x, y))
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def checkCheck(self, color) -> bool:
|
def checkCheck(self, color) -> bool:
|
||||||
"""Check whether a team is caught in check. The color is the color of the team to check"""
|
"""Check whether a team is caught in check. The color is the color of the team to check"""
|
||||||
king = self.getPositionsWhere(lambda piece: piece.type == 'k' and piece.color == color)
|
king = self.getPositionsWhere(lambda piece: piece.type == 'k' and piece.color == color)[0]
|
||||||
piecesToCheck = self.getPositionsWhere(lambda piece: piece.color != color)
|
piecesToCheck = self.getPositionsWhere(lambda piece: piece.color != color)
|
||||||
return any([king in Piece.possibleMoves(*piece, self) for piece in piecesToCheck])
|
return any([king in Piece.possibleMoves(*piece, self) for piece in piecesToCheck])
|
||||||
|
|
||||||
def getPositionsToProtectKing(self, color) -> Iterable[tuple]:
|
def getPositionsToProtectKing(self, color) -> Iterable[tuple]:
|
||||||
"""Get a list of the positions to protect in order to protect the king when in check. The color is the color of the team who's in check"""
|
"""Get a list of the positions to protect in order to protect the king when in check. The color is the color of the team who's in check"""
|
||||||
king = self.getPositionsWhere(lambda piece: piece.type == 'k' and piece.color == color)
|
king = self.getPositionsWhere(lambda piece: piece.type == 'k' and piece.color == color)[0]
|
||||||
piecesToCheck = self.getPositionsWhere(lambda piece: piece.color != color)
|
piecesToCheck = self.getPositionsWhere(lambda piece: piece.color != color)
|
||||||
for piece in piecesToCheck:
|
for piece in piecesToCheck:
|
||||||
if king not in Piece.possibleMoves(*piece, self):
|
if king not in Piece.possibleMoves(*piece, self):
|
||||||
|
@ -178,7 +204,7 @@ class Board:
|
||||||
|
|
||||||
direction = getDirection(piece, king)
|
direction = getDirection(piece, king)
|
||||||
|
|
||||||
def getPositionsUntilKing(x, y, direction):
|
def getPositionsUntilKing(x, y, direction) -> Iterable[tuple]:
|
||||||
result = []
|
result = []
|
||||||
while self.getPieceAt(x, y) == None:
|
while self.getPieceAt(x, y) == None:
|
||||||
result.append((x, y))
|
result.append((x, y))
|
||||||
|
@ -190,19 +216,19 @@ class Board:
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def playerHasLegalMoves(self, color) -> bool:
|
||||||
|
enemyPieces = self.getPositionsWhere(lambda piece: piece.color == color)
|
||||||
|
getLegalMoves = lambda piece: Piece.possibleMoves(
|
||||||
|
*piece, self, legalMoves=self.getPositionsToProtectKing(color))
|
||||||
|
return not any(getLegalMoves(piece) == None for piece in enemyPieces)
|
||||||
|
|
||||||
def checkStaleMate(self, color) -> bool:
|
def checkStaleMate(self, color) -> bool:
|
||||||
"""Check whether a team is caught in stalemate. The color is the color of the team to check"""
|
"""Check whether a team is caught in stalemate. The color is the color of the team to check"""
|
||||||
enemyPieces = self.getPositionsWhere(lambda piece: piece.color == color)
|
return (not self.checkCheck(color)) and not self.playerHasLegalMoves(color)
|
||||||
getLegalMoves = lambda piece: Piece.possibleMoves(*piece, self, legalMoves = self.getPositionsToProtectKing(color))
|
|
||||||
piecesHasNoLegalMoves = any( getLegalMoves(piece) == None for piece in enemyPieces)
|
|
||||||
return (not self.checkCheck(color)) and piecesHasNoLegalMoves
|
|
||||||
|
|
||||||
def checkCheckMate(self, color) -> bool:
|
def checkCheckMate(self, color) -> bool:
|
||||||
"""Check whether a team is caught in checkmate. The color is the color of the team to check"""
|
"""Check whether a team is caught in checkmate. The color is the color of the team to check"""
|
||||||
enemyPieces = self.getPositionsWhere(lambda piece: piece.color == color)
|
return self.checkCheck(color) and not self.playerHasLegalMoves(color)
|
||||||
getLegalMoves = lambda piece: Piece.possibleMoves(*piece, self, legalMoves = self.getPositionsToProtectKing(color))
|
|
||||||
piecesHasNoLegalMoves = any( getLegalMoves(piece) == None for piece in enemyPieces)
|
|
||||||
return self.checkCheck(color) and piecesHasNoLegalMoves
|
|
||||||
|
|
||||||
def movePiece(self, position, toPosition, piecesToRemove=None):
|
def movePiece(self, position, toPosition, piecesToRemove=None):
|
||||||
x, y = position
|
x, y = position
|
||||||
|
@ -213,4 +239,3 @@ class Board:
|
||||||
if piecesToRemove != None:
|
if piecesToRemove != None:
|
||||||
for x, y in piecesToRemove:
|
for x, y in piecesToRemove:
|
||||||
self.boardArray[y][x] = None
|
self.boardArray[y][x] = None
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from os import system
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from board import Board
|
from board import Board
|
||||||
|
from piece import Piece
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Player:
|
class Player:
|
||||||
|
@ -12,21 +13,42 @@ class Chess:
|
||||||
|
|
||||||
def __init__(self, players):
|
def __init__(self, players):
|
||||||
self.players = players
|
self.players = players
|
||||||
|
self.board = Board()
|
||||||
|
|
||||||
def lose(self, player):
|
def makeMove(self, player):
|
||||||
print(player.name, 'lost.')
|
chosenTile = 0,0
|
||||||
|
while True:
|
||||||
|
piece = self.board.selectPiece(player, *chosenTile)
|
||||||
|
chosenTile = piece
|
||||||
|
possibleMoves = Piece.possibleMoves(*piece, self.board)
|
||||||
|
if move := self.board.selectMove(player, *piece, possibleMoves):
|
||||||
|
break
|
||||||
|
print(move)
|
||||||
|
input()
|
||||||
|
self.board.movePiece(piece, move)
|
||||||
|
|
||||||
|
def win(self, player):
|
||||||
|
print(player.name, 'won.')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
def tie(self):
|
||||||
|
print('Stalemate')
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
system('clear')
|
system('clear')
|
||||||
board.selectPiece(players[0])
|
self.makeMove(players[0])
|
||||||
if board.checkCheckMate(players[1].color):
|
# if self.board.checkCheckMate(players[1].color):
|
||||||
self.lose(players[1])
|
# self.win(players[0])
|
||||||
|
# elif self.board.checkStaleMate(players[1].color):
|
||||||
|
# self.tie()
|
||||||
|
|
||||||
system('clear')
|
system('clear')
|
||||||
board.selectPiece(players[1])
|
self.makeMove(players[1])
|
||||||
if board.checkCheckMate(players[0].color):
|
# if self.board.checkCheckMate(players[0].color):
|
||||||
self.lose(players[0])
|
# self.win(players[1])
|
||||||
|
# elif self.board.checkStaleMate(players[0].color):
|
||||||
|
# self.tie()
|
||||||
|
|
||||||
def loop(self):
|
def loop(self):
|
||||||
while True:
|
while True:
|
||||||
|
@ -40,7 +62,7 @@ if __name__ == "__main__":
|
||||||
Player('Spiller 2', 'black'),
|
Player('Spiller 2', 'black'),
|
||||||
)
|
)
|
||||||
|
|
||||||
# game = Chess(('Spiller 1', 'Spiller 2'))
|
game = Chess(('Spiller 1', 'Spiller 2'))
|
||||||
# game.loop()
|
game.loop()
|
||||||
board = Board()
|
# board = Board()
|
||||||
print(board.selectPiece(players[0], centering=True))
|
# print(board.selectPiece(players[0], centering=True))
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from typing import Iterable, Callable
|
from typing import Iterable, Callable
|
||||||
from itertools import product
|
from itertools import product
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from sys import setrecursionlimit as setRecursionLimit
|
||||||
|
setRecursionLimit(100000)
|
||||||
|
|
||||||
|
|
||||||
class Piece:
|
class Piece:
|
||||||
|
@ -12,6 +14,25 @@ class Piece:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.type.upper() if self.color == 'white' else self.type
|
return self.type.upper() if self.color == 'white' else self.type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def symbol(self):
|
||||||
|
symbols = [{
|
||||||
|
'p': '♙',
|
||||||
|
'r': '♖',
|
||||||
|
'n': '♘',
|
||||||
|
'b': '♗',
|
||||||
|
'q': '♕',
|
||||||
|
'k': '♔',
|
||||||
|
}, {
|
||||||
|
'p': '♟︎',
|
||||||
|
'r': '♜',
|
||||||
|
'n': '♞',
|
||||||
|
'b': '♝',
|
||||||
|
'q': '♛',
|
||||||
|
'k': '♚',
|
||||||
|
}]
|
||||||
|
return symbols[0 if self.color == 'white' else 1][self.type]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def possibleMoves(x, y, board, legalMoves=None) -> Callable[[int, int], Iterable[tuple]]:
|
def possibleMoves(x, y, board, legalMoves=None) -> Callable[[int, int], Iterable[tuple]]:
|
||||||
piece = board.getPieceAt(x, y)
|
piece = board.getPieceAt(x, y)
|
||||||
|
@ -22,6 +43,7 @@ class Piece:
|
||||||
pieceIsEnemyColor = lambda pieceToCheck: pieceToCheck != None and pieceToCheck.color != piece.color
|
pieceIsEnemyColor = lambda pieceToCheck: pieceToCheck != None and pieceToCheck.color != piece.color
|
||||||
pieceIsEmpty = lambda pieceToCheck: pieceToCheck == None
|
pieceIsEmpty = lambda pieceToCheck: pieceToCheck == None
|
||||||
pieceIsEmptyOrEnemyColor = lambda pieceToCheck: pieceToCheck == None or pieceToCheck.color != piece.color
|
pieceIsEmptyOrEnemyColor = lambda pieceToCheck: pieceToCheck == None or pieceToCheck.color != piece.color
|
||||||
|
positionInsideBounds = lambda x, y: x in range(8) and y in range(8)
|
||||||
|
|
||||||
def addMoveIfTrue(xOffset, yOffset, condition: Callable[[Piece], bool]):
|
def addMoveIfTrue(xOffset, yOffset, condition: Callable[[Piece], bool]):
|
||||||
"""Tests a condition against a position away from self. Adds if condition returns true"""
|
"""Tests a condition against a position away from self. Adds if condition returns true"""
|
||||||
|
@ -30,15 +52,15 @@ class Piece:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# TODO: fix deepcopy segfault and recursion error
|
||||||
def assertNotCheck(newX, newY) -> bool:
|
def assertNotCheck(newX, newY) -> bool:
|
||||||
testBoard = deepcopy(board)
|
testBoard = deepcopy(board)
|
||||||
testBoard.movePiece((x, y), (newX, newY)) # J
|
testBoard.movePiece((x, y), (newX, newY))
|
||||||
return not testBoard.checkCheck()
|
return not testBoard.checkCheck(piece.color)
|
||||||
|
|
||||||
def addWhileInsideBoard(direction: tuple):
|
def addWhileInsideBoard(direction: tuple):
|
||||||
localX = x
|
localX, localY = x, y
|
||||||
localY = y
|
while positionInsideBounds(localX, localY):
|
||||||
while localX not in [0, 7] and localY not in [0, 7]:
|
|
||||||
localX += direction[0]
|
localX += direction[0]
|
||||||
localY += direction[1]
|
localY += direction[1]
|
||||||
if board.getPieceAt(localX, localY) == None:
|
if board.getPieceAt(localX, localY) == None:
|
||||||
|
@ -49,13 +71,25 @@ class Piece:
|
||||||
return
|
return
|
||||||
|
|
||||||
if piece.type == 'p':
|
if piece.type == 'p':
|
||||||
addMoveIfTrue(1, 1, pieceIsEnemyColor)
|
localY = 1 if piece.color == 'black' else -1
|
||||||
addMoveIfTrue(-1, 1, pieceIsEnemyColor)
|
startPosition = 1 if piece.color == 'black' else 6
|
||||||
if addMoveIfTrue(0, 1, pieceIsEmpty):
|
addMoveIfTrue(1, localY, pieceIsEnemyColor)
|
||||||
addMoveIfTrue(0, 2, lambda pieceToCheck: pieceToCheck == None and piece.moves == 0)
|
addMoveIfTrue(-1, localY, pieceIsEnemyColor)
|
||||||
|
if addMoveIfTrue(0, localY, pieceIsEmpty):
|
||||||
|
addMoveIfTrue(0, localY * 2,
|
||||||
|
lambda pieceToCheck: pieceToCheck == None and y == startPosition)
|
||||||
|
|
||||||
elif piece.type == 'n':
|
elif piece.type == 'n':
|
||||||
positions = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)]
|
positions = [
|
||||||
|
(-2, -1),
|
||||||
|
(-2, 1),
|
||||||
|
(-1, -2),
|
||||||
|
(-1, 2),
|
||||||
|
(1, -2),
|
||||||
|
(1, 2),
|
||||||
|
(2, -1),
|
||||||
|
(2, 1),
|
||||||
|
]
|
||||||
for position in positions:
|
for position in positions:
|
||||||
addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor)
|
addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor)
|
||||||
|
|
||||||
|
@ -65,10 +99,8 @@ class Piece:
|
||||||
for position in positions:
|
for position in positions:
|
||||||
addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor)
|
addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor)
|
||||||
|
|
||||||
moves = [position for position in moves if assertNotCheck(*position)]
|
|
||||||
|
|
||||||
elif piece.type == 'r':
|
elif piece.type == 'r':
|
||||||
for direction in product([0, 1], repeat=2):
|
for direction in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
|
||||||
addWhileInsideBoard(direction)
|
addWhileInsideBoard(direction)
|
||||||
|
|
||||||
elif piece.type == 'b':
|
elif piece.type == 'b':
|
||||||
|
@ -81,9 +113,14 @@ class Piece:
|
||||||
for direction in directions:
|
for direction in directions:
|
||||||
addWhileInsideBoard(direction)
|
addWhileInsideBoard(direction)
|
||||||
|
|
||||||
#TODO: remove moves that will put the king in check
|
# Remove moves that will lead the piece out of the board
|
||||||
|
moves = [move for move in moves if positionInsideBounds(*move)]
|
||||||
|
|
||||||
|
# Remove moves that won't block the path for whichever piece has caused the game to check
|
||||||
if legalMoves != None and piece.type != 'k':
|
if legalMoves != None and piece.type != 'k':
|
||||||
moves = [move for move in moves if move in legalMoves]
|
moves = [move for move in moves if move in legalMoves]
|
||||||
|
|
||||||
|
# Remove moves that will put the king in check
|
||||||
|
# moves = [position for position in moves if assertNotCheck(*position)]
|
||||||
|
|
||||||
return moves
|
return moves
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
from shutil import get_terminal_size as getTerminalSize
|
||||||
|
|
||||||
|
# ░█▀▄░█▀█░█▀█░█▀▄░█▀█░█▄█░░░█▀▀░█░█░▀█▀░▀█▀
|
||||||
|
# ░█▀▄░█▀█░█░█░█░█░█░█░█░█░░░▀▀█░█▀█░░█░░░█░
|
||||||
|
# ░▀░▀░▀░▀░▀░▀░▀▀░░▀▀▀░▀░▀░░░▀▀▀░▀░▀░▀▀▀░░▀░
|
||||||
|
|
||||||
|
def centerText(text):
|
||||||
|
terminalWidth = getTerminalSize((60, 0))[0] # Column size 60 as fallback
|
||||||
|
return "\n".join(line.center(terminalWidth) for line in text.split('\n'))
|
||||||
|
|
||||||
|
def centerBlockText(text):
|
||||||
|
terminalWidth = getTerminalSize((60, 0))[0] # Column size 60 as fallback
|
||||||
|
textArray = text.split('\n')
|
||||||
|
offset = int((terminalWidth - len(textArray[0])) / 2)
|
||||||
|
return "\n".join(offset * ' ' + line for line in textArray)
|
||||||
|
|
||||||
|
boxCharsToBoldBoxCharsMap = {
|
||||||
|
'─': '═',
|
||||||
|
'│': '║',
|
||||||
|
'┼': '╬',
|
||||||
|
'╰': '╚',
|
||||||
|
'╯': '╝',
|
||||||
|
'╭': '╔',
|
||||||
|
'╮': '╗',
|
||||||
|
'├': '╠',
|
||||||
|
'┴': '╩',
|
||||||
|
'┤': '╣',
|
||||||
|
'┬': '╦',
|
||||||
|
}
|
||||||
|
|
||||||
|
def determineMove(key, x, y, maxmin) -> tuple:
|
||||||
|
if key in ['s', 'j'] and y != maxmin[1]: return (0, 1)
|
||||||
|
elif key in ['w', 'k'] and y != maxmin[0]: return (0, -1)
|
||||||
|
elif key in ['d', 'l'] and x != maxmin[1]: return (1, 0)
|
||||||
|
elif key in ['a', 'h'] and x != maxmin[0]: return (-1, 0)
|
||||||
|
else: return False
|
Loading…
Reference in New Issue