Skip to content

Instantly share code, notes, and snippets.

@OzTamir
Created December 31, 2013 14:12
Show Gist options
  • Save OzTamir/8197345 to your computer and use it in GitHub Desktop.
Save OzTamir/8197345 to your computer and use it in GitHub Desktop.
sudo's winning code, cleaned up and documented properly - now in a public gist. Written by Oz Tamir, Tomer Schlesinger and Eden Rozen.
def DoTurn(pw):
Overtake(pw)
def Attack(pw, source, target, ships):
'''
A custom controller for pw built-in IssueOrder() method
'''
if source.NumShips() < ships:
send = source.NumShips()
else:
send = ships
pw.IssueOrder(source, target, send)
def Overtake(pw):
'''
The commanding function. Responsible for deciding what planet to attack and from what planet to launch the attacks.
'''
# Get a list of my planets, sorted by amount of ships (From high to low)
my_planets = sorted(pw.MyPlanets(), key = lambda planet: planet.NumShips(), reverse = True)
# Get a list of possible targets for attack
targets = pw.NotMyPlanets()
# Get a list of all the planet currently under attack
fleetTargets = [pw.GetPlanet(fleet.DestinationPlanet()) for fleet in (pw.EnemyFleets() + pw.MyFleets())]
# Narrow the targets down to those that can be captured without any doubt (as for the current turn)
targets = [target for target in targets if target not in fleetTargets]
if len(targets) > 0:
# Iterate over all the planets which are under my control and find a target (if possible)
for i in range(len(my_planets)):
planet = my_planets[i]
# Get a list of target that can be captured by the current planet
targetsForOvertake = []
for target in targets:
# Calculate the predicted number of ships on targeted planet upon arrival
futureShips = futureShipsInPlanet(target, pw.Distance(planet, target))
# If the planet can be captured, add it to the list of the current planet's targets
if planet.NumShips() > futureShips + 1:
targetsForOvertake.append(target)
# Get a list of the target's Factors (see calcFactor())
optimalTargetsFactor = map(calcFactor, targetsForOvertake)
if optimalTargetsFactor:
# Find the target with the best factor...
maxFactor = max(optimalTargetsFactor)
maxIndex = 0
for i in targetsForOvertake:
if maxFactor == i:
maxIndex = i
# ... and the corresponding target
target = targetsForOvertake[maxIndex]
# Finally, attack the selected planet with the minimal number of ships required to capture it
Attack(pw, planet, target , futureShipsInPlanet(target, pw.Distance(planet, target)) + 1)
def calcFactor(target):
'''
Calculate the factor of target as a function of it's number of ships and it's owner.
The factor indicate how recommended will it be to launch an attack on target.
'''
# The factor take into account the owner of the target, and friendly planet will have smaller factors.
ownerMult = 10
if target.Owner == 1:
ownerMult = 15
return target.GrowthRate() / ((target.NumShips() + 1) * ownerMult)
def futureShipsInPlanet(planet, turns):
'''
Predict the number of ships in planet in 'turns' turns (assuming that our fleet will be the first to get ther in 'turns')
'''
# Netural planet don't grow, therefore the number of ships won't change
if planet.Owner() == 0:
return planet.NumShips()
# Else, return the predicted number of ships as
return planet.NumShips() + planet.GrowthRate() * turns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment