Exemple #1
0
        /// <summary>
        /// Makes move on the table, and flips the active player. A Move can be created using GetMove(command).
        /// </summary>
        public void MakeMove(Move move)
        {
            _moveNo++;
            if (move == null)
            {
                throw new NullReferenceException();
            }
            currentMove = move;
            switch (move.MoveType)
            {
            case MoveTypes.Throwaway:
                GetActivePlayer().RemoveCard(move.CardPlayed);
                CardsOnTable.Add(move.CardPlayed);
                break;

            case MoveTypes.Pickup:
                GetActivePlayer().RemoveCard(move.CardPlayed);
                GetActivePlayer().AddCardsToLocalDeck(move.CardsPickedUp.Concat(new List <byte> {
                    move.CardPlayed
                }).ToList());
                CardsOnTable.RemoveAll(x => move.CardsPickedUp.Contains(x));
                break;

            case MoveTypes.Build: break;

            case MoveTypes.Capture: break;

            default: throw new Exception(Errorstr.NoMove());
            }
            FlipActivePlayer();
        }
Exemple #2
0
            /*********************************************************************/
            /************************** UTILITY METHODS **************************/
            /*********************************************************************/

            /// <summary>
            /// Assumes all BuildNames are extracted beforehand (example: alpha, beta). Run
            /// ExtractBuildNamesFromString() if there is uncertainty.
            /// </summary>
            private static List <byte> ExtractCardsFromString(string cmd)
            {
                cmd = cmd.Replace("10", "T");
                string      remain = cmd;
                List <byte> result = new List <byte>();

                while (remain.Length > 0)
                {
                    if (!charcardValAbbr.Contains(char.ToUpper(remain[0])))
                    {
                        throw new UnparseableMoveException(Errorstr.CardFormat(), cmd);
                    }
                    if (remain.Length > 1 && cardSuitAbbrAscii.Contains(remain[1]))   //example 5h
                    {
                        result.Add(ExtractCardFromString(remain.Substring(0, 2)));
                        remain = remain.Substring(2);
                    }
                    else     //examples 9, 92 (only parses 9 in both scenarios)
                    {
                        result.Add(ExtractCardFromString(remain.Substring(0, 1)));
                        remain = remain.Substring(1);
                    }
                }
                return(result);
            }
Exemple #3
0
 /// <summary>
 /// These cards will enter the player's Hand (playable cards), and not their local deck (earned cards).
 /// </summary>
 /// <param name="newCards">Cards received directly from Deck. Must be limited to max number of cards available in Hand at once.</param>
 public bool ReceiveCards(List <byte> newCards)
 {
     if (newCards.Count > (MAX_NUMBER_OF_CARDS - CountCardsInHand))
     {
         throw new Exception(Errorstr.TooManyCards(Name + "'s hand",
                                                   MAX_NUMBER_OF_CARDS, newCards.Count));
     }
     _hand.AddRange(newCards);
     return(true);
 }
Exemple #4
0
 public Move AddCardsToExistingBuild(Build buildName, List <byte> cardsToAdd)
 {
     if ((cardsToAdd != null) && (!cardsToAdd.Any()))
     {
         CardsAddedToExistingBuild = new Tuple <Build, List <byte> >(buildName, cardsToAdd);
     }
     else
     {
         throw new Exception(Errorstr.EmptyBuild());
     }
     return(this);
 }
Exemple #5
0
 public Move CreateNewBuild(List <byte> cardsInNewBuild)
 {
     if ((cardsInNewBuild != null) && (!cardsInNewBuild.Any()))
     {
         NewBuildCards = cardsInNewBuild;
     }
     else
     {
         throw new Exception(Errorstr.EmptyBuild());
     }
     return(this);
 }
Exemple #6
0
            private static byte ExtractCardFromString(string cmd)
            {
                cmd = cmd.Replace("10", "T");
                cmd = cmd.ToLower();
                if (cmd.Length < 1 || cmd.Length > 2)
                {
                    throw new UnparseableMoveException(Errorstr.CardFormat(), cmd);
                }

                CardVals  value    = CardVals.NONE;
                CardSuits suit     = CardSuits.NONE;
                char      cmdValue = cmd[0];
                char      cmdSuit  = '\0';

                if (cmd.Length == 2)
                {
                    cmdSuit = cmd[1];
                }
                foreach (CardVals val in Enum.GetValues(typeof(CardVals)))
                {
                    char valabbr = char.ToLower(GetCardValAbbr((byte)val, true)[0]);
                    if (valabbr == cmdValue)
                    {
                        value = val; break;
                    }
                }
                if (value == CardVals.NONE)
                {
                    throw new UnparseableMoveException(Errorstr.CardFormat(), cmd);
                }

                if (cmdSuit != '\0')
                {
                    cmdSuit = char.ToLower(cmdSuit);
                    foreach (CardSuits suitf in Enum.GetValues(typeof(CardSuits)))
                    {
                        char suitabbr = GetCardSuitAbbr((byte)suitf, true);
                        if (suitabbr == cmdSuit)
                        {
                            suit = suitf; break;
                        }
                    }
                    if (suit == CardSuits.NONE)
                    {
                        throw new UnparseableMoveException("Invalid suit provided to a card", cmd);
                    }
                }

                byte result = GetCardDigit(value, suit);

                return(result);
            }
