Skip to content

Instantly share code, notes, and snippets.

@sandordargo
Last active February 28, 2017 16:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sandordargo/705965bc55a0e9cafca9b6852c0fcf97 to your computer and use it in GitHub Desktop.
Save sandordargo/705965bc55a0e9cafca9b6852c0fcf97 to your computer and use it in GitHub Desktop.
ghost in the cell bronze top 50
import sys
from collections import defaultdict
# send to multiples from one, if can
# if closest is enemy and three or two, bomb
# zero prod could bomb
class Increase(object):
def __init__(self, factory):
self.factory = factory
def __str__(self):
return "INC {}".format(self.factory)
class Move(object):
def __init__(self, source, target, size=100):
self.source = source
self.target = target
self.size = size
def __str__(self):
return "MOVE {} {} {}".format(self.source, self.target, self.size)
class BombAction(object):
def __init__(self, source, target):
self.source = source
self.target = target
def __str__(self):
return "BOMB {} {}".format(self.source, self.target)
class Link(object):
def __init__(self, factory_1, factory_2, distance):
self.factory_1 = factory_1
self.factory_2 = factory_2
self.distance = distance
def __str__(self):
return "LINK from {} to {} takes {}".format(self.factory_1, self.factory_2, self.distance)
class Factory(object):
def __init__(self, entity_id, owner, population, production):
self.entity_id = entity_id
self.owner = owner
self.population = population
self.production = production
def __repr__(self):
return "*** id: {id}, owner: {owner}, population: {population}, production: {production}\n***".format(
id=self.entity_id, owner=self.owner,
population=self.population, production=self.production)
def __str__(self):
return self.__repr__()
class Troop(object):
def __init__(self, entity_id, owner, source, target, size, turns_to_arrive):
self.entity_id = entity_id
self.owner = owner
self.source = source
self.target = target
self.size = size
self.turns_to_arrive = turns_to_arrive
def __repr__(self):
return "*** id: {id}, owner: {owner}, source: {source}, target: {target}, size: {size}: arrival {arrival}***".format(
id=self.entity_id, owner=self.owner, source=self.source, target=self.target,
size=self.size, arrival=self.turns_to_arrive)
class Bomb(object):
def __init__(self, entity_id, owner, source, target, turns_to_arrive):
self.entity_id = entity_id
self.owner = owner
self.source = source
self.target = target
self.turns_to_arrive = turns_to_arrive
def get_factory_by_id(factories, id):
for factory in factories:
if factory.entity_id == id:
return factory
class Game(object):
def __init__(self, links, bombs_available):
self.links = links
self.bombs_available = bombs_available
self.turns = 0
self.turns_since_last_bomb = 0
self.factories = []
self.bombs = []
def get_next_turn(self):
actions = []
for factory in self.get_own_factories():
new_actions = self.get_next_action_of_factory(factory)
if new_actions:
actions.extend(new_actions)
action_strings = [str(action) for action in actions]
if not action_strings:
print("WAIT")
return
print(";".join(action_strings))
def get_own_factories(self):
return [factory for factory in self.factories if factory.owner == 1]
def get_next_action_of_factory(self, factory):
moves = []
candidate_points_map = defaultdict(float)
for candidate in self.factories:
if candidate == factory:
continue
candidate_points_map[candidate] = self.calculate_value_of(candidate, factory)
print("NEW TURN for factory {}".format(factory.entity_id), file=sys.stderr)
for w in sorted(candidate_points_map, key=candidate_points_map.get, reverse=True):
print(w, candidate_points_map[w], file=sys.stderr)
candidates = sorted(candidate_points_map, key=candidate_points_map.get, reverse=True)
if not candidates:
return
while factory.population > 0:
action = self.add_move(factory, candidates)
if not action:
break
if isinstance(action, Move):
factory.population -= action.size
moves.append(action)
candidates.pop(0)
if not candidates:
return moves
return moves
def add_move(self, source, candidates):
if source.production == 0 and source.population > 10:
print("increase man", file=sys.stderr)
return Increase(source.entity_id)
if candidates[0].owner == -1 and candidates[0].production in [2, 3] and self.bombs_available > 0 and not self.is_bomb_targeting(candidates[0]):
self.bombs_available -= 1
return BombAction(source.entity_id, candidates[0].entity_id)
if candidates[0].owner != 1:
return Move(source.entity_id, candidates[0].entity_id, candidates[0].population + 1)
else:
return Move(source.entity_id, candidates[0].entity_id, source.population // 2)
def calculate_value_of(self, candidate, factory):
value_of_candidate = candidate.production
distance = self.get_distance_between(candidate, factory)
if candidate.owner == 1 and candidate.population < 10:
value_of_candidate += 1
if candidate.owner == 1 and candidate.population > 10:
value_of_candidate -= 1
if distance:
value_of_candidate += 10 * (1/distance)
else:
value_of_candidate = -1
return value_of_candidate
def get_distance_between(self, candidate, factory):
for link in self.links:
if link.factory_1 == candidate.entity_id and link.factory_2 == factory.entity_id:
return link.distance
if link.factory_2 == candidate.entity_id and link.factory_1 == factory.entity_id:
return link.distance
return None
def is_bomb_targeting(self, candidate):
for bomb in self.bombs:
if bomb.target == candidate.entity_id:
return True
return False
factory_count = int(input()) # the number of factories
link_count = int(input()) # the number of links between factories
links = []
for i in range(link_count):
factory_1, factory_2, distance = [int(j) for j in input().split()]
links.append(Link(factory_1, factory_2, distance))
# for link in links:
# print(link, file=sys.stderr)
bombs_available = 2
game = Game(links, bombs_available)
while True:
factories = []
troops = []
bombs = []
entity_count = int(input()) # the number of entities (e.g. factories and troops)
for i in range(entity_count):
entity_id, entity_type, arg_1, arg_2, arg_3, arg_4, arg_5 = input().split()
entity_id = int(entity_id)
arg_1 = int(arg_1)
arg_2 = int(arg_2)
arg_3 = int(arg_3)
arg_4 = int(arg_4)
arg_5 = int(arg_5)
if entity_type == "FACTORY":
factories.append(Factory(entity_id, arg_1, arg_2, arg_3))
if entity_type == "TROOP":
troops.append(Troop(entity_id, arg_1, arg_2, arg_3, arg_4, arg_5))
if entity_type == "BOMB":
bombs.append(Bomb(entity_id, arg_1, arg_2, arg_3, arg_4))
game.factories = factories
game.bombs = bombs
game.get_next_turn()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment