This commit is contained in:
Jonas Zeunert
2021-03-07 15:47:45 +01:00
parent c54ab2e311
commit 6450ee22dc
10 changed files with 277 additions and 29 deletions

View File

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

View File

@@ -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"]

View File

@@ -10,3 +10,7 @@ class BankEvent(Event):
def trigger(self, target):
super().trigger(target)
self.bankSolenoid.trigger()
self.advanceBonus()
def advanceBonus(self):
self.playerState().advanceBonus()

View File

@@ -10,5 +10,4 @@ class BottomLeftBankEvent(BankEvent):
super().trigger(target)
playerState = self.playerState()
playerState.advanceLeftOrangeSpecial()
if playerState.upperPlayfieldTime < 30:
playerState.addUpperPlayfieldTime(5)
playerState.advanceUpperPlayfieldTime()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)

View File

@@ -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)

View File

@@ -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")
])

7
utils/RepeatTimer.py Normal file
View File

@@ -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)