From 4335edea974ebaa5ae7137ba6d8a854594c03329 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Tue, 10 Nov 2020 23:56:21 +0100 Subject: [PATCH] Add partial exercise 10 --- .gitignore | 3 +- Exercise 10/1.py | 17 +++++ Exercise 10/2.py | 7 ++ Exercise 10/chess/board.py | 131 +++++++++++++++++++++++++++++++++++++ Exercise 10/chess/chess.py | 33 ++++++++++ Exercise 10/chess/piece.py | 74 +++++++++++++++++++++ 6 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 Exercise 10/1.py create mode 100644 Exercise 10/2.py create mode 100644 Exercise 10/chess/board.py create mode 100644 Exercise 10/chess/chess.py create mode 100644 Exercise 10/chess/piece.py diff --git a/.gitignore b/.gitignore index f7d5d75..b10d2b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__ -.vscode \ No newline at end of file +.vscode +.vim diff --git a/Exercise 10/1.py b/Exercise 10/1.py new file mode 100644 index 0000000..5dbb4fb --- /dev/null +++ b/Exercise 10/1.py @@ -0,0 +1,17 @@ +from math import floor + +recursive_sum = lambda n: 1 if n == 1 else n + recursive_sum(n - 1) + +merge_sum = lambda lst: lst[0] if len(lst) == 1 else merge_sum(lst[0:floor(len( + lst) / 2)]) + merge_sum(lst[floor(len(lst) / 2):len(lst)]) + + +def find_smallest_element(lst): + if len(lst) == 1: return lst[0] + smallest_element = find_smallest_element(lst[1:]) + return lst[0] if lst[0] < smallest_element else smallest_element + + +def binary_search(numbers, element): + + return -float('inf') diff --git a/Exercise 10/2.py b/Exercise 10/2.py new file mode 100644 index 0000000..18e5ddb --- /dev/null +++ b/Exercise 10/2.py @@ -0,0 +1,7 @@ +from math import sin +import matplotlib.pyplot as plt + +x_verdier = [x/10 for x in range(301)] +y_verdier = [sin(x) for x in x_verdier] +plt.plot(x_verdier, y_verdier, c='r') +plt.show() diff --git a/Exercise 10/chess/board.py b/Exercise 10/chess/board.py new file mode 100644 index 0000000..3aeb4be --- /dev/null +++ b/Exercise 10/chess/board.py @@ -0,0 +1,131 @@ +from os import system + +from piece import Piece + + +class Board: + + def __init__(self): + self.boardArray = [ + # [], + [Piece('p', 'black') for _ in range(8)], + [Piece('p', 'black') for _ in range(8)], + *[[None for _ in range(8)] for _ in range(4)], + [Piece('p', 'white') for _ in range(8)], + [Piece('p', 'white') for _ in range(8)], + # [], + ] + + def draw( + self, + config={ + 'highlightedContent': [], + 'highlightEscapeCodes': ('\033[32;5;7m', '\033[0m'), + 'highlightedBoxes': [], + 'center': False + } + ) -> str: + """Returns a string representing the board + + config options: + highlightedContent: [(x,y)] - Pieces to color + highlightEscapeCodes: (str, str) - Terminal escape codes to color highlightedContent with + highlightedBoxes: [(x,y)] - Boxes to make bold + center: Bool - Whether or not to indent the board into the center + """ + + def fillConfigDefaultValue(key, defaultValue): + if key not in config: + config[key] = defaultValue + + fillConfigDefaultValue('highlightedContent', []) + fillConfigDefaultValue('highlightedBoxes', []) + fillConfigDefaultValue('highlightEscapeCodes', ('\033[32;5;7m', '\033[0m')) + fillConfigDefaultValue('center', False) + + # Draw general outline + stringArray = [list('┼' + '───┼' * 8)] + [[None] for _ in range(8 * 2)] + for y, row in enumerate(self.boardArray): + for x, column in enumerate(row): + stringArray[2 * y + 1][4 * x] = '│' + stringArray[2 * y + 2][4 * x] = '┼' + + stringArray[2 * y + 1] += list( + ' {} │'.format(str(self.boardArray[y][x]) if self.boardArray[y][x] != None else ' ')) + stringArray[2 * y + 2] += list('───┼') + + # Overwrite corners + stringArray[0][0] = '╭' + stringArray[0][-1] = '╮' + stringArray[-1][0] = '╰' + stringArray[-1][-1] = '╯' + + # Overwrite T-junctions + for i in range(int(len(stringArray[0]) / 4) - 1): + stringArray[0][i * 4 + 4] = '┬' + stringArray[-1][i * 4 + 4] = '┴' + for i in range(int(len(stringArray) / 2) - 1): + stringArray[i * 2 + 2][0] = '├' + stringArray[i * 2 + 2][-1] = '┤' + + def highlightContent(x, y): + """highlight contents of a piece with xterm-256colors modifiers""" + stringArray[y * 2 + + 1][x * 4 + + 1] = config['highlightEscapeCodes'][0] + stringArray[y * 2 + 1][x * 4 + 1] + stringArray[y * 2 + 1][x * 4 + 3] += config['highlightEscapeCodes'][1] + + def highlightBox(x, y): + """Make box around a piece bold""" + + characterMap = { + '─': '═', + '│': '║', + '┼': '╬', + '╰': '╚', + '╯': '╝', + '╭': '╔', + '╮': '╗', + '├': '╠', + '┴': '╩', + '┤': '╣', + '┬': '╦', + } + + pointsToChange = \ + [(x * 4 + 0, y * 2 + i) for i in range(3)] + \ + [(x * 4 + 4, y * 2 + i) for i in range(3)] + \ + [(x * 4 + i, y * 2 + 0) for i in range(1,4)] + \ + [(x * 4 + i, y * 2 + 2) for i in range(1,4)] + + for x, y in pointsToChange: + stringArray[y][x] = characterMap[ + stringArray[y][x]] if stringArray[y][x] in characterMap else stringArray[y][x] + + for x, y in config['highlightedBoxes']: + highlightBox(x, y) + for x, y in config['highlightedContent']: + highlightContent(x, y) + + # TODO: Center board + + return '\n'.join([''.join(line) for line in stringArray]) + + def selectPiece(self, player) -> tuple: + """Lets the user select a piece from a graphic board""" + + x, y = 0, 0 + while True: + system('clear') + print(player.name, '\n') + print(self.draw({'highlightedBoxes': [(x, y)]}), '\n') + + key = input(f" W E\n A S D <- Enter : ")[0] + if key in ['s', 'j'] and y != 7: y += 1 + elif key in ['w', 'k'] and y != 0: y -= 1 + elif key in ['d', 'l'] and x != 7: x += 1 + elif key in ['a', 'h'] and x != 0: x -= 1 + elif key == 'e': return (x, y) + + def getPieceAt(self, x, y) -> Piece: + return self.boardArray[y][x] diff --git a/Exercise 10/chess/chess.py b/Exercise 10/chess/chess.py new file mode 100644 index 0000000..baad40a --- /dev/null +++ b/Exercise 10/chess/chess.py @@ -0,0 +1,33 @@ +from board import Board +from os import system +from dataclasses import dataclass + +@dataclass +class Player: + name: str + color: str + +class Chess: + + def __init__(self, players): + self.players = players + + def update(self): + system('clear') + + def loop(self): + while True: + self.update() + + +if __name__ == "__main__": + + players = ( + Player('Spiller 1', 'white'), + Player('Spiller 2', 'black'), + ) + + # game = Chess(('Spiller 1', 'Spiller 2')) + # game.loop() + board = Board() + print(board.selectPiece(players[0])) diff --git a/Exercise 10/chess/piece.py b/Exercise 10/chess/piece.py new file mode 100644 index 0000000..32f7414 --- /dev/null +++ b/Exercise 10/chess/piece.py @@ -0,0 +1,74 @@ +from typing import Iterable, Callable +from itertools import product + + +class Piece: + + def __init__(self, type, color): + self.type = type + self.color = color + + def __str__(self): + return self.type.upper() if self.color == 'white' else self.type + + @staticmethod + def possibleMoves(x, y, board) -> Callable[[int, int], Iterable[tuple]]: + piece = board.getPieceAt(x, y) + moves = [] + + pieceIsEnemyColor = lambda pieceToCheck: pieceToCheck != None and pieceToCheck.color != piece.color + pieceIsEmpty = lambda pieceToCheck: pieceToCheck == None + pieceIsEmptyOrEnemyColor = lambda pieceToCheck: pieceToCheck == None or pieceToCheck.color != piece.color + + def addMoveIfTrue(xOffset, yOffset, condition): + if condition(board.getPieceAt(x + xOffset, y + yOffset)): + moves.append((x + xOffset, y + yOffset)) + return True + return False + + def addWhileInsideBoard(direction): + localX = x + localY = y + while localX not in [0, 7] and localY not in [0, 7]: + localX += direction[0] + localY += direction[1] + if board.getPieceAt(localX, localY) == None: + moves.append((localX, localY)) + else: + if board.getPieceAt(localX, localY).color != piece.color: + moves.append((localX, localY)) + return + + if piece.type == 'p': + addMoveIfTrue(1, 1, pieceIsEnemyColor) + addMoveIfTrue(-1, 1, pieceIsEnemyColor) + if addMoveIfTrue(0, 1, pieceIsEmpty): + addMoveIfTrue(0, 2, lambda pieceToCheck: pieceToCheck == None and piece.moves == 0) + + elif piece.type == 'n': + positions = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)] + for position in positions: + addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor) + + elif piece.type == 'k': + positions = list(product([-1, 0, 1], repeat=2)) + positions.remove((0, 0)) + for position in positions: + addMoveIfTrue(*position, pieceIsEmptyOrEnemyColor) + # TODO: Check moves for check and remove the bad ones + + elif piece.type == 'r': + for direction in product([0, 1], repeat=2): + addWhileInsideBoard(direction) + + elif piece.type == 'b': + for direction in product([-1, 1], repeat=2): + addWhileInsideBoard(direction) + + elif piece.type == 'q': + directions = list(product([-1, 0, 1], repeat=2)) + directions.remove((0, 0)) + for direction in directions: + addWhileInsideBoard(direction) + + return moves