2023-08-16 09:45:20 -04:00
|
|
|
from st3m.reactor import Responder
|
|
|
|
from st3m.run import run_responder
|
|
|
|
|
|
|
|
UP = 0
|
|
|
|
LEFT = 1
|
|
|
|
DOWN = 2
|
|
|
|
RIGHT = 3
|
|
|
|
|
2023-08-16 13:51:55 -04:00
|
|
|
def dir_str(dir):
|
|
|
|
if dir == UP:
|
|
|
|
return 'back'
|
|
|
|
elif dir == LEFT:
|
|
|
|
return 'left'
|
|
|
|
elif dir == DOWN:
|
|
|
|
return 'front'
|
|
|
|
elif dir == RIGHT:
|
|
|
|
return 'right'
|
|
|
|
|
|
|
|
def image_path(dir, step):
|
|
|
|
return f"/flash/sprites/{dir_str(dir)}{str(step + 1)}.png"
|
|
|
|
|
2023-08-16 09:45:20 -04:00
|
|
|
|
|
|
|
class Random:
|
|
|
|
def __init__(self):
|
|
|
|
self._state = 0x9ec5_9ec5 # (two gecs)
|
|
|
|
|
|
|
|
# idk its fine its just for choosing delay and direction
|
|
|
|
def next(self):
|
|
|
|
self._state *= 37
|
|
|
|
self._state &= 0xffff_ffff
|
|
|
|
return self._state >> 24
|
|
|
|
|
|
|
|
def direction(self):
|
|
|
|
return self.next() & 3
|
|
|
|
|
|
|
|
def delay(self):
|
|
|
|
return Box.TURN_DELAY_BASE + self.next()
|
|
|
|
|
|
|
|
# screen coords range ±120 each side
|
|
|
|
|
|
|
|
class Box(Responder):
|
2023-08-16 13:51:55 -04:00
|
|
|
STEP_DELAY = 250
|
2023-08-16 09:45:20 -04:00
|
|
|
TURN_DELAY_BASE = 1400
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self.random = Random()
|
|
|
|
self.choose_direction()
|
|
|
|
self.choose_turn_delay()
|
|
|
|
self.step = 0
|
|
|
|
self.step_delay = Box.STEP_DELAY
|
|
|
|
|
|
|
|
def draw(self, ctx):
|
|
|
|
self.clear(ctx)
|
|
|
|
# self.text(ctx)
|
2023-08-16 13:51:55 -04:00
|
|
|
self.image(ctx)
|
2023-08-16 09:45:20 -04:00
|
|
|
|
|
|
|
def clear(self, ctx):
|
|
|
|
ctx.rgb(0, 0, 0) \
|
|
|
|
.rectangle(-120, -120, 240, 240) \
|
|
|
|
.fill()
|
|
|
|
|
2023-08-16 13:51:55 -04:00
|
|
|
def image(self, ctx):
|
|
|
|
path = image_path(self.direction, self.step)
|
|
|
|
ctx.image(path, -10, -10, -1, -1)
|
|
|
|
|
2023-08-16 09:45:20 -04:00
|
|
|
@staticmethod
|
|
|
|
def coord(d):
|
|
|
|
if d == UP:
|
|
|
|
return (-20, -100)
|
|
|
|
elif d == LEFT:
|
|
|
|
return (-100, -20)
|
|
|
|
elif d == RIGHT:
|
|
|
|
return (100, 20)
|
|
|
|
elif d == DOWN:
|
|
|
|
return (20, 100)
|
|
|
|
|
|
|
|
def rect(self, ctx):
|
|
|
|
if self.step:
|
|
|
|
ctx = ctx.rgb(.1, .6, .3)
|
|
|
|
else:
|
|
|
|
ctx = ctx.rgb(.1, .3, .6)
|
|
|
|
ctx.rectangle(0, 0, *Box.coord(self.direction)).fill()
|
|
|
|
|
|
|
|
def text(self, ctx):
|
2023-08-16 13:51:55 -04:00
|
|
|
msg = f"{self.turn_delay}; {self.step_delay}; {self.direction}; {self.step}"
|
|
|
|
ctx.font_size = 16.0
|
|
|
|
ctx.text_align = ctx.CENTER
|
|
|
|
ctx.rgb(1, 1, 1).move_to(0, -100).text(msg)
|
2023-08-16 09:45:20 -04:00
|
|
|
|
|
|
|
def think(self, state, Δ):
|
|
|
|
self.update_delay(Δ)
|
|
|
|
|
|
|
|
def update_delay(self, Δ):
|
|
|
|
self.turn_delay -= Δ
|
|
|
|
self.step_delay -= Δ
|
|
|
|
if self.turn_delay <= 0:
|
|
|
|
old_delay = self.turn_delay
|
|
|
|
self.choose_direction()
|
|
|
|
self.choose_turn_delay(old_delay)
|
|
|
|
if self.step_delay <= 0:
|
|
|
|
self.step_delay = Box.STEP_DELAY
|
2023-08-16 13:51:55 -04:00
|
|
|
self.step = (self.step + 1) & 3
|
2023-08-16 09:45:20 -04:00
|
|
|
|
|
|
|
def choose_direction(self):
|
|
|
|
self.direction = self.random.direction()
|
|
|
|
|
|
|
|
def choose_turn_delay(self, subtract=0):
|
|
|
|
self.turn_delay = self.random.delay() - subtract
|
|
|
|
|
|
|
|
run_responder(Box())
|