Initial Commit
This commit is contained in:
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user