Fix Playability
ci / checks (push) Failing after 23m26s

This commit is contained in:
khodowany
2026-10-08 19:04:06 -05:00
parent bc7baea7c4
commit 3f63b255ac
23 changed files with 633 additions and 374 deletions
+52
View File
@@ -0,0 +1,52 @@
"""Four-fret hand windows shared by chord and single-note placement.
This describes playable regions, not an anatomical fingering solver. Chord
and single tones may occupy any frets within the window. Only shifting the
window is movement. Actual sounded-note limits remain in fretboard.py.
"""
import functools
import typing
import generator.fretboard
VERSION = 'hand-window-2'
class Motion(typing.NamedTuple):
shift: int = 0
fingers: int = 0
strings: int = 0
@property
def ergonomics(self):
return self.fingers + self.strings
def base(shape):
return min((p.fret for p in shape), default=0)
@functools.lru_cache(maxsize=4096)
def regions(shape):
if not shape:
return tuple([0])
return tuple(range(max(1, max(p.fret for p in shape) - 3), min(base(shape), generator.fretboard.MAX_ANCHOR_FRET) + 1))
@functools.lru_cache(maxsize=32768)
def motion(previous, current, old_hand, hand, acoustic=False):
if not previous or not current:
return Motion()
if len(previous) == len(current) == 1:
pairs = ((previous[0], current[0]),)
unmatched = 0
else:
def voices(shape):
return {('bass' if acoustic and p.string_number in (5, 6) else p.string_number): p for p in shape}
a, b = voices(previous), voices(current)
pairs = tuple((a[s], b[s]) for s in a.keys() & b.keys())
unmatched = len(a.keys() ^ b.keys())
return Motion(abs(hand - old_hand),
unmatched + sum(abs((a.fret - old_hand) - (b.fret - hand)) for a, b in pairs),
sum(abs(a.string_number - b.string_number) for a, b in pairs))
def summary(shifts):
shifts = tuple(shifts)
return {'total_travel': sum(shifts), 'shift_count': sum(s > 0 for s in shifts), 'largest_shift': max(shifts, default=0)}