private static PaymentInformation CalculateTenpaiPayment(Board board) { var scoreChanges = new int[4]; var tenhouTenpai = board.Seats.Select(s => TenhouShanten.IsTenpai(s.Hand, s.ConcealedTiles, s.Melds.Count)).ToList(); var tenpaiCount = tenhouTenpai.Count(s => s); if (tenpaiCount == 4) { return(new PaymentInformation(0, 0, scoreChanges, Yaku.None)); } for (var i = 0; i < 4; i++) { if (tenhouTenpai[i]) { scoreChanges[i] = 3000 / tenpaiCount; } else { scoreChanges[i] = -3000 / (4 - tenpaiCount); } } return(new PaymentInformation(0, 0, scoreChanges, Yaku.None)); }
protected static bool CanRiichi(Board board) { var seat = board.ActiveSeat; if (seat.DeclaredRiichi || board.Wall.RemainingDraws < 4 || seat.Melds.Any(m => m.MeldType != MeldType.ClosedKan)) { return(false); } return(TenhouShanten.IsTenpai(seat.Hand, seat.ConcealedTiles, seat.Melds.Count)); }
public override void Update(Board board, Wall wall) { if (board.Seats.Any(s => s.Score < 0)) { _nextState = new Owari(); return; } var oorasu = board.RoundWind == TileType.Nan && board.Seats[3].IsOya; if ((oorasu || board.RoundWind == TileType.Shaa) && board.Seats.Any(s => s.Score >= 30000)) { _nextState = new Owari(); return; } var oyaWin = _winningSeatIndexes.Any(i => board.Seats[i].IsOya); var oyaTenpai = TenhouShanten.IsTenpai(board.Oya.Hand, board.Oya.ConcealedTiles, board.Oya.Melds.Count); var oyaHighestScore = board.Oya.Score > board.Seats.Where(s => !s.IsOya).Max(s => s.Score); if (oyaWin || oyaTenpai) { if (oorasu && oyaHighestScore && board.Oya.Score >= 30000) { _nextState = new Owari(); return; } board.Honba += 1; _nextState = new InitGame(); return; } if (!_winningSeatIndexes.Any()) { RotateWinds(board); } else { board.Honba = 0; RotateWinds(board); } if (board.RoundWind == TileType.Pei) { _nextState = new Owari(); return; } _nextState = new InitGame(); }