using Milimoe.FunGame.Core.Model;
using Milimoe.FunGame.Testing.Solutions;
using Oshima.FunGame.WebAPI.Controllers;
namespace Milimoe.FunGame.Testing.Tests
{
///
/// 肉鸽客户端原型测试
///
public class RogueLikeTest
{
public RogueLike RogueLike { get; set; }
public RogueLikeServer RogueLikeServer { get; set; }
public RogueLikeTest(FunGameController controller)
{
RogueLikeDispatcher dispatcher = new(controller);
RogueLike = new(dispatcher);
RogueLikeServer = new(dispatcher);
dispatcher.RogueLikeInstance = RogueLike;
dispatcher.RogueLikeServer = RogueLikeServer;
RogueLike.ReadInputStringHandler += RogueLike_ReadInputStringHandler;
RogueLike.ReadInputNumberHandler += RogueLike_ReadInputNumberHandler;
RogueLike.ReadInputInquiryResponseHandler += RogueLike_ReadInputInGameResponseHandler;
}
///
/// 此方法完全自主处理options并输入
///
///
///
private async Task RogueLike_ReadInputInGameResponseHandler(InquiryOptions options)
{
InquiryResponse response = new(options);
switch (options.InquiryType)
{
case Core.Library.Constant.InquiryType.Choice:
case Core.Library.Constant.InquiryType.BinaryChoice:
{
int index = 0;
Dictionary indexToChoice = [];
foreach (string choice in options.Choices.Keys)
{
index++;
indexToChoice[index] = choice;
string description = options.Choices[choice];
RogueLike.WriteLine($"{index}. {choice}{(description.Trim() != "" ? $":{description}" : "")}");
}
RogueLike.WriteLine($"--- {options.Topic} ---");
bool resolve = false;
while (!resolve)
{
RogueLike.WriteLine($"选择一个选项(输入序号,输入 !c 表示取消):");
string result = (await Console.In.ReadLineAsync())?.Trim() ?? "";
if (result == "!c")
{
response.Cancel = true;
resolve = true;
}
else if (int.TryParse(result, out int inputIndex) && indexToChoice.TryGetValue(inputIndex, out string? value))
{
response.Choices = [value];
resolve = true;
}
}
break;
}
case Core.Library.Constant.InquiryType.MultipleChoice:
{
int index = 0;
Dictionary indexToChoice = [];
foreach (string choice in options.Choices.Keys)
{
index++;
indexToChoice[index] = choice;
RogueLike.WriteLine($"{index}. {choice}:{options.Choices[choice]}");
}
RogueLike.WriteLine($"--- {options.Topic} ---");
bool resolve = false;
while (!resolve)
{
RogueLike.WriteLine($"选择多个选项(输入序号,空格分隔,包含 !c 时表示取消):");
string result = (await Console.In.ReadLineAsync())?.Trim() ?? "";
if (result.Contains("!c"))
{
response.Cancel = true;
break;
}
string[] strings = result.Split(' ', StringSplitOptions.RemoveEmptyEntries);
foreach (string str in strings)
{
if (int.TryParse(str, out int inputIndex) && indexToChoice.TryGetValue(inputIndex, out string? value))
{
response.Choices.Add(value);
}
}
if (response.Choices.Count > 0)
{
resolve = true;
}
}
break;
}
case Core.Library.Constant.InquiryType.TextInput:
{
RogueLike.WriteLine($"--- {options.Topic} ---");
bool resolve = false;
while (!resolve)
{
RogueLike.WriteLine("输入回应(输入 !c 表示取消):");
string result = (await Console.In.ReadLineAsync())?.Trim() ?? "";
if (result == "!c")
{
response.Cancel = true;
resolve = true;
}
else if (result != "")
{
response.TextResult = result;
resolve = true;
}
}
break;
}
case Core.Library.Constant.InquiryType.NumberInput:
{
RogueLike.WriteLine($"--- {options.Topic} ---");
bool resolve = false;
while (!resolve)
{
RogueLike.WriteLine("输入结果(输入 !c 表示取消):");
string result = await Console.In.ReadLineAsync() ?? "";
if (result.Trim() == "!c")
{
response.Cancel = true;
resolve = true;
}
else if (double.TryParse(result, out double doubleResult))
{
response.NumberResult = doubleResult;
resolve = true;
}
}
break;
}
case Core.Library.Constant.InquiryType.Custom:
break;
default:
break;
}
return response;
}
private async Task RogueLike_ReadInputStringHandler(Dictionary args, List results)
{
string input = await Console.In.ReadLineAsync() ?? "";
if (input.Trim().Equals("!c", StringComparison.CurrentCultureIgnoreCase))
{
args["cancel"] = true;
}
results.Add(input.Trim());
}
private async Task RogueLike_ReadInputNumberHandler(Dictionary args, List results)
{
string input = await Console.In.ReadLineAsync() ?? "";
if (input.Trim().Equals("!c", StringComparison.CurrentCultureIgnoreCase))
{
args["cancel"] = true;
}
if (double.TryParse(input.Trim(), out double result))
{
results.Add(result);
}
}
}
///
/// 仅本地测试原型用,实际使用时需替换为网络层
///
public class RogueLikeDispatcher(FunGameController controller)
{
public FunGameController Controller { get; set; } = controller;
public RogueLike? RogueLikeInstance { get; set; } = null;
public RogueLikeServer? RogueLikeServer { get; set; } = null;
public bool Running => RogueLikeInstance?.Running ?? false;
public void WriteLine(string str)
{
if (RogueLikeInstance is null) return;
RogueLikeInstance.WriteLine(str);
}
public void AddDialog(string speaker, string message)
{
if (RogueLikeInstance is null) return;
RogueLikeInstance.AddDialog(speaker, message);
}
public async Task> GetChoiceResultsAsync(InquiryOptions options, Dictionary args)
{
if (RogueLikeInstance is null) return [];
return await RogueLikeInstance.GetChoiceResultsAsync(options, args);
}
public async Task> GetNumberResultsAsync(Dictionary args)
{
if (RogueLikeInstance is null) return [];
return await RogueLikeInstance.GetNumberResultsAsync(args);
}
public async Task GetTextResultsAsync(Dictionary args)
{
if (RogueLikeInstance is null) return "";
return await RogueLikeInstance.GetTextResultsAsync(args);
}
public async Task GetInquiryResponse(InquiryOptions options)
{
if (RogueLikeInstance is null) return new(options);
return await RogueLikeInstance.GetInquiryResponse(options);
}
public async Task DataRequestComplete(Guid guid, DataRequestArgs response)
{
if (RogueLikeInstance is null) return;
await RogueLikeInstance.DataRequestComplete(guid, response);
}
public async Task DataRequest(Guid guid, DataRequestArgs args)
{
if (RogueLikeServer is null) return;
RogueLikeServer.ReceiveDataRequest(guid, args);
await Task.CompletedTask;
}
public void StartServer()
{
RogueLikeServer?.Guard ??= Task.Run(RogueLikeServer.DataRequestGuard);
}
public async Task CreateGameLoop(string username)
{
if (RogueLikeServer is null) return;
await RogueLikeServer.CreateGameLoop(username);
}
}
public class DataRequestArgs(string type)
{
public string RequestType { get; } = type;
public bool Success { get; set; } = true;
public Dictionary Data { get; set; } = [];
}
}