change over to new Game Board class from old Game Storage class

This commit is contained in:
2024-04-18 23:41:53 +02:00
parent 1f4d17d42f
commit db3a353090
2 changed files with 40 additions and 137 deletions
-100
View File
@@ -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}"
+40 -37
View File
@@ -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)