399 lines
9.3 KiB
Python
399 lines
9.3 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_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_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")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|