From 6450ee22dcd27b2b654e52f1e47f02695adf6e26 Mon Sep 17 00:00:00 2001 From: Jonas Zeunert Date: Sun, 7 Mar 2021 15:47:45 +0100 Subject: [PATCH] asdf --- PlayerState.py | 164 +++++++++++++++++++++++++---- config.py | 10 +- events/BankEvent.py | 6 +- events/BottomLeftBankEvent.py | 3 +- events/FixedTargetEvent.py | 11 ++ events/LeaveUpperPlayfieldEvent.py | 6 +- factories/EventFactory.py | 10 ++ lamps/Lamp.py | 15 +++ lamps/LampGroup.py | 74 +++++++++++++ utils/RepeatTimer.py | 7 ++ 10 files changed, 277 insertions(+), 29 deletions(-) create mode 100644 events/FixedTargetEvent.py create mode 100644 utils/RepeatTimer.py diff --git a/PlayerState.py b/PlayerState.py index 2c8c5b2..4a2420b 100644 --- a/PlayerState.py +++ b/PlayerState.py @@ -1,42 +1,139 @@ from threading import Timer +from utils.RepeatTimer import RepeatTimer import time +import random + import config +from lamps.Lamp import Lamp +from lamps.LampGroup import CHAMP_LAMPS +from lamps.LampGroup import UPPER_PLAYFIELD_TIME_LAMPS +from lamps.LampGroup import BONUS_MULTIPLIER_LAMPS +from lamps.LampGroup import BONUS_LAMPS + +from events.LeaveUpperPlayfieldEvent import LeaveUpperPlayfieldEvent + class PlayerState: - def __init__(self, display, specialDisplay, id, ballsToPlay, upperPlayfieldTime = 5, bonusTime = 0): + display = None + specialDisplay = None + id = 0 + points = 0 + bonus = 0 + bonusMultiplier = 1 + ballsLeft = 0 + replayBall = False + + redSpecial = 0 + redSpecialLit = False + + orangeSpecialLeft = False + orangeSpecialRight = False + orangeSpecialLit = False + + advanceTimeLeft = False + advanceTimeRight = False + timeAdvanceLeftTimer = None + timeAdvanceRightTimer = None + + upperPlayfieldTimer = None + upperPlayfieldTime = 0 + + def __init__(self, display, specialDisplay, id, ballsToPlay): self.display = display self.specialDisplay = specialDisplay self.id = id self.points = 0 self.ballsLeft = ballsToPlay + self.enableTiming() + self.bonusTime = config.BEGINNING_BONUS_TIME self.reset() + def enableTiming(self): + if config.BONUS_TIME_ALGORITHM == config.BONUS_TIME_ALGORITHM_OPTIONS.RANDOM: + self.disableAdvanceTimeLeft() + self.disableAdvanceTimeRight() + self.timeAdvanceLeft() + self.timeAdvanceRight() + elif config.BONUS_TIME_ALGORITHM == config.BONUS_TIME_ALGORITHM_OPTIONS.ALWAYS: + self.enableAdvanceTimeLeft() + self.enableAdvanceTimeRight() + + def timeAdvanceLeft(self): + choiceList = [True] * config.BONUS_TIME_ACTIVATION_PROBABILITY * 100 \ + + [False] * (1 - config.BONUS_TIME_ACTIVATION_PROBABILITY) * 100 + + if random.choice(choiceList): + self.enableAdvanceTimeLeft() + else: + self.disableAdvanceTimeLeft() + + activationTime = random.randrange(config.BONUS_TIME_MIN_RANDOM_TIME, config.BONUS_TIME_MAX_RANDOM_TIME) + self.timeAdvanceLeftTimer = time.Timer(activationTime, self.timeAdvanceLeft) + + def timeAdvanceLeft(self): + choiceList = [True] * config.BONUS_TIME_ACTIVATION_PROBABILITY * 100 \ + + [False] * (1 - config.BONUS_TIME_ACTIVATION_PROBABILITY) * 100 + + if random.choice(choiceList): + self.enableAdvanceTimeRight() + else: + self.disableAdvanceTimeRight() + + activationTime = random.randrange(config.BONUS_TIME_MIN_RANDOM_TIME, config.BONUS_TIME_MAX_RANDOM_TIME) + self.timeAdvanceLeftTimer = time.Timer(activationTime, self.timeAdvanceRight) + + def enableAdvanceTimeLeft(self): + self.advanceTimeLeft = True + Lamp("Left Advance Time").activate() + + def disableAdvanceTimeLeft(self): + self.advanceTimeLeft = False + Lamp("Left Advance Time").deactivate() + + def enableAdvanceTimeRight(self): + self.advanceTimeRight = True + Lamp("Right Advance Time").activate() + + def disableAdvanceTimeRight(self): + self.advanceTimeRight = False + Lamp("Right Advance Time").deactivate() + def reset(self): - self.bonus = 0 - self.bonusMultiplier = 1 - self.timer = None - self.timerStartTime = None + self.upperPlayfieldTimer = None self.replayBall = False self.upperPlayfieldTime = config.BEGINNING_UPPER_PLAYFIELD_TIME + self.resetBonus() self.resetTargets() + def resetBonus(self): + self.bonus = 0 + self.bonusMultiplier = 1 + BONUS_LAMPS.deactivate() + BONUS_MULTIPLIER_LAMPS.deactivate() + def resetTargets(self): self.resetRedSpecial() self.resetOrangeSpecial() - self.tunnelLit = 0 + self.resetTunnel() def resetRedSpecial(self): self.redSpecial = 0 self.redSpecialLit = False + Lamp("Special Red").deactivate() + CHAMP_LAMPS.deactivate() def resetOrangeSpecial(self): self.orangeSpecialLeft = False self.orangeSpecialRight = False self.orangeSpecialLit = False + Lamp("Special Orange").deactivate() + + def resetTunnel(self): + self.tunnelLit = 0 def advanceRightOrangeSpecial(self): self.orangeSpecialRight = True @@ -52,22 +149,41 @@ class PlayerState: elif config.ORANGE_SPECIAL_BANK == config.ORANGE_SPECIAL_BANK_OPTIONS.BOTH: self.orangeSpecialLit = self.orangeSpecialRight and self.orangeSpecialLeft + if self.orangeSpecialLit: + Lamp("Special Orange").activate() + def advanceRedSpecial(self): self.redSpecial += 1 + CHAMP_LAMPS.activateNext() if(self.redSpecial == config.RED_SPECIAL_TIMES): self.redSpecialLit = True + Lamp("Special Red").activate() + + def advanceTunnel(self): + if self.tunnelLit <= 5: + self.tunnelLit += 1 + + def advanceBonus(self): + if self.bonus >= 20: + return + + self.bonus += 1 + BONUS_LAMPS.activateNext() def advanceBonusMultiplier(self): if self.bonusMultiplier >= 15: return if self.bonusMultiplier == 1: - self.bonusMultiplier = 5 - return + self.bonusMultiplier = 10 + elif self.bonusMultiplier == 10: + self.bonusMultiplier = 20 + elif self.bonusMultiplier == 20: + self.bonusMultiplier == 50 - self.bonusMultiplier *= 2 + BONUS_MULTIPLIER_LAMPS.activateNext() def setReplayBall(self): self.replayBall = True @@ -87,25 +203,31 @@ class PlayerState: self.ballsLeft -= 1 self.specialDisplay.printBallsToPlay(self.ballsLeft) - def addUpperPlayfieldTime(self, time): - self.upperPlayfieldTime += time + def advanceUpperPlayfieldTime(self): + if self.upperPlayfieldTime == 0: + self.upperPlayfieldTime = 5 + elif self.upperPlayfieldTime == 5: + self.upperPlayfieldTime = 10 + elif self.upperPlayfieldTime == 10: + self.upperPlayfieldTime = 20 + elif self.upperPlayfieldTime == 20: + self.upperPlayfieldTime = 30 - def __setUpperPlayfieldTime(self, time): - self.upperPlayfieldTime = time + UPPER_PLAYFIELD_TIME_LAMPS.activateNext() def startUpperPlayfieldTimer(self): - self.timerStartTime = time.time() - self.timer = Timer(self.upperPlayfieldTime, self.stopUpperPlayfieldTimer) + self.upperPlayfieldTimer = Timer(1, self.updatePlayfieldTime) - def stopUpperPlayfieldTimer(self): - if not self.timer: + def updatePlayfieldTime(self): + if self.upperPlayfieldTime == 0: + self.upperPlayfieldTimer = None return - self.timer.cancel() + if self.upperPlayfieldTime in [0, 5, 10, 20]: + UPPER_PLAYFIELD_TIME_LAMPS.deactivateCurrent() - elapsedTime = time.time() - self.timerStartTime - timeLeft = self.upperPlayfieldTime - elapsedTime - self.__setUpperPlayfieldTime(timeLeft) + self.upperPlayfieldTime -= 1 + self.upperPlayfieldTimer = Timer(1, self.updatePlayfieldTime) def addBonusTimeSecond(self): self.bonusTime += 1 diff --git a/config.py b/config.py index e5346fa..4f205cc 100644 --- a/config.py +++ b/config.py @@ -2,7 +2,8 @@ import os from events.SpecialEvent import SpecialEvent from enum import Enum -ORANGE_SPECIAL_BANK_OPTIONS = Enum("BOTH", "ONE") +ORANGE_SPECIAL_BANK_OPTIONS = Enum("ORANGE_SPECIAL_BANK_OPTIONS", ["BOTH", "ONE"]) +BONUS_TIME_ALGORITHM_OPTIONS = Enum("BONUS_TIME_ALGORITHM_OPTIONS", ["ALWAYS", "RANDOM"]) # Game Config ## Network Config @@ -13,8 +14,13 @@ OUTPUT_SOCKET_NAME = "/S.flippR_driver.out" BALLS_PER_GAME = 3 BEGINNING_UPPER_PLAYFIELD_TIME = 5 BEGINNING_BONUS_TIME = 0 +## Bonus Time Algorithm +BONUS_TIME_ALGORITHM = BONUS_TIME_ALGORITHM_OPTIONS["RANDOM"] +BONUS_TIME_MIN_RANDOM_TIME = 5 +BONUS_TIME_MAX_RANDOM_TIME = 15 +BONUS_TIME_ACTIVATION_PROBABILITY = 0.1 ## Special config RED_SPECIAL = SpecialEvent.replay RED_SPECIAL_TIMES = 1 ORANGE_SPECIAL = SpecialEvent.points -ORANGE_SPECIAL_BANK = ORANGE_SPECIAL_BANK_OPTIONS.BOTH +ORANGE_SPECIAL_BANK = ORANGE_SPECIAL_BANK_OPTIONS["BOTH"] diff --git a/events/BankEvent.py b/events/BankEvent.py index c8aaeb5..c82381d 100644 --- a/events/BankEvent.py +++ b/events/BankEvent.py @@ -9,4 +9,8 @@ class BankEvent(Event): def trigger(self, target): super().trigger(target) - self.bankSolenoid.trigger() \ No newline at end of file + self.bankSolenoid.trigger() + self.advanceBonus() + + def advanceBonus(self): + self.playerState().advanceBonus() diff --git a/events/BottomLeftBankEvent.py b/events/BottomLeftBankEvent.py index fc8a802..ee44556 100644 --- a/events/BottomLeftBankEvent.py +++ b/events/BottomLeftBankEvent.py @@ -10,5 +10,4 @@ class BottomLeftBankEvent(BankEvent): super().trigger(target) playerState = self.playerState() playerState.advanceLeftOrangeSpecial() - if playerState.upperPlayfieldTime < 30: - playerState.addUpperPlayfieldTime(5) + playerState.advanceUpperPlayfieldTime() diff --git a/events/FixedTargetEvent.py b/events/FixedTargetEvent.py new file mode 100644 index 0000000..21387ce --- /dev/null +++ b/events/FixedTargetEvent.py @@ -0,0 +1,11 @@ +from Event import Event + + +class FixedTargetEvent(Event): + def __init__(self, playerState): + super().__init__("Fixed Target Event") + self.playerState = playerState + + def trigger(self, target): + super().trigger(target) + self.playerState().advanceTunnel() diff --git a/events/LeaveUpperPlayfieldEvent.py b/events/LeaveUpperPlayfieldEvent.py index 80786dd..e1c2000 100644 --- a/events/LeaveUpperPlayfieldEvent.py +++ b/events/LeaveUpperPlayfieldEvent.py @@ -1,13 +1,13 @@ from Event import Event +from solenoids.TopFlipper import TopFlipper class LeaveUpperPlayfieldEvent(Event): def __init__(self, playerState, flipper): self.playerState = playerState - self.flipper = flipper + self.flipper = TopFlipper() super().__init__("Leave Upper Playfield Event") def trigger(self, target): super().trigger(target) - self.flipper.deactivate() - self.playerState().stopUpperPlayfieldTimer() \ No newline at end of file + self.flipper.deactivate() \ No newline at end of file diff --git a/factories/EventFactory.py b/factories/EventFactory.py index 681cb66..427c7fb 100644 --- a/factories/EventFactory.py +++ b/factories/EventFactory.py @@ -17,6 +17,7 @@ from events.TunnelEvent import TunnelEvent from events.RedSpecialEvent import RedSpecialEvent from events.OrangeSpecialEvent import OrangeSpecialEvent from events.SpinnerEvent import SpinnerEvent +from events.FixedTargetEvent import FixedTargetEvent class EventFactory: def __init__(self, targets, currentPlayer): @@ -113,5 +114,14 @@ class EventFactory: self.__registerEventToTarget(event, self.targets["Spinner"]) return event + def createFixedTargetEvent(self): + event = FixedTargetEvent(self.currentPlayer) + self.__registerEventToTarget(event, self.targets["Fixed Target 1"]) + self.__registerEventToTarget(event, self.targets["Fixed Target 2"]) + self.__registerEventToTarget(event, self.targets["Fixed Target 3"]) + self.__registerEventToTarget(event, self.targets["Fixed Target 4"]) + self.__registerEventToTarget(event, self.targets["Fixed Target 5"]) + return event + def __registerEventToTarget(self, event, target): target.on(target.hit_key, event.trigger) diff --git a/lamps/Lamp.py b/lamps/Lamp.py index e69de29..4695279 100644 --- a/lamps/Lamp.py +++ b/lamps/Lamp.py @@ -0,0 +1,15 @@ +from networking.Networking import Networking + +class Lamp: + def __init__(self, name): + self.name = name + + def activate(self): + Networking().activateLamp(self) + + def deactivate(self): + Networking().deactivateLamp() + + def isActivated(self): + Networking().getLamps(self) + diff --git a/lamps/LampGroup.py b/lamps/LampGroup.py index e69de29..5c1c94d 100644 --- a/lamps/LampGroup.py +++ b/lamps/LampGroup.py @@ -0,0 +1,74 @@ +from lamps.Lamp import Lamp +class LampGroup: + def __init__(self, lamps): + self.lamps = lamps + self.currentLamp = 0 + self.deactivate() + + def activate(self): + for lamp in self.lamps: + lamp.activate() + + def deactivate(self): + for lamp in self.lamps: + lamp.deactivate() + + def activateNext(self): + self.lamps[self.currentLamp].activate() + + if self.currentLamp == len(self.lamps): + return + + self.currentLamp += 1 + + def deactivateCurrent(self): + self.lamps[self.currentLamp].deactivate() + + if self.currentLamp == 0: + return + + self.currentLamp -= 1 + +CHAMP_LAMPS = LampGroup([ + Lamp("C Of Champ"), + Lamp("H Of Champ"), + Lamp("A Of Champ"), + Lamp("M Of Champ"), + Lamp("P Of Champ") +]) + +UPPER_PLAYFIELD_TIME_LAMPS = LampGroup([ + Lamp("Lamp 5 Sec"), + Lamp("Lamp 10 Sec"), + Lamp("Lamp 20 Sec"), + Lamp("Lamp 30 Sec") +]) + +BONUS_MULTIPLIER_LAMPS = LampGroup([ + Lamp("Bonus Multiplier x10"), + Lamp("Bonus Multiplier x20"), + Lamp("Bonus Multiplier x50") +]) + +BONUS_LAMPS = LampGroup([ + Lamp("Bonus 1000"), + Lamp("Bonus 2000"), + Lamp("Bonus 3000"), + Lamp("Bonus 4000"), + Lamp("Bonus 5000"), + Lamp("Bonus 6000"), + Lamp("Bonus 7000"), + Lamp("Bonus 8000"), + Lamp("Bonus 9000"), + Lamp("Bonus 10000"), + Lamp("Bonus 11000"), + Lamp("Bonus 12000"), + Lamp("Bonus 13000"), + Lamp("Bonus 14000"), + Lamp("Bonus 15000"), + Lamp("Bonus 16000"), + Lamp("Bonus 17000"), + Lamp("Bonus 18000"), + Lamp("Bonus 19000"), + Lamp("Bonus 20000") +]) diff --git a/utils/RepeatTimer.py b/utils/RepeatTimer.py new file mode 100644 index 0000000..af79915 --- /dev/null +++ b/utils/RepeatTimer.py @@ -0,0 +1,7 @@ +from threading import Timer + + +class RepeatTimer(Timer): + def run(self): + while not self.finished.wait(self.interval): + self.function(*self.args, **self.kwargs) \ No newline at end of file