public object onChi(int actor, int target, Pai pai, List<Pai> consumed) { foreach (var component in components) component.onChi(actor, target, pai, consumed); return onNaki(actor, target, pai, consumed); }
public Furo(FuroType type, int actor, int target, Pai pai, List<Pai> consumed) { this.type = type; this.actor = actor; this.target = target; this.pai = pai; this.consumed = consumed; }
public void onChi(int actor, int target, Pai pai, List<Pai> consumed) { SoundEffects.Chi(pan(actor - majong.Id + 4) % 4); lock (mutex) { foreach (var component in components) { component.onChi(actor, target, pai, consumed); } } }
public object onDahai(int actor, Pai pai, bool tsumogiri) { foreach (var component in components) component.onDahai(actor, pai, tsumogiri); if (actor == id) { tehai.Remove(pai); return Protocol.none(); } else { List<SelectionType> alternatives = new List<SelectionType>(); if ((actor + 1) % 4 == id && Algorithm.canChi(tehai, pai)) alternatives.Add(SelectionType.Chi); if (Algorithm.canPon(tehai, pai)) { Console.WriteLine(string.Join(", ", tehai.Select(p => p.ToString()).ToArray())); alternatives.Add(SelectionType.Pon); } if (Algorithm.canKan(tehai, pai)) alternatives.Add(SelectionType.Kan); if (Algorithm.canRon(tehai, pai)) alternatives.Add(SelectionType.Ron); if (!alternatives.Any()) { return Protocol.none(); } else { alternatives.Add(SelectionType.Pass); return window.Select2(alternatives).match<object>( (pai1, pai2) => Protocol.chi(id, actor, pai, new List<Pai> { pai1, pai2 }) , (pai1, pai2) => Protocol.pon(id, actor, pai, new List<Pai> { pai1, pai2 }) , () => Protocol.kan(id, actor, pai, tehai.FindAll(p => p.RemoveRed() == pai.RemoveRed())) , () => Protocol.hora(id, actor, pai) , () => Protocol.none() ); } } }
public static Pai3D Get(Pai pai) { int x = pai.ToInt34(); if (count[x] >= cache[x].Count) { Pai3D p = new Pai3D(pai); count[x]++; cache[x].Add(p); return p; } else { return cache[x][count[x]++]; } }
public object onStartKyoku(Pai bakaze, int kyoku, int honba, int kyotaku, int oya, Pai doraMarker, List<List<Pai>> tehais) { foreach (var component in components) component.onStartKyoku(bakaze, kyoku, honba, kyotaku, oya, doraMarker, tehais); return Protocol.none(); }
public static bool canRon(IEnumerable<Pai> tehai, Pai pai) { List<Pai> tmp = tehai.ToList(); tmp.Add(pai); return shanten(tmp) == -1; }
public static bool canChi(IEnumerable<Pai> tehai, Pai pai) { if (pai.Suit == Suit.Jihai) return false; tehai = tehai.Select(p => p.RemoveRed()); pai = pai.RemoveRed(); if (pai.Num >= 3 && tehai.Contains(pai - 2) && tehai.Contains(pai - 1)) return true; if (pai.Num >= 2 && pai.Num <= 8 && tehai.Contains(pai - 1) && tehai.Contains(pai + 1)) return true; if (pai.Num <= 7 && tehai.Contains(pai + 1) && tehai.Contains(pai + 2)) return true; return false; }
public void onStartKyoku(Pai bakaze, int kyoku, int honba, int kyotaku, int oya, Pai doraMarker, List<List<Pai>> tehais) { lock (mutex) { foreach (var component in components) { component.onStartKyoku(bakaze, kyoku, honba, kyotaku, oya, doraMarker, tehais); } } }
static object naki(string type, int actor, int target, Pai pai, List<Pai> consumed) { consumed.Sort(); return new { type = type, actor = actor, target = target, pai = pai.ToString(), consumed = consumed.Select(p => p.ToString()).ToList() }; }
public static object dahai(int actor, Pai pai, bool tsumogiri) { return new { type = "dahai", actor = actor, pai = pai.ToString(), tsumogiri = tsumogiri }; }
public MajongComponent() { Id = 0; Tehais = new List<Pai>[4]; Kawas = new List<Sutehai>[4]; Furos = new List<Furo>[4]; for (int i = 0; i < 4; i++) { Tehais[i] = new List<Pai>(); Kawas[i] = new List<Sutehai>(); Furos[i] = new List<Furo>(); } Scores = new List<int>(Enumerable.Repeat(25000, 4)); Reaches = new List<int>(Enumerable.Repeat(-1, 4)); Names = new List<string>(Enumerable.Repeat("", 4)); Bakaze = Pais.Ton; Kyoku = 0; Honba = 0; Oya = 0; DoraMarker = Pais.Man1; }
object onNaki(int actor, int target, Pai pai, List<Pai> consumed) { if (actor != id) { return Protocol.none(); } else { object res; while (true) { res = window.Select1(new List<SelectionType>()).match<object>( (pai2, tsumogiri) => Protocol.dahai(id, pai2, false) // TODO: 喰い替えチェック , (pai2) => { Debug.Assert(false); return null; }, (pai2) => { Debug.Assert(false); return null; }, () => { Debug.Assert(false); return null; }, () => { Debug.Assert(false); return null; } ); if (res != null) break; } return res; } }
public object onTsumo(int actor, Pai pai) { foreach (var component in components) component.onTsumo(actor, pai); if (actor != id) { return Protocol.none(); } else if (reach) { return Protocol.dahai(id, pai, true); } else { List<SelectionType> alternatives = new List<SelectionType>(); if (menzen && Algorithm.shanten(tehai) <= 0) { alternatives.Add(SelectionType.Reach); } if (Algorithm.shanten(tehai) == -1) { alternatives.Add(SelectionType.Tsumo); } if (Algorithm.canKan(tehai)) { alternatives.Add(SelectionType.Kan); } return window.Select1(alternatives).match<object>( (dahai, tsumogiri) => { if (!tehai.Contains(dahai)) // 消極的対処 return Protocol.dahai(id, pai, true); else return Protocol.dahai(id, dahai, tsumogiri); }, (kanPai) => { throw new NotImplementedException("XnaGuiAI: Ankan is not yet implemented."); }, (kanPai) => { throw new NotImplementedException("XnaGuiAI: Kakan is not yet implemented."); }, () => { if (score >= 1000) return Protocol.reach(id); else return Protocol.dahai(id, pai, true); }, () => Protocol.hora(id, id, pai) ); } }
public Pai3D(Pai pai) { this.x = pai.ToInt34(); }
public static object hora(int actor, int target, Pai pai) { return new { type = "hora", actor = actor, target = target, pai = pai.ToString() }; }
public void onStartKyoku(Pai bakaze, int kyoku, int honba, int kyotaku, int oya, Pai doraMarker, List<List<Pai>> tehais) { Bakaze = bakaze; Kyoku = kyoku; Honba = honba; Kyotaku = kyotaku; Oya = oya; DoraMarker = doraMarker; Reaches = new List<int>(Enumerable.Repeat(-1, 4)); for (int i = 0; i < 4; i++) { Tehais[i] = tehais[i].ToList(); Furos[i] = new List<Furo>(); Kawas[i] = new List<Sutehai>(); } }
public static object chi(int actor, int target, Pai pai, List<Pai> consumed) { return naki("chi", actor, target, pai, consumed); }
public void onTsumo(int actor, Pai pai) { Console.WriteLine("onTsumo: actor = {0}, pai = {1}", actor.ToString(), pai.ToString()); Console.WriteLine(Tehais[Id].Count); Tehais[actor].Add(pai); Console.WriteLine(Tehais[Id].Count); }
public void onHora(int actor, int target, Pai pai, List<Pai> horaTehais, List<YakuN> yakus, int fu, int fan, int horaPoints, List<int> deltas, List<int> scores) { if (actor == target) { SoundEffects.Tsumo(pan(actor - majong.Id + 4) % 4); } else { SoundEffects.Ron(pan(actor - majong.Id + 4) % 4); } lock (mutex) { foreach (var component in components) { component.onHora(actor, target, pai, horaTehais, yakus, fu, fan, horaPoints, deltas, scores); } } }
public void onDahai(int actor, Pai pai, bool tsumogiri) { Kawas[actor].Add(new Sutehai(pai, tsumogiri)); if (actor == Id) { Tehais[Id].Remove(pai); Tehais[Id].Sort(); } else Tehais[actor].Remove(Pais.Unknown); }
public void onTsumo(int actor, Pai pai) { lock (mutex) { foreach (var component in components) { component.onTsumo(actor, pai); } } }
public void onKan(int actor, int target, Pai pai, List<Pai> consumed) { Kawas[target].Pop(); foreach (Pai c in consumed) { if (actor == Id) Tehais[Id].Remove(c); else Tehais[actor].Remove(Pais.Unknown); } Furos[actor].Add(new Furo(FuroType.Pon, actor, target, pai, consumed)); }
public void onDahai(int actor, Pai pai, bool tsumogiri) { SoundEffects.Dahai(pan(actor - majong.Id + 4) % 4); lock (mutex) { foreach (var component in components) { component.onDahai(actor, pai, tsumogiri); } } }
public void onHora(int actor, int target, Pai pai, List<Pai> horaTehais, List<YakuN> yakus, int fu, int fan, int horaPoints, List<int> deltas, List<int> scores) { Scores = scores; }
public static bool canKan(IEnumerable<Pai> tehai, Pai pai) { tehai = tehai.Select(p => p.RemoveRed()); pai = pai.RemoveRed(); return tehai.Count(p => p == pai) >= 3; }
public Sutehai(Pai pai, bool tsumogiri) { this.pai = pai; this.tsumogiri = tsumogiri; }
public static IEnumerable<List<Pai>> allChiCandidates(IEnumerable<Pai> tehai, Pai pai) { List<List<Pai>> ans = new List<List<Pai>>(); foreach (var p1 in tehai) { foreach (var p2 in tehai) { List<Pai> tmp = new List<Pai>() { pai, p1, p2 }; tmp.Sort(); if (tmp[0].Num <= 7 && tmp[1].Num <= 8 && tmp[0] + 1 == tmp[1] && tmp[1] + 1 == tmp[2]) { ans.Add((p1 < p2) ? new List<Pai>() { p1, p2 } : new List<Pai>() { p2, p1 }); } } } return ans.Distinct(); }
public object onHora(int actor, int target, Pai pai, List<Pai> horaTehais, List<YakuN> yakus, int fu, int fan, int horaPoints, List<int> deltas, List<int> scores) { foreach (var component in components) component.onHora(actor, target, pai, horaTehais, yakus, fu, fan, horaPoints, deltas, scores); return Protocol.none(); }