from django.db import models from .names import WorkerNames, OrderNames from .timer import Timer from .timer import Timer from .company import Company from .order import Order # from .action import Action from .offer import Offer from ..initialdatabase import InitialDatabase from .engineeringmodel import ( ModelChaotic, ModelScrum, ModelSpiral, ModelV, ModelWaterfall, ModelHeyJoe, ) # Spielklasse kontrollier das gamegeschehen class Game(models.Model): name = models.CharField(default="Game", max_length=20) gamemaster = models.CharField(max_length=20) running = models.BooleanField(default=False) participants = models.ManyToManyField(Company) maxRounds = models.IntegerField(default=10) currentRound = models.IntegerField(default=1) ordermarket = models.ManyToManyField(Order) actionpool = models.ManyToManyField("Action") timer = models.ForeignKey(Timer, default=1, on_delete=models.CASCADE) acceptedOffers = models.ManyToManyField(Offer, blank=True) ordermarketsize = models.IntegerField(default=5) def __str__(self): return self.name # Standard Datenbankeinträge generieren die hart codiert sind (in initialdatabase.py) def initializeDatabase(self): data = InitialDatabase() self.createWorkernames(data) self.createOrdernames(data) self.createEngineeringmodels(data) def createWorkernames(self, data): for name in data.workernames: WorkerNames.objects.get_or_create(name=name) def createOrdernames(self, data): for name in data.ordernames: OrderNames.objects.get_or_create(name=name) def createEngineeringmodels(self, data): ModelV.objects.get_or_create( name=data.engineeringmodelnames[0], description=data.engineeringmodeldescription[0], pros=data.engineeringmodelprocon[0][0], cons=data.engineeringmodelprocon[0][1], ) ModelSpiral.objects.get_or_create( name=data.engineeringmodelnames[1], description=data.engineeringmodeldescription[1], pros=data.engineeringmodelprocon[1][0], cons=data.engineeringmodelprocon[1][1], ) ModelWaterfall.objects.get_or_create( name=data.engineeringmodelnames[2], description=data.engineeringmodeldescription[2], pros=data.engineeringmodelprocon[2][0], cons=data.engineeringmodelprocon[2][1], ) ModelScrum.objects.get_or_create( name=data.engineeringmodelnames[3], description=data.engineeringmodeldescription[3], pros=data.engineeringmodelprocon[3][0], cons=data.engineeringmodelprocon[3][1], ) ModelChaotic.objects.get_or_create( name=data.engineeringmodelnames[4], description=data.engineeringmodeldescription[4], pros=data.engineeringmodelprocon[4][0], cons=data.engineeringmodelprocon[4][1], ) ModelHeyJoe.objects.get_or_create( name=data.engineeringmodelnames[5], description=data.engineeringmodeldescription[5], pros=data.engineeringmodelprocon[5][0], cons=data.engineeringmodelprocon[5][1], ) # ----------------------------------------------------------------------------------- # Bearbeitung des Gameablaufs mit diesen Funktionen kontrollieren: def startGame(self): # klarmachen dass workernames ordernames engineeringmodels und spezialorders # alle definiert sind -> sonst datenbankeinträge generieren self.setDefault() self.initializeDatabase() # spiel auf running stellen self.running = True self.save() # runde starten self.startRound() # timer starten self.runTimer() def setDefault(self): self.currentRound = 1 self.save() for company in self.participants.all(): for worker in company.workers.all(): worker.delete() for order in company.orders.all(): order.delete() company.money = 300000 company.customersatisfaction = 100 company.workersatisfaction = 100 company.save() def endGame(self): # game running False stellen self.running = False self.save() def startRound(self): # ordermarket generieren self.generateOrdermarket() # companys ihren workermarket generieren lassen self.generateWorkermarket() def processGameround(self): # events von LETZTER RUNDE clearen() self.clearEvents() # arbeiter bezahlen self.paySalary() # schauen ob worker quittet (zufällig mit steigender wahrscheinlichkeit je niedriger) self.checkWorkerQuit() # companyOrder verbleibende Workload neu berechnen self.calculateOrderWorkload() # alle Aktionen ausführen und clearen self.executeActions() # Krankheit zufällig generieren self.calculateSick() # unlock locked workers wenn countdown auf 0; dann zähle countdown runter self.countdownLockedWorkers() # recalculate der models auf orders anwenden self.modelsRecalculateOrders() # SpecialOrders passieren lassen() self.specialordersOccure() # beste offer für jede order auf ordermarket rausfinden self.calculateBestOffers() # offers an beste berechnete company verteilen self.distributeBestOffers() # passive regeln anpassen self.passiveGamerules() # checken ob es letzte runde ist gameend = self.checkLastRound() # runde hochzählen self.increaseRound() # nächste Runde starten self.startRound() # gameende signalisieren return gameend # ----------------------------------------------------------------------------------- def passiveGamerules(self): for company in self.participants.all(): company.calculateWorkerSatisfaction(2) company.calculateCustomerSatisfaction(2) for worker in company.workers.all(): worker.calculateHappyness(1) # Spielexecution Funktionen die Funktionen zur Spielkontorlle implementieren # adde 5 elemente zu ordermarket def generateOrdermarket(self): self.clearOrdermarket() for x in range(self.ordermarketsize): order = Order.createRandom() self.addOrder(order) def generateWorkermarket(self): for company in self.participants.all(): company.generateWorkermarket() def clearParticipants(self, username): for player in self.participants.all(): # alle comapnys ausser gamemaster company kicken if not (player.user == username): self.participants.remove(player) def clearEvents(self): for company in self.participants.all(): company.clearEvents() def callbackTimerCompleted(self): gameend = self.processGameround() if gameend: self.timer.stop() def runTimer(self): self.timer.start(callback=self.callbackTimerCompleted) def getRemainingTimer(self): return self.timer.remainingtimer def checkWorkerQuit(self): for company in self.participants.all(): company.checkWorkerQuit() def countdownLockedWorkers(self): for company in self.participants.all(): for worker in company.workers.all(): # unlocken wenn locked und countdown = 0 und setze sick false if worker.lockedRounds <= 0 and worker.status == 3: worker.setStatus(1) worker.setSick(False) # countdown lockedRounds wenn größer 0 elif worker.lockedRounds > 0: rounds = worker.lockedRounds - 1 worker.setLockedRounds(rounds) def calculateSick(self): for company in self.participants.all(): for worker in company.workers.all(): worker.calculateSick() def executeActions(self): for company in self.participants.all(): for action in company.actions.all(): action.execute() for action in company.actions.all(): action.delete() def calculateOrderWorkload(self): for company in self.participants.all(): company.calculateOrderWorkload() def calculateBestOffers(self): for order in self.ordermarket.all(): bestoffer = order.calculateBestOffer() self.acceptedOffers.add(bestoffer) def modelsRecalculateOrders(self): for company in self.participants.all(): for order in company.orders.all(): order.recalculate(company) def distributeBestOffers(self): for acceptedoffer in self.acceptedOffers.all(): acceptedoffer.order.setStatus(1) self.ordermarket.remove(acceptedoffer.order) acceptedoffer.company.addOrder(acceptedoffer.order) acceptedoffer.offerAcceptedEvent() # offers deleten da nicht mehr gebraucht acceptedoffer.delete() def specialordersOccure(self): for company in self.participants.all(): for order in company.orders.all(): order.specialorder.occure(company=company) def increaseRound(self): self.currentRound += 1 self.save() def checkLastRound(self): if self.maxRounds <= self.currentRound: self.endGame() # beende spiel return True return False def addOrder(self, order): self.ordermarket.add(order) def removeOrder(self, order): self.ordermarket.remove(order) def clearOrdermarket(self): for order in self.ordermarket.all(): if order.status == 0: order.delete() self.ordermarket.clear() def paySalary(self): for company in self.participants.all(): company.paySalary() def createLeaderboard(self): tuples = [] for company in self.participants.all(): tuples.append((company.money, company)) tuples = sorted(tuples, key=lambda x: x[0], reverse=True) # companys aus den tuples ziehen leaderboard = [] i = 1 for element in tuples: leaderboard.append((i, element[1])) i = i + 1 return leaderboard