main #3
@@ -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
@@ -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
@@ -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"]]
|
||||||
|
|||||||
Reference in New Issue
Block a user