1
0
mirror of synced 2024-12-12 15:01:09 +01:00

[#mono-column] #circlefree mode accepts non-16ths notes and falls back to normal symbols when needed

This commit is contained in:
Stepland 2021-05-04 11:27:03 +02:00
parent 9e0c4f5c2b
commit 857dd899a7
5 changed files with 25 additions and 52 deletions

View File

@ -1,4 +1,6 @@
# Unreleased
## Added
- [#mono-column] #circlefree mode accepts non-16ths notes and falls back to normal symbols when needed
## Fixed
- [jubeat-analyser]
- Raise exception earlier when a mono-column file is detected by the other #memo parsers (based on "--" separator lines)

View File

@ -31,6 +31,7 @@ from ..dump_tools import (
DEFAULT_EXTRA_SYMBOLS,
DIRECTION_TO_ARROW,
DIRECTION_TO_LINE,
NOTE_TO_CIRCLE_FREE_SYMBOL,
JubeatAnalyserDumpedSection,
LongNoteEnd,
SortedDefaultDict,
@ -38,7 +39,6 @@ from ..dump_tools import (
fraction_to_decimal,
jubeat_analyser_file_dumper,
)
from ..symbols import CIRCLE_FREE_SYMBOLS, NOTE_SYMBOLS
class MonoColumnDumpedSection(JubeatAnalyserDumpedSection):
@ -62,19 +62,18 @@ class MonoColumnDumpedSection(JubeatAnalyserDumpedSection):
frames: List[Dict[NotePosition, str]] = []
frame: Dict[NotePosition, str] = {}
for note in self.notes:
time_in_section = note.time - self.current_beat
symbol = self.symbols[time_in_section]
if isinstance(note, LongNote):
needed_positions = set(note.positions_covered())
if needed_positions & frame.keys():
frames.append(frame)
frame = {}
direction = note.tail_direction()
arrow = DIRECTION_TO_ARROW[direction]
line = DIRECTION_TO_LINE[direction]
for is_first, is_last, pos in mark_ends(note.positions_covered()):
if is_first:
time_in_section = note.time - self.current_beat
symbol = self.symbols[time_in_section]
frame[pos] = symbol
elif is_last:
frame[pos] = arrow
@ -84,18 +83,13 @@ class MonoColumnDumpedSection(JubeatAnalyserDumpedSection):
if note.position in frame:
frames.append(frame)
frame = {}
time_in_section = note.time - self.current_beat
symbol = self.symbols[time_in_section]
frame[note.position] = symbol
elif isinstance(note, LongNoteEnd):
if note.position in frame:
frames.append(frame)
frame = {}
time_in_section = note.time - self.current_beat
if circle_free:
symbol = CIRCLE_FREE_SYMBOLS[int(time_in_section)]
else:
symbol = self.symbols[time_in_section]
if circle_free and symbol in NOTE_TO_CIRCLE_FREE_SYMBOL:
symbol = NOTE_TO_CIRCLE_FREE_SYMBOL[symbol]
frame[note.position] = symbol
frames.append(frame)
@ -108,9 +102,7 @@ class MonoColumnDumpedSection(JubeatAnalyserDumpedSection):
yield "".join(frame.get(NotePosition(x, y), "") for x in range(4))
def _raise_if_unfit_for_mono_column(
chart: Chart, timing: Timing, circle_free: bool = False
) -> None:
def _raise_if_unfit_for_mono_column(chart: Chart, timing: Timing) -> None:
if len(timing.events) < 1:
raise ValueError("No BPM found in file") from None
@ -128,16 +120,6 @@ def _raise_if_unfit_for_mono_column(
" mono_column format is not supported by jubeatools"
)
if circle_free and any(
(note.time + note.duration) % BeatsTime(1, 4) != 0
for note in chart.notes
if isinstance(note, LongNote)
):
raise ValueError(
"Chart contains long notes whose ending timing aren't"
" representable in #circlefree mode"
)
def _section_factory(b: BeatsTime) -> MonoColumnDumpedSection:
return MonoColumnDumpedSection(current_beat=b)
@ -151,7 +133,7 @@ def _dump_mono_column_chart(
circle_free: bool = False,
) -> StringIO:
_raise_if_unfit_for_mono_column(chart, timing, circle_free)
_raise_if_unfit_for_mono_column(chart, timing)
sections = create_sections_from_chart(
_section_factory, chart, difficulty, timing, metadata, circle_free

View File

@ -188,24 +188,16 @@ class MonoColumnParser(JubeatAnalyserParser):
unfinished_longs: Dict[NotePosition, UnfinishedLongNote] = {}
for section_starting_beat, section, bloc in self._iter_blocs():
should_skip: Set[NotePosition] = set()
# 1/3 : look for ends to unfinished long notes
for pos, unfinished_long in unfinished_longs.items():
x, y = astuple(pos)
symbol = bloc[y][x]
if self.circle_free:
if symbol in CIRCLE_FREE_SYMBOLS:
if self.circle_free and symbol in CIRCLE_FREE_SYMBOLS:
should_skip.add(pos)
symbol_time = CIRCLE_FREE_TO_BEATS_TIME[symbol]
note_time = section_starting_beat + symbol_time
yield unfinished_long.ends_at(note_time)
elif symbol in section.symbols:
raise SyntaxError(
"Can't have a note symbol on the holding square of"
" an unfinished long note when #circlefree is on"
)
else:
if symbol in section.symbols:
should_skip.add(pos)
symbol_time = section.symbols[symbol]
note_time = section_starting_beat + symbol_time

View File

@ -2,9 +2,8 @@ from typing import Iterable, Union
import pytest
from jubeatools.song import BeatsTime, LongNote, NotePosition, TapNote
from jubeatools.formats.jubeat_analyser.mono_column.load import MonoColumnParser
from jubeatools.song import BeatsTime, LongNote, NotePosition, TapNote
def compare_chart_notes(

View File

@ -5,6 +5,9 @@ from typing import List, Set, Union
import hypothesis.strategies as st
from hypothesis import given
from jubeatools.formats import Format
from jubeatools.formats.jubeat_analyser.mono_column.dump import _dump_mono_column_chart
from jubeatools.formats.jubeat_analyser.mono_column.load import MonoColumnParser
from jubeatools.song import (
BeatsTime,
BPMEvent,
@ -12,19 +15,14 @@ from jubeatools.song import (
LongNote,
Metadata,
SecondsTime,
Song,
TapNote,
Timing,
Song
)
from jubeatools.testutils.strategies import NoteOption, long_note
from jubeatools.testutils.strategies import notes as notes_strat
from jubeatools.testutils.strategies import tap_note
from jubeatools.formats import Format
from jubeatools.formats.jubeat_analyser.mono_column.dump import _dump_mono_column_chart
from jubeatools.formats.jubeat_analyser.mono_column.load import MonoColumnParser
from ..test_utils import load_and_dump_then_check, memo_compatible_song