Files
snake-python/server/GameBoard.py
T

163 lines
4.2 KiB
Python

from snakes.TemplateSnake import TemplateSnake
from datetime import datetime
class GameBoard:
def __init__(self, game_id:str, width:int, height:int, ruleset:dict, source:str, map:str, snake_class:TemplateSnake):
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 = []
# Accept old "ladder" value and current API values "league"/"arena" as competitive sources
self.is_ladder = source in {'ladder', 'league', 'arena'}
self.ruleset = ruleset
self.map = map
self.url = self._get_game_url(True if ruleset["version"] == "cli" else False)
self.timeout = 500
# Snake Helper Functions
def get_snake_name_and_version(self) -> tuple[str, str]:
return self.snake_class.name, self.snake_class.version
# 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:dict):
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_map(self):
return self.map
def get_ruleset(self):
return self.ruleset
def get_timeout(self):
return self.timeout
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"])
self.timeout = int(game_data.get('game', {}).get('timeout', 500))
async 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_game()
# Function get Called from Server
def snake_neat_make_a_move(self):
move = self.snake_class.choose_move(self)
self.turns.append({
"turn": 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_game(self):
if self.init_snakes == 2:
return {"name": "duel", "is_ladder": self.is_ladder}
return {"name": self.type, "is_ladder": self.is_ladder}
def __getstate__(self):
state = self.__dict__.copy()
state['turns'] = [] # strip turn history — grows linearly, not needed for move computation
return state
async def save(self, store_class, **kwargs):
store = store_class(**kwargs)
await store.save(self)
del store