def ends_at(self, end: BeatsTime) -> LongNote: if end < self.time: raise ValueError( "Invalid end time. A long note starting at " f"{self.time} cannot end at {end} (which is earlier)") return LongNote( time=self.time, position=self.position, duration=end - self.time, tail_tip=self.tail_tip, )
def test_circle_free() -> None: chart = """ #holdbyarrow=1 #circlefree=1 □□□□ □□□□ □□□□ >□□① -- □□□□ □□□□ □□□□ □□□13 -- """ expected = [ LongNote(BeatsTime(0), NotePosition(3, 3), BeatsTime(7), NotePosition(0, 3)) ] compare_chart_notes(chart, expected)
def long_note( draw: DrawFunc, time_strat: st.SearchStrategy[BeatsTime] = beat_time(max_section=10), duration_strat: st.SearchStrategy[BeatsTime] = beat_time(min_numerator=1, max_section=3), ) -> LongNote: time = draw(time_strat) position = draw(note_position()) duration = draw(duration_strat) tail_is_vertical = draw(st.booleans()) tail_offset = draw(st.integers(min_value=1, max_value=3)) if tail_is_vertical: x = position.x y = (position.y + tail_offset) % 4 else: x = (position.x + tail_offset) % 4 y = position.y tail_tip = NotePosition(x, y) return LongNote(time, position, duration, tail_tip)
def notes( draw: DrawFunc, collisions: bool = False, note_strat: st.SearchStrategy[Union[TapNote, LongNote]] = st.one_of( tap_note(), long_note()), beat_time_strat: st.SearchStrategy[BeatsTime] = beat_time(max_section=3), ) -> Set[Union[TapNote, LongNote]]: raw_notes: Set[Union[TapNote, LongNote]] = draw(st.sets(note_strat, max_size=32)) if collisions: return raw_notes else: last_notes: Dict[NotePosition, Optional[BeatsTime]] = { NotePosition(x, y): None for y, x in product(range(4), range(4)) } notes: Set[Union[TapNote, LongNote]] = set() for note in sorted(raw_notes, key=lambda n: (n.time, n.position)): last_note_time = last_notes[note.position] if last_note_time is None: new_time = draw(beat_time_strat) else: numerator = draw( st.integers(min_value=1, max_value=last_note_time.denominator * 4)) distance = BeatsTime(numerator, last_note_time.denominator) new_time = last_note_time + distance if isinstance(note, LongNote): notes.add( LongNote( time=new_time, position=note.position, duration=note.duration, tail_tip=note.tail_tip, )) last_notes[note.position] = new_time + note.duration else: notes.add(TapNote(time=new_time, position=note.position)) last_notes[note.position] = new_time return notes
def test_long_notes_simple_solution_no_warning() -> None: chart = """ #holdbyarrow=1 □□□□ >①①< □□□□ □□□□ -- □□□□ □①①□ □□□□ □□□□ -- """ expected = [ LongNote(BeatsTime(0), NotePosition(x, y), BeatsTime(4), NotePosition(tx, ty)) for (x, y), (tx, ty) in [ ((1, 1), (0, 1)), ((2, 1), (3, 1)), ] ] compare_chart_notes(chart, expected)
def test_long_notes_complex_case() -> None: chart = """ #holdbyarrow=1 □□□□ □□∨□ □∨□□ >①①① -- □□□□ □□□□ □□□□ □①①① -- """ expected = [ LongNote(BeatsTime(0), NotePosition(x, y), BeatsTime(4), NotePosition(tx, ty)) for (x, y), (tx, ty) in [ ((1, 3), (1, 2)), ((2, 3), (2, 1)), ((3, 3), (0, 3)), ] ] compare_chart_notes(chart, expected)
def test_long_notes_ambiguous_case() -> None: chart = """ #holdbyarrow=1 ①①<< □□□□ □□□□ □□□□ -- ①①□□ □□□□ □□□□ □□□□ -- """ expected = [ LongNote(BeatsTime(0), NotePosition(x, y), BeatsTime(4), NotePosition(tx, ty)) for (x, y), (tx, ty) in [ ((0, 0), (2, 0)), ((1, 0), (3, 0)), ] ] with pytest.warns(UserWarning): compare_chart_notes(chart, expected)
def test_long_notes() -> None: chart = """ #holdbyarrow=1 ①□□< □□□□ □□□□ □□□□ -- ①□□□ □□□□ □□□□ □□□□ -- """ expected = [ LongNote( time=BeatsTime(0), position=NotePosition(0, 0), duration=BeatsTime(4), tail_tip=NotePosition(3, 0), ) ] compare_chart_notes(chart, expected)
from fractions import Fraction from jubeatools.song import LongNote, NotePosition, TapNote notes = { TapNote(time=Fraction(0, 1), position=NotePosition(x=0, y=0)), TapNote(time=Fraction(0, 1), position=NotePosition(x=0, y=1)), TapNote(time=Fraction(0, 1), position=NotePosition(x=0, y=3)), LongNote( time=Fraction(0, 1), position=NotePosition(x=1, y=0), duration=Fraction(1, 16), tail_tip=NotePosition(x=2, y=0), ), TapNote(time=Fraction(0, 1), position=NotePosition(x=1, y=1)), LongNote( time=Fraction(0, 1), position=NotePosition(x=1, y=2), duration=Fraction(1, 3), tail_tip=NotePosition(x=2, y=2), ), LongNote( time=Fraction(1, 8), position=NotePosition(x=0, y=3), duration=Fraction(1, 4), tail_tip=NotePosition(x=2, y=3), ), TapNote(time=Fraction(1, 4), position=NotePosition(x=0, y=0)), TapNote(time=Fraction(5, 16), position=NotePosition(x=1, y=0)), LongNote( time=Fraction(1, 2),