FunGame-Testing/Library/Tests/RogueLikeTest.cs
2026-04-08 00:50:26 +08:00

258 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Milimoe.FunGame.Core.Model;
using Milimoe.FunGame.Testing.Solutions;
using Oshima.FunGame.WebAPI.Controllers;
namespace Milimoe.FunGame.Testing.Tests
{
/// <summary>
/// 肉鸽客户端原型测试
/// </summary>
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;
}
/// <summary>
/// 此方法完全自主处理options并输入
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
private async Task<InquiryResponse> 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<int, string> 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 == "!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<int, string> 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<string, object> args, List<string> 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<string, object> args, List<double> 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);
}
}
}
/// <summary>
/// 仅本地测试原型用,实际使用时需替换为网络层
/// </summary>
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<List<string>> GetChoiceResultsAsync(InquiryOptions options, Dictionary<string, object> args)
{
if (RogueLikeInstance is null) return [];
return await RogueLikeInstance.GetChoiceResultsAsync(options, args);
}
public async Task<List<double>> GetNumberResultsAsync(Dictionary<string, object> args)
{
if (RogueLikeInstance is null) return [];
return await RogueLikeInstance.GetNumberResultsAsync(args);
}
public async Task<string> GetTextResultsAsync(Dictionary<string, object> args)
{
if (RogueLikeInstance is null) return "";
return await RogueLikeInstance.GetTextResultsAsync(args);
}
public async Task<InquiryResponse> 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<string, object> Data { get; set; } = [];
}
}