def validate(self): print("validate") # MUST: for shipName, order in self.combatOrders.items(): print(shipName, "order:", dataModel.prettyOrders(order)) # MUST have orders for every ship if (not order): print(shipName, "Has no orders") return False # MUST select an overall tactic for each ship if (order['tactic'][0] == 'tactic'): print(shipName, "Has no tactic") return False # MUST specify a target if using beams if (order['beams'][1] > 0): if (order['beams'][0] == 'target'): print(shipName, "Using Beams with no target") return False # MUST specify a target if using a missile for missile in order['missiles']: if (missile[1] > 0): if (missile[0] == 'target'): print(shipName, "Using Missile with no target") return False # WARNING: # Did they spend all their PD? # Did they pick any target? return True
def giveOrder(self): #lets print out all the energy we are using! print("giveOrder for:", self.ship['name']) self.combatOrders[self.ship['name']] = { 'ship': self.ship['name'], 'tactic': [self.tacticVar.get(), self.moveVar.get()], 'beams': [self.beamTargetVar.get(), self.beamVar.get()], 'screens': self.screenVar.get(), 'missiles': [[self.Tubes[i].targetVar.get(), self.Tubes[i].var.get()] for i in range(len(self.Tubes))] } for name, order in self.combatOrders.items(): print(name, "order:", dataModel.prettyOrders(order))
def resolveCombat(logger, game, orders): # For testing #for ship in game['objects']['shipList']: # ship['damage'] = 5 print("ALLorders:") print(orders) # What are the combat orders? # Find each combat order. # Find target of each order (an order can have multiple targets) # Find the orders for each target. # Match them up and resolve - so I need a simple function # for one v one orders to resolve against the chart # Table of orders is: # Array of players (dict) # For each player there is an array of ships (dict) # For each ship there is an order # each order can have a unique target for player, playerOrders in orders.items(): for myShip, shipOrders, in playerOrders.items(): if (not shipOrders): print("ERROR:", myShip, "has no orders") print("Should assert ... but must fix client") continue if 'conquer' in shipOrders: # This is a change of ownership. for baseName in shipOrders['conquer']: logger.log( dataModel.playerNameGet(game, player) + ": conquers " + baseName + " with " + myShip) base = dataModel.findBase(game, baseName) base['owner'] = player continue pretty = dataModel.prettyOrders(shipOrders) logger.log( dataModel.playerNameGet(game, player) + ": " + myShip + ": " + pretty) myPower = shipOrders['beams'][1] if (myPower > 0): myTactic = shipOrders['tactic'][0] myDrive = shipOrders['tactic'][1] myTarget = shipOrders['beams'][0] figureStuffOut(logger, game, orders, myShip, myPower, myTactic, myDrive, myTarget) else: for missile in shipOrders['missiles']: myPower = 2 myTactic = 'ATTACK' myDrive = missile[1] myTarget = missile[0] if (myDrive > 0): # Need ship to deduct missiles ship = dataModel.findShip(game, myShip) assert (ship) assert (ship['M']['cur'] > 0) ship['M']['cur'] -= 1 figureStuffOut(logger, game, orders, myShip, myPower, myTactic, myDrive, myTarget)
def figureStuffOut(logger, game, orders, myShipName, myPower, myTactic, myDrive, myTarget): targetShipOrders = findTargetShipOrders(myTarget, orders) if (targetShipOrders): pretty = dataModel.prettyOrders(targetShipOrders) print("targetship:", myTarget, "order:", pretty) targetTactic = targetShipOrders['tactic'][0] targetDrive = targetShipOrders['tactic'][1] targetScreen = targetShipOrders['screens'] else: # Can't find orders for the target. # That shouldn't happen. assert? # Maybe the target player was just lazy? # ??? This should be considered an error on the part # of the client. print("targetship:", myTarget, "CAN'T FIND ORDERS!!!!") logger.log(myTarget + " No orders. Assume RETREAT D=0") targetTactic = 'RETREAT' targetDrive = 0 targetScreen = 0 # We know what the offense is doing, we know what the defense is doing # rock, paper, scissors the results result = combatChartLookup(myTactic, myDrive, targetTactic, targetDrive) # ugly if statement on results # combatChartLookup should probably just return the number if result == "Miss": damage = 0 elif result == "Hit": damage = 0 + myPower elif result == "Hit+1": damage = 1 + myPower elif result == "Hit+2": damage = 2 + myPower elif result == "Escapes": damage = -1 else: print('ERROR!') logger.log(" " + myShipName + " " + result + " " + myTarget + " for " + str(damage) + " damage") print("%s Beam/Missile '%s' %s" % (myShipName, result, myTarget)) # A negative number means the target # has escaped. BUT it can't escape unless EVERY attack results in "escape" if (damage < 0): return # This damage calculation is incorrect. # Lookup the rules and the screens only protect you from # the TOTAL number of hits in the round. So a whole bunch # of "1" damage can overcome the shields eventually. # Target didn't escape but has the screen protected it? if (damage < targetScreen): damage = 0 else: damage -= targetScreen targetShip = dataModel.findShip(game, myTarget) # This is a worse error on the part of the client #assert(targetShip) if (targetShip is None): print("targetship:", myTarget, "CAN'T FIND SHIP!!!!") return if (targetShip['damage'] < 0): # target was trying to escape. # Show that they didn't targetShip['damage'] = 0 targetShip['damage'] += damage
def singleShip(self, frame, ship, enemyList, initialOrders): assert (ship) self.ship = ship print("singleShip:", self.ship['name'], self.ship) print("initOrders:", dataModel.prettyOrders(initialOrders)) shipFrame = LabelFrame(frame, text=ship['name'], bg="orange", bd=1, relief="sunken") shipFrame.pack(fill=BOTH, expand=1) # Shrink the image (and I needed self.photo instead of photo # Something online suggested a tk bug?) self.photo = tk.PhotoImage(file="resource/images/" + ship['image']) self.photo = self.photo.zoom(3) w = Canvas(shipFrame, relief=SUNKEN, width='6c', height='4c', bg="pink") scaleW = int(self.photo.width() / w.winfo_reqwidth()) scaleH = int(self.photo.height() / w.winfo_reqheight()) self.photo = self.photo.subsample(scaleW, scaleH) w.create_image(0, 0, anchor=NW, image=self.photo) w.pack(fill=BOTH, expand=1) CurPD = ship['PD']['cur'] self.powerFrame = LabelFrame(shipFrame, text="PowerDrive", bg="blue", bd=1, relief="sunken") self.powerFrame.pack(fill=BOTH, expand=1) if (initialOrders): initMove = initialOrders['tactic'][1] else: initMove = 0 self.moveVar = IntVar(self.powerFrame) self.moveVar.set(initMove) tmp = Label(self.powerFrame, text="Move") tmp.grid(row=2, column=0, sticky="W") self.Move = Spinbox(self.powerFrame, width=3, from_=0, to=CurPD, textvariable=self.moveVar, state="readonly") self.Move.grid(row=2, column=1) if (initialOrders): initTactic = initialOrders['tactic'][0] else: initTactic = "tactic" self.tacticVar = StringVar(self.powerFrame) self.tacticVar.set(initTactic) tacticList = ["ATTACK", "DODGE", "RETREAT"] tactic = OptionMenu(self.powerFrame, self.tacticVar, *tacticList) tactic.grid(row=2, column=2) self.energyFrame = LabelFrame(shipFrame, text="Energy Weapons", bg="blue", bd=1, relief="sunken") self.energyFrame.pack(fill=BOTH, expand=1) if (initialOrders): initBeam = initialOrders['beams'][1] else: initBeam = 0 self.beamVar = IntVar(self.energyFrame) self.beamVar.set(initBeam) CurB = ship['B']['cur'] text = "Beams:" + str(CurB) + " of " + str(ship['B']['max']) tmp = Label(self.energyFrame, text=text) tmp.grid(row=3, column=0, sticky="W") self.Beams = Spinbox(self.energyFrame, width=3, from_=0, to=CurB, textvariable=self.beamVar, state="readonly") self.Beams.grid(row=3, column=1) if (initialOrders): initTarget = initialOrders['beams'][0] else: initTarget = "target" self.beamTargetVar = StringVar(self.energyFrame) self.beamTargetVar.set(initTarget) target = self.createTargetList(self.energyFrame, enemyList, self.beamTargetVar) target.grid(row=3, column=2) if (initialOrders): initScreen = initialOrders['screens'] else: initScreen = 0 self.screenVar = IntVar(self.energyFrame) self.screenVar.set(initScreen) CurS = ship['S']['cur'] text = "Screens:" + str(CurS) + " of " + str(ship['S']['max']) tmp = Label(self.energyFrame, text=text) tmp.grid(row=4, column=0, sticky="W") self.Screens = Spinbox(self.energyFrame, width=3, from_=0, to=CurS, textvariable=self.screenVar, state="readonly") self.Screens.grid(row=4, column=1) CurM = ship['M']['cur'] self.missleFrame = LabelFrame(shipFrame, text="Missiles", bg="blue", bd=1, relief="sunken") self.missleFrame.pack(fill=BOTH, expand=1) MaxT = ship['T']['max'] self.Tubes = [] for i in range(0, MaxT): tmp = Spinbox(self.missleFrame, width=3, from_=0, to=99) tmp.grid(row=i, column=1) self.Tubes.append(tmp) tmp = Label(self.missleFrame, text="Tube_" + str(i + 1)) tmp.grid(row=i, column=0, sticky="W") self.Tubes[i].label = tmp if (initialOrders): initDrive = initialOrders['missiles'][i][1] else: initDrive = 0 tmp = IntVar(self.missleFrame) tmp.set(initDrive) tmp.trace("w", self.allUpdate) self.Tubes[i].var = tmp if (initialOrders): initTarget = initialOrders['missiles'][i][0] else: initTarget = "target" self.Tubes[i].targetVar = StringVar(self.missleFrame) self.Tubes[i].targetVar.set(initTarget) tmp = self.createTargetList(self.missleFrame, enemyList, self.Tubes[i].targetVar) tmp.grid(row=i, column=2) self.Tubes[i].target = tmp self.Tubes[i].configure(textvariable=self.Tubes[i].var) # Figure out which of those tubes to enable/disable self.enableTubes() # Begin Trace late. (After all objects are instantiated) self.moveVar.trace("w", self.allUpdate) self.beamVar.trace("w", self.allUpdate) self.screenVar.trace("w", self.allUpdate) self.updatePowerDrive() self.updateMissiles()