def runTest(Inventory): import Ant import Construction ant1 = Ant.Ant((2,3), Ant.QUEEN, 1) ant2 = Ant.Ant((4,5), Ant.WORKER, 1) construction1 = Construction.Construction((3,4), Construction.TUNNEL) construction2 = Construction.Construction((1,2), Construction.ANTHILL) testInventory = Inventory.Inventory(1,[ant1, ant2], [construction1, construction2], 3) testQueen = testInventory.getQueen() if testQueen == None: raise Exception("getQueen method is not returning existing Queen Ant") testAntHill = testInventory.getAnthill() if testAntHill == None: raise Exception("getAnthill method is not returning existing Ant Hill") testInventoryClone = testInventory.clone() if testInventoryClone == testInventory: raise Exception("The cloned inventory is equal to the original") if testInventoryClone.player != testInventory.player: raise Exception("The cloned inventory does not have the same player as the original Inventory") if testInventoryClone.ants != testInventory.ants: raise Exception("The cloned inventory does not have the same set of ants as the original Inventory") if testInventoryClone.constructions != testInventory.constructions: raise Exception("The cloned inventory does not have the same set of constructions as the original Inventory") if testInventoryClone.foodCount != testInventory.foodCount: raise Exception("The cloned inventory does not have the same number of food pieces as the original Inventory") testInventoryClone.foodCount = 5 if testInventoryClone.foodCount == testInventory.foodCount: raise Exception("The changed cloned inventory food count is the same as the original")
def putFood(neutralInventory): for i in range(0,9): ourGrass = Construction((i, 0), GRASS) otherGrass = Construction((i,9), GRASS) neutralInventory.constrs.append(ourGrass) neutralInventory.constrs.append(otherGrass) for i in range(0,2): ourFood = Construction((i,1), FOOD) otherFood = Construction((i,8), FOOD) neutralInventory.constrs.append(ourFood) neutralInventory.constrs.append(otherFood)
def runTest(Location): import Ant import Construction ant1 = Ant.Ant((2, 3), Ant.QUEEN, 1) ant2 = Ant.Ant((5, 6), Ant.WORKER, 1) construction1 = Construction.Construction((3, 4), Construction.TUNNEL) testLocation = Location.Location((2, 3)) testLocation2 = Location.Location((4, 5)) testLocation.ant = ant1 testLocation.constr = construction1 if (testLocation.ant == None): raise Exception( "Ant is not found at a location where there should be an Ant") if (testLocation.constr == None): raise Exception( "Construction is not found at a location where they should be a Construction" ) if (testLocation2.ant != None): raise Exception("Ant is found at a location where there is no Ant") if (testLocation2.constr != None): raise Exception( "Construction is found at a location where there is not Construction" ) locationClone = testLocation.clone() if locationClone == testLocation: raise Exception("The cloned location is equal to the original") if locationClone.ant != testLocation.ant: raise Exception( "The cloned location does not have the same ant object as the original location" ) if locationClone.constr != testLocation.constr: raise Exception( "The cloned location does not have the same construction as the original location" ) locationClone.ant = ant2 if locationClone.ant == testLocation.ant: raise Exception( "The ant on the cloned location has been changed but is not recognized as different from the original location" )
def getNextState(currentState, move): # variables I will need myGameState = currentState.fastclone() myInv = getCurrPlayerInventory(myGameState) me = myGameState.whoseTurn myAnts = myInv.ants # If enemy ant is on my anthill or tunnel update capture health myTunnels = myInv.getTunnels() myAntHill = myInv.getAnthill() for myTunnel in myTunnels: ant = getAntAt(myGameState, myTunnel.coords) if ant is not None: opponentsAnts = myGameState.inventories[not me].ants if ant in opponentsAnts: myTunnel.captureHealth -= 1 if getAntAt(myGameState, myAntHill.coords) is not None: ant = getAntAt(myGameState, myAntHill.coords) opponentsAnts = myGameState.inventories[not me].ants if ant in opponentsAnts: myAntHill.captureHealth -= 1 # If an ant is built update list of ants antTypes = [WORKER, DRONE, SOLDIER, R_SOLDIER] if move.moveType == BUILD: if move.buildType in antTypes: ant = Ant(myInv.getAnthill().coords, move.buildType, me) myInv.ants.append(ant) # Update food count depending on ant built if move.buildType == WORKER: myInv.foodCount -= 1 elif move.buildType == DRONE or move.buildType == R_SOLDIER: myInv.foodCount -= 2 elif move.buildType == SOLDIER: myInv.foodCount -= 3 # If a building is built update list of buildings and the update food count if move.moveType == BUILD: if move.buildType == TUNNEL: building = Construction(move.coordList[0], move.buildType) myInv.constrs.append(building) myInv.foodCount -= 3 # If an ant is moved update their coordinates and has moved if move.moveType == MOVE_ANT: newCoord = move.coordList[len(move.coordList) - 1] startingCoord = move.coordList[0] for ant in myAnts: if ant.coords == startingCoord: ant.coords = newCoord ant.hasMoved = False # If an ant is carrying food and ends on the anthill or tunnel drop the food if ant.carrying and ant.coords == myInv.getAnthill().coords: myInv.foodCount += 1 ant.carrying = False for tunnels in myTunnels: if ant.carrying and (ant.coords == tunnels.coords): myInv.foodCount += 1 ant.carrying = False # If an ant doesn't have food and ends on the food grab food if not ant.carrying: foods = getConstrList(myGameState, None, (FOOD, )) for food in foods: if food.coords == ant.coords: ant.carrying = True # If my ant is close to an enemy ant attack it adjacentTiles = listAdjacent(ant.coords) for adj in adjacentTiles: if getAntAt(myGameState, adj) is not None: # If ant is adjacent my ant closeAnt = getAntAt(myGameState, adj) if closeAnt.player != me: # if the ant is not me closeAnt.health = closeAnt.health - UNIT_STATS[ ant.type][ATTACK] # attack # If an enemy is attacked and looses all its health remove it from the other players # inventory if closeAnt.health <= 0: enemyAnts = myGameState.inventories[ not me].ants for enemy in enemyAnts: if closeAnt.coords == enemy.coords: myGameState.inventories[ not me].ants.remove(enemy) # If attacked an ant already don't attack any more break return myGameState
def putTheirInventory(inventory): inventory.constrs.append(Construction((0, 7), ANTHILL)) inventory.constrs.append(Construction((1, 7), TUNNEL)) queen = Ant((0, 7), QUEEN, PLAYER_TWO) queen.health = 1 inventory.ants.append(queen) # Queen
def putOurInventory(inventory): inventory.constrs.append(Construction((0,3), ANTHILL)) inventory.constrs.append(Construction((1,3), TUNNEL)) inventory.ants.append(Ant((0,3), QUEEN, PLAYER_ONE)) # Queen inventory.ants.append(Ant((0,6), DRONE, PLAYER_ONE)) # Queen
def getFutureState(self, currentState, move): # create a bare-bones copy of the state to modify newState = currentState.fastclone() # get references to the player inventories playerInv = newState.inventories[newState.whoseTurn] enemyInv = newState.inventories[1 - newState.whoseTurn] if move.moveType == BUILD: # BUILD MOVE if move.buildType < 0: # building a construction playerInv.foodCount -= CONSTR_STATS[move.buildType][BUILD_COST] playerInv.constrs.append( Construction(move.coordList[0], move.buildType)) else: # building an ant playerInv.foodCount -= UNIT_STATS[move.buildType][COST] playerInv.ants.append( Ant(move.coordList[0], move.buildType, newState.whoseTurn)) elif move.moveType == MOVE_ANT: # MOVE AN ANT # get a reference to the ant ant = getAntAt(newState, move.coordList[0]) # update the ant's location after the move ant.coords = move.coordList[-1] ant.hasMoved = True # get a reference to a potential construction at the destination coords constr = getConstrAt(newState, move.coordList[-1]) # check to see if a worker ant is on a food or tunnel or hill and act accordingly if constr and ant.type == WORKER: # if destination is food and ant can carry, pick up food if constr.type == FOOD: if not ant.carrying: ant.carrying = True # if destination is dropoff structure and and is carrying, drop off food elif constr.type == TUNNEL or constr.type == ANTHILL: if ant.carrying: ant.carrying = False playerInv.foodCount += 1 # get a list of the coordinates of the enemy's ants enemyAntCoords = [enemyAnt.coords for enemyAnt in enemyInv.ants] # contains the coordinates of ants that the 'moving' ant can attack validAttacks = [] # go through the list of enemy ant locations and check if # we can attack that spot, and if so add it to a list of # valid attacks (one of which will be chosen at random) for coord in enemyAntCoords: if UNIT_STATS[ant.type][RANGE]**2 >= abs( ant.coords[0] - coord[0])**2 + abs(ant.coords[1] - coord[1])**2: validAttacks.append(coord) # if we can attack, pick a random attack and do it if validAttacks: enemyAnt = getAntAt(newState, random.choice(validAttacks)) attackStrength = UNIT_STATS[ant.type][ATTACK] if enemyAnt.health <= attackStrength: # just to be safe, set the health to 0 enemyAnt.health = 0 # remove the enemy ant from their inventory enemyInv.ants.remove(enemyAnt) else: # lower the enemy ant's health because they were attacked enemyAnt.health -= attackStrength # return the modified copy of the original state return newState
def getFutureState(self, currentState, nextMove): """ :type currentState: GameState :type nextMove: Move :rtype: GameState """ # for ending turns, there is no change to the board if nextMove.moveType == END: return currentState futureState = currentState.fastclone() """:type : GameState""" playerId = currentState.whoseTurn enemyId = playerId * (-1) + 1 if nextMove.moveType == BUILD: if nextMove.buildType == TUNNEL: futureState.inventories[playerId].foodCount -= CONSTR_STATS[ TUNNEL][BUILD_COST] futureState.inventories[playerId].constrs.append( Construction(nextMove.coordList[0], nextMove.buildType)) else: # build an ant futureState.inventories[playerId].foodCount -= UNIT_STATS[ nextMove.buildType][COST] futureState.inventories[playerId].ants.append( Ant(nextMove.coordList[0], nextMove.buildType, playerId)) else: # the move is a MOVE_ANT move, so # find the ant and move it to the target ant = getAntAt(futureState, nextMove.coordList[0]) """:type : Ant""" ant.coords = nextMove.coordList[-1] # see if it moved onto a structure constr = getConstrAt(futureState, nextMove.coordList[-1]) if constr and ant.type == WORKER: # pickup/dropoff food if ant.carrying and (constr.type == ANTHILL or constr.type == TUNNEL): ant.carrying = False futureState.inventories[playerId].foodCount += 1 elif not ant.carrying and constr.type == FOOD: ant.carrying = True # search for possible attacks and execute one for coords in listAdjacent(ant.coords): targetAnt = getAntAt(futureState, coords) """:type : Ant""" # verify that the targetAnt is an enemy if targetAnt and targetAnt.player == playerId: targetAnt = None if targetAnt: targetAnt.health -= UNIT_STATS[ant.type][ATTACK] # remove from board if enemy is killed if targetAnt.health < 1: futureState.inventories[enemyId].ants.remove(targetAnt) continue return futureState
Ant((0, 0), QUEEN, PLAYER_ONE) ], [ Building((2, 2), ANTHILL, PLAYER_ONE), Building((3, 4), TUNNEL, PLAYER_ONE) ], 1) inventory2 = Inventory(PLAYER_TWO, [ Ant((0, 9), SOLDIER, PLAYER_TWO), Ant((1, 9), WORKER, PLAYER_TWO), Ant((7, 2), WORKER, PLAYER_TWO), Ant((9, 9), QUEEN, PLAYER_TWO) ], [ Building((8, 8), ANTHILL, PLAYER_TWO), Building((2, 8), TUNNEL, PLAYER_TWO) ], 1) inventory3 = Inventory( NEUTRAL, [], [Construction((9, 6), GRASS), Construction((4, 0), FOOD)], 0) test1InitState = GameState(None, (inventory1, inventory2, inventory3), PLAY_PHASE, PLAYER_ONE) # evaluate the initial board eval1 = aiPlayer.evaluateState(test1InitState) testMoveBuildDrone = Move(BUILD, [(8, 3)], DRONE) futureState = aiPlayer.getFutureState(test1InitState, testMoveBuildDrone) # verify that the future state is correct droneExists = False for ant in futureState.inventories[PLAYER_ONE].ants: if ant.type == DRONE and ant.coords == (8, 3): droneExists = True