183 lines
5.1 KiB
Python
183 lines
5.1 KiB
Python
from server.Files import save_file
|
|
from datetime import datetime
|
|
import os
|
|
|
|
class GameBoard:
|
|
save_folder_dict = {
|
|
"standart": "01_Standart",
|
|
"duel": "02_Duels",
|
|
"constrictor": "04_Constrictor",
|
|
}
|
|
|
|
def __init__(self, game_id:str, width:int, height:int, ruleset:dict, source:str, map:str, snake_class):
|
|
self.id = game_id
|
|
self.width = width
|
|
self.height = height
|
|
self.type = ruleset["name"]
|
|
self.snake_class = snake_class
|
|
|
|
# What will get Stored
|
|
self.winner_snake_names = None
|
|
self.now_date = datetime.now()
|
|
self.turns = {}
|
|
self.is_ladder = True if source == "ladder" else False
|
|
self.ruleset = ruleset
|
|
self.map = map
|
|
|
|
# Setter Functions
|
|
def _set_snakes(self, snakes:list[dict]):
|
|
self.other_snakes = [ x for x in snakes if x["id"] != self.my_snake["id"] ]
|
|
|
|
def _set_my_snake(self, my_snake:str):
|
|
self.my_snake = my_snake
|
|
|
|
def _set_food(self, food:list[dict]):
|
|
self.food = food
|
|
|
|
def _set_hazards(self, hazards:list[dict]):
|
|
self.hazards = hazards
|
|
|
|
def _set_turn(self, turn:int):
|
|
self.turn = turn
|
|
|
|
# Getter Functions
|
|
def get_other_snakes(self):
|
|
return self.other_snakes
|
|
|
|
def get_my_snake(self):
|
|
return self.my_snake
|
|
|
|
def get_food(self):
|
|
return self.food
|
|
|
|
def get_hazard(self):
|
|
return self.hazards
|
|
|
|
def get_turn(self):
|
|
return self.turn
|
|
|
|
def get_dimension(self):
|
|
return {"width": self.width, "height": self.height}
|
|
|
|
def get_width(self):
|
|
return self.width
|
|
|
|
def get_height(self):
|
|
return self.height
|
|
|
|
def get_type(self):
|
|
return self.type
|
|
|
|
def get_my_snake_head(self):
|
|
return self.my_snake["head"]
|
|
|
|
def get_my_snake_body(self):
|
|
return self.my_snake["body"]
|
|
|
|
def get_my_snake_tail(self):
|
|
return self.my_snake["body"][-1]
|
|
|
|
def get_game_board_as_dict(self):
|
|
snakes = [self.my_snake]
|
|
snakes.extend(self.other_snakes)
|
|
|
|
return {
|
|
"height": self.height,
|
|
"width": self.width,
|
|
"snakes": snakes,
|
|
"food": self.food,
|
|
"hazards": self.hazards
|
|
}
|
|
|
|
# Game Functions
|
|
def read_game_data(self, game_data:dict):
|
|
self._set_food(game_data['board']['food'])
|
|
self._set_hazards(game_data['board']['hazards'])
|
|
|
|
self._set_my_snake(game_data['you'])
|
|
self._set_snakes(game_data['board']['snakes'])
|
|
|
|
self._set_turn(game_data["turn"])
|
|
|
|
def start_game(self, game_data:dict):
|
|
self.init_snakes = len(game_data['board']['snakes'])
|
|
|
|
def end_game(self, game_data:dict):
|
|
self._set_winner_snake_name(game_data['board']['snakes'])
|
|
self._get_type_of_gameboard()
|
|
|
|
# Function get Called from Server
|
|
def snake_neat_make_a_move(self):
|
|
move = self.snake_class.choose_move(self)
|
|
self.turns[self.turn] = {
|
|
"move": move,
|
|
"game_board": self.get_game_board_as_dict()
|
|
}
|
|
return move
|
|
|
|
# Save functions
|
|
def _get_game_url(self, local_game:bool):
|
|
if local_game:
|
|
return None
|
|
return f"https://play.battlesnake.com/game/{self.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_winner(self):
|
|
return self.winner_snake_names
|
|
|
|
def _get_type_of_gameboard(self):
|
|
if self.init_snakes == 2:
|
|
return {"name": "duel", "is_ladder": self.is_ladder}
|
|
elif self.type == "constrictor":
|
|
return {"name": "constrictor", "is_ladder": self.is_ladder}
|
|
return {"name": "standart", "is_ladder": self.is_ladder}
|
|
|
|
def _get_correct_folder_for_save_file(self, file_path:str, file_name:str, game_type:str, leader_board:bool, winner:bool):
|
|
storage_folder = file_path
|
|
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_path:str, callback=None, **kwargs):
|
|
game_type = self._get_type_of_gameboard()
|
|
save_file_path = self._get_correct_folder_for_save_file(
|
|
file_path,
|
|
f"{self.snake_class.__class__.__name__}_{datetime.now().strftime('%H-%M-%S')}_{self.id}.json",
|
|
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._get_game_url(True if self.ruleset["version"] == "cli" else False),
|
|
"id": self.id,
|
|
"final_turns": self.turn,
|
|
"map": self.map,
|
|
"type": game_type,
|
|
"ruleset": self.ruleset,
|
|
},
|
|
"moves": self.turns,
|
|
"snake": {
|
|
"type": self.snake_class.__class__.__name__,
|
|
"calculations": self.snake_class.get_history(),
|
|
},
|
|
}, callback=callback, **kwargs)
|