def introMap(self): intro = True GUI.setMenu() msgA = "This map shows the different continents and the connections between territories." msgB = "Click the current player at token any time to see this map again." msgC = "Please note: the button to move to the next phase of your turn will be red when active or grey if action must be taken." msgAr = [msgA,msgB,msgC] UI.makeButton(black,0,512,GUI.width,100,'',0) UI.makeButton(grey,2,513,GUI.width-4,97,'',0) down = 30 for i in range (3): UI.makeButton(grey,50,(520+down*i),900,20,msgAr[i],16) UI.makeButton(black,385,445,180,60,'',0) UI.makeButton(red,390,450,170,50,'Let\'s Play!',30) while intro: mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if 390 < mouse[0] < 390+170 and 450 < mouse[1] < 500: UI.makeButton(brightRed,390,450,170,50,'Let\'s Play!',30) if click[0] == 1: intro = False else: UI.makeButton(red,390,450,170,50,'Let\'s Play!',30)
def menu(self): UI.info() GUI.setMenu() UI.makeButton(white,280,516,440,90,'',0) UI.makeButton(black,480,529,40,40,'',0) UI.makeButton(Data.playerList[Data.turn].color,485,534,30,30,'',0) UI.makeButton(white,440,578,120,20,Data.playerList[Data.turn].name,20) col = [red,yellow,green,blue] bri = [brightRed,brightYellow,brightGreen,brightBlue] msg = ['Resume','Restart','Tutorial','Hints'] xInc = 255 yInc = 49 menu = True style = None for i in range(4): side = i%2 down = i//2 UI.makeButton(black,(305+side*xInc),(519+down*yInc),135,35,'',0) UI.makeButton(col[i],(310+side*xInc),(524+down*yInc),125,25,msg[i],25) while menu: pygame.event.pump() pygame.event.clear() mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() #highlight/get click if mouse enters player token if (480) < mouse[0] < (480+40) and (529) < mouse[1] < (529+40): UI.makeButton(Data.playerList[Data.turn].bright,485,534,30,30,'',0) if click[0] == 1: style = 0 menu = False else: UI.makeButton(Data.playerList[Data.turn].color,485,534,30,30,'',0) for j in range(4): side = j%2 down = j//2 #highlight/get click if mouse enters button if (305+side*xInc) < mouse[0] < (305+side*xInc+135) and (519+down*yInc) < mouse[1] < (519+down*yInc+35): UI.makeButton(bri[j],(310+side*xInc),(524+down*yInc),125,25,msg[j],25) if click[0] == 1: style = j menu = False else: UI.makeButton(col[j],(310+side*xInc),(524+down*yInc),125,25,msg[j],25) #handle each button with appropriate method if style == 0: GUI.setMap() if style == 1: self.confirm() if style == 2: self.tutorial(True) if style == 3: self.hints()
def placing(num): Data.terrList[terr].units += num if base == None: Data.playerList[self.player].units += num if num > 1: UI.box3 = str(num)+' troops added' else: UI.box3 = str(num)+' troop added' UI.update() GUI.highlight(terr, True)
def territoryConquered(self, base, target, defender): self.addCard = True self.choice = False GUI.updateBoard(target) GUI.highlight(base, False) self.eliminated(defender) if Data.checkWin(): #break out of attack - handle win logging.info(Data.playerList[self.player].name+' wins') UI.box1 = Data.playerList[self.player].name+' Wins!' UI.box2 = 'World Domination Complete' UI.box3 = 'Interested in a rematch?' UI.update() self.pick = False else: logging.info('Territory conquered') UI.box3 = 'Territory conquered' UI.update() if Data.terrList[base].units > 1: troops = Data.terrList[base].units - 1 Data.terrList[base].units -= troops GUI.displayUnits() GUI.drawLines(base, target) self.placement(troops, base, target) bonus = self.cardChoice(False) if bonus > 0: self.placement(bonus)
def fortify(self): UI.nextMsg = 'End Turn' UI.nextHover = False UI.box1 = Data.playerList[self.player].name+' - Fortify' UI.update() while self.done and not self.restart: UI.nextColor = True UI.box2 = ('Select territory to move units') UI.box3 = ('Click \'End Turn\' when finished') UI.update() base = self.clickMapAny(False) if base == None or not base: break else: troops = Data.terrList[base].units - 1 Data.terrList[base].units -= troops GUI.highlight(base, False) self.placement(troops, base, False) GUI.setMap()
def placement(self, troops, base=None, style=None): troops = troops def placing(num): Data.terrList[terr].units += num if base == None: Data.playerList[self.player].units += num if num > 1: UI.box3 = str(num)+' troops added' else: UI.box3 = str(num)+' troop added' UI.update() GUI.highlight(terr, True) UI.nextColor = False #loop while there are troops to place while troops > 0 and not self.restart: UI.box2 = str(troops)+' unit(s) to place' UI.update() if style == None: terr, click = self.clickMapAny() else: GUI.drawLines(base, style) terr, click = self.clickMapSpecific(base, style) if click != None: #left click places one unit if click == 1: placing(1) troops -= 1 #right click places multiple units - 10, 5, or remaining elif click == 3: #if more than 50 troops to place, place 10 at a time if troops >= 50: placing(10) troops -= 10 #if less than 50 but more than 5, place 5 at a time elif 50 > troops > 5: placing(5) troops -= 5 #if less than 5 troops, place remaining else: placing(troops) troops -= troops time.sleep(.05) GUI.highlight(terr, False)
def main(): Moves = RiskMoves.MoveSet() while True: if Data.reset: num = Intro.pickPlayer() Data.restart(num) Moves.restart = False else: num = Intro.fullIntro() Data.begin(num) GUI.currentBoard() gameLoop = True while not Moves.restart: #check that player is still in the game if Data.playerList[Data.turn].units > 0 and Data.playerList[ Data.turn].units > 0: Moves.fullMove() Data.turnCounter() else: Data.turnCounter()
def attack(self): UI.nextMsg = 'Fortify' UI.nextHover = False UI.update() #loop to get appropriate attacking territory or advance to fortify while self.pick and not self.restart: UI.nextColor = True UI.box1 = Data.playerList[self.player].name+' - Attack' UI.box2 = 'Select one of your territories' UI.box3 = 'to launch attack from' UI.update() base = self.clickMapAny(True) if base == None or not base: self.pick = False else: self.choice = True #set default troops to max attackers, can be changed by player self.numAttackers = min(Data.terrList[base].units-1, 3) UI.numBoxSetArray(base, self.numAttackers) #loop to get target or handle break to send back to first loop while self.choice and not self.restart: UI.nextColor = False UI.update() GUI.drawLines(base, None) target = self.clickMapSpecific(base) if target != None and target != False: #roll dice, handle results defender = Data.terrList[target].owner attLoss, defLoss, change = self.dice(base, target) logging.info('Attacker lost '+str(attLoss)+', defender lost '+str(defLoss)+', change: '+str(change)) UI.box2 = ('You lost '+str(attLoss)+', defender lost '+str(defLoss)) UI.box3 = ('Click to attack again or water to reset') UI.update() #handle for less available attackers if Data.terrList[base].units-1 < self.numAttackers: self.numAttackers = Data.terrList[base].units-1 GUI.displayUnits() #not enough units to keep attacking if change == False: logging.info('Too few units to continue attacking') GUI.highlight(base, False) GUI.highlight(target, False) self.choice = False #territory conquered if change: self.territoryConquered(base, target, defender)
def display(self, function=None): # Loads png sprites for highlighting selected territories worldTerritories = glob.glob(c.mapPath + "*.png") territorySprites = [] highlightedTerritories = [] selectedTerritory = -1 # Boolean flags for player functions selectFlag = False attackFlag = False helpFlag = False gameEnd = False gui = GUI() runcommands = Interacting() finalLayout = uiInteractions.formatTerr(self, worldTerritories, territorySprites, highlightedTerritories, gui) # Event handler while (not gameEnd): gameEnd, helpFlag, selectFlag, selectedTerritory = \ uiInteractions.eventHandler(self, gameEnd, helpFlag, selectFlag, selectedTerritory) uiInteractions.sendSurface(self, finalLayout) uiInteractions.topLay(self, helpFlag, gui) # Highlight territories as cursor moves over them mouse = pygame.mouse.get_pos() try: tempColorValue = self.surfaces[2][0].get_at( (mouse[0], mouse[1])) except IndexError as e: print(e) pass # Setups user GUI layout and enables player functions try: if tempColorValue != (0, 0, 0, 0) and tempColorValue != (0, 0, 0, 255): temptroopValID = tempColorValue[0] - 100 spriteLayer = next( (territorySprite for territorySprite in highlightedTerritories if territorySprite.id == temptroopValID), None) click = uiInteractions.updateVisualGetClick( self, temptroopValID, selectedTerritory, spriteLayer) # Placing reinforcements on owned territories if self.turn.list_phase[self.turn.phase] == "Placement": uiInteractions.placing(self, click, temptroopValID) # Attacking neighboring territories with n-1 troops elif self.turn.list_phase[self.turn.phase] == "Attack": if click[0] == 1 and not selectFlag: startTerritory = next( (p for p in self.map.territories if p.id == temptroopValID), None) self.selectedTerritory = startTerritory if startTerritory.id_player == self.turn.turnCount and startTerritory.num_troops > 1: self.troopCount = startTerritory.num_troops - 1 self.tempTerritoryList.append( spriteLayer.layout) selectFlag = True selectedTerritory = temptroopValID elif click[0] == 1: # Selecting territory to attack endTerritory = next( (p for p in self.map.territories if p.id == temptroopValID), None) if attackFlag and endTerritory == targetTerritory and startTerritory.num_troops > 1: self.turn.troopMovement( startTerritory, endTerritory, self.troopCount) selectFlag = False self.tempTerritoryList = [] attackFlag = False elif attackFlag: selectFlag = False self.tempTerritoryList = [] attackFlag = False elif endTerritory.id_player != self.turn.turnCount and endTerritory.id in startTerritory.neighbors: # Attack with home troops try: self.interfaceDice = [] attackResult, diceResults = self.turn.attack( startTerritory, endTerritory, self.troopCount) for i, res in enumerate(diceResults): gui.diceRolls( self, res[0], res[2], 600, territorySprites[0].layout. get_height() + 10 + i * c.diceSize * 1.1) gui.diceRolls( self, res[1], res[3], 800, territorySprites[0].layout. get_height() + 10 + i * c.diceSize * 1.1) pygame.time.wait(100) except ValueError as e: print(e.args) attackResult = False selectFlag = False self.tempTerritoryList = [] if attackResult: # On successful attack, update visuals sprite = next((s for s in territorySprites if s.id == temptroopValID), None) gui.setSurfaceColor( sprite, self.turn.players[self.turn.turnCount - 1].color, 255) finalLayout.blit(sprite.layout, (0, 0)) attackFlag = True targetTerritory = endTerritory self.troopCount = startTerritory.num_troops - 1 else: selectFlag = False self.tempTerritoryList = [] # Moving troops between territories elif self.turn.list_phase[self.turn.phase] == "Movement": selectFlag = uiInteractions.moving( self, click, selectFlag, temptroopValID, spriteLayer, startTerritory) # Update troop text overlay visuals self.textList = [] gui.troopDisplay(self.textList, territorySprites, self.map) except ValueError as e: pass # Update HUD text visuals self.interfaceText = [] gui.display_hud(self.troopCount, self.interfaceText, self.turn, (75, territorySprites[0].layout.get_height() + 10)) pygame.display.flip()
def clickMapAny(self, style=None): button = False if style != None: button = True while True and not self.restart: (x,y), click = getMouseClick(button) if y > 512: #handle for button and menu if 305 < x < 333 and 518 < y < 546: Intro.menu() if Data.reset == True: logging.info('Restart selected') self.breakMove() if style == None: return None, None else: return None if button and 618 < x < 717 and 518 < y < 546: return False else: continue else: p = GUI.MasterMap.get_at((x,y)) #output not owned territory if 0 < p[0] < 43 and Data.terrList[p[0]].owner != self.player: logging.info('Not your territory') UI.box3 = 'Must select your own territory' UI.update() time.sleep(.05) continue elif 0 < p[0] < 43 and Data.terrList[p[0]].owner == self.player: #None for placing units if style == None: return p[0], click #handle for right click elif click == 3: continue #handle for too few units elif click == 1 and Data.terrList[p[0]].units < 2: GUI.highlight(p[0], True) logging.info('Must have more than 1 unit') UI.box3 = 'Must have more than 1 unit' UI.update() time.sleep(.05) GUI.highlight(p[0], False) continue #attack/fortify elif click == 1 and Data.terrList[p[0]].units > 1: #make sure there are targets to pick from targets = False for i in Data.terrList[p[0]].touch: #True for attack, False for fortify if style and Data.terrList[i].owner != self.player: UI.box2 = ('Select enemy territory to attack') UI.box3 = ('Click water/same territory to reset') UI.update() targets = True break elif not style and Data.terrList[i].owner == self.player: targets = True UI.box3 = 'Territories must be touching' break #needs output to user if targets: GUI.highlight(p[0], True) return p[0] #handle for no enemies to attack else: GUI.highlight(p[0], True) logging.info('No valid connecting territories') UI.box3 = 'No valid connecting territories' UI.update() time.sleep(.05) GUI.highlight(p[0], False) continue
def clickMapSpecific(self, base, style=None): while True and not self.restart: GUI.drawLines(base, style) #add numberBox here - or in clickMapSpecific if style == None: UI.numBoxSetArray(base, self.numAttackers) UI.numBox() #could be handled with a none (x,y), click = getMouseClick(style) else: (x,y), click = getMouseClick() if y > 512: #handle for menu - button will not be live if 305 < x < 333 and 518 < y < 546: Intro.menu() if Data.reset == True: logging.info('Restart selected') self.breakMove() if style == None: return None else: return None, None else: continue else: waterBreak = True #set self.numAttackers without resetting from water click margin = 80 for i in range(3): if style == None and (405+margin*i) < x < (405+margin*i+30) and (470) < y < (470+30): self.numAttackers = i+1 waterBreak = False p = GUI.MasterMap.get_at((x,y)) #handle for water click reset if p[0] == 162 and style == None and waterBreak: self.choice = False logging.info('Water clicked - resetting') UI.box2 = ('Resetting selected territory') UI.box3 = ('Select territory to attack from') UI.update() GUI.highlight(base, False) return False elif 0 < p[0] < 43: #redistribute - only base or conquered territory if type(style) is int and 0 < style < 43: if p[0] == style or p[0] == base: return p[0], click else: logging.info('Must be attacking or new territory') UI.box3 = 'Must be attacking or new territory' UI.update() continue else: if p[0] not in Data.terrList[base].touch or p[0] != base: logging.info('Territories must be touching') UI.box2 = 'Territories must be touching' if p[0] in Data.terrList[base].touch or p[0] == base: #fortify - base or connected owned territories if style == False: if Data.terrList[p[0]].owner == self.player: return p[0], click else: logging.info('Must choose your own territory') UI.box3 = 'Must choose your own territory' UI.update() continue #attack - connected non-owned territories elif style == None: if Data.terrList[p[0]].owner != self.player: return p[0] #handle for clicking same country - reset elif p[0] == base: self.choice = False logging.info('Resetting selected territory') UI.box2 = ('Resetting selected territory') UI.box3 = ('Select territory to attack from') UI.update() GUI.highlight(p[0], False) return False else: logging.info('Cannot attack owned territory') UI.box2 = 'Cannot attack owned territory' UI.update() continue
def display(self, function=None): # Loads png sprites for highlighting selected territories worldTerritories = glob.glob(c.mapPath + "*.png") territorySprites = [] highlightedTerritories = [] spriteSelected = -1 # Adds an AI player to do moves, new constants serve as player data for the CPU selectFlag = False attackFlag = False helpFlag = False gameEnd = False startTerritory = None targetTerritory = None AI = self.players count = 0 idxP = 0 idxAi = 0 AIPLAYER = [] Players = [] ID = [] for i in AI: f = i.name if "AI" not in f: Players.append(f) print( str(Players[idxP]) + " is the " + str(count) + " index in list") idxP += 1 ID.append(idxP) else: AIPLAYER.append(f) print( str(AIPLAYER[idxAi]) + " is the " + str(count) + " index in list") idxAi += 1 ID.append(idxAi) count += 1 # Initializes player UI gui = GUI() finalLayout = uiInteractions.formatTerr(self, worldTerritories, territorySprites, highlightedTerritories, gui) # Event handler for mouse and button interactions while (not gameEnd): pName = self.turn.players[self.turn.turnCount - 1].name gameEnd, helpFlag, selectFlag, spriteSelected = \ uiInteractions.eventHandler(self, gameEnd, helpFlag, selectFlag, spriteSelected, pName) uiInteractions.sendSurface(self, finalLayout) uiInteractions.topLay(self, helpFlag, gui) # Highlight territories as cursor moves over them mouse = pygame.mouse.get_pos() try: tempColorValue = self.surfaces[2][0].get_at( (mouse[0], mouse[1])) except IndexError as e: print(e) pass # Setups user GUI layout and enables player functions try: if tempColorValue != (0, 0, 0, 0) and tempColorValue != (0, 0, 0, 255): temptroopValID = tempColorValue[0] - 100 spriteLayer = next( (territorySprite for territorySprite in highlightedTerritories if territorySprite.id == temptroopValID), None) click = uiInteractions.updateVisualGetClick( self, temptroopValID, spriteSelected, spriteLayer) # Placing reinforcements on owned territories if self.turn.list_phase[self.turn.phase] == "Placement": if "AI" in pName: avail = [] for p in self.map.territories: # Gets all territories if p.id_player == self.turn.turnCount: avail.append(p) # Randomly pick a country the AI owns... randCountry = random.randrange(0, len(avail) - 1) troopsMax = self.turn.players[self.turn.turnCount - 1].num_troops randTroops = random.randrange(1, troopsMax + 1) self.turn.placeTroops(avail[randCountry], randTroops) uiInteractions.placing(self, click, temptroopValID) # Attacking neighboring territories with n-1 troops elif self.turn.list_phase[self.turn.phase] == "Attack": if "AI" in pName: totavail = [] availWTroops = [] for p in self.map.territories: # Gets all territories if p.id_player == self.turn.turnCount: totavail.append(p) for i in range(len(totavail)): if totavail[i].num_troops > 1: availWTroops.append(totavail[i]) maxT = 0 idxV = 0 idxN = [] for i in availWTroops: numtroops = i.num_troops idxN.append((numtroops, i)) if numtroops > maxT: maxT = numtroops idxV = i if len(availWTroops) < 1: for i in totavail: numtroops = i.num_troops idxN.append((numtroops, i)) if numtroops > maxT: maxT = numtroops idxV = i # Now that we have max troops we want to attack a neighbor, since this AI is dumb just randomly pick one totTargets = [] for p in self.map.territories: if p.id_player != self.turn.turnCount: totTargets.append(p) attackable = [] for i in totTargets: if i.id in idxV.neighbors: attackable.append(i) # Randomly chooses a valid target and attacks with all troops randTarget = random.randrange(0, len(attackable)) tgts = [] if maxT == idxV.num_troops: for i in idxV.neighbors: tgts.append(i) if idxV.id_player == self.turn.turnCount and idxV.id in attackable[ randTarget].neighbors: try: self.interfaceDice = [] attackResult, diceResults = self.turn.attack( idxV, totTargets[randTarget], idxV.num_troops - 1) for i, res in enumerate(diceResults): gui.diceRolls( self, res[0], res[2], 600, territorySprites[0].layout. get_height() + 10 + i * c.diceSize * 1.1) gui.diceRolls( self, res[1], res[3], 800, territorySprites[0].layout. get_height() + 10 + i * c.diceSize * 1.1) pygame.time.wait(100) except ValueError as e: print(e.args) attackResult = False self.tempTerritoryList = [] if attackResult: # On successful attack, update visuals sprite = next( (s for s in territorySprites if s.id == temptroopValID), None) gui.setSurfaceColor( sprite, self.turn.players[ self.turn.turnCount - 1].color, 255) finalLayout.blit(sprite.layout, (0, 0)) targetTerritory = totTargets[ randTarget] self.numTroops = idxV.num_troops - 1 else: self.tempTerritoryList = [] elif idxV.num_troops > 1: print("Using army with less troops") else: print("No available attacks") # Updates flags after event check attackFlag, selectFlag, startTerritory, targetTerritory = uiInteractions.attacking( self, click, selectFlag, temptroopValID, spriteLayer, attackFlag, gui, territorySprites, finalLayout, startTerritory, targetTerritory) # Moving troops between territories elif self.turn.list_phase[self.turn.phase] == "Movement": if click[0] == 1 and not selectFlag: # On left click select territory startTerritory = next( (p for p in self.map.territories if p.id == temptroopValID), None) self.selectedTerritory = startTerritory if startTerritory.id_player == self.turn.turnCount and startTerritory.num_troops > 1: self.troopCount = startTerritory.num_troops - 1 self.tempTerritoryList.append( spriteLayer.layout) selectFlag = True spriteSelected = temptroopValID elif click[ 0] == 1: # On right click unselect territory endTerritory = next( (p for p in self.map.territories if p.id == temptroopValID), None) path = self.map.checkValidPath( self.turn.players[self.turn.turnCount - 1].territories, startTerritory, endTerritory) selectFlag = False spriteSelected = 0 self.tempTerritoryList = [] if path and endTerritory.id != startTerritory.id: self.turn.troopMovement( startTerritory, endTerritory, self.troopCount) self.turn.next() # Update troop text overlay visuals self.textList = [] gui.troopDisplay(self.textList, territorySprites, self.map) except ValueError as e: pass # Update HUD text visuals self.interfaceText = [] gui.display_hud(self.troopCount, self.interfaceText, self.turn, (75, territorySprites[0].layout.get_height() + 10)) pygame.display.flip()