Files
snake-python/tests/test_BestBattleSnake.py
T

834 lines
20 KiB
Python

import unittest
from snakes.BestBattleSnake import BestBattleSnake
from server.GameBoard import GameBoard
def make_board(game_state):
board = GameBoard(
game_id=game_state["game"]["id"],
width=game_state["board"]["width"],
height=game_state["board"]["height"],
ruleset=game_state["game"]["ruleset"],
source=game_state["game"]["source"],
map=game_state["game"]["map"],
snake_class=BestBattleSnake(),
)
board.read_game_data(game_state)
return board
class TestBestBattleSnake(unittest.TestCase):
def test_avoids_walls_and_body(self):
game_state = {
"game": {
"id": "test-wall-body",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 20,
"board": {
"height": 7,
"width": 7,
"food": [{"x": 5, "y": 5}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 90,
"length": 4,
"head": {"x": 0, "y": 0},
"body": [
{"x": 0, "y": 0},
{"x": 0, "y": 1},
{"x": 1, "y": 1},
{"x": 1, "y": 0},
],
}
],
},
"you": {
"id": "me",
"name": "me",
"health": 90,
"length": 4,
"head": {"x": 0, "y": 0},
"body": [
{"x": 0, "y": 0},
{"x": 0, "y": 1},
{"x": 1, "y": 1},
{"x": 1, "y": 0},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertEqual(move, "right")
def test_prioritizes_food_when_low_health(self):
game_state = {
"game": {
"id": "test-food-low-health",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 32,
"board": {
"height": 11,
"width": 11,
"food": [{"x": 6, "y": 5}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 10,
"length": 3,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
],
}
],
},
"you": {
"id": "me",
"name": "me",
"health": 10,
"length": 3,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertEqual(move, "right")
def test_prioritizes_food_when_safe(self):
game_state = {
"game": {
"id": "test-food-safe",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 8,
"board": {
"height": 11,
"width": 11,
"food": [{"x": 6, "y": 5}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 95,
"length": 3,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
],
}
],
},
"you": {
"id": "me",
"name": "me",
"health": 95,
"length": 3,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertEqual(move, "right")
def test_avoids_losing_head_to_head(self):
game_state = {
"game": {
"id": "test-head-to-head",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 44,
"board": {
"height": 11,
"width": 11,
"food": [{"x": 1, "y": 1}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 90,
"length": 3,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
],
},
{
"id": "enemy",
"name": "enemy",
"health": 90,
"length": 6,
"head": {"x": 7, "y": 5},
"body": [
{"x": 7, "y": 5},
{"x": 7, "y": 4},
{"x": 7, "y": 3},
{"x": 7, "y": 2},
{"x": 7, "y": 1},
{"x": 6, "y": 1},
],
},
],
},
"you": {
"id": "me",
"name": "me",
"health": 90,
"length": 3,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertNotEqual(move, "right")
def test_duel_small_length_lead_does_not_head_hunt(self):
game_state = {
"game": {
"id": "test-duel-small-no-head-hunt",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 20,
"board": {
"height": 11,
"width": 11,
"food": [{"x": 1, "y": 1}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 90,
"length": 7,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
{"x": 4, "y": 3},
{"x": 4, "y": 4},
{"x": 4, "y": 5},
{"x": 4, "y": 6},
],
},
{
"id": "enemy",
"name": "enemy",
"health": 90,
"length": 6,
"head": {"x": 7, "y": 5},
"body": [
{"x": 7, "y": 5},
{"x": 7, "y": 4},
{"x": 7, "y": 3},
{"x": 7, "y": 2},
{"x": 7, "y": 1},
{"x": 6, "y": 1},
],
},
],
},
"you": {
"id": "me",
"name": "me",
"health": 90,
"length": 7,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
{"x": 4, "y": 3},
{"x": 4, "y": 4},
{"x": 4, "y": 5},
{"x": 4, "y": 6},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertNotEqual(move, "right")
def test_duel_big_length_lead_can_head_hunt(self):
game_state = {
"game": {
"id": "test-duel-big-head-hunt",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 20,
"board": {
"height": 11,
"width": 11,
"food": [{"x": 1, "y": 1}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 90,
"length": 8,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
{"x": 4, "y": 3},
{"x": 4, "y": 4},
{"x": 4, "y": 5},
{"x": 4, "y": 6},
{"x": 5, "y": 6},
],
},
{
"id": "enemy",
"name": "enemy",
"health": 90,
"length": 6,
"head": {"x": 7, "y": 5},
"body": [
{"x": 7, "y": 5},
{"x": 7, "y": 4},
{"x": 7, "y": 3},
{"x": 7, "y": 2},
{"x": 7, "y": 1},
{"x": 6, "y": 1},
],
},
],
},
"you": {
"id": "me",
"name": "me",
"health": 90,
"length": 8,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
{"x": 4, "y": 3},
{"x": 4, "y": 4},
{"x": 4, "y": 5},
{"x": 4, "y": 6},
{"x": 5, "y": 6},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertEqual(move, "right")
def test_does_not_step_into_stacked_tail(self):
game_state = {
"game": {
"id": "test-stacked-tail",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 15,
"board": {
"height": 11,
"width": 11,
"food": [{"x": 10, "y": 10}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 90,
"length": 5,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 4, "y": 4},
{"x": 4, "y": 5},
{"x": 4, "y": 5},
],
}
],
},
"you": {
"id": "me",
"name": "me",
"health": 90,
"length": 5,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 4, "y": 4},
{"x": 4, "y": 5},
{"x": 4, "y": 5},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertNotEqual(move, "left")
def test_avoids_food_if_it_is_a_dead_end(self):
game_state = {
"game": {
"id": "test-food-dead-end",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 30,
"board": {
"height": 7,
"width": 7,
"food": [{"x": 3, "y": 4}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 70,
"length": 3,
"head": {"x": 3, "y": 3},
"body": [
{"x": 3, "y": 3},
{"x": 3, "y": 2},
{"x": 3, "y": 1},
],
},
{
"id": "enemy",
"name": "enemy",
"health": 90,
"length": 5,
"head": {"x": 2, "y": 4},
"body": [
{"x": 2, "y": 4},
{"x": 2, "y": 5},
{"x": 3, "y": 5},
{"x": 4, "y": 5},
{"x": 4, "y": 4},
],
},
],
},
"you": {
"id": "me",
"name": "me",
"health": 70,
"length": 3,
"head": {"x": 3, "y": 3},
"body": [
{"x": 3, "y": 3},
{"x": 3, "y": 2},
{"x": 3, "y": 1},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertNotEqual(move, "up")
def test_avoids_enemy_block_in_trap(self):
game_state = {
"game": {
"id": "test-enemy-block-in-trap",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 24,
"board": {
"height": 7,
"width": 7,
"food": [{"x": 3, "y": 3}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 72,
"length": 4,
"head": {"x": 3, "y": 2},
"body": [
{"x": 3, "y": 2},
{"x": 3, "y": 1},
{"x": 2, "y": 1},
{"x": 2, "y": 2},
],
},
{
"id": "enemy-a",
"name": "enemy-a",
"health": 90,
"length": 6,
"head": {"x": 4, "y": 4},
"body": [
{"x": 4, "y": 4},
{"x": 4, "y": 3},
{"x": 4, "y": 2},
{"x": 5, "y": 2},
{"x": 5, "y": 3},
{"x": 5, "y": 4},
],
},
{
"id": "enemy-b",
"name": "enemy-b",
"health": 90,
"length": 6,
"head": {"x": 1, "y": 3},
"body": [
{"x": 1, "y": 3},
{"x": 1, "y": 4},
{"x": 0, "y": 4},
{"x": 0, "y": 3},
{"x": 0, "y": 2},
{"x": 1, "y": 2},
],
},
],
},
"you": {
"id": "me",
"name": "me",
"health": 72,
"length": 4,
"head": {"x": 3, "y": 2},
"body": [
{"x": 3, "y": 2},
{"x": 3, "y": 1},
{"x": 2, "y": 1},
{"x": 2, "y": 2},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertEqual(move, "left")
def test_royale_uses_ruleset_hazard_damage_setting(self):
game_state = {
"game": {
"id": "test-royale-hazard-setting",
"ruleset": {
"name": "standard",
"version": "v1.0.0",
"settings": {"hazardDamagePerTurn": 22},
},
"source": "custom",
"map": "royale",
},
"turn": 5,
"board": {
"height": 11,
"width": 11,
"food": [],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 80,
"length": 3,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
],
}
],
},
"you": {
"id": "me",
"name": "me",
"health": 80,
"length": 3,
"head": {"x": 5, "y": 5},
"body": [
{"x": 5, "y": 5},
{"x": 5, "y": 4},
{"x": 5, "y": 3},
],
},
}
board = make_board(game_state)
snake = board.snake_class
self.assertEqual(snake._hazard_damage_per_turn(board), 22)
def test_royale_new_hazard_has_spawn_grace(self):
snake = BestBattleSnake()
point = (4, 4)
hazard_set = {point}
self.assertFalse(
snake._hazard_is_active(
point, ate_food=False, hazard_set=hazard_set, previous_hazard_set=set()
)
)
self.assertTrue(
snake._hazard_is_active(
point,
ate_food=False,
hazard_set=hazard_set,
previous_hazard_set=hazard_set,
)
)
self.assertFalse(
snake._hazard_is_active(
point,
ate_food=True,
hazard_set=hazard_set,
previous_hazard_set=hazard_set,
)
)
def test_constrictor_avoids_growth_dead_end(self):
game_state = {
"game": {
"id": "test-constrictor-dead-end",
"ruleset": {"name": "constrictor", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 12,
"board": {
"height": 7,
"width": 7,
"food": [],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 100,
"length": 4,
"head": {"x": 1, "y": 1},
"body": [
{"x": 1, "y": 1},
{"x": 1, "y": 0},
{"x": 0, "y": 0},
{"x": 0, "y": 1},
],
},
{
"id": "enemy",
"name": "enemy",
"health": 100,
"length": 8,
"head": {"x": 4, "y": 4},
"body": [
{"x": 4, "y": 4},
{"x": 3, "y": 4},
{"x": 3, "y": 3},
{"x": 2, "y": 3},
{"x": 2, "y": 2},
{"x": 2, "y": 0},
{"x": 2, "y": 2},
{"x": 3, "y": 1},
],
},
],
},
"you": {
"id": "me",
"name": "me",
"health": 100,
"length": 4,
"head": {"x": 1, "y": 1},
"body": [
{"x": 1, "y": 1},
{"x": 1, "y": 0},
{"x": 0, "y": 0},
{"x": 0, "y": 1},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertEqual(move, "up")
def test_duel_tightens_space_when_enemy_is_encased(self):
game_state = {
"game": {
"id": "test-encase-tighten",
"ruleset": {"name": "standard", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 40,
"board": {
"height": 7,
"width": 7,
"food": [{"x": 0, "y": 0}],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 92,
"length": 8,
"head": {"x": 2, "y": 3},
"body": [
{"x": 2, "y": 3},
{"x": 2, "y": 2},
{"x": 1, "y": 2},
{"x": 1, "y": 3},
{"x": 1, "y": 4},
{"x": 2, "y": 4},
{"x": 3, "y": 4},
{"x": 3, "y": 5},
],
},
{
"id": "enemy",
"name": "enemy",
"health": 88,
"length": 5,
"head": {"x": 4, "y": 3},
"body": [
{"x": 4, "y": 3},
{"x": 5, "y": 3},
{"x": 5, "y": 2},
{"x": 4, "y": 2},
{"x": 4, "y": 1},
],
},
],
},
"you": {
"id": "me",
"name": "me",
"health": 92,
"length": 8,
"head": {"x": 2, "y": 3},
"body": [
{"x": 2, "y": 3},
{"x": 2, "y": 2},
{"x": 1, "y": 2},
{"x": 1, "y": 3},
{"x": 1, "y": 4},
{"x": 2, "y": 4},
{"x": 3, "y": 4},
{"x": 3, "y": 5},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertEqual(move, "right")
def test_constrictor_prefers_choke_when_safe(self):
game_state = {
"game": {
"id": "test-constrictor-choke",
"ruleset": {"name": "constrictor", "version": "v1.0.0"},
"source": "custom",
"map": "standard",
},
"turn": 25,
"board": {
"height": 7,
"width": 7,
"food": [],
"hazards": [],
"snakes": [
{
"id": "me",
"name": "me",
"health": 100,
"length": 7,
"head": {"x": 2, "y": 3},
"body": [
{"x": 2, "y": 3},
{"x": 2, "y": 2},
{"x": 1, "y": 2},
{"x": 1, "y": 3},
{"x": 1, "y": 4},
{"x": 2, "y": 4},
{"x": 2, "y": 5},
],
},
{
"id": "enemy",
"name": "enemy",
"health": 100,
"length": 7,
"head": {"x": 4, "y": 3},
"body": [
{"x": 4, "y": 3},
{"x": 5, "y": 3},
{"x": 5, "y": 2},
{"x": 4, "y": 2},
{"x": 4, "y": 1},
{"x": 5, "y": 1},
{"x": 6, "y": 1},
],
},
],
},
"you": {
"id": "me",
"name": "me",
"health": 100,
"length": 7,
"head": {"x": 2, "y": 3},
"body": [
{"x": 2, "y": 3},
{"x": 2, "y": 2},
{"x": 1, "y": 2},
{"x": 1, "y": 3},
{"x": 1, "y": 4},
{"x": 2, "y": 4},
{"x": 2, "y": 5},
],
},
}
move = make_board(game_state).snake_neat_make_a_move()
self.assertEqual(move, "right")
if __name__ == "__main__":
unittest.main()