71 lines
2.2 KiB
C#
71 lines
2.2 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
|
||
namespace DDD
|
||
{
|
||
internal static class SpawnScheduleUtils
|
||
{
|
||
public static string NextRoundRobin(IReadOnlyList<string> source, ref int index)
|
||
{
|
||
if (source == null || source.Count == 0) return null;
|
||
|
||
if (index >= source.Count)
|
||
{
|
||
index = 0;
|
||
}
|
||
|
||
return source[index++];
|
||
}
|
||
|
||
/// <summary>
|
||
/// 비율 분배 시퀀스(N/S)를 생성합니다. 스페셜 우선이 아니라 '노말 우선'입니다.
|
||
/// accumulator += specialQuota; if (accumulator > total) => S, else N.
|
||
/// </summary>
|
||
public static List<CustomerType> BuildProportionalKinds(int normalQuota, int specialQuota)
|
||
{
|
||
int normal = Math.Max(0, normalQuota);
|
||
int special = Math.Max(0, specialQuota);
|
||
int total = normal + special;
|
||
|
||
var kinds = new List<CustomerType>(total);
|
||
if (total == 0) return kinds;
|
||
|
||
int accumulator = 0;
|
||
for (int i = 0; i < total; i++)
|
||
{
|
||
accumulator += special;
|
||
if (accumulator >= total) // 스페셜 개수 보장
|
||
{
|
||
kinds.Add(CustomerType.Special);
|
||
accumulator -= total;
|
||
}
|
||
else
|
||
{
|
||
kinds.Add(CustomerType.Normal);
|
||
}
|
||
}
|
||
return kinds;
|
||
}
|
||
|
||
public static void PickUniqueIndices(int total, int pickCount, Random randomGenerator, HashSet<int> output)
|
||
{
|
||
output.Clear();
|
||
pickCount = Math.Min(Math.Max(0, pickCount), total);
|
||
if (pickCount == 0 || total == 0) return;
|
||
|
||
// 0..total-1을 부분 Fisher–Yates
|
||
var indices = new int[total];
|
||
for (int i = 0; i < total; i++)
|
||
{
|
||
indices[i] = i;
|
||
}
|
||
|
||
for (int i = 0; i < pickCount; i++)
|
||
{
|
||
int j = randomGenerator.Next(i, total);
|
||
(indices[i], indices[j]) = (indices[j], indices[i]);
|
||
output.Add(indices[i]);
|
||
}
|
||
}
|
||
}
|
||
} |