def getMove(self, currentState): #Get my inventory myInv = None for inv in currentState.inventories: if inv.player == currentState.whoseTurn: myInv = inv break #If my inventory is still none, then I don't have one. if myInv == None: return Move(END, None, None) #Try to build an ant if myInv.foodCount >= UNIT_STATS[SOLDIER][COST]: #is there enough food? #Detect whether the anthill has nothing on top of it hill = myInv.getAnthill() if currentState.board[hill.coords[0]][hill.coords[1]].ant == None: #build a random ant toPlace = random.randint(WORKER, R_SOLDIER) return Move(BUILD, [hill.coords], random.randint(WORKER, R_SOLDIER)) #See if you can move any ants antsToMove = [] for ant in myInv.ants: if not ant.hasMoved: antsToMove.append(ant) #Move first of these ants if antsToMove != []: chosen = antsToMove[0] coordList = [chosen.coords] totalCost = 0 lastStep = None while totalCost < UNIT_STATS[chosen.type][MOVEMENT]: #pick a random direction that won't move me back. possibleDirections = [(0, 1), (0, -1), (1, 0), (-1, 0)] validDirections = [] for direction in possibleDirections: nextLoc = addCoords(coordList[-1], direction) #Check that the move would be inside the board bounds if nextLoc[0] > 9 or nextLoc[0] < 0 or nextLoc[1] > 9 or nextLoc[1] < 0: continue #Check that the move cost would not exceed what this ant is capable of costOfStep = currentState.board[nextLoc[0]][nextLoc[1]].getMoveCost() if currentState.board[nextLoc[0]][nextLoc[1]].ant == None and UNIT_STATS[chosen.type][MOVEMENT] >= totalCost + costOfStep: validDirections.append(direction) #If no directions are valid, break out of the loop. if validDirections == []: break else: #Choose a random direction randDir = random.randint(0, len(validDirections) - 1) #Apply it nextCoord = addCoords(coordList[-1], validDirections[randDir]) coordList.append(nextCoord) #Add its cost to the total move cost totalCost += currentState.board[nextCoord[0]][nextCoord[1]].getMoveCost() #Return the chosen move return Move(MOVE_ANT, coordList, None) #If I can't to anything, end turn return Move(END, None, None)
def drawTextBox(self): #Start by drawing the text box in the appropriate color. pygame.draw.rect(self.screen, DARK_RED if self.textBoxContent == '' else LIGHT_GREEN, self.buttonRect.move(self.textPosition)) #Then draw the number in the text box. label = self.gameFont.render(self.textBoxContent + ('|' if self.boxSelected else ''), True, BLACK) offset = subtractCoords(self.buttonRect.center, label.get_rect().center) self.screen.blit(label, addCoords(self.textPosition, offset)) #Finally, draw the text box title. boxLabel = self.gameFont.render("Games to play:", True, BLACK) boxLabelOffset = (0, - boxLabel.get_height() - FIELD_SPACING) self.screen.blit(boxLabel, addCoords(self.textPosition, boxLabelOffset))
def drawCaptureHealth(self, health, coords, player): #Create and add settings to the text we want to draw. Background needs to be set so we don't have per pixel alpha. label = self.captureFont.render(str(health), True, LIGHT_RED if player == PLAYER_ONE else LIGHT_BLUE, WHITE) label.set_colorkey(WHITE) label.set_alpha(100) #Find where to place the text. sizeDiff = subtractCoords(CELL_SIZE.size, subtractCoords(label.get_size(), (0, 10))) halfDiff = (sizeDiff[0] / 2, sizeDiff[1] / 2) #Draw the text. self.screen.blit(label, addCoords(coords, halfDiff))
def getMove(self, currentState): #Get my inventory myInv = None for inv in currentState.inventories: if inv.player == currentState.whoseTurn: myInv = inv break #If my inventory is still none, then I don't have one. if myInv == None: return Move(END, None, None) #If you have the food for an ant tunnel, try to purchase something random. if myInv.foodCount >= CONSTR_STATS[TUNNEL][BUILD_COST]: #First detect whether you have an ant WORKER with nothing under it placeableAnts = [] for ant in myInv.ants: if currentState.board[ant.coords[0]][ant.coords[1]].constr == None and ant.type == WORKER and not ant.hasMoved: placeableAnts.append(ant) #Then detect whether you have an anthill with nothing on top of it placeableHill = False hill = myInv.getAnthill() if currentState.board[hill.coords[0]][hill.coords[1]].ant == None: placeableHill = True #Choose randomly between building ants or tunnels if len(placeableAnts) != 0 and placeableHill: #randint returns up to the max, so no need to add or subtract for placeableHill's sake toPlace = random.randint(0, 5) if toPlace == 5: #build a tunnel location = random.randint(0, len(placeableAnts) - 1) return Move(BUILD, [placeableAnts[location].coords], TUNNEL) else: #build an ant return Move(BUILD, [hill.coords], random.randint(WORKER, R_SOLDIER)) elif len(placeableAnts) != 0: #build a tunnel location = random.randint(0, len(placeableAnts) - 1) return Move(BUILD, [placeableAnts[location].coords], TUNNEL) elif placeableHill: #build an ant return Move(BUILD, [hill.coords], random.randint(WORKER, R_SOLDIER)) else: #I have resources to build, but no place to build things pass #See if you can move any ants antsToMove = [] for ant in myInv.ants: if not ant.hasMoved: antsToMove.append(ant) #Move first of these ants if antsToMove != []: chosen = antsToMove[0] coordList = [chosen.coords] totalCost = 0 lastStep = None #Variable to check if worker has moved hasMoved = 0 while totalCost < UNIT_STATS[chosen.type][MOVEMENT]: #pick a random direction that won't move me back. possibleDirections = [(0, 1), (0, -1), (1, 0), (-1, 0)] validDirections = [] for direction in possibleDirections: nextLoc = addCoords(coordList[-1], direction) #Check that the move would be inside the board bounds if nextLoc[0] > 9 or nextLoc[0] < 0 or nextLoc[1] > 9 or nextLoc[1] < 0: continue #Check that the move cost would not exceed what this ant is capable of costOfStep = currentState.board[nextLoc[0]][nextLoc[1]].getMoveCost() if currentState.board[nextLoc[0]][nextLoc[1]].ant == None and UNIT_STATS[chosen.type][MOVEMENT] >= totalCost + costOfStep: validDirections.append(direction) #If no directions are valid, break out of the loop. if validDirections == []: break #Worker ant commands elif chosen.type == WORKER: #Move toward adjacent food if not carrying if chosen.carrying == False: for direction in validDirections: nextCoord = addCoords(coordList[-1], direction) if currentState.board[nextCoord[0]][nextCoord[1]].constr == FOOD: coordList.append(nextCoord) totalCost += currentState.board[nextCoord[0]][nextCoord[1]].getMoveCost() hasMoved = 1 #Move toward adjacent anthill or tunnel if carrying else: for direction in validDirections: nextCoord = addCoords(coordList[-1], direction) if currentState.board[nextCoord[0]][nextCoord[1]].constr == ANTHILL or currentState.board[nextCoord[0]][nextCoord[1]].constr == TUNNEL and currentState.board[nextCoord[0]][nextCoord[1]].ant == None: coordList.append(nextCoord) totalCost += currentState.board[nextCoord[0]][nextCoord[1]].getMoveCost() hasMoved = 1 if hasMoved == 0: #store backward moves in array backMove = [] #move back or to the side if on border if chosen.coords[1] >=3: for direction in validDirections: if direction[1] <= 0: backMove.append(direction) randNum = random.randint(0, len(backMove) - 1) nextCoord = addCoords(coordList[-1], backMove[randNum]) coordList.append(nextCoord) totalCost += currentState.board[nextCoord[0]][nextCoord[1]].getMoveCost() #random move if not on border else: #Choose a random direction randDir = random.randint(0, len(validDirections) - 1) #Apply it nextCoord = addCoords(coordList[-1], validDirections[randDir]) coordList.append(nextCoord) #Add its cost to the total move cost totalCost += currentState.board[nextCoord[0]][nextCoord[1]].getMoveCost() #Soldier/Drone commands elif chosen.type == SOLDIER or chosen.type == DRONE: #have ants move and stay in enemy territory if chosen.coords[1] <= 6: #append foward valid directions to array forwardMove = [] for direction in validDirections: if direction[1] == 1: forwardMove.append(direction) #randomly choose forward direction randDir = random.randint(0, len(forwardMove) - 1) nextCoord = addCoords(coordList[-1], forwardMove[randDir]) coordList.append(nextCoord) totalCost += currentState.board[nextCoord[0]][nextCoord[1]].getMoveCost() #move randomly if already on enemy side else: randDir = random.randint(0, len(validDirections) - 1) nextCoord = addCoords(coordList[-1], validDirections[randDir]) coordList.append(nextCoord) totalCost += currentState.board[nextCoord[0]][nextCoord[1]].getMoveCost() #random move if not worker or soldier else: #Choose a random direction randDir = random.randint(0, len(validDirections) - 1) #Apply it nextCoord = addCoords(coordList[-1], validDirections[randDir]) coordList.append(nextCoord) #Add its cost to the total move cost totalCost += currentState.board[nextCoord[0]][nextCoord[1]].getMoveCost() #return the move created return Move(MOVE_ANT, coordList, None) #If I can't to anything, end turn return Move(END, None, None)
def handleEvents(self, mode): #Make sure we check the right buttons relButtons = {} if self.choosingAIs else self.humanButtons if mode == HUMAN_MODE else self.aiButtons if mode == AI_MODE else {} #It should be impossible for self.buildAntMenu to be True unless mode is HUMAN_MODE and AIs have already been chosen. if mode == HUMAN_MODE and self.buildAntMenu: relButtons = self.antButtons #Check what to do for each event for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN and time.clock() - self.lastClicked > self.clickCooldown: self.lastClicked = time.clock() #Start by checking the basic buttons that always get drawn for key in self.buttons: if self.buttonRect.move(self.buttons[key][0]).collidepoint(event.pos): self.handleButton(key, 0, self.buttons) #Then check the buttons that congregate at the top of the screen, and change based on context for key in relButtons: if self.buttonRect.move(relButtons[key][0]).collidepoint(event.pos): self.handleButton(key, 0, relButtons) #Check to see if text box should be selected or deselected if mode == TOURNAMENT_MODE and self.buttonRect.move(self.textPosition).collidepoint(pygame.mouse.get_pos()): self.boxSelected = True else: self.boxSelected = False #Additionally, check if a cell on the board has been clicked. if mode != TOURNAMENT_MODE and not self.choosingAIs: if event.pos[0] % (CELL_SPACING + CELL_SIZE.width) > CELL_SPACING and event.pos[1] % (CELL_SPACING + CELL_SIZE.height) > CELL_SPACING: x = event.pos[0] / (CELL_SPACING + CELL_SIZE.width) y = event.pos[1] / (CELL_SPACING + CELL_SIZE.height) if x < BOARD_SIZE.width and y < BOARD_SIZE.height: self.locationClicked((x, y)) elif self.choosingAIs: self.handleAICheckList(event, mode) #Handle the AI selecting button. AIKey = self.submitSelected.keys()[0] if self.buttonRect.move(self.submitSelected[AIKey][0]).collidepoint(event.pos): self.handleButton(AIKey, 0, self.submitSelected) elif event.type == pygame.MOUSEBUTTONUP: #Start by checking the basic buttons that always get drawn for key in self.buttons: if self.buttonRect.move(self.buttons[key][0]).collidepoint(event.pos): self.handleButton(key, 1, self.buttons) #Then check the buttons that congregate at the top of the screen, and change based on context for key in relButtons: if self.buttonRect.move(relButtons[key][0]).collidepoint(event.pos): self.handleButton(key, 1, relButtons) #Handle the AI selecting button. if self.choosingAIs: AIKey = self.submitSelected.keys()[0] if self.buttonRect.move(self.submitSelected[AIKey][0]).collidepoint(event.pos): self.handleButton(AIKey, 1, self.submitSelected) #Check to see if text box should be selected or deselected if mode == TOURNAMENT_MODE and self.buttonRect.move(self.textPosition).collidepoint(pygame.mouse.get_pos()): boxSelected = True else: boxSelected = False elif event.type == pygame.MOUSEMOTION and event.buttons[0]: #Start by checking the basic buttons that always get drawn for key in self.buttons: if self.buttonRect.move(self.buttons[key][0]).collidepoint(addCoords(event.pos, event.rel)): self.buttons[key][1] = 0 else: self.buttons[key][1] = 1 #Then check the buttons that congregate at the top of the screen, and change based on context for key in relButtons: if self.buttonRect.move(relButtons[key][0]).collidepoint(addCoords(event.pos, event.rel)): relButtons[key][1] = 0 else: relButtons[key][1] = 1 #Handle the AI selecting button. if self.choosingAIs: AIKey = self.submitSelected.keys()[0] if self.buttonRect.move(self.submitSelected[AIKey][0]).collidepoint(event.pos): self.submitSelected[AIKey][1] = 0 else: self.submitSelected[AIKey][1] = 1 elif self.boxSelected and event.type == KEYDOWN: if str(event.unicode) in [str(i) for i in range(0, 10)]: self.textBoxContent += str(event.unicode) elif event.key == 8 and self.textBoxContent != '': self.textBoxContent = self.textBoxContent[:-1] elif event.type == KEYDOWN: self.handleHotkey(mode, str(event.unicode))
def drawScoreBoard(self, player1Score, player2Score): label1 = self.gameFont.render("Player 1: " + str(player1Score) + " food", True, BLACK) label2 = self.gameFont.render("Player 2: " + str(player2Score) + " food", True, BLACK) self.screen.blit(label1, self.scoreLocation) self.screen.blit(label2, addCoords(self.scoreLocation, (0, label2.get_rect().height)))
def drawButton(self, key, buttons): label = self.gameFont.render(key, True, BLACK) offset = subtractCoords(self.buttonRect.center, label.get_rect().center) self.screen.blit(self.buttonTextures[buttons[key][1]], buttons[key][0]) self.screen.blit(label, addCoords(buttons[key][0], offset))