M board.py => board.py +13 -0
@@ 1,4 1,17 @@
from copy import deepcopy
+from typing import List, Union
+from state import Snake, Pos
+
+# TODO: notes
+def get_snake_bodies_2(snakes: List[Snake], you: Union[Snake, None]=None) -> List[Pos]:
+ bodies = []
+ for snake in snakes:
+ body = deepcopy(snake[1])
+ if you != None and snake == you:
+ bodies += body[1:]
+ else:
+ bodies += body
+ return bodies
def get_snake_bodies(snakes, you=None):
"""
M logic.py => logic.py +35 -1
@@ 4,12 4,46 @@ import itertools
from typing import Literal, Tuple, List
import bitboard
from state import State
-from board import is_snake_in_board, get_snake_bodies, get_next_pos
+from board import is_snake_in_board, get_snake_bodies, get_snake_bodies_2, get_next_pos
Dir = Literal["up", "down", "left", "right"]
Move = Tuple[str, Dir]
# TODO: advance_state that handles new state format
+def advance_state_2(prev_state: State, moves: List[Move]) -> State:
+ snakes = deepcopy(prev_state["snakes"]) # TODO: verify this copy is correct
+ food = deepcopy(prev_state["food"]) # TODO: verify this copy is correct
+
+ # move snakes
+ for [snake_id, body] in snakes:
+ move = None
+ for [move_snake_id, snake_move] in moves:
+ if move_snake_id == snake_id:
+ move = snake_move
+ break
+ head = get_next_pos(prev_state["board"], body[0], move)
+ body = [head] + body # NOTE: might be a more efficient way to do this
+
+ # kill off snakes that run into each other
+ # TODO: handle head-to-head interactions
+ alive_snakes = []
+ for snake in snakes:
+ if snake[1][0] not in get_snake_bodies_2(snakes, snake):
+ alive_snakes.append(snake)
+
+
+ # handle food / growth interactions
+ # loop through food
+ # if food is at head of snake, remove snake and keep snake at length
+ # if snake hasn't eaten, remove tail
+
+ return {
+ "turn": prev_state["turn"] + 1,
+ "board": prev_state["board"],
+ "hazards": prev_state["hazards"],
+ "food": [], # TODO
+ "snakes": alive_snakes,
+ }
def advance_state(state, moves: List[Move]):
new_state = deepcopy(state) # gross
M state.py => state.py +8 -8
@@ 1,14 1,7 @@
from typing import Dict, List, Tuple, TypedDict
Pos = Tuple[int, int]
-Snake = Tuple[str, List[Pos]]
-
-def dict_to_tuple(pos: Dict[str, int]) -> Pos:
- """
- Convert a dictionary of `{"x": 0, "y": 0}` to a tuple of `(0, 0)` for more
- efficient (and immutable) position storage.
- """
- return (pos["x"], pos["y"])
+Snake = Tuple[str, List[Pos]] # TODO: health?
class State(TypedDict):
"""
@@ 21,6 14,13 @@ class State(TypedDict):
hazards: List[Pos]
snakes: List[Snake]
+def dict_to_tuple(pos: Dict[str, int]) -> Pos:
+ """
+ Convert a dictionary of `{"x": 0, "y": 0}` to a tuple of `(0, 0)` for more
+ efficient (and immutable) position storage.
+ """
+ return (pos["x"], pos["y"])
+
def parse_state(state) -> State:
"""
Turn the game state object from the Battlesnake API into the format used