commit c62cb433f73273cea5766917f535fcf950e1606b Author: Boyan Date: Sat Aug 12 01:29:34 2023 +0300 Made the game and README diff --git a/README.md b/README.md new file mode 100644 index 0000000..b722907 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ + +# Othelloworld + +This is a small exercise which involves creating a functioning othello/reversi game in the terminal and implementing the minimax algorithm in order to create an AI for the player to play against. Part of a hobby hackathon with my friends. + +## Network +To be continued... diff --git a/src/game.py b/src/game.py new file mode 100644 index 0000000..5573c5f --- /dev/null +++ b/src/game.py @@ -0,0 +1,137 @@ +from enum import Enum +from terminaltables import AsciiTable +from os import system +import shutil + +class Color(Enum): + WHITE = 1 + BLACK = 2 + EMPTY = -1 + +class Direction(Enum): + UP = (0, -1) + DOWN = (0, 1) + LEFT = (-1, 0) + RIGHT = (1, 0) + UP_LEFT = (-1, -1) + UP_RIGHT = (1, -1) + DOWN_LEFT = (-1, 1) + DOWN_RIGHT = (1, 1) + +class Board: + def __init__(self): + # Initialize board + self.board = {i: [Color.EMPTY.value for _ in range(8)] for i in range(8)} + + self.play_move(Color.WHITE, 3,3, initial=True) + self.play_move(Color.WHITE, 4,4, initial=True) + self.play_move(Color.BLACK, 3,4, initial=True) + self.play_move(Color.BLACK, 4,3, initial=True) + self.mover = False + + # print(self.board) + + # Correcting the syntax error and redefining the function + + def check_direction(self, move, x, y, direction): + opponent = Color.WHITE if move == Color.BLACK else Color.BLACK + + dx, dy = direction.value + to_flip = list() + x += dx + y += dy + to_flip = list() + if not (0 <= x < 8 and 0 <= y < 8) or self.board[x][y] != opponent.value: + return False + + while 0 <= x < 8 and 0 <= y < 8 and self.board[x][y] == opponent.value: + to_flip.append((x, y)) + x += dx + y += dy + + if not (0 <= x < 8 and 0 <= y < 8) or self.board[x][y] == Color.EMPTY.value: + return False + + for i in to_flip: + self.board[i[0]][i[1]] = move.value + + return self.board[x][y] == move.value + + def check_move(self, move:Color, x:int, y:int): + once = False + for direction in Direction: + result = self.check_direction(move, x, y, direction) + if result: + once = True + return once + + def play_move(self, move:Color, x:int, y:int, initial=False): + # Check if move is valid + if not initial: + if self.board[x][y] != Color.EMPTY.value: + raise KeyError("On top") + + result = self.check_move(move, x, y) + + if not result: + raise KeyError("Invalid move") + self.board[x][y] = move.value + + def display_board(self): + table_data = [[" " for i in range(8)] for j in range(8)] + + for x in range(8): + for y in range(8): + if self.board[x][y] == 1: + table_data[y][x] = "■" + elif self.board[x][y] == 2: + table_data[y][x] = "□" + else: + table_data[y][x] = "🟨" + + table_data.insert(0, [" ", 0, 1, 2, 3, 4, 5, 6, 7]) + for i in range(8): + table_data[i+1].insert(0, i) + + table = AsciiTable(table_data) + table.inner_column_border = False + table.column_max_width = 1 + table.title = self.get_mover().name.lower() + "'s turn" + table.padding_right =0 + return print(table.table) + + def switch_mover(self): + self.mover = not self.mover + + def get_mover(self): + if not self.mover: + return Color.BLACK + else: + return Color.WHITE + +def main(): + board = Board() + + while True: + system("clear") + + board.display_board() + + move = input("What is your move?\n") + move = move.split(" ") + move = [int(move[0]), int(move[1])] + try: + board.play_move(move=board.get_mover(), x=move[0], y=move[1]) + + except KeyError as e: + print("Invalid move: " + str(move)) + input("Press enter to continue...") + + + board.switch_mover() + +if __name__=="__main__": + try: + main() + except KeyboardInterrupt: + pass \ No newline at end of file