Merge pull request 'main' (#3) from main into dev

Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
2024-04-13 11:48:40 +02:00
3 changed files with 43 additions and 17 deletions
+1 -2
View File
@@ -12,7 +12,6 @@
# To get you started we've included code to prevent your Battlesnake from moving backwards. # To get you started we've included code to prevent your Battlesnake from moving backwards.
# For more info see docs.battlesnake.com # For more info see docs.battlesnake.com
from server.SnakeBuilder import SnakeBuilder
from server.Server import Server from server.Server import Server
from dotenv import load_dotenv, find_dotenv from dotenv import load_dotenv, find_dotenv
@@ -24,7 +23,7 @@ if __name__ == "__main__":
server = Server( server = Server(
data_path=os.path.dirname(__file__), data_path=os.path.dirname(__file__),
snake=SnakeBuilder.build(os.environ.get("SNAKE", "DummSnake")), snake_type=os.environ.get("SNAKE", "DummSnake"),
) )
if os.environ.get("STORE_GAME_HISTORY", None): if os.environ.get("STORE_GAME_HISTORY", None):
+20 -3
View File
@@ -5,6 +5,7 @@ class GameStorage:
def __init__(self, snake:str, path:str): def __init__(self, snake:str, path:str):
self.snake_type = snake self.snake_type = snake
self.folder = path self.folder = path
self.winner_snake_names = None
def start_new_game(self, game_type:dict, game_board:dict, snake:dict): def start_new_game(self, game_type:dict, game_board:dict, snake:dict):
self.game_type = game_type self.game_type = game_type
@@ -16,27 +17,43 @@ class GameStorage:
self.game_board.append(game_board) self.game_board.append(game_board)
self.moves.append(my_move) self.moves.append(my_move)
def add_end_state(self, game_board:dict, snake_history_state:list[dict]): def add_end_state(self, game_board:dict, snake_history_state:list[dict], final_turns:int):
self.game_board.append(game_board) self.game_board.append(game_board)
self.snake_history = snake_history_state self.snake_history = snake_history_state
self._set_winner_snake_name(game_board['snakes'])
self.final_turns = final_turns
def set_winner_snake_name(self, snakes:list[dict]): def _set_winner_snake_name(self, snakes:list[dict]):
if self.start_position["id"] in [ x["id"] for x in snakes]: if self.start_position["id"] in [ x["id"] for x in snakes]:
self.winner_snake_names = "me" self.winner_snake_names = "me"
else: else:
self.winner_snake_names = [ x["name"] for x in snakes] self.winner_snake_names = [ x["name"] for x in snakes]
def _get_type_of_gameboard(self):
if len(self.game_board[0]["snakes"]) == 2:
return "duel"
return "standart"
def save(self, path:str, callback=None, **kwargs): def save(self, path:str, callback=None, **kwargs):
if self.winner_snake_names == "me" and self.final_turns <= 10:
return None
save_file(os.path.join(self.folder, path), { save_file(os.path.join(self.folder, path), {
"snake": { "snake": {
"type": self.snake_type, "type": self.snake_type,
"choices": self.snake_history, "choices": self.snake_history,
}, },
"game": { "game": {
"type": self.game_type, "type": self._get_type_of_gameboard(),
"infos": self.game_type,
"snake_start": self.start_position, "snake_start": self.start_position,
"final_turns": self.final_turns,
"gameboard": self.game_board, "gameboard": self.game_board,
"my_moves": self.moves, "my_moves": self.moves,
}, },
"winner": self.winner_snake_names, "winner": self.winner_snake_names,
}, callback=callback, **kwargs) }, 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}"
+22 -12
View File
@@ -1,6 +1,7 @@
from server.Files import read_file, save_file from server.Files import read_file, save_file
from server.GameStorage import GameStorage from server.GameStorage import GameStorage
from snakes.TemplateSnake import TemplateSnake from snakes.TemplateSnake import TemplateSnake
from server.SnakeBuilder import SnakeBuilder
from datetime import datetime from datetime import datetime
from flask import Flask from flask import Flask
@@ -10,13 +11,16 @@ import logging, json, os
class Server: class Server:
default_snake_config = {"apiversion":"1","author":"","color":"#888888","head":"default","tail":"default"} default_snake_config = {"apiversion":"1","author":"","color":"#888888","head":"default","tail":"default"}
def __init__(self, data_path:str, snake:TemplateSnake, debug:bool=False): def __init__(self, data_path:str, snake_type:str, debug:bool=False):
self.debug = debug self.debug = debug
self.snake = snake self.snake_type = snake_type
self.config_file = os.path.join(data_path, 'data', 'snake-config.json') self.config_file = os.path.join(data_path, 'data', 'snake-config.json')
self.game_state_storage = GameStorage(snake.__class__.__name__, path=os.path.join(data_path, 'data', 'history')) self.data_path = data_path
self.store_game_state = False self.store_game_state = False
self.running_games:dict[str, GameStorage] = {}
self.running_snake:dict[str, TemplateSnake] = {}
self.app = Flask("Battlesnake") self.app = Flask("Battlesnake")
@@ -51,7 +55,7 @@ class Server:
def run(self, host:str="0.0.0.0", port:str="8000", debug:bool=False): def run(self, host:str="0.0.0.0", port:str="8000", debug:bool=False):
logging.getLogger("werkzeug").setLevel(logging.ERROR) logging.getLogger("werkzeug").setLevel(logging.ERROR)
print(f"\nRunning Battlesnake at http://{host}:{port} with the {self.snake.__class__.__name__.replace('Snake', '')} Snake") print(f"\nRunning Battlesnake at http://{host}:{port} with the {self.snake_type.replace('Snake', '')} Snake")
self.app.run(host=host, port=port, debug=debug) self.app.run(host=host, port=port, debug=debug)
def _read_json_config_or_create(self): def _read_json_config_or_create(self):
@@ -75,17 +79,20 @@ class Server:
# start is called when your Battlesnake begins a game # start is called when your Battlesnake begins a game
def _start(self, game_state:dict): def _start(self, game_state:dict):
if self.store_game_state: if self.store_game_state:
self.game_state_storage.start_new_game(game_state["game"], game_state["board"], game_state["you"]) self.running_games[game_state["game"]["id"]] = GameStorage(self.snake.__class__.__name__, path=os.path.join(self.data_path, 'data', 'history'))
self.running_games[game_state["game"]["id"]].start_new_game(game_state["game"], game_state["board"], game_state["you"])
self.snake.clear_history() self.running_snake[game_state["game"]["id"]] = SnakeBuilder.build(self.snake_type)
print("GAME START:", game_state["game"]) print("GAME START:", game_state["game"])
# move is called when your Battlesnake game is running game # move is called when your Battlesnake game is running game
def _move(self, game_state:dict) -> dict: def _move(self, game_state:dict) -> dict:
next_move = self.snake.choose_move(game_state) next_move = self.running_snake[game_state["game"]["id"]].choose_move(game_state)
if self.store_game_state: if self.store_game_state:
self.game_state_storage.add_moves(game_state["board"], next_move) self.running_games[game_state["game"]["id"]].add_moves(game_state["board"], next_move)
if self.debug:
print(self.running_games[game_state["game"]["id"]])
print("MOVE:", f"{next_move:5},", "Me:", {"head": game_state["you"]["head"], "length": game_state["you"]["length"]}) print("MOVE:", f"{next_move:5},", "Me:", {"head": game_state["you"]["head"], "length": game_state["you"]["length"]})
return {"move": next_move} return {"move": next_move}
@@ -93,11 +100,14 @@ class Server:
# end is called when your Battlesnake finishes a game # end is called when your Battlesnake finishes a game
def _end(self, game_state:dict): def _end(self, game_state:dict):
if self.store_game_state: if self.store_game_state:
self.game_state_storage.add_end_state(game_state["board"], self.snake.get_history()) snake = self.running_snake[game_state["game"]["id"]]
self.game_state_storage.set_winner_snake_name(game_state["board"]['snakes'])
self.game_state_storage.save( self.running_games[game_state["game"]["id"]].add_end_state(game_state["board"], snake.get_history(), game_state["turn"])
f"{self.snake.__class__.__name__}_{datetime.now().strftime('%d.%m.%Y_%H%M%S')}_{game_state['game']['id']}.json", self.running_games[game_state["game"]["id"]].save(
f"{snake.__class__.__name__}_{datetime.now().strftime('%d.%m.%Y_%H%M%S')}_{game_state['game']['id']}.json",
callback=json.dump, indent=2, ensure_ascii=False callback=json.dump, indent=2, ensure_ascii=False
) )
del self.running_games[game_state["game"]["id"]]
print("GAME OVER:\n- Winner is", [ x["name"] for x in game_state["board"]['snakes']]) print("GAME OVER:\n- Winner is", [ x["name"] for x in game_state["board"]['snakes']])
del self.running_snake[game_state["game"]["id"]]