예제 #1
0
        public void PlayTrumpOrderTest()
        {
            var players      = PlayersSetup.BuildFourAIPlayers();
            var fourthPlayer = players[3];

            var cardsHeldByPlayer   = new Dictionary <IPlayer, List <Card> >();
            var cardsPlayedByPlayer = new Dictionary <IPlayer, List <Card> >();

            var heart = SuitHelper.GetSuit(CardSuit.Heart);

            cardsHeldByPlayer[players[0]] = new List <Card> {
                new Card(RankHelper.GetRank("7"), heart)
            };
            cardsHeldByPlayer[players[1]] = new List <Card> {
                new Card(RankHelper.GetRank("A"), heart)
            };
            cardsHeldByPlayer[players[2]] = new List <Card> {
                new Card(RankHelper.GetRank("8"), heart)
            };
            cardsHeldByPlayer[players[3]] = new List <Card> {
                new Card(RankHelper.GetRank("9"), heart)
            };

            var trick = new Trick(players, heart);

            trick.Play(cardsHeldByPlayer, cardsPlayedByPlayer);
            var winner = trick.GetTaker();

            Assert.AreEqual(fourthPlayer, winner);
        }
예제 #2
0
        public void PlayMultipleColors()
        {
            var players     = PlayersSetup.BuildFourAIPlayers();
            var firstPlayer = players[0];

            var cardsHeldByPlayer   = new Dictionary <IPlayer, List <Card> >();
            var cardsPlayedByPlayer = new Dictionary <IPlayer, List <Card> >();

            var heart = SuitHelper.GetSuit(CardSuit.Heart);
            var spade = SuitHelper.GetSuit(CardSuit.Spade);
            var club  = SuitHelper.GetSuit(CardSuit.Club);

            cardsHeldByPlayer[players[0]] = new List <Card> {
                new Card(RankHelper.GetRank("7"), heart)
            };
            cardsHeldByPlayer[players[1]] = new List <Card> {
                new Card(RankHelper.GetRank("A"), club)
            };
            cardsHeldByPlayer[players[2]] = new List <Card> {
                new Card(RankHelper.GetRank("8"), club)
            };
            cardsHeldByPlayer[players[3]] = new List <Card> {
                new Card(RankHelper.GetRank("9"), club)
            };

            var trick = new Trick(players, spade);

            trick.Play(cardsHeldByPlayer, cardsPlayedByPlayer);
            var winner = trick.GetTaker();

            Assert.AreEqual(firstPlayer, winner);
        }
예제 #3
0
            public override void HandleCardPlayed(Seats source, Suits suit, Ranks rank)
            {
#if syncTrace
                Log.Trace(2, "{0}.HandleCardPlayed: {1} plays {3} of {2}", this.Owner, source, suit, rank);
#endif
                var manForCurrentCard = this.Play.man;
                base.HandleCardPlayed(source, suit, rank);
#if syncTrace
                Log.Trace(2, "{0}.HandleCardPlayed: next card by {1}", this.Owner, this.Play.whoseTurn);
#endif
                if ((source == this.tmc.seat && this.tmc.seat != this.Play.Dummy) || (source == this.Play.Dummy && this.tmc.seat == this.Play.Dummy.Partner()))
                {
                    var message = string.Format("{0} plays {2}{1}",
                                                // TM bug: TM does not recognize the phrase 'Dummy plays 8C', eventhough the protocol defines it
                                                //whoseTurn != this.seat ? "Dummy" : whoseTurn.ToString(),
                                                source,
                                                SuitHelper.ToXML(suit),
                                                rank.ToXML());

                    if (manForCurrentCard == 1)
                    {
                        this.tmc.ChangeState(TableManagerProtocolState.WaitForLead, false, false, new string[] { "" }, message);
                    }
                    else
                    {
                        this.tmc.ChangeState(this.tmc.state, false, this.Play.PlayEnded || (this.Play.man == 1 && (this.Play.whoseTurn == this.tmc.seat || (this.Play.whoseTurn == this.Play.Dummy && this.tmc.seat == this.Play.Contract.Declarer))), this.tmc.tableManagerExpectedResponse, message);
                    }
                }
            }
