From db3a353090f2fee32e486f5512aedfee45b3cf61 Mon Sep 17 00:00:00 2001 From: Daniel Dolezal Date: Thu, 18 Apr 2024 23:41:53 +0200 Subject: [PATCH] change over to new Game Board class from old Game Storage class --- server/GameStorage.py | 100 ------------------------------------------ server/Server.py | 77 ++++++++++++++++---------------- 2 files changed, 40 insertions(+), 137 deletions(-) delete mode 100644 server/GameStorage.py diff --git a/server/GameStorage.py b/server/GameStorage.py deleted file mode 100644 index b5afad7..0000000 --- a/server/GameStorage.py +++ /dev/null @@ -1,100 +0,0 @@ -from server.Files import save_file -from datetime import datetime -import os - -class GameStorage: - save_folder_dict = { - "standart": "01_Standart", - "duel": "02_Duels", - "constrictor": "04_Constrictor", - } - - def __init__(self, snake:str, path:str, no_store_turns:int=10): - self.snake_type = snake - self.folder = path - self.winner_snake_names = None - self.turns = {} - self.not_store_file_when_you_are_the_winner_and_turns_are = no_store_turns - - def start_new_game(self, game_info:dict, game_board:dict, snake:dict): - self.init_game_board = game_board - self.game_info = game_info - - self.my_snake_id = snake['id'] - self.moves = [] - self.now_date = datetime.now() - self.game_url = self._get_game_url(True if game_info["ruleset"]["version"] == "cli" else False) - - def add_moves(self, turn:int, game_board:dict, my_move:str): - self.turns[turn] = { - "move": my_move, - "game_board": game_board - } - - def add_end_state(self, game_board:dict, snake_history_state:list[dict], final_turns:int): - self.final_turns = final_turns - self.snake_history = snake_history_state - self._set_winner_snake_name(game_board['snakes']) - - def _get_game_url(self, local_game:bool): - if local_game: - return None - return f"https://play.battlesnake.com/game/{self.game_info['id']}" - - def _set_winner_snake_name(self, snakes:list[dict]): - if self.my_snake_id in [ x["id"] for x in snakes]: - self.winner_snake_names = "me" - else: - self.winner_snake_names = [ x["name"] for x in snakes] - if len(self.winner_snake_names) == 0: - self.winner_snake_names = None - - def _get_type_of_gameboard(self): - if len(self.init_game_board["snakes"]) == 2: - return {"name": "duel", "is_ladder": True if self.game_info["source"] == "ladder" else False} - elif self.game_info["ruleset"]["name"] == "constrictor": - return {"name": "constrictor", "is_ladder": True if self.game_info["source"] == "ladder" else False} - - return {"name": "standart", "is_ladder": True if self.game_info["source"] == "ladder" else False} - - def _get_correct_folder_for_save_file(self, file_name:str, game_type:str, leader_board:bool, winner:bool): - storage_folder = self.folder - if leader_board: - storage_folder = os.path.join(storage_folder, "00_Leaderboards") - - storage_folder = os.path.join(storage_folder, self.save_folder_dict[game_type]) - storage_folder = os.path.join(storage_folder, self.now_date.strftime('%Y'), self.now_date.strftime('%m_%B'), self.now_date.strftime('%d')) - - if winner: - storage_folder = os.path.join(storage_folder, "Winner") - else: - storage_folder = os.path.join(storage_folder, "Lost") - - return os.path.join(storage_folder, file_name) - - def save(self, file_name:str, callback=None, **kwargs): - if self.winner_snake_names == "me" and self.final_turns <= self.not_store_file_when_you_are_the_winner_and_turns_are: - return None - - game_type = self._get_type_of_gameboard() - save_file_path = self._get_correct_folder_for_save_file(file_name, game_type["name"], game_type["is_ladder"], True if self.winner_snake_names == "me" else False) - - save_file(save_file_path, { - "winner": self.winner_snake_names, - "game": { - "url": self.game_url, - "id": self.game_info["id"], - "final_turns": self.final_turns, - "map": self.game_info["map"], - "type": game_type, - "ruleset": self.game_info["ruleset"], - }, - "moves": self.turns, - "snake": { - "type": self.snake_type, - "calculations": self.snake_history, - }, - }, callback=callback, **kwargs) - - def __str__(self): - return f"<{self.__class__.__name__}> Snake: {self.snake_type}, Folder: {self.folder}, Winner: {self.winner_snake_names}, Old Moves: {self.moves}" diff --git a/server/Server.py b/server/Server.py index 5672e9e..879e8ad 100644 --- a/server/Server.py +++ b/server/Server.py @@ -1,9 +1,7 @@ from server.Files import read_file -from server.GameStorage import GameStorage -from snakes.TemplateSnake import TemplateSnake +from server.GameBoard import GameBoard from server.SnakeBuilder import SnakeBuilder -from datetime import datetime from flask import Flask from flask import request import logging, json, os, re @@ -21,8 +19,7 @@ class Server: self.store_game_state = False self.store_game_when_win_and_moves_are_bigger_as = store_game_when_win_and_moves_are_bigger_as - self.running_games:dict[str, GameStorage] = {} - self.running_snake:dict[str, TemplateSnake] = {} + self.running_games:dict[str, GameBoard] = {} self.app = Flask("Battlesnake") @@ -73,6 +70,36 @@ class Server: config[key.lower()] = os.environ.get(f"SNAKE_{key.upper()}") return config + def _create_game_board(self, game_state:dict): + new_game_board = GameBoard( + game_id=game_state["game"]["id"], + width=game_state['board']['width'], + height=game_state['board']['height'], + ruleset=game_state['game']["ruleset"], + source=game_state['game']['source'], + map=game_state['game']['map'], + snake_class=SnakeBuilder.build(self.snake_type) + ) + new_game_board.start_game(game_state) + + self.running_games[game_state["game"]["id"]] = new_game_board + return new_game_board + + def _delete_game_board(self, game_state): + del self.running_games[game_state["game"]["id"]] + + def _get_game_board(self, game_state:str, end:bool=False): + try: + game_board = self.running_games[game_state["game"]["id"]] + except KeyError: + game_board = self._create_game_board(game_state) + + game_board.read_game_data(game_state) + if end: + game_board.end_game(game_state) + + return game_board + def enable_store_game_state(self): self.store_game_state = True @@ -87,32 +114,13 @@ class Server: # start is called when your Battlesnake begins a game def _start(self, game_state:dict): - if self.store_game_state: - self.running_games[game_state["game"]["id"]] = GameStorage( - self.snake_type, - path=os.path.join(self.data_path, 'data'), - no_store_turns=self.store_game_when_win_and_moves_are_bigger_as - ) - self.running_games[game_state["game"]["id"]].start_new_game(game_state["game"], game_state["board"], game_state["you"]) - - self.running_snake[game_state["game"]["id"]] = SnakeBuilder.build(self.snake_type) + self._create_game_board(game_state) print("GAME START:", game_state["game"]) # move is called when your Battlesnake game is running game def _move(self, game_state:dict) -> dict: - try: - next_move = self.running_snake[game_state["game"]["id"]].choose_move(game_state) - except KeyError: - self.running_snake[game_state["game"]["id"]] = SnakeBuilder.build(self.snake_type) - next_move = self.running_snake[game_state["game"]["id"]].choose_move(game_state) - - if self.store_game_state: - try: - self.running_games[game_state["game"]["id"]].add_moves(game_state["turn"], game_state["board"], next_move) - if self.debug: - print(self.running_games[game_state["game"]["id"]]) - except KeyError: - pass + game_board = self._get_game_board(game_state) + next_move = game_board.snake_neat_make_a_move() if self.debug: print("TURN:", f'{game_state["turn"]:3},', "MOVE:", f"{next_move:5}") @@ -122,17 +130,12 @@ class Server: # end is called when your Battlesnake finishes a game def _end(self, game_state:dict): if self.store_game_state: - snake = self.running_snake[game_state["game"]["id"]] - - try: - self.running_games[game_state["game"]["id"]].add_end_state(game_state["board"], snake.get_history(), game_state["turn"]) - self.running_games[game_state["game"]["id"]].save( - f"{snake.__class__.__name__}_{datetime.now().strftime('%H-%M-%S')}_{game_state['game']['id']}.json", + game_board = self._get_game_board(game_state, end=True) + if not game_board.get_winner() == "me" and not game_board.get_turn() <= self.store_game_when_win_and_moves_are_bigger_as: + game_board.save( + file_path=os.path.join(self.data_path, 'data'), callback=json.dump, indent=2, ensure_ascii=False ) - del self.running_games[game_state["game"]["id"]] - except KeyError: - print(f"ERROR: Can't find Game {game_state['game']['id']} in Storage") print("GAME ENDED: Winner is", [ x["name"] for x in game_state["board"]['snakes']]) - del self.running_snake[game_state["game"]["id"]] + self._delete_game_board(game_state)