123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- 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
|