예제 #4
0
        public void BuildAllSuitsTest()
        {
            var allSuits = SuitHelper.BuildAllSuits();

            Assert.AreEqual(4, allSuits.Count);
            var allSuitsName = string.Join("|", allSuits.Select(t => t.ToString()));

            Assert.AreEqual("♠|♥|♦|♣", allSuitsName);
        }
예제 #5
0
        public static void HandleProtocolPlay(string message, BridgeEventBus bus)
        {
            // North plays 3C
            string[] answer = message.Split(' ');
            var      player = SeatsExtensions.FromXML(answer[0]);
            var      suit   = SuitHelper.FromXML(answer[2][1]);
            var      rank   = Rank.From(answer[2][0]);

            bus.HandleCardPosition(player, suit, rank);
            bus.HandleCardPlayed(player, suit, rank);
        }
예제 #6
0
        public void Play()
        {
            Trump = SuitHelper.GetSuit("Heart");
            var trick = new Trick(Players, Trump);

            for (int i = 0; i < BelotteRules.TrickNumber; i++)
            {
                trick.Play(CardsHeldByPlayers, CardsPlayedByPlayers);

                var newPlayersOrder = RoundHelper.OrderPlayersForNewTrick(Players, trick.GetTaker());
                LastTrickWinner = trick.GetTaker();
                trick           = new Trick(newPlayersOrder, Trump);
            }
        }
예제 #7
0
        public void PlayWithRankTest()
        {
            var players      = PlayersSetup.BuildFourAIPlayers();
            var secondPlayer = players[1];

            var cardsHeldByPlayer   = new Dictionary <IPlayer, List <Card> >();
            var cardsPlayedByPlayer = new Dictionary <IPlayer, List <Card> >();

            var heart = SuitHelper.GetSuit(CardSuit.Heart);
            var spade = SuitHelper.GetSuit(CardSuit.Spade);

            cardsHeldByPlayer[players[0]] = new List <Card> {
                new Card(RankHelper.GetRank("7"), heart)
            };
            cardsHeldByPlayer[players[1]] = new List <Card> {
                new Card(RankHelper.GetRank("A"), heart)
            };
            cardsHeldByPlayer[players[2]] = new List <Card> {
                new Card(RankHelper.GetRank("8"), heart)
            };
            cardsHeldByPlayer[players[3]] = new List <Card> {
                new Card(RankHelper.GetRank("9"), heart)
            };

            var trick = new Trick(players, spade);

            trick.Play(cardsHeldByPlayer, cardsPlayedByPlayer);
            var winner = trick.GetTaker();

            Assert.AreEqual(secondPlayer, winner);

            var playedCards = trick.GetPlayedCards();

            Assert.IsNotNull(playedCards);
            Assert.AreEqual(4, playedCards.Count);
        }
