move modules to src/modules and add some other ones

This commit is contained in:
randomuser 2023-07-23 20:47:35 -05:00
parent 733c381b41
commit e107e28947
7 changed files with 341 additions and 29 deletions

43
src/constants.py Normal file
View File

@ -0,0 +1,43 @@
from modules.wires import WiresModule
from modules.button import ButtonModule
from modules.password import PasswordModule
modules = {
'wires': WiresModule,
'button': ButtonModule,
'keypad': None,
'simon': None,
'first': None,
'memory': None,
'morse': None,
'compwires': ComplicatedWiresModule,
'seqwires': None,
'maze': None,
'password': PasswordModule,
'vent': None,
'discharge': None,
'knob': None,
}
indicators = [
'SND',
'CLR',
'CAR',
'IND',
'FRQ',
'SIG',
'NSA',
'MSA',
'TRN',
'BOB',
'FRK',
]
ports = [
'DVI',
'Para',
'PS2',
'RJ45',
'Serial',
'RCA',
]

0
src/modules/__init__.py Normal file
View File

69
src/modules/button.py Normal file
View File

@ -0,0 +1,69 @@
from enum import Enum, auto
from prompt_toolkit import prompt
from prompt_toolkit.completion import WordCompleter
class ButtonAction(Enum):
RELEASE = auto(),
HOLD = auto()
class ButtonModule:
def __init__(self, color, text, state):
self.color = color
self.text = text.lower()
self.state = state
def solve(self):
if self.color == "blue" and self.text == "abort":
return ButtonAction.HOLD
elif self.state.batteries > 1 and self.text == "detonate":
return ButtonAction.RELEASE
try:
if self.color == "white" and self.indicators["CAR"] == True:
return ButtonAction.HOLD
except KeyError: pass
try:
if self.state.batteries > 2 and self.indicators["FRK"] == True:
return ButtonAction.RELEASE
except KeyError: pass
if self.color == "yellow":
return ButtonAction.HOLD
elif self.color == "red" and self.text == "hold":
return ButtonAction.RELEASE
return ButtonAction.HOLD
def hold(self, color):
if color == "blue":
return 4
elif color == "white":
return 1
elif color == "yellow":
return 5
return 1
@classmethod
def interactive(cls, state, cmdline):
print("Please enter button color")
color = prompt('button> ')
print("Please enter button text")
text = prompt('button> ')
button = cls(color, text, state)
result = button.solve()
if result == ButtonAction.HOLD:
print("What is the held button color")
heldcolor = prompt('button> ')
print("Release until the timer has a {} in any position".format(
str(button.hold(heldcolor))
))
else:
print("Release")

View File

@ -1,4 +1,6 @@
from enum import Enum, auto from enum import Enum, auto
from prompt_toolkit import prompt
from prompt_toolkit.completion import WordCompleter
class MappedAction(Enum): class MappedAction(Enum):
CUT_UNCONDITIONALLY = auto(), CUT_UNCONDITIONALLY = auto(),
@ -11,18 +13,7 @@ class FinalAction(Enum):
CUT = auto(), CUT = auto(),
NO_CUT = auto() NO_CUT = auto()
class GlobalState: class ComplicatedWiresModule:
def __init__(self, serial, parallel, batteries):
self.serial = serial
self.parallel = parallel
self.batteries = batteries
if int(self.serial[-1]) % 2 == 0:
self.serial_even = True
else:
self.serial_even = False
class ComplicatedWire:
def __init__(self, red, blue, star, led, state): def __init__(self, red, blue, star, led, state):
self.red = red self.red = red
self.blue = blue self.blue = blue
@ -63,7 +54,6 @@ class ComplicatedWire:
def resolveAction(self): def resolveAction(self):
action = self.getAction() action = self.getAction()
print(action)
if action == MappedAction.CUT_UNCONDITIONALLY: if action == MappedAction.CUT_UNCONDITIONALLY:
return FinalAction.CUT return FinalAction.CUT
@ -72,12 +62,12 @@ class ComplicatedWire:
return FinalAction.NO_CUT return FinalAction.NO_CUT
elif action == MappedAction.CUT_IF_DIGIT_EVEN: elif action == MappedAction.CUT_IF_DIGIT_EVEN:
if self.state.serial_even: if self.state.serial.is_even:
return FinalAction.CUT return FinalAction.CUT
return FinalAction.NO_CUT return FinalAction.NO_CUT
elif action == MappedAction.CUT_IF_PARALLEL: elif action == MappedAction.CUT_IF_PARALLEL:
if self.state.parallel: if 'Para' in self.state.ports:
return FinalAction.CUT return FinalAction.CUT
return FinalAction.NO_CUT return FinalAction.NO_CUT
@ -87,22 +77,23 @@ class ComplicatedWire:
return FinalAction.NO_CUT return FinalAction.NO_CUT
@classmethod @classmethod
def human_helper(cls): def interactive(cls, state, cmdline):
serial = input("serial (string)? ") completer = WordCompleter(['red', 'blue', 'star', 'led', 'quit', 'exit'])
parallel = cls.custom_bool(input("parallel (bool)? "))
batteries = int(input("number of batteries (int)? "))
red = cls.custom_bool(input("is red (bool)? ")) # there are 6 wires in the complicated wires module
blue = cls.custom_bool(input("is blue (bool)? ")) while True:
star = cls.custom_bool(input("is star (bool)? ")) text = prompt('compwires> ', completer=completer, complete_while_typing=True)
led = cls.custom_bool(input("is led (bool)? "))
print(red, blue, star, led) if text == "quit":
return
state = GlobalState(serial, parallel, batteries) elif text == "exit":
wire = cls(red, blue, star, led, state) return
print(wire.resolveAction()) attr = [i in text for i in ['red', 'blue', 'star', 'led']]
if __name__ == "__main__": try:
ComplicatedWire.human_helper() print("CUT" if cls(*attr, state).resolveAction() == FinalAction.CUT else "NO CUT")
except AttributeError:
print("the state hasn't been completed. maybe fill out the serial?")

