protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { int[] counts = { -3, -1, -1, -1, -1, -1, -1, -1, -3 }; for (int i = 0; i < tiles.Count; i++) { counts[(tiles[i].BaseTile as NumberTile).Number - 1]++; } int val = 0; for (int i = 0; i < 9; i++) { val |= counts[i]; } if (val != 1) { return(false); } int extraNumber = Array.IndexOf(counts, 1) + 1; var extraTile = tiles.Added.BaseTile as NumberTile; if (extraTile.Number == extraNumber) { result.Add(YakuValue.FromFullYaku(this, "纯正九莲宝灯", 1)); } else { result.Add(YakuValue.FromFullYaku(this, "九莲宝灯", 1)); } return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if ((env & YakuEnvironment.门前清) == 0) { return(false); } int[,] counts = new int[3, 7]; foreach (var g in groups.JunkoList) { counts[g.Key.SortedLevel, (g.Key as NumberTile).Number - 1]++; } int count = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 7; j++) { if (counts[i, j] % 2 == 0) { count += counts[i, j]; if (count == 4) { result.Add(YakuValue.FromFanValue(this, "二杯口", 3)); return(true); } } } } return(false); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { int[,] counts = new int[3, 7]; foreach (var g in groups.JunkoList) { counts[g.Key.SortedLevel, (g.Key as NumberTile).Number - 1]++; } bool yes = false; for (int i = 0; i < 3; i++) { for (int j = 0; j < 7; j++) { if (counts[i, j] >= 2 && counts[i, j] < 4) { yes = !yes; // 防止二杯口 } } } if (!yes) { return(false); } result.Add(YakuValue.FromFanValue(this, "一杯口", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if (groups.PungList.Any(g => !(g is Gan))) { return(false); } result.Add(YakuValue.FromFullYaku(this, "四杠子", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if (groups.Any(g => !g.Key.IsTerminal)) { return(false); } result.Add(YakuValue.FromFullYaku(this, "清老头", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if (groups.Any(g => !g.IsTerminal)) { return(false); } result.Add(YakuValue.FromFanValue(this, "混全带幺九", (env & YakuEnvironment.门前清) != 0 ? 2 : 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if ((env & YakuEnvironment.抢杠) == 0) { return(false); } result.Add(YakuValue.FromFanValue(this, "抢杠", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if (tiles.Any(t => !t.BaseTile.IsTerminal)) { return(false); } result.Add(YakuValue.FromFanValue(this, "混老头", 2)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if (!TestRon(tiles, env)) { return(false); } result.Add(YakuValue.FromFanValue(this, "七对子", 2)); return(true); }
protected override bool Test(ICollection<YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if (!TestRon(tiles, env)) return false; if (tiles.HandTiles.Take(13).Any(t => t.BaseTile == tiles.Added.BaseTile)) { result.Add(YakuValue.FromFullYaku(this, "国士无双十三面", 1)); } else { result.Add(YakuValue.FromFullYaku(this, "国士无双", 1)); } return true; }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { const KanjiTile.Kanji check = KanjiTile.Kanji.东 | KanjiTile.Kanji.南 | KanjiTile.Kanji.西 | KanjiTile.Kanji.北; if (groups.PungList.Any(g => !(g.Key is KanjiTile t) || (t.Value & check) == 0)) { return(false); } result.Add(YakuValue.FromFullYaku(this, "大四喜", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { const YakuEnvironment cmp = YakuEnvironment.自摸 | YakuEnvironment.海底; if ((env & cmp) != cmp) { return(false); } result.Add(YakuValue.FromFanValue(this, "海底摸月", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { int count = groups.PungList.Count(g => g is Gan); if (count < 3) { return(false); } result.Add(YakuValue.FromFanValue(this, "三杠子", 2)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { int dora = tiles.Count(t => t.IsRedDora); if (dora == 0) { return(false); } result.Add(YakuValue.FromFanValue(this, "赤宝牌", 0, dora)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { const KanjiTile.Kanji check = KanjiTile.Kanji.白 | KanjiTile.Kanji.发 | KanjiTile.Kanji.中; int count = groups.PungList.Count(g => g.Key is KanjiTile t && (t.Value & check) != 0); if (count < 3) { return(false); } result.Add(YakuValue.FromFullYaku(this, "大三元", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { KanjiTile.Kanji GetKanjis(YakuEnvironment e) { int slefWind = ((int)e >> 6) & 0xf; int fieldWind = ((int)e >> 10) & 0xf; return((KanjiTile.Kanji)(slefWind | fieldWind)); } if ((env & YakuEnvironment.门前清) == 0) { return(false); } if (groups.Pair.Type == GroupType.和牌) { return(false); } foreach (var g in groups.JunkoList) { if (g.Type == GroupType.副露) { return(false); } if (g.Type == GroupType.和牌) { var numTile = g.Key as NumberTile; switch (g.AddedIndex) { case 0 when numTile.Number == 7: //边张 case 1: //嵌张 case 2 when numTile.Number == 1: //边张 return(false); } } } if (groups.Pair.Key is KanjiTile t) { var excludeKanji = KanjiTile.Kanji.白 | KanjiTile.Kanji.发 | KanjiTile.Kanji.中 | GetKanjis(env); if ((t.Value & excludeKanji) != 0) { return(false); } } result.Add(YakuValue.FromFanValue(this, "平和", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { long flags = 0; for (int i = 0; i < tiles.Count; i++) { flags |= (1L << tiles[i].BaseTile.SortedIndex); } if ((flags | CheckFlags) != CheckFlags) { return(false); } result.Add(YakuValue.FromFullYaku(this, "绿一色", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { const KanjiTile.Kanji check = KanjiTile.Kanji.东 | KanjiTile.Kanji.南 | KanjiTile.Kanji.西 | KanjiTile.Kanji.北; int count = groups.PungList.Count(g => g.Key is KanjiTile t && (t.Value & check) != 0); if (count != 3) { return(false); } if (!(groups.Pair.Key is KanjiTile t2) || (t2.Value & check) == 0) { return(false); } result.Add(YakuValue.FromFullYaku(this, "小四喜", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { bool[,] flags = new bool[3, 7]; foreach (var g in groups.JunkoList) { flags[g.Key.SortedLevel, (g.Key as NumberTile).Number - 1] = true; } for (int i = 0; i < 3; i++) { if (flags[i, 0] && flags[i, 3] && flags[i, 6]) { result.Add(YakuValue.FromFanValue(this, "一气通贯", (env & YakuEnvironment.门前清) != 0 ? 2 : 1)); return(true); } } return(false); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { const KanjiTile.Kanji cmp = KanjiTile.Kanji.白 | KanjiTile.Kanji.发 | KanjiTile.Kanji.中; if (!(groups.Pair.Key is KanjiTile t) || (t.Value & cmp) == 0) { return(false); } int count = groups.PungList.Count(g => g.Key is KanjiTile t2 && (t2.Value & cmp) != 0); if (count < 2) { return(false); } result.Add(YakuValue.FromFanValue(this, "小三元", 2)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if (!TestRon(tiles, env)) { return(true); } if (tiles.Count(t => t.BaseTile == tiles.Added.BaseTile) == 2) { result.Add(YakuValue.FromFullYaku(this, "国士无双十三面", 1)); } else { result.Add(YakuValue.FromFullYaku(this, "国士无双", 1)); } return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { int[] counts = new int[9]; foreach (var g in groups.PungList) { if (g.Key is NumberTile t) { counts[t.Number]++; } } for (int i = 0; i < 9; i++) { if (counts[i] == 3) { result.Add(YakuValue.FromFanValue(this, "三色同刻", 2)); return(true); } } return(false); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { Kanji Get自风(YakuEnvironment e) => (Kanji)(((int)e >> 6) & 0xf); Kanji Get场风(YakuEnvironment e) => (Kanji)(((int)e >> 10) & 0xf); Kanji selfWind = Get自风(env), fieldWind = Get场风(env); var cmp = selfWind | fieldWind | Kanji.白 | Kanji.发 | Kanji.中; bool yes = false; foreach (var g in groups.PungList) { if (g.Key is KanjiTile t) { if ((t.Value & cmp) != 0) { yes = true; if (t.Value == selfWind) { result.Add(YakuValue.FromFanValue(this, "自风" + selfWind, 1)); } if (t.Value == fieldWind) { result.Add(YakuValue.FromFanValue(this, "场风" + fieldWind, 1)); } else if (t.Value == Kanji.白) { result.Add(YakuValue.FromFanValue(this, "役牌白", 1)); } else if (t.Value == Kanji.发) { result.Add(YakuValue.FromFanValue(this, "役牌发", 1)); } else { result.Add(YakuValue.FromFanValue(this, "役牌中", 1)); } } } } return(yes); }
public void SetYakuItem(YakuValue yaku, bool 青天井 = false) { Debug.Assert(YakuName != null, nameof(YakuName) + " != null"); YakuName.text = yaku.Name; if (yaku.Type == YakuType.Normal || 青天井) { // use normal display Normal.gameObject.SetActive(true); YakuMan.gameObject.SetActive(false); int value = yaku.Type == YakuType.Normal ? yaku.Value : yaku.Value * MahjongConstants.YakumanBaseFan; Debug.Log($"{yaku.Name}: {value}"); FanController.SetNumber(value); } else { Debug.Log($"{yaku.Name}: YakuMan"); // use yaku man display Normal.gameObject.SetActive(false); YakuMan.gameObject.SetActive(true); } }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { int count = 0; foreach (var g in groups.PungList) { if (g.Type == GroupType.副露) { continue; } if (g.Type == GroupType.和牌 && !SelfWindEquals(g.AddedWind, env)) { continue; } count++; } if (count < 3) { return(false); } result.Add(YakuValue.FromFanValue(this, "三暗刻", 2)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { if ((env & YakuEnvironment.第一巡) == 0) { return(false); } if ((env & YakuEnvironment.自摸) != 0) { if ((env & YakuEnvironment.自风东) != 0) { result.Add(YakuValue.FromFullYaku(this, "天和", 1)); } else { result.Add(YakuValue.FromFullYaku(this, "地和", 1)); } } else { result.Add(YakuValue.FromFullYaku(this, "人和", 1)); } return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { foreach (var g in groups.PungList) { if (g.Type == GroupType.副露) { return(false); } if (g.Type == GroupType.和牌 && !SelfWindEquals(g.AddedWind, env)) { return(false); } } if (groups.Pair.Type == GroupType.和牌) { result.Add(YakuValue.FromFullYaku(this, "四暗刻单骑", 1)); } else { result.Add(YakuValue.FromFullYaku(this, "四暗刻", 1)); } return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { result.Add(YakuValue.FromFullYaku(this, "字一色", 1)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { // 当役满发生时,该役会被移除 result.Add(YakuValue.FromFanValue(this, "对对和", 2)); return(true); }
protected override bool Test(ICollection <YakuValue> result, ITiles tiles, IGroups groups, YakuEnvironment env) { result.Add(YakuValue.FromFanValue(this, "清一色", (env & YakuEnvironment.门前清) != 0 ? 6 : 5)); return(true); }