예제 #8
0
        private void ProcessMessage(string message)
        {
#if syncTrace
            Log.Trace(2, "Client {1} processing '{0}'", message, seat);
#endif

            if (message == "End of session" ||
                message.StartsWith("NS:")               // something new from Bridge Moniteur: session ends with
                )
            {
                this.EventBus.HandleTournamentStopped();
                return;
            }

            if (Expected(message))
            {
                try
                {
                    switch (this.state)
                    {
                    case TableManagerProtocolState.WaitForSeated:
                        this.HandleSeated();
                        this.ChangeState(TableManagerProtocolState.WaitForTeams, false, false, new string[] { "Teams" }, "{0} ready for teams", this.seat);
                        break;

                    case TableManagerProtocolState.WaitForTeams:
                        this.teamNS = message.Substring(message.IndexOf("N/S : \"") + 7);
                        this.teamNS = teamNS.Substring(0, teamNS.IndexOf("\""));
                        this.teamEW = message.Substring(message.IndexOf("E/W : \"") + 7);
                        this.teamEW = teamEW.Substring(0, teamEW.IndexOf("\""));
                        if (this.team != (this.seat.IsSameDirection(Seats.North) ? this.teamNS : this.teamEW))
                        {
                            throw new ArgumentOutOfRangeException("team", "Seated in another team");
                        }

                        this.HandleTeams(teamNS, teamEW);
                        this.ChangeState(TableManagerProtocolState.WaitForStartOfBoard, false, false, new string[] { "Start of board", "End of session" }, "{0} ready to start", this.seat);
                        break;

                    case TableManagerProtocolState.WaitForStartOfBoard:
                        if (message.StartsWith("Teams"))
                        {               // bug in BridgeMoniteur when tournament is restarted
                        }
                        else if (message.StartsWith("Timing"))
                        {
                            // Timing - N/S : this board [minutes:seconds], total [hours:minutes:seconds]. E/W : this board [minutes:seconds], total [hours:minutes:seconds]".
                            // Bridge Moniteur does not send the '.' at the end of the message
                            // Timing - N/S : this board  01:36,  total  0:01:36.  E/W : this board  01:34,  total  0:01:34
                            if (!message.EndsWith("."))
                            {
                                message += ".";
                            }
                            string[] timing  = message.Split('.');
                            string[] parts   = timing[0].Split(',');
                            string   boardNS = "00:" + parts[0].Substring(parts[0].IndexOf("board") + 6).Trim();
                            string   totalNS = parts[1].Substring(parts[1].IndexOf("total") + 6).Trim();
                            parts = timing[1].Split(',');
                            string boardEW = "00:" + parts[0].Substring(parts[0].IndexOf("board") + 6).Trim();
                            string totalEW = parts[1].Substring(parts[1].IndexOf("total") + 6).Trim();

                            TimeSpan _boardNS = ParseTimeUsed(boardNS);
                            TimeSpan _totalNS = ParseTimeUsed(totalNS);
                            TimeSpan _boardEW = ParseTimeUsed(boardEW);
                            TimeSpan _totalEW = ParseTimeUsed(totalEW);
                            this.EventBus.HandleTimeUsed(_boardNS, _totalNS, _boardEW, _totalEW);
                        }
                        else
                        {
                            this.ChangeState(TableManagerProtocolState.WaitForBoardInfo, false, false, new string[] { "Board number" }, "{0} ready for deal", this.seat);
                        }
                        break;

                    case TableManagerProtocolState.WaitForBoardInfo:
                        // "Board number 1. Dealer North. Neither vulnerable."
                        string[] dealInfoParts = message.Split('.');
                        int      boardNumber   = Convert.ToInt32(dealInfoParts[0].Substring(13));
                        this.theDealer = SeatsExtensions.FromXML(dealInfoParts[1].Substring(8));
                        Vulnerable vulnerability = Vulnerable.Neither;
                        switch (dealInfoParts[2].Substring(1))
                        {
                        case "Both vulnerable":
                            vulnerability = Vulnerable.Both; break;

                        case "N/S vulnerable":
                            vulnerability = Vulnerable.NS; break;

                        case "E/W vulnerable":
                            vulnerability = Vulnerable.EW; break;
                        }

                        var board = new Board2(this.theDealer, vulnerability, new Distribution());
                        this.CurrentResult = new TMBoardResult(this, board, new SeatCollection <string>(new string[] { this.teamNS, this.teamEW, this.teamNS, this.teamEW }));

                        this.EventBus.HandleBoardStarted(boardNumber, this.theDealer, vulnerability);
                        this.ChangeState(TableManagerProtocolState.WaitForMyCards, false, false, new string[] { this.seat + "'s cards : " }, "{0} ready for cards", this.seat);
                        break;

                    case TableManagerProtocolState.WaitForMyCards:
                        // "North's cards : S J 8 5.H A K T 8.D 7 6.C A K T 3."
                        // "North's cards : S J 8 5.H A K T 8.D.C A K T 7 6 3."
                        // "North's cards : S -.H A K T 8 4 3 2.D.C A K T 7 6 3."
                        string   cardInfo = message.Substring(2 + message.IndexOf(":"));
                        string[] suitInfo = cardInfo.Split('.');
                        for (int s1 = 0; s1 < 4; s1++)
                        {
                            suitInfo[s1] = suitInfo[s1].Trim();
                            Suits s = SuitHelper.FromXML(suitInfo[s1].Substring(0, 1));
                            if (suitInfo[s1].Length > 2)
                            {
                                string cardsInSuit = suitInfo[s1].Substring(2) + " ";
                                if (cardsInSuit.Substring(0, 1) != "-")
                                {
                                    while (cardsInSuit.Length > 1)
                                    {
                                        Ranks rank = Rank.From(cardsInSuit.Substring(0, 1));
                                        this.EventBus.HandleCardPosition(this.seat, s, rank);
                                        cardsInSuit = cardsInSuit.Substring(2);
                                    }
                                }
                            }
                        }

                        //this.EventBus.WaitForEventCompletion();
                        // TM is now expecting a response: either a bid or a 'ready for bid'
                        this.EventBus.HandleCardDealingEnded();

                        break;

                    case TableManagerProtocolState.WaitForOtherBid:
                        if (message.StartsWith("Explain "))
                        {
                            message = message.Substring(8);
                            string[] answer = message.Split(' ');
                            Seats    bidder = SeatsExtensions.FromXML(answer[0]);
                            var      bid    = new Bid(answer[answer.Length - 1], "");

                            this.EventBus.HandleExplanationNeeded(bidder, bid);
                        }
                        else
                        {
                            this.WaitForBridgeEvents = true;
                            ProtocolHelper.HandleProtocolBid(message, this.EventBus);
                        }

                        break;

                    case TableManagerProtocolState.WaitForDummiesCards:
                        //Log.Trace("Client {1} processing dummies cards", message, seat);
                        string   dummiesCards = message.Substring(2 + message.IndexOf(":"));
                        string[] suitInfo2    = dummiesCards.Split('.');
                        for (Suits s = Suits.Spades; s >= Suits.Clubs; s--)
                        {
                            int suit = 3 - (int)s;
                            suitInfo2[suit] = suitInfo2[suit].Trim();
                            if (suitInfo2[suit].Length > 2)
                            {
                                string cardsInSuit = suitInfo2[suit].Substring(2) + " ";
                                if (cardsInSuit.Substring(0, 1) != "-")
                                {
                                    while (cardsInSuit.Length > 1)
                                    {
                                        Ranks rank = Rank.From(cardsInSuit.Substring(0, 1));
                                        this.EventBus.HandleCardPosition(this.CurrentResult.Play.Dummy, s, rank);
                                        cardsInSuit = cardsInSuit.Substring(2);
                                    }
                                }
                            }
                        }

                        this.WaitForProtocolSync = false;
                        this.EventBus.HandleShowDummy(this.CurrentResult.Play.Dummy);
                        break;

                    case TableManagerProtocolState.WaitForLead:
                        this.WaitForProtocolSync = false;
                        break;

                    case TableManagerProtocolState.WaitForCardPlay:
                        if (message.Contains("to lead"))
                        {
                            /// This indicates a timing issue: TM sent a '... to lead' message before TD sent its HandleTrickFinished event
                            /// Wait until I receveive the HandleTrickFinished event
                            Log.Trace(1, "TableManagerClient.ProcessMessage {0}: received 'to lead' before HandleTrickFinished", this.seat);
                            //Debugger.Break();
                        }
                        else
                        {
                            string[] cardPlay = message.Split(' ');
                            Seats    player   = SeatsExtensions.FromXML(cardPlay[0]);
                            Card     card     = new Card(SuitHelper.FromXML(cardPlay[2].Substring(1, 1)), Rank.From(cardPlay[2].Substring(0, 1)));
                            if (player != this.CurrentResult.Play.Dummy)
                            {
                                this.EventBus.HandleCardPosition(player, card.Suit, card.Rank);
                            }
                            this.WaitForBridgeEvents = true;
                            this.EventBus.HandleCardPlayed(player, card.Suit, card.Rank);
                        }

                        break;

                    case TableManagerProtocolState.WaitForDisconnect:
                        this.state = TableManagerProtocolState.Finished;
                        this.EventBus.HandleTournamentStopped();
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Log.Trace(0, "Error while processing message '{0}' in state {1}: {2}", message, state, ex.ToString());
                    throw;
                }
            }
            else
            {           // unexpected message
            }
        }
예제 #9
0
        public void GetSuitTest()
        {
            var rank = SuitHelper.GetSuit(CardSuit.Heart);

            Assert.IsNotNull(rank);
        }