Try to avoid mines
This commit is contained in:
parent
d7fb6f278a
commit
47fb9df56c
1 changed files with 133 additions and 55 deletions
|
@ -1,19 +1,24 @@
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
from enum import Enum
|
|
||||||
from typing import List, Union, Sequence, TypeVar, Optional, Dict
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from enum import Enum, IntEnum
|
||||||
BARREL = 'BARREL'
|
from typing import List, Sequence, Optional, Dict
|
||||||
SHIP = 'SHIP'
|
|
||||||
MINE = 'MINE'
|
|
||||||
CANNONBALL = 'CANNONBALL'
|
|
||||||
|
|
||||||
DEFAULT_SHOOT_WAIT = 2
|
DEFAULT_SHOOT_WAIT = 2
|
||||||
DEFAULT_MINE_WAIT = 4
|
DEFAULT_MINE_WAIT = 4
|
||||||
|
|
||||||
|
|
||||||
|
class EntityType(Enum):
|
||||||
|
BARREL = 'BARREL'
|
||||||
|
SHIP = 'SHIP'
|
||||||
|
MINE = 'MINE'
|
||||||
|
CANNONBALL = 'CANNONBALL'
|
||||||
|
|
||||||
|
|
||||||
|
class Orientation(IntEnum):
|
||||||
|
RIGHT, TOP_RIGHT, TOP_LEFT, LEFT, BOTTOM_LEFT, BOTTOM_RIGHT = range(6)
|
||||||
|
|
||||||
|
|
||||||
class Action(Enum):
|
class Action(Enum):
|
||||||
MINE = 'MINE'
|
MINE = 'MINE'
|
||||||
MOVE = 'MOVE'
|
MOVE = 'MOVE'
|
||||||
|
@ -63,6 +68,8 @@ class GameMap:
|
||||||
def add_my_ship(self, ship: 'Ship'):
|
def add_my_ship(self, ship: 'Ship'):
|
||||||
my_ship = self.my_ships.get(ship.id, None)
|
my_ship = self.my_ships.get(ship.id, None)
|
||||||
if my_ship:
|
if my_ship:
|
||||||
|
my_ship.x = ship.x
|
||||||
|
my_ship.y = ship.y
|
||||||
my_ship.orientation = ship.orientation
|
my_ship.orientation = ship.orientation
|
||||||
my_ship.speed = ship.speed
|
my_ship.speed = ship.speed
|
||||||
my_ship.stock = ship.stock
|
my_ship.stock = ship.stock
|
||||||
|
@ -85,6 +92,9 @@ class GameMap:
|
||||||
def _add_to_map(self, entity: 'Entity'):
|
def _add_to_map(self, entity: 'Entity'):
|
||||||
self.map[entity.coord] = entity
|
self.map[entity.coord] = entity
|
||||||
|
|
||||||
|
def get_at(self, tile: 'Tile'):
|
||||||
|
return self.map[tile.coord]
|
||||||
|
|
||||||
|
|
||||||
class Tile:
|
class Tile:
|
||||||
def __init__(self, x: int, y: int):
|
def __init__(self, x: int, y: int):
|
||||||
|
@ -95,6 +105,40 @@ class Tile:
|
||||||
def coord(self):
|
def coord(self):
|
||||||
return '{};{}'.format(self.x, self.y)
|
return '{};{}'.format(self.x, self.y)
|
||||||
|
|
||||||
|
def top_left(self):
|
||||||
|
y = self.y - 1
|
||||||
|
x = self.x
|
||||||
|
if self.y % 2 == 0:
|
||||||
|
x -= 1
|
||||||
|
return Tile(x, y)
|
||||||
|
|
||||||
|
def top_right(self):
|
||||||
|
y = self.y - 1
|
||||||
|
x = self.x
|
||||||
|
if self.y % 2 != 0:
|
||||||
|
x += 1
|
||||||
|
return Tile(x, y)
|
||||||
|
|
||||||
|
def left(self):
|
||||||
|
return Tile(self.x - 1, self.y)
|
||||||
|
|
||||||
|
def right(self):
|
||||||
|
return Tile(self.x + 1, self.y)
|
||||||
|
|
||||||
|
def bottom_left(self):
|
||||||
|
y = self.y + 1
|
||||||
|
x = self.x
|
||||||
|
if self.y % 2 == 0:
|
||||||
|
x -= 1
|
||||||
|
return Tile(x, y)
|
||||||
|
|
||||||
|
def bottom_right(self):
|
||||||
|
y = self.y + 1
|
||||||
|
x = self.x
|
||||||
|
if self.y % 2 != 0:
|
||||||
|
x += 1
|
||||||
|
return Tile(x, y)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Tile(x={}, y={})'.format(self.x, self.y)
|
return 'Tile(x={}, y={})'.format(self.x, self.y)
|
||||||
|
|
||||||
|
@ -145,46 +189,97 @@ class Ship(Entity):
|
||||||
entity_id: int, x: int, y: int,
|
entity_id: int, x: int, y: int,
|
||||||
orientation: int, speed: int, stock: int, mine: bool = True):
|
orientation: int, speed: int, stock: int, mine: bool = True):
|
||||||
super().__init__(game_map, entity_id, x, y)
|
super().__init__(game_map, entity_id, x, y)
|
||||||
self.orientation = orientation
|
|
||||||
|
self.orientation = Orientation(orientation)
|
||||||
self.speed = speed
|
self.speed = speed
|
||||||
self.stock = stock
|
self.stock = stock
|
||||||
self.mine = mine
|
self.mine = mine
|
||||||
self.mine_wait = DEFAULT_MINE_WAIT
|
self.mine_wait = DEFAULT_MINE_WAIT
|
||||||
self.shoot_wait = DEFAULT_SHOOT_WAIT
|
self.shoot_wait = DEFAULT_SHOOT_WAIT
|
||||||
self.action = None # type: Optional[Action]
|
|
||||||
self.target = None # type: Optional[Tile]
|
|
||||||
|
|
||||||
def play_turn(self):
|
def play_turn(self):
|
||||||
if self.action is Action.MINE:
|
action = None
|
||||||
|
target = None
|
||||||
|
|
||||||
|
rand = random.random()
|
||||||
|
perr('rand', rand)
|
||||||
|
perr('pos', self.tile)
|
||||||
|
perr('mine_wait', self.mine_wait)
|
||||||
|
perr('shoot_wait', self.shoot_wait)
|
||||||
|
|
||||||
|
perr('on path', self.tiles_on_path())
|
||||||
|
for tile in self.tiles_on_path():
|
||||||
|
if isinstance(tile, Mine) or isinstance(tile, Cannonball):
|
||||||
|
action, target = self.avoid(tile)
|
||||||
|
break
|
||||||
|
|
||||||
|
if not action:
|
||||||
|
if (self.mine_wait > 0 and self.shoot_wait > 0) or rand > 0.4:
|
||||||
|
target = Tile(random.randint(0, 23), random.randint(0, 21))
|
||||||
|
if self.game_map.barrels:
|
||||||
|
target = self.nearest_barrel()
|
||||||
|
|
||||||
|
action = Action.MOVE
|
||||||
|
elif rand > 0.2:
|
||||||
|
action = Action.FIRE
|
||||||
|
target = self.nearest_opponent()
|
||||||
|
else:
|
||||||
|
action = Action.MINE
|
||||||
|
|
||||||
|
if action is Action.MINE:
|
||||||
self.mine_wait = DEFAULT_MINE_WAIT
|
self.mine_wait = DEFAULT_MINE_WAIT
|
||||||
elif self.action is Action.FIRE:
|
elif action is Action.FIRE:
|
||||||
self.shoot_wait = DEFAULT_SHOOT_WAIT
|
self.shoot_wait = DEFAULT_SHOOT_WAIT
|
||||||
|
|
||||||
if self.target:
|
if target:
|
||||||
print('{} {} {}'.format(self.action.value, self.target.x, self.target.y))
|
print('{} {} {}'.format(action.value, target.x, target.y))
|
||||||
else:
|
else:
|
||||||
print(self.action.value)
|
print(action.value)
|
||||||
self.action = None
|
|
||||||
self.target = None
|
|
||||||
self.mine_wait -= 1
|
self.mine_wait -= 1
|
||||||
self.shoot_wait -= 1
|
self.shoot_wait -= 1
|
||||||
|
|
||||||
def drop_mine(self):
|
def avoid(self, tile: Tile):
|
||||||
self.action = Action.MINE
|
action = Action.MOVE
|
||||||
|
target = None
|
||||||
|
if self.orientation is Orientation.RIGHT:
|
||||||
|
target = tile.top_right()
|
||||||
|
elif self.orientation is Orientation.TOP_RIGHT:
|
||||||
|
target = tile.right()
|
||||||
|
elif self.orientation is Orientation.TOP_LEFT:
|
||||||
|
target = tile.left()
|
||||||
|
elif self.orientation is Orientation.LEFT:
|
||||||
|
target = tile.top_left()
|
||||||
|
elif self.orientation is Orientation.BOTTOM_LEFT:
|
||||||
|
target = tile.left()
|
||||||
|
elif self.orientation is Orientation.BOTTOM_RIGHT:
|
||||||
|
target = tile.right()
|
||||||
|
return action, target
|
||||||
|
|
||||||
def wait(self):
|
@property
|
||||||
self.action = Action.WAIT
|
def tile(self):
|
||||||
|
return Tile(self.x, self.y)
|
||||||
|
|
||||||
def slower(self):
|
def tiles_on_path(self):
|
||||||
self.action = Action.SLOWER
|
tile = self.tile
|
||||||
|
perr('tile', tile)
|
||||||
|
tiles = []
|
||||||
|
for _ in range(self.speed + 1):
|
||||||
|
if self.orientation is Orientation.RIGHT:
|
||||||
|
tile = tile.right()
|
||||||
|
elif self.orientation is Orientation.TOP_RIGHT:
|
||||||
|
tile = tile.top_right()
|
||||||
|
elif self.orientation is Orientation.TOP_LEFT:
|
||||||
|
tile = tile.top_left()
|
||||||
|
elif self.orientation is Orientation.LEFT:
|
||||||
|
tile = tile.left()
|
||||||
|
elif self.orientation is Orientation.BOTTOM_LEFT:
|
||||||
|
tile = tile.bottom_left()
|
||||||
|
elif self.orientation is Orientation.BOTTOM_RIGHT:
|
||||||
|
tile = tile.bottom_right()
|
||||||
|
tiles.append(tile)
|
||||||
|
|
||||||
def shoot(self, target: 'Entity'):
|
return tiles
|
||||||
self.action = Action.FIRE
|
|
||||||
self.target = target
|
|
||||||
|
|
||||||
def move(self, target: Tile):
|
|
||||||
self.action = Action.MOVE
|
|
||||||
self.target = target
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return ('Ship(id={}, x={}, y={}, orientation={}, speed={}, stock={}, mine={})'
|
return ('Ship(id={}, x={}, y={}, orientation={}, speed={}, stock={}, mine={})'
|
||||||
|
@ -226,12 +321,13 @@ def main():
|
||||||
entity_id = int(entity_id)
|
entity_id = int(entity_id)
|
||||||
x = int(x)
|
x = int(x)
|
||||||
y = int(y)
|
y = int(y)
|
||||||
|
entity_type = EntityType(entity_type)
|
||||||
|
|
||||||
if entity_type == BARREL:
|
if entity_type is EntityType.BARREL:
|
||||||
rhum_quantity = int(arg_1)
|
rhum_quantity = int(arg_1)
|
||||||
game_map.add_barrel(Barrel(game_map, entity_id, x, y, rhum_quantity))
|
game_map.add_barrel(Barrel(game_map, entity_id, x, y, rhum_quantity))
|
||||||
|
|
||||||
elif entity_type == SHIP:
|
elif entity_type is EntityType.SHIP:
|
||||||
orientation = int(arg_1)
|
orientation = int(arg_1)
|
||||||
speed = int(arg_2)
|
speed = int(arg_2)
|
||||||
rhum_stock = int(arg_3)
|
rhum_stock = int(arg_3)
|
||||||
|
@ -242,10 +338,10 @@ def main():
|
||||||
else:
|
else:
|
||||||
game_map.add_opponent_ship(ship)
|
game_map.add_opponent_ship(ship)
|
||||||
|
|
||||||
elif entity_type == MINE:
|
elif entity_type is EntityType.MINE:
|
||||||
game_map.add_mine(Mine(game_map, entity_id, x, y))
|
game_map.add_mine(Mine(game_map, entity_id, x, y))
|
||||||
|
|
||||||
elif entity_type == CANNONBALL:
|
elif entity_type is EntityType.CANNONBALL:
|
||||||
shooter_id = int(arg_1)
|
shooter_id = int(arg_1)
|
||||||
turns_before_impact = int(arg_2)
|
turns_before_impact = int(arg_2)
|
||||||
game_map.add_cannonball(Cannonball(game_map, entity_id, x, y, shooter_id, turns_before_impact))
|
game_map.add_cannonball(Cannonball(game_map, entity_id, x, y, shooter_id, turns_before_impact))
|
||||||
|
@ -254,24 +350,6 @@ def main():
|
||||||
|
|
||||||
# Play
|
# Play
|
||||||
for ship in game_map.my_ships.values():
|
for ship in game_map.my_ships.values():
|
||||||
rand = random.random()
|
|
||||||
perr('rand', rand)
|
|
||||||
perr('mine_wait', ship.mine_wait)
|
|
||||||
perr('shoot_wait', ship.shoot_wait)
|
|
||||||
|
|
||||||
if (ship.mine_wait > 0 and ship.shoot_wait > 0) or rand > 0.4:
|
|
||||||
target = Tile(random.randint(0, 23), random.randint(0, 21))
|
|
||||||
if game_map.barrels:
|
|
||||||
target = ship.nearest_barrel()
|
|
||||||
|
|
||||||
ship.move(target)
|
|
||||||
|
|
||||||
elif rand > 0.2:
|
|
||||||
opponent = ship.nearest_opponent()
|
|
||||||
ship.shoot(opponent)
|
|
||||||
else:
|
|
||||||
ship.drop_mine()
|
|
||||||
|
|
||||||
ship.play_turn()
|
ship.play_turn()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue