コード例 #1
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        private bool HasGameWinnerFromZones(out Player winner)
        {
            if (IsInfoEnabled) log.Info("HasGameWinnerFromZones?");

            var requiredN = RequiredAdjacentZoneCount[players.Length];
            var requiredT = RequiredTotalZoneCount[players.Length];

            if (IsDebugEnabled) log.Debug("Must have {0} adjacent or {1} total zone", requiredN, requiredT);

            foreach (var p in players)
            {
                var playerN = Table.GetAdjacentZoneCount(p);
                var playerT = Table.GetOccupiedZoneCount(p);

                if (IsInfoEnabled) log.Info("Player {0} has {1} adjacent & {2} total.", p, playerN, playerT);

                if (playerN == requiredN || playerT == requiredT)
                {
                    winner = p;

                    return true;
                }
            }

            winner = null;
            return false;
        }
コード例 #2
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        private bool HasGameWinnerIfTableFull(out Player winner)
        {
            if (IsInfoEnabled) log.Info("HasGameWinnerIfTableFull?");

            if (Table.FreeZoneCount > 0)
            {
                if (IsInfoEnabled) log.Info("Table is not full yet.");

                winner = null;
                return false;
            }

            var playerZones = players.ToLookup(p => Table.GetOccupiedZoneCount(p));
            winner = GetTopPlayerByScore(playerZones);

            return true;
        }
コード例 #3
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        private void FromHandToDesk(Player p, Card c)
        {
            var state = states[p];

            Debug.Assert(state.Hand.Contains(c));
            Debug.Assert(!state.Desk.Contains(c));

            state.Hand.Remove(c);
            state.Desk.Add(c);
        }
コード例 #4
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        private void FromHandToPool(Player p, Card c)
        {
            var state = states[p];

            deck.Pool(c);
            state.Hand.Remove(c);
        }
コード例 #5
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
 private void ExpectCurrentPlayer(Player p)
 {
     if (p != currentPlayer)
         throw new InvalidOperationException("Player {0} is not the active player.".F(p));
 }
コード例 #6
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        private Card ExpectInstanceOnDesk(Player p, CardType card)
        {
            var state = states[p];
            var retval = state.Desk.FirstOrDefault(c => c.Kind == card);

            if (retval == null)
            {
                if (IsWarnEnabled)
                    log.Warn("Expected card ON DESK {0} for {1}, not found", p, card);

                throw new InvalidOperationException("Player {0} does not have {1} in hand.".F(p, card));
            }

            return retval;
        }
コード例 #7
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        /// <summary>
        /// The player can move one card from Desk to Hand.
        /// </summary>
        public void RetrieveCard(Player p, Card card)
        {
            ExpectStep(Steps.RetrieveCard);
            ExpectCurrentPlayer(p);

            // -> selected card goes into hand (from desk)
            // specials cannot be retrieved
            // if card is null the player did not retrieve anything
            if (card != null)
            {
                var instance = ExpectInstanceOnDesk(p, card.Kind);
                if (instance.IsSpecial)
                    throw new InvalidOperationException("Special cards cannot be retrieved. ({0}, {1})".F(p, card));

                FromDeskToHand(p, instance);
            }

            // sc -> pool
            FromHandToPool(p, ExpectInstanceInHand(p, CardType.Scarecrow));

            CurrentStep = Steps.PlayerDone;
        }
コード例 #8
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        private void CalcNextStarter(Player winner)
        {
            if (IsInfoEnabled) log.Info("Game did not end, calculating next player.");

            // null -> the player next to the previous starter will start
            Player starter = null;

            if (winner != null)
            {
                // player having the most C on desk starts the next round
                // if no one has C on desk the winner will start the next round
                // if there is a tie then the last winner starts
                // if there is no winner the next player to the one starting the last round will start (eww)
                var courtesans = states.ToLookup(kvp => kvp.Value.Desk.Count(c => c.Kind == CardType.Courtesan), kvp => kvp.Key);

                if (log.IsDebugEnabled)
                {
                    foreach (var g in courtesans)
                        log.Debug("{0} courtesans: {1}", g.Key, String.Join(", ", g.Select(p => p.ToString())));
                }

                starter = (courtesans[0].Count() == players.Length)
                                ? winner
                                : GetTopPlayerByScore(courtesans); // returns null if there is a tie
            }
            else
            {
                if (IsInfoEnabled) log.Info("Battle finished with tie, player after {0} starts.", players[battleStartPlayer]);
            }

            if (starter == null)
            {
                battleStartPlayer = (battleStartPlayer + 1) % players.Length;

                if (IsInfoEnabled) log.Info("Next player starts ({0})", players[battleStartPlayer]);
            }
            else
            {
                battleStartPlayer = Array.IndexOf<Player>(players, starter);

                if (IsInfoEnabled) log.Info("Calculated player starts ({0})", starter);
            }
        }
