mirror of
https://github.com/osukey/osukey.git
synced 2025-05-19 20:47:24 +09:00
Softly-handle infinite loops in mania beatmap conversion
This commit is contained in:
parent
da01501a1c
commit
2019a89a08
@ -176,16 +176,23 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
|
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column
|
// Find available column
|
||||||
|
RunWhile(() => pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn), () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
});
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn, startTime, EndTime);
|
addToPattern(pattern, nextColumn, startTime, EndTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is can't be combined with the above loop due to RNG
|
// This is can't be combined with the above loop due to RNG
|
||||||
for (int i = 0; i < noteCount - usableColumns; i++)
|
for (int i = 0; i < noteCount - usableColumns; i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn))
|
RunWhile(() => pattern.ColumnHasObject(nextColumn), () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
});
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn, startTime, EndTime);
|
addToPattern(pattern, nextColumn, startTime, EndTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,16 +218,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
RunWhile(() => PreviousPattern.ColumnHasObject(nextColumn), () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastColumn = nextColumn;
|
int lastColumn = nextColumn;
|
||||||
for (int i = 0; i < noteCount; i++)
|
for (int i = 0; i < noteCount; i++)
|
||||||
{
|
{
|
||||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||||
while (nextColumn == lastColumn)
|
|
||||||
|
RunWhile(() => nextColumn == lastColumn, () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
});
|
||||||
|
|
||||||
lastColumn = nextColumn;
|
lastColumn = nextColumn;
|
||||||
startTime += SegmentDuration;
|
startTime += SegmentDuration;
|
||||||
@ -393,14 +405,18 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
RunWhile(() => PreviousPattern.ColumnHasObject(nextColumn), () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < columnRepeat; i++)
|
for (int i = 0; i < columnRepeat; i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn))
|
RunWhile(() => pattern.ColumnHasObject(nextColumn), () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
});
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn, startTime, EndTime);
|
addToPattern(pattern, nextColumn, startTime, EndTime);
|
||||||
startTime += SegmentDuration;
|
startTime += SegmentDuration;
|
||||||
@ -427,8 +443,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(holdColumn))
|
RunWhile(() => PreviousPattern.ColumnHasObject(holdColumn), () =>
|
||||||
|
{
|
||||||
holdColumn = Random.Next(RandomStart, TotalColumns);
|
holdColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the hold note
|
// Create the hold note
|
||||||
@ -455,8 +473,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
for (int j = 0; j < noteCount; j++)
|
for (int j = 0; j < noteCount; j++)
|
||||||
{
|
{
|
||||||
while (rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn)
|
RunWhile(() => rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn, () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
});
|
||||||
|
|
||||||
addToPattern(rowPattern, nextColumn, startTime, startTime);
|
addToPattern(rowPattern, nextColumn, startTime, startTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
int nextColumn = Random.Next(start, TotalColumns);
|
int nextColumn = Random.Next(start, TotalColumns);
|
||||||
|
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
RunWhile(() => PreviousPattern.ColumnHasObject(nextColumn), () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(start, TotalColumns);
|
nextColumn = Random.Next(start, TotalColumns);
|
||||||
|
});
|
||||||
|
|
||||||
return nextColumn;
|
return nextColumn;
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
for (int i = 0; i < noteCount; i++)
|
for (int i = 0; i < noteCount; i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn) && !allowStacking)
|
RunWhile(() => pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn) && !allowStacking, () =>
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.Gathered))
|
if (convertType.HasFlag(PatternType.Gathered))
|
||||||
{
|
{
|
||||||
@ -244,7 +244,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
});
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn);
|
addToPattern(pattern, nextColumn);
|
||||||
}
|
}
|
||||||
@ -295,8 +295,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int nextColumn = Random.Next(RandomStart, columnLimit);
|
int nextColumn = Random.Next(RandomStart, columnLimit);
|
||||||
for (int i = 0; i < noteCount; i++)
|
for (int i = 0; i < noteCount; i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn))
|
RunWhile(() => pattern.ColumnHasObject(nextColumn), () =>
|
||||||
|
{
|
||||||
nextColumn = Random.Next(RandomStart, columnLimit);
|
nextColumn = Random.Next(RandomStart, columnLimit);
|
||||||
|
});
|
||||||
|
|
||||||
// Add normal note
|
// Add normal note
|
||||||
addToPattern(pattern, nextColumn);
|
addToPattern(pattern, nextColumn);
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||||
@ -12,6 +15,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal abstract class PatternGenerator
|
internal abstract class PatternGenerator
|
||||||
{
|
{
|
||||||
|
private const int max_rng_iterations = 100;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The last pattern.
|
/// The last pattern.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -42,6 +47,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
|||||||
TotalColumns = Beatmap.TotalColumns;
|
TotalColumns = Beatmap.TotalColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void RunWhile([InstantHandle] Func<bool> condition, Action action)
|
||||||
|
{
|
||||||
|
int iterations = 0;
|
||||||
|
|
||||||
|
while (condition() && iterations++ < max_rng_iterations)
|
||||||
|
action();
|
||||||
|
|
||||||
|
if (iterations < max_rng_iterations)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Generate + log an error/stacktrace
|
||||||
|
|
||||||
|
Logger.Log($"Allowable time exceeded for hitobject generation:\n{new StackTrace(0)}", level: LogLevel.Error);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates the patterns for <see cref="HitObject"/>, each filled with hit objects.
|
/// Generates the patterns for <see cref="HitObject"/>, each filled with hit objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user