/// <summary> /// 打出卡牌 /// 從手牌中打出 1張卡牌,正面朝上置於桌面場內。 /// 從牌堆抽取最上方一張牌,正面朝外,置於手牌上。 /// 打出的卡牌必須符合下列原則: /// 牌上數字須為桌面場內同色牌未出現,且須接續在已出現同色牌數字後。 /// 若打出的卡牌不符合以上原則,即算施放失敗。 /// 取 1個紅色錯誤指示物,施放失敗的花火卡則正面朝上置於棄牌區 /// 若玩家完成一組顏色花火卡牌施放(即數字1~5依照順序排列的「同花順」) /// 得到 1個藍色傳達指示物做為獎勵。 /// 若已無藍色傳達指示物,則無此獎勵行動。 /// </summary> /// <param name="cardIndex">打出的牌</param> /// <param name="player">出牌玩家</param> /// <param name="board">遊戲資訊</param> /// <param name="drawedCard">出牌後的補牌</param> /// <returns>出牌的結果</returns> public PlayCardResult PlayCard(CardIndexType cardIndex, IHanabiPlayer player, GameBoard board, out Card drawedCard) { Card playedCard = player.GetCard(cardIndex); if (playedCard == null) { drawedCard = null; return(PlayCardResult.InvalidCardIndex); } player.PlayCard(cardIndex); drawedCard = board.Draw(); if (drawedCard != null) { player.DrawCard(drawedCard); } if (board.Play(playedCard)) { if (playedCard.Value == CardValueType.Value5) { board.Reward(); } return(PlayCardResult.Success); } else { board.Punish(); board.Discard(playedCard); return(PlayCardResult.FailNoSlot); } }
/// <summary> /// 丟棄手牌 /// 從手牌中丟棄一張牌,正面朝上置於棄牌區。 /// 從牌堆抽取最上方一張牌,正面朝外,置於手牌上。 /// 得到 1個藍色傳達指示物,若已無已消耗藍色傳達指示物,則不可執行此行動。 /// </summary> /// <param name="cardIndex">丟棄的牌</param> /// <param name="player">丟牌玩家</param> /// <param name="board">遊戲資訊</param> /// <param name="drawedCard">出牌後的補牌</param> /// <returns>棄牌結果</returns> public DiscardCardResult DiscardCard(CardIndexType cardIndex, IHanabiPlayer player, GameBoard board, out Card drawedCard) { Card discardedCard = player.GetCard(cardIndex); if (discardedCard == null) { drawedCard = null; return(DiscardCardResult.InvalidCardIndex); } player.DiscardCard(cardIndex); drawedCard = board.Draw(); if (drawedCard != null) { player.DrawCard(drawedCard); } board.Discard(discardedCard); board.Reward(); return(DiscardCardResult.Success); }
public void Discard(IHanabiPlayer player, RequestDiscardCard card) { if (!IsCurrentPlayer(player)) { ResponseDiscardCard invalidResponse = new ResponseDiscardCard(); invalidResponse.Result = DiscardCardResult.InvalidTurn; SendCommandToPlayer(player, ActionType.DiscardCard, invalidResponse); return; } CardIndexType cardIndex = new CardIndexType(card.CardIndex); Card oldCard = player.GetCard(cardIndex); Card newCard = null; DiscardCardResult result = Rule.DiscardCard(cardIndex, player, Board, out newCard); if (result != DiscardCardResult.Success) { ResponseDiscardCard invalidResponse = new ResponseDiscardCard(); invalidResponse.Result = result; SendCommandToPlayer(player, ActionType.DiscardCard, invalidResponse); return; } ResponseDiscardCard response = new ResponseDiscardCard(); response.Result = result; response.Nickname = player.Nickname.Value; response.OldCard = oldCard.Info; response.NewCard = (newCard != null) ? newCard.Info : null; response.Token = Board.Tokens.Info; response.DrawPileCount = Board.Size; CardInfo info = (newCard != null) ? newCard.Info : null; if (info != null) { info.Color = ( int )CardColorType.Unknown; info.Value = ( int )CardValueType.Unknown; } ResponseDiscardCard notify = new ResponseDiscardCard(); notify.Result = result; notify.Nickname = player.Nickname.Value; notify.OldCard = oldCard.Info; notify.NewCard = info; notify.Token = Board.Tokens.Info; notify.DrawPileCount = Board.Size; foreach (var notifyPlayer in Players) { if (notifyPlayer == player) { SendCommandToPlayer(notifyPlayer, ActionType.DiscardCard, notify); } else { SendCommandToPlayer(notifyPlayer, ActionType.DiscardCard, response); } } CheckLastRound(); NextActivePlayer(); NotifyNextPlayer(); }