コード例 #9
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        public void PlayCard(Player p, Card card)
        {
            ExpectStep(Steps.PlayerStart);
            ExpectCurrentPlayer(p);

            if (IsDebugEnabled) log.Debug("{0} played card {1}", p, card);

            card = ExpectInstanceInHand(p, card.Kind);

            // when a card transitions into a different state
            // then its state handler will select the next player
            switch (card.Kind)
            {
                // ask the player to select
                // which card to retrieve from the desk
                case CardType.Scarecrow:
                    CurrentStep = Steps.RetrieveCard;
                    return;

                // ask the player to protect/unprotect a zone
                // remove top non-specials
                case CardType.Bishop:
                    CurrentStep = Steps.ProtectZone;
                    return;

                // end of battle
                case CardType.Key:
                    FromHandToPool(p, card);
                    explicitNext = Steps.Key;
                    return;

                // remove all winters from desk
                case CardType.Spring:
                    FromDeskToPool(CardType.Winter);
                    break;

                // remove all springs from desk
                case CardType.Winter:
                    FromDeskToPool(CardType.Spring);
                    break;
            }

            CurrentStep = Steps.PlayerDone;
            // just place the card on the desk
            FromHandToDesk(p, card);
        }
コード例 #10
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        /// <summary>
        /// Bishop was played:
        ///  - The player can mark one zone as Protected. (Use null to remove the current protection.)
        ///  - Bishop also removes the largest card(s) from the desk
        /// </summary>
        public void ProtectZone(Player p, string zone)
        {
            ExpectStep(Steps.ProtectZone);
            ExpectCurrentPlayer(p);

            Table.ProtectedZone = zone;

            // bishop -> pool
            FromHandToPool(p, ExpectInstanceInHand(p, CardType.Bishop));

            // technically the tops card must be removed when the bishop is played
            // OTOH the client can still fail while entering the marked zone
            // so delay the removal until every input is valid
            RemoveTopCards();

            CurrentStep = Steps.PlayerDone;
        }
コード例 #11
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        /// <summary>
        /// The player will not play more cards in this turn.
        /// </summary>
        /// <param name="p"></param>
        public void Pass(Player p)
        {
            ExpectStep(Steps.PlayerStart);
            ExpectCurrentPlayer(p);

            if (IsDebugEnabled) log.Debug("{0} passed", p);

            states[p].DidPass = true;

            CurrentStep = (states.Values.All(s => s.DidPass))
                            ? Steps._AllPassed
                            : Steps.PlayerDone;
        }
コード例 #12
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        /// <summary>
        /// Move to the next player
        /// </summary>
        public void NextPlayer()
        {
            CurrentStep = Steps.PlayerStart;
            for (var i = 0; i < players.Length; i++)
            {
                currentPlayerIndex = (currentPlayerIndex + 1) % players.Length;
                currentPlayer = players[currentPlayerIndex];

                if (!states[currentPlayer].DidPass) return;
            }

            throw new InvalidOperationException("Everyone did pass and still looking for next?");
        }
コード例 #13
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        public void NewBattle()
        {
            ExpectStep(Steps.BattleStart);

            BattleIndex++;

            log.Info("New Battle: " + RoundIndex);

            foreach (var state in states.Values)
            {
                state.DidPass = false;

                // desk -> pool
                deck.Pool(state.Desk);
                state.Desk.Clear();
            }

            if (IsDebugEnabled)
                log.Debug("BattleStartPlayer: " + players[battleStartPlayer]);

            currentPlayerIndex = battleStartPlayer;
            currentPlayer = players[battleStartPlayer];
        }
コード例 #14
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        public void MarkZone(Player p, string zone)
        {
            ExpectStep(Steps.MarkZone);
            ExpectCurrentPlayer(p);

            Table.CurrentZone = zone;

            if (IsInfoEnabled)
                log.Info("Player {0} marked zone {1}", p, zone);
        }
コード例 #15
0
ファイル: GameState.cs プロジェクト: enyim/Hackathon
        public void DropHand(Player p)
        {
            var state = states[p];

            if (IsDebugEnabled)
                log.Debug("Dropping cards of {0}", p);

            // hand -> pool
            deck.Pool(state.Hand);
            state.Hand.Clear();
        }