Exemple #7
0
 /// <summary>
 /// Adds cards directly to the deck at a specified index.
 /// </summary>
 /// <param name="atIndex">For atIndex = 0 being the top-most position, state the index to insert the first card.</param>
 /// <param name="cards">How many cards should be inserted?</param>
 public virtual Deck AddCards(short atIndex, List <byte> cards)
 {
     if (cards.Count + CardCount <= DECK_SIZE)
     {
         _cardDeck.InsertRange(atIndex, cards);
     }
     else
     {
         throw new Exception(Errorstr.TooManyCards("Adding cards", DECK_SIZE, cards.Count));
     }
     canCreateNewDeck = false;
     return(this);
 }
Exemple #8
0
 /// <summary>
 /// Remove cards directly from this deck. NOTE: Use DrawCards() instead to have the function return the removed cards.
 /// </summary>
 /// <param name="startIndex">For startIndex = 0 being the top card, state index of first removable card.</param>
 /// <param name="count">From startIndex, how many cards should be removed?</param>
 public Deck RemoveCards(short startIndex, short count)
 {
     if (count == 0)
     {
         return(this);
     }
     if (count <= _cardDeck.Count)
     {
         _cardDeck.RemoveRange(startIndex, count);
     }
     else
     {
         throw new Exception(Errorstr.TooManyCards("Removing cards", CardCount, count));
     }
     return(this);
 }
Exemple #9
0
 public Table(Deck deck, Player playerOne, Player playerTwo)
 {
     if (playerOne == null || p2 == playerTwo)
     {
         throw new NullReferenceException();
     }
     p1 = playerOne;
     p2 = playerTwo;
     if ((deck.GetDeck().Count - INITIAL_CARDS_ON_TABLE) % CARDS_PER_PLAYER != 0)
     {
         throw new Exception(Errorstr.UnevenDeck());
     }
     if (deck.GetDeck().Count != DECK_SIZE)
     {
         throw new Exception(
                   Errorstr.WrongCardCount("The table", DECK_SIZE, deck.GetDeck().Count));
     }
     TURN  = Players.One;
     _deck = deck;
 }
Exemple #10
0
            private static Move Throwaway(string[] cmdArgs)
            {
                byte card = 0;

                if (cmdArgs.Length != 2)
                {
                    throw new UnparseableMoveException("Two arguments expected. First argument throwaway, " +
                                                       "second argument the card that is being thrown away.", string.Join(' ', cmdArgs));
                }
                string throwawayCard = cmdArgs[1];

                if (ExtractBuildNamesFromString(ref throwawayCard)?.Count() != 0)
                {
                    throw new UnparseableMoveException("Build names cannot be used when throwing away cards.",
                                                       string.Join(' ', cmdArgs));
                }
                try {
                    card = ExtractCardsFromString(throwawayCard)[0];
                } catch (Exception ex) {
                    if (ex is ArgumentOutOfRangeException || ex is ArgumentNullException || ex is UnparseableMoveException)
                    {
                        throw new UnparseableMoveException(Errorstr.NoMove(), string.Join(' ', cmdArgs));
                    }
                    else
                    {
                        throw ex;
                    }
                }

                card = GetCorrespondingCards(new List <byte> {
                    card
                }, table.GetActivePlayer().Hand,
                                             (table.GetActivePlayer().PlayerNo == Players.One) ? CardLocations.PlayerOneHand : CardLocations.PlayerTwoHand)[0];

                return(new Move(MoveTypes.Throwaway, card));
            }
