public void PenchanFuTest() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "123456", pin: "55", sou: "12456"); var winTile = TileId.Parse(sou: "3"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(2, PENCHAN))); AreEqual(fu, 40); tiles = TileIds.Parse(man: "123456", pin: "55", sou: "34589"); winTile = TileId.Parse(sou: "7"); hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); (fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(2, PENCHAN))); AreEqual(fu, 40); }
public void Tsumo(HandConfig config) { var tsumo = wall_.Tsumo(); if (tsumo is null) { return; } Hand.Tsumo(tsumo); var result = HandCalculator.EstimateHandValue(Hand.AllTiles, Hand.TsumoTile, doraIndicators: DoraIndicators, config: config); if (result.Error is null) { IsAgari = true; Result = result; } else { IsAgari = false; Result = null; } }
public void ClosedHonorPonFuTest() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "123456", sou: "1178", honors: "111"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(8, CLOSED_TERMINAL_PON))); AreEqual(fu, 40); tiles = TileIds.Parse(man: "123456", sou: "11678", honors: "11"); winTile = TileId.Parse(honors: "1"); hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); (fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(4, OPEN_TERMINAL_PON))); AreEqual(fu, 40); }
public void SixtupleYakumanTest() { var tiles = TileIds.Parse(honors: "11122233344455"); var winTile = TileId.Parse(honors: "5"); var config = new HandConfig(isTenhou: true); var result = EstimateHandValue(tiles, winTile, config: config); AreEqual(null, result.Error); AreEqual(78, result.Han); AreEqual(192000, result.Cost.Main); }
public void CalculateScoresAndRonTest() { var config = new HandConfig( options: new OptionalRules(kazoeLimit: Kazoe.Nolimit)); var result = CalculateScores(han: 1, fu: 30, config: config); AreEqual(1000, result.Main); result = CalculateScores(han: 1, fu: 110, config: config); AreEqual(3600, result.Main); result = CalculateScores(han: 2, fu: 30, config: config); AreEqual(2000, result.Main); result = CalculateScores(han: 3, fu: 30, config: config); AreEqual(3900, result.Main); result = CalculateScores(han: 4, fu: 30, config: config); AreEqual(7700, result.Main); result = CalculateScores(han: 4, fu: 40, config: config); AreEqual(8000, result.Main); result = CalculateScores(han: 5, fu: 0, config: config); AreEqual(8000, result.Main); result = CalculateScores(han: 6, fu: 0, config: config); AreEqual(12000, result.Main); result = CalculateScores(han: 8, fu: 0, config: config); AreEqual(16000, result.Main); result = CalculateScores(han: 11, fu: 0, config: config); AreEqual(24000, result.Main); result = CalculateScores(han: 13, fu: 0, config: config); AreEqual(32000, result.Main); result = CalculateScores(han: 26, fu: 0, config: config); AreEqual(64000, result.Main); result = CalculateScores(han: 39, fu: 0, config: config); AreEqual(96000, result.Main); result = CalculateScores(han: 52, fu: 0, config: config); AreEqual(128000, result.Main); result = CalculateScores(han: 65, fu: 0, config: config); AreEqual(160000, result.Main); result = CalculateScores(han: 78, fu: 0, config: config); AreEqual(192000, result.Main); }
public void OpenHandWithoutAdditionalFuTest() { var tiles = TileIds.Parse(man: "234567", pin: "22", sou: "234678"); var winTile = TileId.Parse(sou: "6"); var melds = new List <Meld> { MakeMeld(MeldType.CHI, sou: "234") }; var config = new HandConfig(options: new OptionalRules(hasOpenTanyao: true, fuForOpenPinfu: false)); var result = EstimateHandValue(tiles, winTile, melds, config: config); AreEqual(1, result.Han); AreEqual(20, result.Fu); AreEqual(700, result.Cost.Main); }
public void TsumoHandBaseTest() { var config = new HandConfig(isTsumo: true); var tiles = TileIds.Parse(man: "123456", pin: "11", sou: "22278"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var(fuDetails, _) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); IsTrue(fuDetails.Contains(new FuDetail(20, BASE))); }
public void KokushimusouMultipleYakuman() { var tiles = TileIds.Parse(man: "19", pin: "19", sou: "19", honors: "12345677"); var winTile = TileId.Parse(honors: "1"); var handConfig = new HandConfig(isTsumo: true, isTenhou: true, isChiihou: false); var handCalculation = EstimateHandValue(tiles, winTile, config: handConfig); AreEqual(null, handCalculation.Error); AreEqual(2, handCalculation.Yaku.Count); IsTrue(handCalculation.Yaku.Any(x => x.GetType() == typeof(KokushiMusou))); IsFalse(handCalculation.Yaku.Any(x => x.GetType() == typeof(DaburuKokushiMusou))); IsTrue(handCalculation.Yaku.Any(x => x.GetType() == typeof(Tenhou))); IsFalse(handCalculation.Yaku.Any(x => x.GetType() == typeof(Chiihou))); AreEqual(26, handCalculation.Han); }
public void CalculateScoresAndRonByDealerTest() { var config = new HandConfig(playerWind: Constants.EAST, options: new OptionalRules(kazoeLimit: Kazoe.Nolimit)); var result = CalculateScores(han: 1, fu: 30, config: config); AreEqual(1500, result.Main); result = CalculateScores(han: 2, fu: 30, config: config); AreEqual(2900, result.Main); result = CalculateScores(han: 3, fu: 30, config: config); AreEqual(5800, result.Main); result = CalculateScores(han: 4, fu: 30, config: config); AreEqual(11600, result.Main); result = CalculateScores(han: 5, fu: 0, config: config); AreEqual(12000, result.Main); result = CalculateScores(han: 6, fu: 0, config: config); AreEqual(18000, result.Main); result = CalculateScores(han: 8, fu: 0, config: config); AreEqual(24000, result.Main); result = CalculateScores(han: 11, fu: 0, config: config); AreEqual(36000, result.Main); result = CalculateScores(han: 13, fu: 0, config: config); AreEqual(48000, result.Main); result = CalculateScores(han: 26, fu: 0, config: config); AreEqual(96000, result.Main); result = CalculateScores(han: 39, fu: 0, config: config); AreEqual(144000, result.Main); result = CalculateScores(han: 52, fu: 0, config: config); AreEqual(192000, result.Main); result = CalculateScores(han: 65, fu: 0, config: config); AreEqual(240000, result.Main); result = CalculateScores(han: 78, fu: 0, config: config); AreEqual(288000, result.Main); }
public void ChitoitsuFuTest() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "115599", pin: "6", sou: "112244"); var winTile = TileId.Parse(pin: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); AreEqual(1, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(25, BASE))); AreEqual(fu, 25); }
public void ClosedPonFuTest() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "123456", pin: "11", sou: "22278"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(4, CLOSED_PON))); AreEqual(fu, 40); }
public void PairWaitFu() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "123456", pin: "1", sou: "123678"); var winTile = TileId.Parse(pin: "1"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(2, PAIR_WAIT))); AreEqual(fu, 40); }
public void TsumoAndDisabledPinfuTest() { var config = new HandConfig(isTsumo: true, options: new OptionalRules(fuForPinfuTsumo: true)); var tiles = TileIds.Parse(man: "123456", pin: "123", sou: "2278"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(20, BASE))); IsTrue(fuDetails.Contains(new FuDetail(2, TSUMO))); AreEqual(fu, 30); }
public void KiriageManganTest() { var config = new HandConfig( options: new OptionalRules(kiriage: true)); var result = CalculateScores(han: 4, fu: 30, config: config); AreEqual(8000, result.Main); result = CalculateScores(han: 3, fu: 60, config: config); AreEqual(8000, result.Main); config = new HandConfig(playerWind: Constants.EAST, options: new OptionalRules(kiriage: true)); result = CalculateScores(han: 4, fu: 30, config: config); AreEqual(12000, result.Main); result = CalculateScores(han: 3, fu: 60, config: config); AreEqual(12000, result.Main); }
public void AkaDoraTest() { var tiles = TileIds.Parse(man: "12355599", pin: "456", sou: "345", hasAkaDora: false); var winTile = TileId.Parse(man: "9"); var handConfig = new HandConfig(isTsumo: true, options: new OptionalRules(hasAkaDora: true)); var handCalculation = EstimateHandValue(tiles, winTile, config: handConfig); AreEqual(null, handCalculation.Error); AreEqual(4, handCalculation.Han); tiles = TileIds.Parse(man: "12355599", pin: "456", sou: "345", hasAkaDora: true); handCalculation = EstimateHandValue(tiles, winTile, config: handConfig); AreEqual(null, handCalculation.Error); AreEqual(1, handCalculation.Han); tiles = TileIds.Parse(man: "12355599", pin: "456", sou: "34r", hasAkaDora: true); handCalculation = EstimateHandValue(tiles, winTile, config: handConfig); AreEqual(null, handCalculation.Error); AreEqual(2, handCalculation.Han); tiles = TileIds.Parse(man: "12355599", pin: "4r6", sou: "34r", hasAkaDora: true); handCalculation = EstimateHandValue(tiles, winTile, config: handConfig); AreEqual(null, handCalculation.Error); AreEqual(3, handCalculation.Han); tiles = TileIds.Parse(man: "123r5599", pin: "4r6", sou: "34r", hasAkaDora: true); handCalculation = EstimateHandValue(tiles, winTile, config: handConfig); AreEqual(null, handCalculation.Error); AreEqual(4, handCalculation.Han); tiles = TileIds.Parse(man: "123rr599", pin: "4r6", sou: "34r", hasAkaDora: true); handCalculation = EstimateHandValue(tiles, winTile, config: handConfig); AreEqual(null, handCalculation.Error); AreEqual(5, handCalculation.Han); tiles = TileIds.Parse(man: "123rrr99", pin: "4r6", sou: "34r", hasAkaDora: true); handCalculation = EstimateHandValue(tiles, winTile, config: handConfig); AreEqual(null, handCalculation.Error); AreEqual(6, handCalculation.Han); }
public void FuBasedOnWinGroup() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "234789", pin: "1234566"); var winTile = TileId.Parse(pin: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var winGroups = hand.Where(x => x.Contains(winTile.ToTileKind())).ToList(); var(fuDetails, fu) = CalculateFu(hand, winTile, winGroups[0], config); AreEqual(30, fu); (fuDetails, fu) = CalculateFu(hand, winTile, winGroups[1], config); AreEqual(40, fu); }
public void OpenHandWithoutAdditionalFu() { var config = new HandConfig(options: new OptionalRules(fuForOpenPinfu: false)); var tiles = TileIds.Parse(man: "234567", pin: "22", sou: "23478"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var melds = new List <Meld> { MakeMeld(MeldType.CHI, sou: "234") }; var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config, melds: melds); AreEqual(1, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(20, BASE))); AreEqual(fu, 20); }
public void ValuedPairFuTest() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "123456", sou: "12378", honors: "11"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var valuedTiles = new List <int> { EAST }; var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config, valuedTiles: valuedTiles); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(2, VALUED_PAIR))); AreEqual(fu, 40); valuedTiles = new List <int> { EAST, EAST }; (fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config, valuedTiles: valuedTiles); AreEqual(3, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(2, VALUED_PAIR))); IsTrue(fuDetails.Contains(new FuDetail(2, VALUED_PAIR))); AreEqual(fu, 40); }
public void OpenPonFuTest() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "123456", sou: "22278", pin: "11"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var melds = new List <Meld> { MakeMeld(MeldType.PON, sou: "222") }; var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config, melds: melds); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(20, BASE))); IsTrue(fuDetails.Contains(new FuDetail(2, OPEN_PON))); AreEqual(fu, 30); }
public void ClosedKanFuTest() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "123456", pin: "11", sou: "22278"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var melds = new List <Meld> { MakeMeld(MeldType.KAN, sou: "222", isOpen: false) }; var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config, melds: melds); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(30, BASE))); IsTrue(fuDetails.Contains(new FuDetail(16, CLOSED_KAN))); AreEqual(fu, 50); }
public void OpenTerminalKanFu() { var config = new HandConfig(); var tiles = TileIds.Parse(man: "123456", pin: "111", sou: "2278"); var winTile = TileId.Parse(sou: "6"); var hand = Hand(new TileIds(tiles.Append(winTile)).ToTiles34()); var melds = new List <Meld> { MakeMeld(MeldType.KAN, pin: "111", isOpen: true) }; var(fuDetails, fu) = CalculateFu(hand, winTile, GetWinGroup(hand, winTile), config, melds: melds); AreEqual(2, fuDetails.Count); IsTrue(fuDetails.Contains(new FuDetail(20, BASE))); IsTrue(fuDetails.Contains(new FuDetail(16, OPEN_TERMINAL_KAN))); AreEqual(fu, 40); }
public (TileIds, TileId, List <Meld>, HandResponseModel) Agari() { var config = new HandConfig(isTsumo: true); var tiles = Hand; var winTile = Hand.Last(); List <Meld> melds = null; var result = EstimateHandValue(Hand, Hand.Last(), config: config); var _res = new HandResponseModel { Cost = new CostModel { Main = result.Cost.Main, Additional = result.Cost.Additional }, Han = result.Han, Fu = result.Fu, Yaku = result.Yaku.Select(x => new YakuModel { YakuId = x.YakuId, TenhouId = x.TenhouId, Name = x.Name, Japanese = x.Japanese, English = x.English, HanOpen = x.HanOpen, HanClosed = x.HanClosed, IsYakuman = x.IsYakuman }).ToList(), Error = result.Error, FuDetailSet = result.FuDetailSet.Select(x => new FuDetailModel { Fu = x.Fu, Reason = x.Reason }).ToList() }; return(tiles, winTile, melds, _res); }
public void KazoeSettingsTest() { var tiles = TileIds.Parse(man: "22244466677788"); var winTile = TileId.Parse(man: "7"); var melds = new List <Meld> { MakeMeld(MeldType.KAN, man: "2222", isOpen: false) }; var doraIndicators = TileIds.Parse(man: "1111"); var config = new HandConfig(isRiichi: true, options: new OptionalRules(kazoeLimit: Kazoe.Limited)); var result = EstimateHandValue(tiles, winTile, melds, doraIndicators, config); AreEqual(28, result.Han); AreEqual(32000, result.Cost.Main); config = new HandConfig(isRiichi: true, options: new OptionalRules(kazoeLimit: Kazoe.Sanbaiman)); result = EstimateHandValue(tiles, winTile, melds, doraIndicators, config); AreEqual(28, result.Han); AreEqual(24000, result.Cost.Main); config = new HandConfig(isRiichi: true, options: new OptionalRules(kazoeLimit: Kazoe.Nolimit)); result = EstimateHandValue(tiles, winTile, melds, doraIndicators, config); AreEqual(28, result.Han); AreEqual(64000, result.Cost.Main); }
private static void Main(string[] args) { /***********************************************************************/ /* タンヤオ ロン */ /***********************************************************************/ var tiles = TileIds.Parse(man: "22444", pin: "333567", sou: "444"); var winTile = TileId.Parse(sou: "4"); var result = HandCalculator.EstimateHandValue(tiles, winTile); PrintHandResult(tiles, winTile, null, result); /***********************************************************************/ /* タンヤオ ツモ */ /***********************************************************************/ result = HandCalculator.EstimateHandValue(tiles, winTile, config: new HandConfig(isTsumo: true)); PrintHandResult(tiles, winTile, null, result); /***********************************************************************/ /* 副露追加 */ /***********************************************************************/ var melds = new List <Meld> { new Meld(MeldType.PON, tiles: TileIds.Parse(man: "444")) }; var config = new HandConfig(options: new OptionalRules(hasOpenTanyao: true)); result = HandCalculator.EstimateHandValue(tiles, winTile, melds, config: config); PrintHandResult(tiles, winTile, melds, result); /***********************************************************************/ /* シャンテン数計算 */ /***********************************************************************/ tiles = TileIds.Parse(man: "13569", pin: "123459", sou: "443"); var shanten = Shanten.CalculateShanten(tiles); Console.WriteLine(tiles.ToOneLineString()); Console.WriteLine($"{shanten}シャンテン"); Console.WriteLine(""); /***********************************************************************/ /* 数え役満 */ /***********************************************************************/ //13翻打ち止め tiles = TileIds.Parse(man: "22244466677788"); winTile = TileId.Parse(man: "7"); melds = new List <Meld> { new Meld(MeldType.KAN, TileIds.Parse(man: "2222"), opened: false) }; var doraIndicators = TileIds.Parse(man: "1111"); //ドラ表示牌 config = new HandConfig(isRiichi: true, options: new OptionalRules(kazoeLimit: Kazoe.Limited)); result = HandCalculator.EstimateHandValue(tiles, winTile, melds, doraIndicators, config); PrintHandResult(tiles, winTile, melds, result); //三倍満扱い config = new HandConfig(isRiichi: true, options: new OptionalRules(kazoeLimit: Kazoe.Sanbaiman)); result = HandCalculator.EstimateHandValue(tiles, winTile, melds, doraIndicators, config); PrintHandResult(tiles, winTile, melds, result); //13翻ごとに役満を重ねる(26翻でダブル役満) config = new HandConfig(isRiichi: true, options: new OptionalRules(kazoeLimit: Kazoe.Nolimit)); result = HandCalculator.EstimateHandValue(tiles, winTile, melds, doraIndicators, config); PrintHandResult(tiles, winTile, melds, result); }
public void CalcylateScoresAndTsumoByDealerTest() { var config = new HandConfig(playerWind: Constants.EAST, isTsumo: true, options: new OptionalRules(kazoeLimit: Kazoe.Nolimit)); var result = CalculateScores(han: 1, fu: 30, config: config); AreEqual(500, result.Main); AreEqual(500, result.Additional); result = CalculateScores(han: 3, fu: 30, config: config); AreEqual(2000, result.Main); AreEqual(2000, result.Additional); result = CalculateScores(han: 3, fu: 60, config: config); AreEqual(3900, result.Main); AreEqual(3900, result.Additional); result = CalculateScores(han: 4, fu: 30, config: config); AreEqual(3900, result.Main); AreEqual(3900, result.Additional); result = CalculateScores(han: 5, fu: 0, config: config); AreEqual(4000, result.Main); AreEqual(4000, result.Additional); result = CalculateScores(han: 6, fu: 0, config: config); AreEqual(6000, result.Main); AreEqual(6000, result.Additional); result = CalculateScores(han: 8, fu: 0, config: config); AreEqual(8000, result.Main); AreEqual(8000, result.Additional); result = CalculateScores(han: 11, fu: 0, config: config); AreEqual(12000, result.Main); AreEqual(12000, result.Additional); result = CalculateScores(han: 13, fu: 0, config: config); AreEqual(16000, result.Main); AreEqual(16000, result.Additional); result = CalculateScores(han: 26, fu: 0, config: config); AreEqual(32000, result.Main); AreEqual(32000, result.Additional); result = CalculateScores(han: 39, fu: 0, config: config); AreEqual(48000, result.Main); AreEqual(48000, result.Additional); result = CalculateScores(han: 52, fu: 0, config: config); AreEqual(64000, result.Main); AreEqual(64000, result.Additional); result = CalculateScores(han: 65, fu: 0, config: config); AreEqual(80000, result.Main); AreEqual(80000, result.Additional); result = CalculateScores(han: 78, fu: 0, config: config); AreEqual(96000, result.Main); AreEqual(96000, result.Additional); }
private async Task computeHandWithAgari(CommandContext ctx, string hand, string agari) { var basicHand = HandParser.GetSimpleHand(hand); var basicAgari = HandParser.GetSimpleHand(agari); var handEmoji = HandParser.GetHandEmojiCodes(hand, ctx.Client); string suitOrder = U.getSuitOrder(basicHand); var hand136 = C.one_line_string_to_136_array(basicHand); var agari136 = C.one_line_string_to_136_array(basicAgari)[0]; StringBuilder sb = new(); sb.AppendLine($"<@!{ctx.User.Id}>: {GetHandMessage(handEmoji)}\n"); var config = new HandConfig(); // TSUMO config.is_tsumo = true; var calculator = new HandCalculator(); var result = calculator.estimate_hand_value(hand136.ToList(), agari136, config: config); var handShape136 = C.from_34_indices_to_136_arrays(result.hand); var setsStr = handShape136.Select(set => C.to_one_line_string(set)); IEnumerable <string> orderedSetStr = new List <string>(); foreach (var chr in suitOrder) { orderedSetStr = orderedSetStr.Concat(setsStr.Where(x => x.Contains(chr))); } sb.AppendLine($"Tsumo:{string.Join(",", orderedSetStr.Select(x => $"{GetHandMessage(HandParser.GetHandEmojiCodes(x, ctx.Client))}"))}"); sb.AppendLine($"{result.han}han {result.fu}fu"); foreach (var yaku in result.yaku) { sb.AppendLine($"{yaku}"); } if (result.cost != null) { foreach (var yaku in result.cost.Keys) { sb.AppendLine($"{yaku}: {result.cost[yaku]}"); } foreach (var detail in result.fu_details) { sb.AppendLine($"{detail.Item2}: +{detail.Item1}fu"); } } //RON config.is_tsumo = false; calculator = new HandCalculator(); result = calculator.estimate_hand_value(hand136.ToList(), agari136, config: config); handShape136 = C.from_34_indices_to_136_arrays(result.hand); setsStr = handShape136.Select(set => C.to_one_line_string(set)); orderedSetStr = new List <string>(); foreach (var chr in suitOrder) { orderedSetStr = orderedSetStr.Concat(setsStr.Where(x => x.Contains(chr))); } sb.AppendLine(); sb.AppendLine($"Ron:{string.Join(",", orderedSetStr.Select(x => $"{GetHandMessage(HandParser.GetHandEmojiCodes(x, ctx.Client))}"))}"); sb.AppendLine($"{result.han}han {result.fu}fu"); foreach (var yaku in result.yaku) { sb.AppendLine($"{yaku}"); } if (result.cost != null) { foreach (var cost in result.cost.Keys) { sb.AppendLine($"{cost}: {result.cost[cost]}"); } } foreach (var detail in result.fu_details) { sb.AppendLine($"{detail.Item2}: +{detail.Item1}fu"); } var message = await ctx.Channel.SendMessageAsync(sb.ToString()); }