/// <summary> /// Checks if <see cref="Yakus"/> and <see cref="YakusCombinations"/> have to be cancelled because of the temporary furiten rule. /// </summary> /// <param name="currentRound">The current round</param> /// <param name="playerIndex">The player index of the hand.</param> /// <returns><c>True</c> if temporary furiten; <c>False</c> otherwise.</returns> internal bool CancelYakusIfTemporaryFuriten(RoundPivot currentRound, int playerIndex) { if (currentRound == null) { return(false); } int i = 0; while (currentRound.PlayerIndexHistory.Count < i && currentRound.PlayerIndexHistory.ElementAt(i) == playerIndex.RelativePlayerIndex(-(i + 1)) && playerIndex.RelativePlayerIndex(-(i + 1)) != playerIndex) { // The tile discarded by the latest player is the tile we ron ! if (i > 0) { TilePivot lastFromDiscard = currentRound.GetDiscard(currentRound.PlayerIndexHistory.ElementAt(i)).LastOrDefault(); if (lastFromDiscard != null && IsCompleteFull(new List <TilePivot>(ConcealedTiles) { lastFromDiscard }, DeclaredCombinations.ToList())) { Yakus = null; YakusCombinations = null; return(true); } } i++; } return(false); }
/// <summary> /// Checks if any CPU player can make a pon call, and computes its decision if any. /// </summary> /// <returns>The player index who makes the call; <c>-1</c> is none.</returns> public int PonDecision() { int opponentPlayerId = _round.OpponentsCanCallPon(); if (opponentPlayerId > -1) { TilePivot tile = _round.GetDiscard(_round.PreviousPlayerIndex).Last(); // Call the pon if : // - the hand is already open // - it's valuable (see "HandCanBeOpened") var opponentHand = _round.GetHand(opponentPlayerId); if (!opponentHand.IsConcealed || HandCanBeOpened(opponentPlayerId, tile, opponentHand)) { return(opponentPlayerId); } opponentPlayerId = -1; } return(opponentPlayerId); }