ICard DecideWhatCardToPlayOutOfYourTurn(SinglePlayerResponseArgs e) { ICard cardTriggering = e.CardTriggering; List <ICard> miniCardList = e.MiniCardList; ICard cardFirst = e.CardFirst; List <Func> funcsCanCounter; List <Func> funcsCanAnnul; ICard cardResponded = null; if (CardJudge.CardCanBeCounteredByAnyPlayer(null, cardFirst, cardTriggering, out funcsCanCounter) != MiniRoundTimingOption.None) { cardResponded = PlayACard(this.FindASpecificCard(funcsCanCounter), PlayerToKill, false); } if (cardResponded != null) { return(cardResponded); } if (CardJudge.CardCanBeAnnulled(null, cardFirst, cardTriggering, out funcsCanAnnul) != MiniRoundTimingOption.None) { cardResponded = PlayACard(this.FindASpecificCard(funcsCanAnnul), PlayerToKill, true); } if (cardResponded != null) { return(cardResponded); } return(null); // Make no response }
void StartACardLifeCycle(IPlayer playerPlaying, IPlayer playerReceiving) { if (playerPlaying.CardPlayed != null) { Util.PrintPlayerAction(playerPlaying, playerPlaying.CardNeedResponse, PlayerAction.Play); } ICard cardTriggering; ICard cardFirst; cardFirst = cardTriggering = playerPlaying.CardNeedResponse; if (!CardJudge.CardHasImmediateEffect(cardFirst)) { // The card played has no immediate effect CardJudge.CardGetDeployed(playerReceiving, cardFirst); Util.PrintPlayerAction(playerReceiving, cardFirst, PlayerAction.Deployed); return; } List <Func> funcsCanCounter; List <Func> funcsCanAnnul; bool cardFirstAnnulled = false; MiniRoundTimingOption timingCountering = CardJudge.CardCanBeCounteredByAnyPlayer(playerPlaying, cardFirst, cardTriggering, out funcsCanCounter); MiniRoundTimingOption timingAnnulling = CardJudge.CardCanBeAnnulled(playerPlaying, cardFirst, cardTriggering, out funcsCanAnnul); // TODO This last option varies from card to card if (timingCountering != MiniRoundTimingOption.None || timingAnnulling != MiniRoundTimingOption.None) { cardFirstAnnulled = EnterCardCounteringArena(playerPlaying, playerReceiving, cardTriggering, cardFirst, timingCountering, timingAnnulling); } if (cardFirstAnnulled) { Util.PrintPlayerAction(playerReceiving, cardFirst, PlayerAction.Annulled); return; } // The card requires drawing more cards from the central card deck List <ICard> cardsExtraDrawn = null; if (CardJudge.CardNeedExtraCard(cardFirst)) { cardsExtraDrawn = CentralCardDeck.DrawCards(CardJudge.CardNeedNumOfExtraCards(cardFirst, cardFirst)); Util.PrintPlayerAction(playerReceiving, cardFirst, cardsExtraDrawn, PlayerAction.Drawn); } CardJudge.CardTakeEffect(playerPlaying, playerReceiving, cardFirst, cardsExtraDrawn); Util.PrintPlayerAction(playerReceiving, null, PlayerAction.TakeDamage); }
ICard DecideWhatCardToPlayOutOfYourTurn(SinglePlayerResponseArgs e) { ICard cardTriggering = e.CardTriggering; List <ICard> miniCardList = e.MiniCardList; ICard cardFirst = e.CardFirst; List <Func> funcsCanCounter; List <Func> funcsCanAnnul; ICard cardResponded = null; //if (CardJudge.CardCanBeAnnulledByEquippable(null, cardFirst, cardTriggering, out funcsCanAnnul) != MiniRoundTimingOption.None) // cardResponded = PlayACard(this.FindASpecificCard(funcsCanAnnul), PlayerToKill, true); // TODO Make the function parameters correct if (CardJudge.CanBePossiblyAnnulledByEquippable(cardFirst.PlayerPlaying, cardFirst, out funcsCanAnnul) != MiniRoundTimingOption.None) { cardResponded = PlayACard(this.FindASpecificCardInEquippable(funcsCanAnnul), PlayerToKill, true, true); } if (cardResponded != null) { return(cardResponded); } // TODO Add the logic about whether I want to intervene if (CardJudge.CardCanBeCounteredByAnyPlayer(null, cardFirst, cardTriggering, out funcsCanCounter) != MiniRoundTimingOption.None) { cardResponded = PlayACard(this.FindASpecificCard(funcsCanCounter), PlayerToKill, false, false); } if (cardResponded != null) { return(cardResponded); } if (CardJudge.CardCanBeAnnulled(null, cardFirst, cardTriggering, out funcsCanAnnul) != MiniRoundTimingOption.None) { cardResponded = PlayACard(this.FindASpecificCard(funcsCanAnnul), PlayerToKill, true, false); } if (cardResponded != null) { return(cardResponded); } return(null); // Make no response }
void JudgeIndividualJade(ICard cardJade, IPlayer playerPlaying, IPlayer playerReceiving) { // TODO Do we need to do this everywhere for jade, prison and bomb? Seriously? ICard cardUsedToJudge = CentralCardDeck.DrawACard(); Util.PrintPlayerAction(playerReceiving, cardUsedToJudge, PlayerAction.Judge); if (CardJudge.CardJudgingResult(cardJade, cardUsedToJudge)) { CardJudge.CardTakeEffect(playerPlaying, playerReceiving, cardJade, null); Util.PrintPlayerAction(playerReceiving, cardJade, PlayerAction.JadeTakeEffect); } else { CardJudge.CardNotTakeEffect(null, playerPlaying, playerReceiving, cardJade); Util.PrintPlayerAction(playerReceiving, cardJade, PlayerAction.JadeNotTakeEffect); } }
void DecideCardsCanBePlayedInYourTurn() { CardsCanBePlayedInThisRound.Clear(); // Cannot play any card if the player is in prison if (InPrison) { return; } foreach (ICard card in CardsHeld) { if (CardJudge.CanPlayerPlayCard(this, this.PlayerToKill, card)) { CardsCanBePlayedInThisRound.Add(card); } } }
void JudgeIndividualBomb(List <IPlayer> playerList, IPlayer playerCarrying) { ICard cardBombCarrying = playerCarrying.CardCarrying.Find(c => c.CardCarryingType == CarriedType.Bomb); if (cardBombCarrying == null) { // Early out if no bomb found return; } ICard cardUsedToJudge = null; //IPlayer playerResponding; // Raise the ResponseNeeded event ICard cardResponded = AllPlayersCanRespond(cardBombCarrying, null); if (cardResponded != null) { Util.PrintPlayerAction(cardResponded.PlayerPlaying, cardResponded, PlayerAction.Counter); CardJudge.CardNotTakeEffect(PlayerList, null, playerCarrying, cardBombCarrying); Util.PrintPlayerAction(playerCarrying, null, PlayerAction.BombNotTakeEffect); } else { Util.PrintPlayerAction(playerCarrying, null, PlayerAction.NoResponseFromAll); cardUsedToJudge = CentralCardDeck.DrawACard(); Util.PrintPlayerAction(playerCarrying, cardUsedToJudge, PlayerAction.Judge); if (CardJudge.CardJudgingResult(cardBombCarrying, cardUsedToJudge)) { CardJudge.CardTakeEffect(null, playerCarrying, cardBombCarrying, null); Util.PrintPlayerAction(playerCarrying, null, PlayerAction.BombTakeEffect); Util.PrintPlayerAction(playerCarrying, null, PlayerAction.TakeDamage); } else { CardJudge.CardNotTakeEffect(PlayerList, null, playerCarrying, cardBombCarrying); Util.PrintPlayerAction(playerCarrying, null, PlayerAction.BombNotTakeEffect); } } }
public void StartGame() { // Start a game while (!IsGameOver()) { // Start a round foreach (IPlayer player in PlayerList) { // Judge the bomb for the player before the player starts his round JudgeIndividualBomb(PlayerList, player); // Check if the player needs to be put in prison before the player starts his round JudgeIndividualPrison(player); // Start a player's turn // Raise the PlayerTurnStarts event or the PlayAnotheCard event for (player.Messenger.OnPlayerTurnStarts(); player.CardNeedResponse != null; player.Messenger.OnPlayAnotheCard()) { // Start a card's life cycle // TODO This behaviour is likely to be changed if (player.CardNeedResponse.IsBomb()) { StartACardLifeCycle(player, player); } else if (player.CardNeedResponse.IsJade()) { if (player.CardNeedResponse.CardAction == CAction.GetEquipped) { StartACardLifeCycle(player, player); player.CardNeedResponse.CardAction = CAction.TakeEffect; } else { // TODO Enable a player to play the jade card for someone else in the future // Need to distinguish beteen the jade card being equipped and being played JudgeIndividualJade(player.CardNeedResponse, player, player); } } else { AffectedPlayer numOfAffectedPlayers = CardJudge.CardAffectNumOfPlayers(player.CardNeedResponse); if (numOfAffectedPlayers == AffectedPlayer.One) { StartACardLifeCycle(player, player.PlayerToKill); } else { foreach (IPlayer playerReceiving in PlayerList) { if (numOfAffectedPlayers == AffectedPlayer.All || numOfAffectedPlayers == AffectedPlayer.AllButMyself && player != playerReceiving) { StartACardLifeCycle(player, playerReceiving); } } } } } // Raise the PlayerTurnEnds event player.Messenger.OnPlayerTurnEnds(); foreach (IPlayer eachPlayer in PlayerList) { Util.PrintPlayerAction(eachPlayer, null, PlayerAction.RemainingHitpoint); } } } Console.ReadLine(); }
bool EnterCardCounteringArena(IPlayer playerPlaying, IPlayer playerReceiving, ICard cardTriggering, ICard cardFirst, MiniRoundTimingOption timingCountering, MiniRoundTimingOption timingAnnulling) { ICard cardResponded; bool cardFirstAnnulled = false; bool firstMiniRound = true; do { cardResponded = null; //IPlayer playerResponding; if (timingCountering == MiniRoundTimingOption.Always || timingCountering == MiniRoundTimingOption.FirstMiniRound && firstMiniRound) { cardResponded = AllPlayersCanRespond(cardTriggering, cardFirst); } firstMiniRound = false; if (cardResponded == null) { // No player has responded with a card as the third party cardResponded = SinglePlayerMustRespond(playerReceiving, cardTriggering, cardFirst); } if (cardResponded == null) { // There is no card played as the response to the card just been played break; } // TODO What about those equipped cards which do not require a judging card? // Certain type of responded cade needs a judging card if (CardJudge.CardNeedJudgingCard(cardResponded)) { ICard cardJudging = CentralCardDeck.DrawACard(); if (CardJudge.CardJudgingResult(cardResponded, cardJudging)) { CardJudge.CardTakeEffect(playerPlaying, playerReceiving, cardResponded, null); Util.PrintPlayerAction(playerReceiving, null, PlayerAction.TakeDamage); // Replace the responded card with the new card played in TakeEffect(), // e.g. Replace JadeCard with DodgeCard if (CardJudge.CardIsIntermediate(cardResponded)) { cardResponded = playerReceiving.CardResponded; } } else { // TODO Consider to move this to NotTakeEffect() if (CardJudge.CardIsIntermediate(cardResponded)) { cardResponded = playerPlaying.CardResponded = null; } // No player has responded with a card as the third party cardResponded = SinglePlayerMustRespond(playerReceiving, cardTriggering, cardFirst); if (cardResponded == null) { // There is no card played as the response to the card just been played break; } } } //Util.PrintPlayerAction(cardResponded.PlayerPlaying, cardResponded, PlayerAction.Counter); cardFirstAnnulled = !cardFirstAnnulled; // This card just being played is an annulling card and cannot be countered if (cardResponded.IsAnnulling) { break; } // Swap players so the player who plays card first in this mini-round needs to respond in the next mini-round Util.SwapPlayers(ref playerPlaying, ref playerReceiving); }while (cardResponded != null); return(cardFirstAnnulled); }