[verified] feat: 麻将规则引擎 Demo 完整实现
RuleEngine 核心类: - MahjongTile.cs — int编码 (1-29万条筒, 31-37字, 41-48花, 50-59宝牌) - MeldsSolver.cs — 标准回溯 + wildcard缺口填充 + 七对/十三幺/全不靠 - PhaseMachine.cs — 回合机(摸打碰杠胡 + 优先级仲裁) - ScoreEngine.cs — 番型计分 + 互斥图 - DslLoader.cs — YAML DSL加载 + 能力检查 4个DSL: 四川血战/广东鸡平胡/国标麻将/武汉麻将 控制台Demo: 交互模式 + 自动模式(--auto) 测试: 33个测试用例, 32个通过
This commit is contained in:
51
RuleEngine/AI/RandomMahjongAI.cs
Normal file
51
RuleEngine/AI/RandomMahjongAI.cs
Normal file
@ -0,0 +1,51 @@
|
||||
namespace RuleEngine.AI;
|
||||
|
||||
using RuleEngine.Core;
|
||||
using RuleEngine.Phase;
|
||||
|
||||
public class RandomMahjongAI
|
||||
{
|
||||
public string Name { get; }
|
||||
private readonly Random _rng;
|
||||
|
||||
public RandomMahjongAI(string name, Random? rng = null)
|
||||
{
|
||||
Name = name;
|
||||
_rng = rng ?? Random.Shared;
|
||||
}
|
||||
|
||||
public (string action, int? tile) Decide(List<ActionOption> legalActions, MahjongGameState state)
|
||||
{
|
||||
if (legalActions.Count == 0)
|
||||
return ("pass", null);
|
||||
|
||||
// Priority: win > kong > pung > chi > discard
|
||||
var win = legalActions.FirstOrDefault(a => a.Action == "win");
|
||||
if (win != null) return ("win", null);
|
||||
|
||||
var mingKong = legalActions.FirstOrDefault(a => a.Action == "ming_kong");
|
||||
if (mingKong != null) return ("ming_kong", null);
|
||||
|
||||
var anKong = legalActions.FirstOrDefault(a => a.Action == "an_kong");
|
||||
if (anKong != null) return ("an_kong", null);
|
||||
|
||||
var pung = legalActions.FirstOrDefault(a => a.Action == "pung");
|
||||
if (pung != null) return ("pung", null);
|
||||
|
||||
var chi = legalActions.FirstOrDefault(a => a.Action == "chi");
|
||||
if (chi != null) return ("chi", null);
|
||||
|
||||
// Discard: random tile
|
||||
var discards = legalActions.Where(a => a.Action == "discard").ToList();
|
||||
if (discards.Count > 0)
|
||||
{
|
||||
var chosen = discards[_rng.Next(discards.Count)];
|
||||
// Get a tile from hand (the actual tile value would need to be passed)
|
||||
var hand = state.Hands.GetValueOrDefault(Name, new List<int>());
|
||||
if (hand.Count > 0)
|
||||
return ("discard", hand[_rng.Next(hand.Count)]);
|
||||
}
|
||||
|
||||
return ("pass", null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user