78
src/modules/wires.py Normal file
View File

@ -0,0 +1,78 @@
from prompt_toolkit import prompt
from prompt_toolkit.completion import WordCompleter
class WiresModule:
def __init__(self, wires, state):
self.state = state
self.wires = wires.split(' ')
self.len = len(self.wires)
def solve(self):
# prints the solved solution
if self.len == 3:
if not 'red' in self.wires:
return "second wire"
elif self.wires[-1] == "white":
return "last wire"
elif self.wires.count('blue') > 1:
return "last blue wire"
else:
return "last wire"
elif self.len == 4:
if self.wires.count('red') > 1 and self.state.serial.is_odd:
return "last red wire"
elif self.wires[-1] == 'yellow' and not 'red' in self.wires:
return "first wire"
elif self.wires.count('blue') == 1:
return "first wire"
elif self.wires.count('yellow') > 1:
return "last wire"
else:
return "second wire"
elif self.len == 5:
if self.wires[-1] == 'black' and self.state.serial.is_odd:
return "fourth wire"
elif self.wires.count('red') == 1 and self.wires.count('yellow') > 1:
return "first wire"
elif not 'black' in self.wires:
return "second wire"
else:
return "first wire"
elif self.len == 6:
if not 'yellow' in self.wires and self.state.serial.is_odd:
return "third wire"
elif self.wires.count('yellow') == 1 and self.wires.count('white') > 1:
return "fourth wire"
elif not 'red' in self.wires:
return "last wire"
else:
return "fourth wire"
@classmethod
def interactive(cls, state, cmdline):
completer = WordCompleter(['red', 'blue', 'yellow', 'white', 'black'])
print("Please enter wire colors from top to bottom.")
text = prompt('wires> ', completer=completer, complete_while_typing=True)
wires = WiresModule(text, state)
print("cut the {}".format(wires.solve()))
return

131
src/shell.py Normal file
View File

@ -0,0 +1,131 @@
from constants import modules, indicators, ports
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import NestedCompleter
maincompleter = NestedCompleter.from_nested_dict({
'help': None,
'mark': None,
'serial': None,
'strike': None,
'batteries': None,
'eval': None,
'indicator': {*[indicator for indicator in indicators]},
'ports': {*[port for port in ports]},
'mod': {*["mod {}".format(module) for module in modules.keys()]},
})
class Serial:
def __init__(self, serial):
self.serial = serial.lower()
@property
def is_even(self):
if int(self.serial[-1]) % 2 == 0:
return True
return False
@property
def is_odd(self):
return not self.is_even
@property
def vowel(self):
for vowel in ['a', 'e', 'i', 'o', 'u']:
if vowel in self.serial:
return True
return False
@property
def no_vowel(self):
return not self.vowel
@property
def text(self):
return self.serial
class GlobalBombState:
def __init__(self):
self.indicators = {}
self.ports = []
self._serial = None
self.batteries = 0
self.modulecount = 0
self.strikes = 0
@property
def serial(self):
return self._serial
@serial.setter
def serial(self, serial):
self._serial = Serial(serial)
def update_toolbar(self):
return "help for help, ports: {}, ind: {}, batt: {}, serial: {}, strikes {}".format(
self.ports, self.indicators, str(self.batteries), self.serial.text if self.serial else "?", str(self.strikes)
)
session = PromptSession(completer=maincompleter)
state = GlobalBombState()
while True:
userinput = session.prompt("ktane> ", bottom_toolbar=state.update_toolbar(), complete_while_typing=True)
splitted = userinput.split(' ')
tokens = len(splitted)
command = splitted[0]
if command == "mod":
if tokens == 1:
print(modules.keys())
elif tokens > 1:
if splitted[1].isnumeric():
state.modulecount = int(splitted[1])
print("module count set to {}".format(str(state.modulecount)))
else:
try:
selectedmodule = modules[splitted[1]]
if selectedmodule:
selectedmodule.interactive(state, splitted[2:])
else:
print("this module doesn't exist!")
except IndexError:
print("you didn't specify a module")
elif command == "serial": # set the serial number
try:
state.serial = splitted[1]
print("serial number set to {}".format(state.serial.text))
except IndexError:
print("specify a serial number, perhaps?")
elif command == "batteries":
try:
state.batteries = int(splitted[1])
print("battery count set to {}".format(str(state.batteries)))
except IndexError:
print("specify a number of batteries, perhaps?")
elif command == "strike":
state.strikes += 1
print("strike given")
elif command == "ports":
try:
state.ports.append(splitted[1])
print("appeneded port {}".format(splitted[1]))
except IndexError:
print("specify a port type")
elif command == "indicator":
try:
state.indicators[splitted[1]] = True if splitted[2] == 't' else False
print("added indicator {} with state {}".format(
splitted[1], state.indicators[splitted[1]]
))
except IndexError: print("specify an indicator and a state")
elif command == "eval":
eval(' '.join(splitted[1:]))