Exemple #11
0
            private static Move Pickup(string[] cmdArgs)
            {
                if (cmdArgs.Length < 2 || cmdArgs.Length > 3)
                {
                    throw new UnparseableMoveException("Two or three arguments expected. First argument pickup, " +
                                                       "second argument card on table, third argument card in hand.", string.Join(' ', cmdArgs));
                }
                if (cmdArgs.Length == 2)
                {
                    //"pickup 4" should be interpreted as "use the sole 4 in hand to pick up the sole 4 on table"
                    cmdArgs = new string[3] {
                        cmdArgs[0], cmdArgs[1], cmdArgs[1]
                    }
                }
                ;
                string fromTable = cmdArgs[1];
                string fromHand  = cmdArgs[2];

                if (ExtractBuildNamesFromString(ref fromTable)?.Count() != 0 || ExtractBuildNamesFromString(ref fromHand)?.Count() != 0)
                {
                    throw new UnparseableMoveException("Build names cannot be used when picking up cards. Use capture instead.",
                                                       string.Join(' ', cmdArgs));
                }
                List <byte> playOnTableRaw, playOnTable;
                byte        playFromHandRaw, playFromHand;

                playOnTableRaw  = playOnTable = new List <byte>();
                playFromHandRaw = playFromHand = 0;

                try {
                    playOnTableRaw  = ExtractCardsFromString(fromTable);
                    playFromHandRaw = ExtractCardFromString(fromHand);
                } catch (Exception ex) {
                    if (ex is ArgumentOutOfRangeException || ex is ArgumentNullException)
                    {
                        throw new UnparseableMoveException(Errorstr.NoMove(), string.Join(' ', cmdArgs));
                    }
                    else
                    {
                        throw ex;
                    }
                }

                playOnTable  = GetCorrespondingCards(playOnTableRaw, table.CardsOnTable, CardLocations.Table);
                playFromHand = GetCorrespondingCards(new List <byte> {
                    playFromHandRaw
                }, table.GetActivePlayer().Hand,
                                                     (table.GetActivePlayer().PlayerNo == Players.One) ? CardLocations.PlayerOneHand : CardLocations.PlayerTwoHand)[0];

                if (ContainsPictureCard(playOnTable.ToList()))
                {
                    if (playOnTable.Count != 1 || !CardsMatchInValue(playFromHand, playOnTable[0]))
                    {
                        throw new IllegalPickupException(
                                  "Cannot pickup multiple picture cards at once", playFromHand, (byte)GetCardValue(playFromHand));
                    }
                }
                else
                {
                    //if no error, then valid move
                    Build build = new Build(BuildNames.NONE, playOnTable, (byte)GetCardValue(playFromHand));
                }

                return(new Move(MoveTypes.Pickup).PlayCard(playFromHand).PickupCards(playOnTable));
            }
Exemple #12
0
        /// <summary>
        /// Use this method at round end. Will assign point values and summary to players themselves.
        /// </summary>
        public void ScoreRound(byte currentRound)
        {
            if (_roundHasBeenScored)
            {
                throw new Exception(Errorstr.DuplicateRoundScore());
            }
            List <ScoreableAttributes> p1Captures, p2Captures;

            p1Captures = new List <ScoreableAttributes>();
            p2Captures = new List <ScoreableAttributes>();
            SetActivePlayer(Players.One);

            /*STATIC VALUES*/
            List <ScoreableAttributes> staticScoreables = CardNumberByStaticAttribute.Select(x => x.Key).ToList();
            /*DYNAMIC VALUES*/
            int p1CardCount, p2CardCount, p1SpadeCount, p2SpadeCount;

            p1SpadeCount = p2SpadeCount = 0;
            p1CardCount  = p1.LocalDeck.CardCount;
            p2CardCount  = p2.LocalDeck.CardCount;

            /*EVALUATE CARDS*/
            do
            {
                Player player = GetActivePlayer();
                List <ScoreableAttributes> captures = new List <ScoreableAttributes>();
                CardVals  value = CardVals.NONE;
                CardSuits suit  = CardSuits.NONE;

                while (player.LocalDeck.CardCount > 0)
                {
                    byte card = player.LocalDeck.DrawCards(1)[0];
                    value = GetCardValue(card);
                    suit  = GetCardSuit(card);

                    /*STATIC*/
                    staticScoreables.Where(attr => CardNumberByStaticAttribute[attr].Equals(card)).ToList()
                    .ForEach(attr => { captures.Add(attr); });
                    staticScoreables.RemoveAll(attr => captures.Contains(attr)); //efficiency reasons
                    /*DYNAMIC*/
                    if (TURN == Players.One)
                    {
                        p1SpadeCount += (suit == CardSuits.Spades) ? 1 : 0;
                    }
                    if (TURN == Players.Two)
                    {
                        p2SpadeCount += (suit == CardSuits.Spades) ? 1 : 0;
                    }
                }
                if (TURN == Players.One)
                {
                    p1Captures.AddRange(captures);
                }
                else
                {
                    p2Captures.AddRange(captures);
                }
                FlipActivePlayer();
            } while (TURN != Players.One);

            /* EVAL DYNAMICS */
            if (p1CardCount > p2CardCount)
            {
                p1Captures.Add(ScoreableAttributes.MostCards);
            }
            else if (p2CardCount > p1CardCount)
            {
                p2Captures.Add(ScoreableAttributes.MostCards);
            }

            if (p1SpadeCount > p2SpadeCount)
            {
                p1Captures.Add(ScoreableAttributes.MostSpades);
            }
            else if (p2SpadeCount > p1SpadeCount)
            {
                p2Captures.Add(ScoreableAttributes.MostSpades);
            }

            /* Conclusion - scores are evaluated by player */
            p1.AddNewScoreLogEntry(p1Captures);
            p2.AddNewScoreLogEntry(p2Captures);
            _roundHasBeenScored = true;
        }