Initial Commit

This commit is contained in:
linkup11
2023-12-01 13:34:27 +01:00
commit b35b0e54be
7830 changed files with 1619698 additions and 0 deletions
View File
+163
View File
@@ -0,0 +1,163 @@
from django.db import models
from polymorphic.models import PolymorphicModel
# from .company import Company
from .worker import Worker
from .offer import Offer
from .order import Order
# Action und erbende Klassen
class Action(PolymorphicModel):
name = models.CharField(default="random Action", max_length=20)
actionmaker = models.ForeignKey("Company", default=1, on_delete=models.CASCADE)
def execute(self):
pass
def cancel(self):
pass
def addActionToCompany(self):
self.actionmaker.addAction(self)
def __str__(self):
return self.name
class ActionEmploy(Action):
worker = models.ForeignKey(Worker, default=1, on_delete=models.CASCADE)
@classmethod
def create(cls, worker, actionmaker):
# klassenobject erstellen
name = "Hiring " + worker.name
action = cls(name=name, worker=worker, actionmaker=actionmaker)
action.save()
# worker von market entferenen und action zu company hinzufügen
actionmaker.removeFromWorkermarket(worker)
action.addActionToCompany()
return action
def execute(self):
self.worker.setStatus(1)
self.worker.save()
self.actionmaker.workers.add(self.worker)
# Arbeiter zu Company hinzufügen
def cancel(self):
self.actionmaker.addToWorkermarket(self.worker)
class ActionUnemploy(Action):
worker = models.ForeignKey(Worker, null=True, blank=True, on_delete=models.CASCADE)
@classmethod
def create(cls, worker, actionmaker):
# klassenobject erstellen
name = "Firing " + worker.name
action = cls(name=name, worker=worker, actionmaker=actionmaker)
action.save()
# workerstatus anpassen und action zu company hinzufügen
actionmaker.workers.remove(worker)
action.addActionToCompany()
return action
def execute(self):
pass # self.worker.delete() hier das delete noch machbar machen
def cancel(self):
self.actionmaker.workers.add(self.worker)
class ActionOffer(Action):
order = models.ForeignKey(Order, default=1, on_delete=models.CASCADE)
amount = models.IntegerField(default=0)
@classmethod
def create(cls, order, amount, actionmaker):
# klassenobject erstellen
name = "Offer for " + order.name
action = cls(
name=name,
order=order,
amount=amount,
actionmaker=actionmaker,
)
action.save()
# order von market entfernen und action zu company hinzufügen
action.addActionToCompany()
return action
def execute(self):
self.order.setStatus(1)
self.order.save()
offer = Offer.objects.create(
company=self.actionmaker, amount=self.amount, order=self.order
)
self.order.offers.add(offer)
# Angebot einer Order auf OrderMarket vorlegen
def cancel(self):
# bleibt leer actually
pass
class ActionCancelOrder(Action):
order = models.ForeignKey(Order, default=1, on_delete=models.CASCADE)
@classmethod
def create(cls, order, actionmaker):
# klassenobject erstellen
name = "Cancel " + order.name
action = cls(
name=name,
order=order,
actionmaker=actionmaker,
)
action.save()
# action zu company hinzufügen
action.addActionToCompany()
return action
def execute(self):
self.actionmaker.calculateCustomerSatisfaction(-30)
self.order.cancelOrder()
self.order.delete()
def cancel(self):
# bleibt leer actually
pass
class ActionTrain(Action):
worker = models.ForeignKey(Worker, null=True, blank=True, on_delete=models.CASCADE)
trainskill = models.CharField(default="empty", max_length=50)
cost = models.IntegerField(default=1000)
@classmethod
def create(cls, worker, trainskill, actionmaker):
# klassenobject erstellen
name = "Train Worker " + worker.name
action = cls(
name=name,
worker=worker,
trainskill=trainskill,
actionmaker=actionmaker,
)
# worker locken status 3
worker.setStatus(3)
action.save()
# action zu company hinzufügen
action.addActionToCompany()
return action
def execute(self):
# Arbeiter in bestimmtem Skill verbesser und für eine runde locken
self.worker.improveAttribute(attribute=self.trainskill, amount=10)
self.worker.setLockedRounds(1)
# trainingskosten zahlen
self.actionmaker.addProfit(-self.cost)
def cancel(self):
self.worker.setStatus(1)
+46
View File
@@ -0,0 +1,46 @@
from django.db import models
import random
# attributeset für worker skills und order workload
class AttributeSet(models.Model):
experience = models.IntegerField(default=10)
reliability = models.IntegerField(default=10)
python = models.IntegerField(default=10)
javascript = models.IntegerField(default=10)
cpp = models.IntegerField(default=10)
management = models.IntegerField(default=10)
def __str__(self):
return "AttributeSet"
@classmethod
def createRandom(cls, median):
attributelist = []
for j in range(6):
randnumber = round(random.uniform(0.5, 1.5) * (median))
# if randnumber > 100:
# randnumber = 100
attributelist.append(randnumber)
attributeset = cls(
experience=attributelist[0],
reliability=attributelist[1],
python=attributelist[2],
javascript=attributelist[3],
cpp=attributelist[4],
management=attributelist[5],
)
attributeset.save()
return attributeset
def increase(self, amount, attribute):
if attribute in [
"experience",
"reliability",
"python",
"javascript",
"cpp",
"management",
]:
setattr(self, attribute, (getattr(self, attribute) + amount))
self.save()
+201
View File
@@ -0,0 +1,201 @@
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
import random
from mygame.backend.event import SpecialOrder
from .worker import Worker
from .order import Order
from .event import Event
from .action import *
# ACTION NOCH IMPORTIEREN?
# company die jeder spieler steuert
class Company(models.Model):
name = models.CharField(default="A company", max_length=20)
user = models.CharField(default="default User", max_length=20)
customersatisfaction = models.IntegerField(
default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
)
workersatisfaction = models.IntegerField(
default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
)
money = models.IntegerField(default=100000)
workermarket = models.ManyToManyField(Worker, related_name="workermarket")
actions = models.ManyToManyField("Action", blank=True)
workers = models.ManyToManyField(Worker, blank=True, related_name="workers")
orders = models.ManyToManyField(Order, blank=True)
events = models.ManyToManyField(Event, blank=True)
def __str__(self):
return self.name
def addProfit(self, profit):
self.money += profit
self.save()
def clearEvents(self):
for event in self.events.all():
# wenn specialorder ignoriert wurde -> penalty und removen (nicht löschen)
if isinstance(event, SpecialOrder):
for order in self.orders.all():
if order.specialorder == event:
event.handle(order=order, company=self, handle=False)
self.events.remove(event)
else:
event.delete()
def addEvent(self, event):
self.events.add(event)
self.save()
def getEvent(self, eventnumber, direction):
# wenn keine events gib leeres event
if not self.events.exists():
event = Event.createEmpty()
return (event, eventnumber)
# bei klick auf eventbutton immer erstes event zeigen
if eventnumber == 0 and direction == "default":
event = self.events.order_by("id")[eventnumber]
elif direction == "previous":
# wenn bei erstem element zurück dann letztes element zeigen
if eventnumber <= 0:
eventnumber = self.events.count() - 1
event = self.events.order_by("id")[eventnumber]
else:
eventnumber -= 1
event = self.events.order_by("id")[eventnumber]
elif direction == "next":
# wenn bei letztem element weiter dann erstes anzeigen
if eventnumber >= (self.events.count() - 1):
eventnumber = 0
event = self.events.order_by("id")[eventnumber]
else:
eventnumber += 1
event = self.events.order_by("id")[eventnumber]
return (event, eventnumber)
def addAction(self, action):
for existingaction in self.actions.all():
if action.name == existingaction.name:
self.cancelAction(existingaction.id)
self.actions.add(action)
def deleteAction(self, action):
self.actions.delete(action)
def calculateCustomerSatisfaction(self, number):
calc = self.customersatisfaction
calc += number
if calc < 0:
calc = 0
if calc > 100:
calc = 100
self.customersatisfaction = calc
self.save()
def calculateWorkerSatisfaction(self, number):
if (self.workersatisfaction + number) > 100:
self.workersatisfaction = 100
elif (self.workersatisfaction + number) < 0:
self.workersatisfaction = 0
else:
self.workersatisfaction += number
self.save()
def calculateAllWorkersHappyness(self, addhappyness):
for worker in self.workers.all():
worker.calculateHappyness(addhappyness)
def paySalary(self):
salarysum = 0
for worker in self.workers.all():
if self.money < salarysum:
worker.calculateHappyness(-50)
else:
salarysum += worker.salary
self.money -= salarysum
self.save()
def checkWorkerQuit(self):
threshhold = 55
for worker in self.workers.all():
if worker.happyness <= threshhold:
diff = threshhold - worker.happyness
randnum = random.randint(1, 100)
if 2 * diff > randnum:
event = Event.createWorkerQuit(
threshhold=threshhold,
workername=worker.name,
workerhappyness=worker.happyness,
)
self.addEvent(event)
worker.quitJob()
def calculateOrderWorkload(self):
for order in self.orders.all():
finished = order.calculateWorkload(self.workersatisfaction)
if finished:
order.finishOrder(self)
event = Event.createOrderFinished(
ordername=order.name, profit=str(order.profit)
)
self.events.add(event)
order.delete()
elif order.maxRounds == 0:
order.cancelOrder()
self.calculateCustomerSatisfaction(-30)
event = Event.createOrderFailed(ordername=order.name)
self.events.add(event)
order.delete()
def addOrder(self, order):
self.orders.add(order)
def deleteOrder(self, order):
self.orders.remove(order)
def addToWorkermarket(self, worker):
self.workermarket.add(worker)
def removeFromWorkermarket(self, worker):
self.workermarket.remove(worker)
def generateWorkermarket(self):
self.clearWorkermarket()
for x in range(5):
worker = Worker.createRandom()
self.addToWorkermarket(worker)
def clearWorkermarket(self):
for worker in self.workermarket.all():
if worker.status == 0:
worker.delete()
self.workermarket.clear()
# actions:
def cancelAction(self, id):
action = Action.objects.get(id=id)
action.cancel()
if action:
action.delete()
def actionEmploy(self, worker):
act = ActionEmploy.create(worker=worker, actionmaker=self)
return act
def actionUnemploy(self, worker):
act = ActionUnemploy.create(worker=worker, actionmaker=self)
return act
def actionOffer(self, order, amount):
act = ActionOffer.create(order=order, amount=amount, actionmaker=self)
return act
def actionCancelOrder(self, order):
act = ActionCancelOrder.create(order=order, actionmaker=self)
return act
def actionTrain(self, worker, trainskill):
act = ActionTrain.create(worker=worker, trainskill=trainskill, actionmaker=self)
return act
+147
View File
@@ -0,0 +1,147 @@
from django.db import models
from polymorphic.models import PolymorphicModel
import random
# EngineeringModel und erbende Klassen
class EngineeringModel(PolymorphicModel):
name = models.CharField(default="random EngineeringModel", max_length=30)
description = models.CharField(default="random description", max_length=200)
pros = models.CharField(default="random pro", max_length=100)
cons = models.CharField(default="random con", max_length=100)
# wird bei zuweisen des models ausgelöst
def recalculate(self, order, company):
pass
# wird bei workload berechnung ausgelöst, wenn workermodel nicht ordermodel
def penalty(self, worker, order):
worker.calculateHappyness(-5)
def bonus(self, worker, order):
pass
def __str__(self):
return self.name
def getPros(self):
return self.pros.split(",")
def getCons(self):
return self.cons.split(",")
class ModelV(EngineeringModel):
def recalculate(self, order, company):
# positives
# +10 workerSatisfaction +10 happyness
company.calculateAllWorkersHappyness(addhappyness=10)
company.calculateWorkerSatisfaction(number=10)
# +10 customerSatisfaction
company.calculateCustomerSatisfaction(10)
# negatives
# 1: extra work for SOPrototyp und SOChangeRequirement
# +10% workload
order.changeWorkload(1.1)
order.recalculated = True
order.save()
company.save()
class ModelSpiral(EngineeringModel):
def recalculate(self, order, company):
# positives
# 1: BONUS AUF SOPrototyp UND SOChangeRequirement
# +10 customerSatisfaciton
company.calculateCustomerSatisfaction(10)
# negatives
# 1: -10 happyness and workersatisfaction
company.calculateAllWorkersHappyness(addhappyness=-10)
company.calculateWorkerSatisfaction(number=-10)
# +10% workload
order.changeWorkload(1.1)
order.recalculated = True
order.save()
company.save()
class ModelWaterfall(EngineeringModel):
def recalculate(self, order, company):
# positives
# +10 workerSatisfaction +10 happyness
company.calculateAllWorkersHappyness(addhappyness=10)
company.calculateWorkerSatisfaction(number=10)
# -10% workload
order.changeWorkload(0.9)
# negatives
# 1: extra work for SOPrototyp und SOChangeRequirement
# -10 customerSatisfaction
company.calculateCustomerSatisfaction(-10)
order.recalculated = True
order.save()
company.save()
class ModelScrum(EngineeringModel):
def recalculate(self, order, company):
# positives
# 1: BONUS bei SOPrototyp und SOChangeRequirement
# 2: +20% if skilledModel of worker is scrum
# IN BONUS HIER UNTEN
# # negatives
# 1: random workload shift zwischen 1% und +20%
randnum = round(random.uniform(1.01, 1.2), 2)
order.changeWorkload(randnum)
# -40% auf skills wenn skilled model nicht scrum
# IN ORDER.CALCULATEWORKLOAD
order.recalculated = True
order.save()
company.save()
def bonus(self, worker, order):
ampnew = worker.amplifyer + 0.2
return ampnew
class ModelChaotic(EngineeringModel):
def recalculate(self, order, company):
# positives
# NIX
# negatives:
# +10% workload
order.changeWorkload(1.1)
# -20 workerSatisfaction -10 happyness
company.calculateAllWorkersHappyness(addhappyness=-10)
company.calculateWorkerSatisfaction(number=-20)
# extra work bei prototyp und changerequirement
order.recalculated = True
order.save()
company.save()
class ModelHeyJoe(EngineeringModel):
def recalculate(self, order, company):
# positives
# 1: BONUS AUF SOPrototyp UND SOChangeRequirement
# +30 customerSatisfaciton
company.calculateCustomerSatisfaction(30)
# negatives
# 1: -10 happyness and workersatisfaction
company.calculateAllWorkersHappyness(addhappyness=-15)
company.calculateWorkerSatisfaction(number=-15)
# +10% workload
order.changeWorkload(1.2)
order.recalculated = True
order.save()
company.save()
+310
View File
@@ -0,0 +1,310 @@
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from polymorphic.models import PolymorphicModel
from .engineeringmodel import EngineeringModel
import random
# Event und erbende Klassen (specialOrder)
class Event(PolymorphicModel):
name = models.CharField(default="random Event", max_length=40)
description = models.CharField(default="Event description here", max_length=200)
@classmethod
def createEmpty(cls):
emptyEvent = cls(
name="Your E-Mails are empty",
description="You do not have E-Mails this round.",
)
emptyEvent.save()
return emptyEvent
@classmethod
def createOrderFailed(cls, ordername):
name = ordername + " canceled."
description = (
"Your order "
+ ordername
+ " ran out of rounds! The order was canceled and your customerSatisfaction decreased."
)
event = cls(
name=name,
description=description,
)
event.save()
return event
@classmethod
def createOrderFinished(cls, ordername, profit):
name = ordername + " finished."
description = (
"Your order "
+ ordername
+ " was completed! The profit of "
+ profit
+ " was added to your companys money."
)
event = cls(
name=name,
description=description,
)
event.save()
return event
@classmethod
def createWorkerQuit(cls, threshhold, workername, workerhappyness):
name = workername + " quit his job."
description = (
"Your worker "
+ workername
+ " quit his job due to his happyness falling to "
+ str(workerhappyness)
+ "! Falling below "
+ str(threshhold)
+ " will result in increasing chance for your worker to quit!"
)
event = cls(
name=name,
description=description,
)
event.save()
return event
@classmethod
def createSpecialOrderPenalty(cls, order):
name = "You ignored the Special Order for " + order.name
description = (
"You ignored the Special Order for the order "
+ order.name
+ ". Penalties have been applied! [-20 Customer Satisfaction; -20% Profit]"
)
event = cls(
name=name,
description=description,
)
event.save()
return event
@classmethod
def createSpecialOrderBonus(cls, order):
name = "You handled the Special Order for " + order.name
description = (
"You handled the Special Order for the order "
+ order.name
+ " in a flexible model. You received a bonus on your order!"
+ " [+10 Customer Satisfaction; +10 Worker Satisfaction; +20% Profit ; +10 happyness all Workers]"
)
event = cls(
name=name,
description=description,
)
event.save()
return event
@classmethod
def createSpecialOrderWrongModel(cls, order):
name = "You handled the Special Order for " + order.name
description = (
"You handled the Special Order for the order "
+ order.name
+ ", but you are working with an unflexible model! You let your workers work overtime to complete the customers wish."
+ " [+30 Workload on all Skills; -20 happyness all Workers; -10 Worker Satsifaction]"
)
event = cls(
name=name,
description=description,
)
event.save()
return event
class EventOfferAccepted(Event):
order = models.ForeignKey("Order", default=1, on_delete=models.CASCADE)
modelset = models.BooleanField(default=False)
def setModel(self, model):
self.order.setEngineeringmodel(model)
self.modelset = True
self.save()
class SpecialOrder(Event):
occuranceProbability = models.IntegerField(
default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
)
validModels = models.ManyToManyField(EngineeringModel, blank=True)
occured = models.BooleanField(default=False)
hint = models.CharField(default="no hint", max_length=100)
def getValidModels(self):
vmodels = []
for model in self.validModels.all():
vmodels.append(model.name)
return vmodels
def setDefaultValidModels(self):
self.validModels.add(EngineeringModel.objects.get(name="ModelScrum"))
self.validModels.add(EngineeringModel.objects.get(name="ModelSpiral"))
self.validModels.add(EngineeringModel.objects.get(name="ModelHeyJoe"))
def createHint(occuranceProbability):
if occuranceProbability <= 10:
hintlist = [
"The project is discussed completely from the beginning, and clear agreements are made regarding the requirements and scope of the project.",
"The customer is known to wish little interaction with its project partners and just wants to get the job done.",
"A tight budget and strict time management allows little changes within the project.",
"The company has emphasized the importance of precise planning and scope definition, indicating their intention to avoid unnecessary changes.",
"The client's primary focus is on efficiency and timely completion, suggesting they are unlikely to introduce substantial changes mid-project.",
"With a fixed project scope and well-defined milestones, the company seems committed to maintaining project stability.",
"Previous collaborations with the company reveal a preference for minimal modifications during the project execution phase.",
]
else:
hintlist = [
"Previous project collaborations with the firm have involved multiple change requests and additional features added throughout the development process.",
"The client has expressed a strong desire for flexibility and creativity in the project execution.",
"Given the dynamic nature of the industry they work in, it is likely that the company will request modifications to adapt to emerging trends.",
"The client has not yet finalized their longterm strategy, which means changes and updates to the project might be needed.",
"The company regularely takes user feedback, which might demand project alteration and updating.",
"The client has expressed an interest in prototyping certain features to explore different possibilities, which may result in the addition of new requirements.",
"The customer wishes for an agile project execution to have the option to get involved in the projects development.",
]
hint = random.choice(hintlist)
return hint
def calculateOccurance(self):
randnum = random.randint(1, 100)
if (self.occuranceProbability >= randnum) and not self.occured:
return True
else:
return False
def createOccuranceProbability():
# 50% chance dass es relativ wahrscheinlich/unwahrscheinlich ist das SO auftritt
randnum = random.randint(1, 2)
if randnum == 1:
# niedrige OP
occuranceProbability = random.randint(1, 5)
else:
# hohe OP
occuranceProbability = random.randint(30, 40)
return occuranceProbability
def occure(self, company):
if self.calculateOccurance():
company.events.add(self)
self.occured = True
self.save()
def handle(self, order, company, handle):
if order.engineeringModel.name in self.getValidModels():
self.bonus(order, company)
event = Event.createSpecialOrderBonus(order)
elif handle == True:
self.invest(order, company)
event = Event.createSpecialOrderWrongModel(order)
else:
self.penalty(order, company)
event = Event.createSpecialOrderPenalty(order)
company.events.remove(self)
company.events.add(event)
return event
def bonus(self, order, company):
company.calculateCustomerSatisfaction(20)
company.calculateWorkerSatisfaction(10)
order.profit *= 1.2
for worker in company.workers.all():
worker.calculateHappyness(10)
order.save()
company.save()
def penalty(self, order, company):
company.calculateCustomerSatisfaction(-20)
order.profit *= 0.8
order.save()
company.save()
def invest(self, order, company):
order.addWorkload(30)
for worker in company.workers.all():
worker.calculateHappyness(-20)
company.calculateWorkerSatisfaction(-10)
order.save()
company.save()
class SOPrototyp(SpecialOrder):
@classmethod
def createRandom(cls, ordername):
name = "Specialorder prototyp request from " + ordername
description = (
"Your customer for the order "
+ ordername
+ " wants you to produce a prototyp for them to review."
)
# hier random low <5% per round oder high < 40% per round
occuranceProbability = cls.createOccuranceProbability()
hint = cls.createHint(occuranceProbability=occuranceProbability)
specialorder = cls(
name=name,
description=description,
occuranceProbability=occuranceProbability,
hint=hint,
)
specialorder.save()
specialorder.setDefaultValidModels()
specialorder.save()
return specialorder
class SORegularIncrementUpdates(SpecialOrder):
@classmethod
def createRandom(cls, ordername):
name = "Specialorder regular incremental updates request from " + ordername
description = (
"Your customer for the order "
+ ordername
+ " wants to get regular updates on the increments of the project!"
)
# hier random low <5% per round oder high < 40% per round
occuranceProbability = cls.createOccuranceProbability()
hint = cls.createHint(occuranceProbability=occuranceProbability)
specialorder = cls(
name=name,
description=description,
occuranceProbability=occuranceProbability,
hint=hint,
)
specialorder.save()
specialorder.setDefaultValidModels()
specialorder.save()
return specialorder
class SOChangeRequirement(SpecialOrder):
@classmethod
def createRandom(cls, ordername):
name = "Specialorder change requirement request from " + ordername
description = (
"Your customer for the order "
+ ordername
+ " wants to change some requirements on your order. "
)
# hier random low <5% per round oder high < 40% per round
occuranceProbability = cls.createOccuranceProbability()
hint = cls.createHint(occuranceProbability=occuranceProbability)
specialorder = cls(
name=name,
description=description,
occuranceProbability=occuranceProbability,
hint=hint,
)
specialorder.save()
specialorder.setDefaultValidModels()
specialorder.save()
return specialorder
+300
View File
@@ -0,0 +1,300 @@
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
+11
View File
@@ -0,0 +1,11 @@
from django.db import models
# Klassen für hartcodierte Datenbank:
# Namen Datenbank
class WorkerNames(models.Model):
name = models.CharField(default="no name", max_length=20)
class OrderNames(models.Model):
name = models.CharField(default="no name", max_length=20)
+25
View File
@@ -0,0 +1,25 @@
from django.db import models
from .event import EventOfferAccepted
# offer für orders
class Offer(models.Model):
company = models.ForeignKey("Company", default=1, on_delete=models.CASCADE)
amount = models.IntegerField(default=0)
order = models.ForeignKey("Order", default=1, on_delete=models.CASCADE)
def offerAcceptedEvent(self):
name = "Offer for " + self.order.name
description = (
"Your offer for the order "
+ self.order.name
+ " has been accepted!"
+ " You have "
+ str(self.order.maxRounds)
+ " rounds time to finish the order and claim your profit of "
+ str(self.order.profit)
)
offeracceptedevent = EventOfferAccepted.objects.create(
name=name, description=description, order=self.order
)
self.company.addEvent(offeracceptedevent)
+211
View File
@@ -0,0 +1,211 @@
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
import random
from .names import OrderNames
from .attributeset import AttributeSet
from .engineeringmodel import EngineeringModel
from .worker import Worker
from .offer import Offer
from .event import (
SpecialOrder,
SOChangeRequirement,
SORegularIncrementUpdates,
SOPrototyp,
)
# in attributeset einbauen?
attributelist = [
"experience",
"reliability",
"python",
"javascript",
"cpp",
"management",
]
# order zum abarbeiten
class Order(models.Model):
name = models.CharField(default="random order", max_length=20)
profit = models.IntegerField(default=1000)
status = models.IntegerField(
default=0, validators=[MinValueValidator(0), MaxValueValidator(1)]
)
maxRounds = models.IntegerField(
default=5, validators=[MinValueValidator(5), MaxValueValidator(100)]
)
requiredWorkload = models.ForeignKey(
AttributeSet, default=1, on_delete=models.CASCADE
)
engineeringModel = models.ForeignKey(
EngineeringModel, default=1, on_delete=models.DO_NOTHING, blank=True
)
assignedWorkers = models.ManyToManyField(Worker, blank=True)
offers = models.ManyToManyField(
Offer,
blank=True,
related_name="order_offers",
)
specialorder = models.ForeignKey(
SpecialOrder, default=1, on_delete=models.CASCADE, blank=True
)
recalculated = models.BooleanField(default=False)
def __str__(self):
return self.name
def getRandomSpecialorder(name):
randnum = random.randint(1, 3)
if randnum == 1:
specialorder = SOPrototyp.createRandom(name)
elif randnum == 2:
specialorder = SOChangeRequirement.createRandom(name)
else:
specialorder = SORegularIncrementUpdates.createRandom(name)
return specialorder
@classmethod
def createRandom(cls):
name = random.choice(OrderNames.objects.all()).name
profit = random.randint(40000, 100000)
maxRounds = round(random.uniform(0.7, 1.3) * (profit / 10000))
requiredWorkload = AttributeSet.createRandom(maxRounds * 13)
engineeringModel = EngineeringModel.objects.all().get(name="ModelChaotic")
specialorder = cls.getRandomSpecialorder(name)
order = cls(
name=name,
profit=profit,
maxRounds=maxRounds,
requiredWorkload=requiredWorkload,
engineeringModel=engineeringModel,
specialorder=specialorder,
)
order.save()
return order
def setStatus(self, status):
self.status = status
self.save()
def assignWorker(self, worker):
worker.setStatus(2)
self.assignedWorkers.add(worker)
def unassignWorker(self, worker):
worker.setStatus(1)
self.assignedWorkers.remove(worker)
def setEngineeringmodel(self, model):
self.engineeringModel = model
self.save()
def decreaseRounds(self):
self.maxRounds -= 1
self.save()
def recalculate(self, company):
if not self.recalculated:
self.engineeringModel.recalculate(order=self, company=company)
print("recalculated")
def calculateWorkload(self, workersatisfaction):
self.decreaseRounds()
finished = False
for worker in self.assignedWorkers.all():
if worker.skilledModels == self.engineeringModel:
if self.engineeringModel.name == "ModelScrum":
amplifyer = self.engineeringModel.bonus(worker=worker, order=self)
else:
amplifyer = worker.amplifyer
else:
self.engineeringModel.penalty(worker=worker, order=self)
if self.engineeringModel.name == "ModelScrum":
amplifyer = 0.6
else:
amplifyer = 1
# arbeit an order wenn nicht blockeirt
if worker.status != 3:
for attribute in attributelist:
newval = getattr(self.requiredWorkload, attribute) - (
getattr(worker.attributes, attribute)
* amplifyer
* (workersatisfaction * 0.01)
)
setattr(
self.requiredWorkload,
attribute,
max(0, newval), # 0 setzen wenn negativwert
)
self.requiredWorkload.save()
# prüfe ob alles abgearbeitet
finished = True
for attribute in attributelist:
if getattr(self.requiredWorkload, attribute) > 0:
finished = False
break
return finished
def changeWorkload(self, number):
for attribute in attributelist:
setattr(
self.requiredWorkload,
attribute,
getattr(self.requiredWorkload, attribute) * number,
)
self.requiredWorkload.save()
def addWorkload(self, number):
for attribute in attributelist:
setattr(
self.requiredWorkload,
attribute,
getattr(self.requiredWorkload, attribute) + number,
)
self.requiredWorkload.save()
def finishOrder(self, company):
company.addProfit(self.profit)
company.calculateCustomerSatisfaction(30)
company.save()
self.cancelOrder()
def addOffer(self, offer):
self.offers.add(offer)
def removeOffer(self, offer):
self.offers.remove(offer)
def checkOffer(self, amount):
if amount > (self.profit * 1.2) or amount < (self.profit * 0.8):
return False
else:
return True
def calculateBestOffer(self):
if self.offers.exists():
# Wenn offers vorhanden
bestoffer = (0, 0)
for offer in self.offers.all():
x = float(offer.company.customersatisfaction) / float(offer.amount)
if x >= bestoffer[0]:
bestoffer = (x, offer)
self.setProfit(offer.amount)
return bestoffer[1]
else:
# wenn keine offers
return
def cancelOrder(self):
for worker in self.assignedWorkers.all():
self.unassignWorker(worker)
self.save()
def setProfit(self, amount):
self.profit = amount
self.save()
+45
View File
@@ -0,0 +1,45 @@
from django.db import models
import threading
import time
# Timer mit Thread damit er seperat vom gamegeschehen läuft
class TimerThread(threading.Thread):
def __init__(self, timermodel, callback):
super(TimerThread, self).__init__()
self.timermodel = timermodel
self.callback = callback
def run(self):
self.timermodel.running = True
while self.timermodel.remainingtimer >= 0 and self.timermodel.running:
time.sleep(1)
self.timermodel.remainingtimer -= 1
self.timermodel.save()
if self.timermodel.remainingtimer <= 1:
# self.stop()
self.callback()
self.reset()
def reset(self):
self.timermodel.remainingtimer = self.timermodel.timer
self.timermodel.save()
def stop(self):
self.timermodel.running = False
self.reset()
# self.join()
class Timer(models.Model):
timer = models.IntegerField(default=60)
remainingtimer = models.IntegerField(default=60)
running = models.BooleanField(default=False)
def start(self, callback):
self.thread = TimerThread(self, callback)
self.thread.start()
def stop(self):
self.thread.stop()
+99
View File
@@ -0,0 +1,99 @@
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
import random
from .engineeringmodel import EngineeringModel, ModelChaotic
from .attributeset import AttributeSet
from .names import WorkerNames
# worker klasse
class Worker(models.Model):
name = models.CharField(default="random worker", max_length=20)
attributes = models.ForeignKey(AttributeSet, default=1, on_delete=models.CASCADE)
skilledModels = models.ForeignKey(
EngineeringModel, on_delete=models.CASCADE, blank=True
)
amplifyer = models.FloatField(
default=1, validators=[MinValueValidator(1.0), MaxValueValidator(2.0)]
)
salary = models.IntegerField(default=1000)
status = models.IntegerField(
default=0, validators=[MinValueValidator(0), MaxValueValidator(3)]
)
# status 0 = in workermarket; 1=in company; 2=wokring on order; 3=locked
lockedRounds = models.IntegerField(default=0, validators=[MinValueValidator(0)])
happyness = models.IntegerField(
default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
)
sick = models.BooleanField(default=False)
def __str__(self):
return self.name
@classmethod
def createRandom(cls):
name = random.choice(WorkerNames.objects.all()).name
attributes = AttributeSet.createRandom(20)
allmodels = EngineeringModel.objects.all()
allmodelsnochaotic = [
model for model in allmodels if not isinstance(model, ModelChaotic)
]
skilledModels = random.choice(allmodelsnochaotic)
if random.random() < 0.8:
value = round(random.uniform(1, 1.3), 1)
else:
value = round(random.uniform(1.3, 1.6), 1)
amplifyer = value
salary = round(amplifyer * 2500 * random.uniform(0.7, 1.3))
worker = cls(
name=name,
attributes=attributes,
skilledModels=skilledModels,
amplifyer=amplifyer,
salary=salary,
status=0,
)
worker.save()
return worker
def improveAttribute(self, attribute, amount):
self.attributes.increase(attribute=attribute, amount=amount)
def calculateHappyness(self, number):
if (self.happyness + number) > 100:
self.happyness = 100
elif (self.happyness + number) < 0:
self.happyness = 0
else:
self.happyness += number
self.save()
def quitJob(self):
self.delete()
def calculateSick(self):
if self.sick == False:
randnumber = random.randint(1, 100)
if randnumber <= 3:
self.setStatus(3)
self.setSick(True)
rounds = random.randint(1, 2)
self.setLockedRounds(rounds)
elif self.sick == True and self.lockedRounds < 0:
self.setSick(False)
self.setStatus(1)
def setStatus(self, status):
self.status = status
self.save()
def getStatus(self):
return self.status
def setLockedRounds(self, amount):
self.lockedRounds = amount
self.save()
def setSick(self, sickness):
self.sick = sickness
self.save()