Browse Source

Working

master
Pete Shadbolt 3 years ago
commit
f581515ada
1 changed files with 117 additions and 0 deletions
  1. +117
    -0
      cheekyfsm.py

+ 117
- 0
cheekyfsm.py View File

@@ -0,0 +1,117 @@
import curses
import random
import sys
import re

ESCAPE = 27
LETTERS = range(97, 122)
NUMBERS = range(48, 57)


class CheekyFSM(object):
def __init__(self):
self.lastkey = -1
self.buffer = ""
self.message = ""
self.edges = {}
self.state = "A"
self.history = " "*30

def show_edges(self):
""" Print the help menu """
y, x = self.w.getmaxyx()
for index, ((start, end), prob) in enumerate(self.edges.items()):
self.w.addstr(10 + index, 2, f"{start} -> {end} : {prob}%")

def update(self):
""" Update the FSM """
edges = list(self.edges.items())
random.shuffle(edges)
for ((start, end), prob) in edges:
if start == self.state:
if random.randint(0, 100) < prob:
self.state = end

self.history = self.history[1:] + self.state

def show_state(self):
""" Show the state of the machine """
self.w.addstr(2, 2, f"Tempo: 120bpm")
self.w.addstr(4, 2, f"State: {self.state}")
self.w.addstr(5, 2, f"History: {self.history}")

offset = 6
for ((start, end), prob) in self.edges.items():
if start == self.state:
self.w.addstr(offset, 2,
f"Going to {end} with probability {prob}%")
offset += 1

def show_status(self):
""" Print the status bar """
y, x = self.w.getmaxyx()
self.w.addstr(y - 2, 2, f"> {self.buffer}", curses.A_BOLD)

def quit(self):
""" Quit the program """
curses.nocbreak()
self.w.keypad(False)
curses.echo()
curses.endwin()
sys.exit(0)

def process_key(self):
""" Process a key """
key = self.w.getch()
self.lastkey = key
if key == ESCAPE:
quit(self.w)
elif key in LETTERS:
self.buffer += chr(key).upper()
elif key in NUMBERS:
self.buffer += chr(key)
elif key == 10:
self.accept()
elif key == 263 and len(self.buffer) > 0:
self.buffer = self.buffer[:-1]

def accept(self):
""" Accept the string """
match = re.match(r"([A-Z])([A-Z])(\d+)", self.buffer)
if not match:
self.message = " Invalid command :("
else:
groups = match.groups()
start = groups[0]
end = groups[1]
prob = int(groups[2])
self.modify(start, end, prob)
self.buffer = ""

def modify(self, start, end, prob):
""" Make a modification """
key = (start, end)
self.edges[key] = prob
self.message = f" {start} -> {end} : {prob}%"
if prob == 0 and key in self.edges:
self.message = f" {start} -> {end} : deleted"
del self.edges[key]

def loop(self, w):
""" Run the loop """
self.w = w
curses.curs_set(0) # invisible
w.timeout(100)
while True:
w.clear()
self.show_edges()
self.show_status()
self.show_state()
self.update()
w.refresh()
self.process_key()


if __name__ == "__main__":
fsm = CheekyFSM()
curses.wrapper(fsm.loop)

Loading…
Cancel
Save