示例#1
0
        public bool PlaceCard(TriadGameData gameData, TriadCard card, ETriadCardOwner owner, int boardPos)
        {
            TriadDeckInstance useDeck = (owner == ETriadCardOwner.Blue) ? gameData.deckBlue : gameData.deckRed;
            int cardIdx = useDeck.GetCardIndex(card);

            return(PlaceCard(gameData, cardIdx, useDeck, owner, boardPos));
        }
示例#2
0
        public DeckCtrl()
        {
            drawMode                 = ECardDrawMode.Detailed;
            allowRearrange           = true;
            enableHitTest            = true;
            enableLocking            = false;
            ignoreDragOnContextClose = false;
            clickAction              = EDeckCtrlAction.Pick;
            deckOwner                = ETriadCardOwner.Blue;

            cardTileSize    = 50;
            cardTileSpacing = 6;

            InitializeComponent();

            toolStripMenuOnlyOwned.Checked = true;
        }
示例#3
0
            public void Load(JsonParser.ObjectValue configOb)
            {
                string ownerStr = configOb["player"] as JsonParser.StringValue;

                owner = (ownerStr == "blue") ? ETriadCardOwner.Blue : (ownerStr == "red") ? ETriadCardOwner.Red : ETriadCardOwner.Unknown;

                boardPos = configOb["pos"] as JsonParser.IntValue;

                if (configOb.entries.ContainsKey("board"))
                {
                    string boardCode = configOb["board"] as JsonParser.StringValue;
                    boardCode = boardCode.Replace(" ", "");

                    expectedState = new ETriadCardOwner[9];
                    for (int idx = 0; idx < expectedState.Length; idx++)
                    {
                        expectedState[idx] = (boardCode[idx] == 'R') ? ETriadCardOwner.Red : (boardCode[idx] == 'B') ? ETriadCardOwner.Blue : ETriadCardOwner.Unknown;
                    }
                }

                var cardName = configOb["card"] as JsonParser.StringValue;

                if (cardName != null)
                {
                    card = TriadCardDB.Get().Find(cardName);
                }
                else
                {
                    var cardSides = configOb["card"] as JsonParser.ArrayValue;

                    int numU = cardSides[0] as JsonParser.IntValue;
                    int numL = cardSides[1] as JsonParser.IntValue;
                    int numD = cardSides[2] as JsonParser.IntValue;
                    int numR = cardSides[3] as JsonParser.IntValue;

                    card = TriadCardDB.Get().Find(numU, numL, numD, numR);
                }
            }
示例#4
0
        public bool SolverFindBestMove(TriadGameData gameData, out int boardPos, out TriadCard card, out TriadGameResultChance probabilities)
        {
            bool bResult = false;

            card            = null;
            boardPos        = -1;
            currentProgress = 0;

            string namePrefix = string.IsNullOrEmpty(solverName) ? "" : ("[" + solverName + "] ");

            // prepare available board data
            int availBoardMask = 0;
            int numAvailBoard  = 0;

            for (int Idx = 0; Idx < gameData.board.Length; Idx++)
            {
                if (gameData.board[Idx] == null)
                {
                    availBoardMask |= (1 << Idx);
                    numAvailBoard++;
                }
            }

            // prepare available cards data
            TriadDeckInstance useDeck   = (gameData.state == ETriadGameState.InProgressBlue) ? gameData.deckBlue : gameData.deckRed;
            ETriadCardOwner   turnOwner = (gameData.state == ETriadGameState.InProgressBlue) ? ETriadCardOwner.Blue : ETriadCardOwner.Red;
            int availCardsMask          = 0;

            if (gameData.state == ETriadGameState.InProgressBlue && gameData.forcedCardIdx >= 0)
            {
                availCardsMask = 1 << gameData.forcedCardIdx;
            }
            else
            {
                availCardsMask = useDeck.availableCardMask;
            }

            if ((modFeatures & TriadGameModifier.EFeature.FilterNext) != 0)
            {
                foreach (TriadGameModifier mod in modifiers)
                {
                    mod.OnFilterNextCards(gameData, ref availCardsMask);
                }
            }

            int numAvailCards = 0;

            for (int Idx = 0; Idx < TriadDeckInstance.maxAvailableCards; Idx++)
            {
                numAvailCards += ((availCardsMask & (1 << Idx)) != 0) ? 1 : 0;
            }

            // check all combinations
            if ((numAvailCards > 0) && (numAvailBoard > 0))
            {
                int numCombinations            = numAvailCards * numAvailBoard;
                TriadGameResultChance bestProb = new TriadGameResultChance(-1.0f, 0);

                int cardProgressCounter = 0;
                for (int cardIdx = 0; cardIdx < TriadDeckInstance.maxAvailableCards; cardIdx++)
                {
                    bool bCardNotAvailable = (availCardsMask & (1 << cardIdx)) == 0;
                    if (bCardNotAvailable)
                    {
                        continue;
                    }

                    currentProgress = 100 * cardProgressCounter / numAvailCards;
                    cardProgressCounter++;

                    for (int boardIdx = 0; boardIdx < gameData.board.Length; boardIdx++)
                    {
                        bool bBoardNotAvailable = (availBoardMask & (1 << boardIdx)) == 0;
                        if (bBoardNotAvailable)
                        {
                            continue;
                        }

                        TriadGameData gameDataCopy = new TriadGameData(gameData);
                        bool          bPlaced      = PlaceCard(gameDataCopy, cardIdx, useDeck, turnOwner, boardIdx);
                        if (bPlaced)
                        {
                            TriadGameResultChance gameProb = SolverFindWinningProbability(gameDataCopy);
                            if (gameProb.IsBetterThan(bestProb))
                            {
                                bestProb = gameProb;
                                card     = useDeck.GetCard(cardIdx);
                                boardPos = boardIdx;
                                bResult  = true;
                            }
                        }
                    }
                }

                probabilities = bestProb;
                Logger.WriteLine(namePrefix + "Solver win:" + bestProb.winChance.ToString("P2") + " (draw:" + bestProb.drawChance.ToString("P2") +
                                 "), blue[" + gameData.deckBlue + "], red[" + gameData.deckRed + "], turn:" + turnOwner + ", availBoard:" + numAvailBoard +
                                 " (" + availBoardMask.ToString("x") + ") availCards:" + numAvailCards + " (" + (useDeck == gameData.deckBlue ? "B" : "R") + ":" + availCardsMask.ToString("x") + ")");
            }
            else
            {
                probabilities = new TriadGameResultChance(0, 0);
                Logger.WriteLine(namePrefix + "Can't find move! availSpots:" + numAvailBoard + " (" + availBoardMask.ToString("x") +
                                 ") availCards:" + numAvailCards + " (" + (useDeck == gameData.deckBlue ? "B" : "R") + ":" + availCardsMask.ToString("x") + ")");
            }

            return(bResult);
        }
示例#5
0
        public bool PlaceCard(TriadGameData gameData, int cardIdx, TriadDeckInstance cardDeck, ETriadCardOwner owner, int boardPos)
        {
            bool bResult = false;

            bool bIsAllowedOwner =
                ((owner == ETriadCardOwner.Blue) && (gameData.state == ETriadGameState.InProgressBlue)) ||
                ((owner == ETriadCardOwner.Red) && (gameData.state == ETriadGameState.InProgressRed));

            TriadCard card = cardDeck.GetCard(cardIdx);

            if (bIsAllowedOwner && (boardPos >= 0) && (gameData.board[boardPos] == null) && (card != null))
            {
                gameData.board[boardPos] = new TriadCardInstance(card, owner);
                gameData.numCardsPlaced++;

                if (owner == ETriadCardOwner.Blue)
                {
                    gameData.deckBlue.OnCardPlacedFast(cardIdx);
                    gameData.state = ETriadGameState.InProgressRed;
                }
                else
                {
                    gameData.deckRed.OnCardPlacedFast(cardIdx);
                    gameData.state = ETriadGameState.InProgressBlue;
                }
                bResult = true;

                bool bAllowCombo = false;
                if ((modFeatures & TriadGameModifier.EFeature.CardPlaced) != 0)
                {
                    foreach (TriadGameModifier mod in modifiers)
                    {
                        mod.OnCardPlaced(gameData, boardPos);
                        bAllowCombo = bAllowCombo || mod.AllowsCombo();
                    }
                }

                List <int> comboList    = new List <int>();
                int        comboCounter = 0;
                CheckCaptures(gameData, boardPos, comboList, comboCounter);

                while (bAllowCombo && comboList.Count > 0)
                {
                    if (gameData.bDebugRules)
                    {
                        Logger.WriteLine(">> combo step: {0}", string.Join(",", comboList));
                    }

                    List <int> nextCombo = new List <int>();
                    comboCounter++;
                    foreach (int pos in comboList)
                    {
                        CheckCaptures(gameData, pos, nextCombo, comboCounter);
                    }

                    comboList = nextCombo;
                }

                if ((modFeatures & TriadGameModifier.EFeature.PostCapture) != 0)
                {
                    foreach (TriadGameModifier mod in modifiers)
                    {
                        mod.OnPostCaptures(gameData, boardPos);
                    }
                }

                if (gameData.numCardsPlaced == gameData.board.Length)
                {
                    OnAllCardsPlaced(gameData);
                }
            }

            return(bResult);
        }
示例#6
0
        public bool PlaceCard(TriadGameData gameData, int cardIdx, TriadDeckInstance cardDeck, ETriadCardOwner owner, int boardPos)
        {
            bool bResult = false;

            bool bIsAllowedOwner =
                ((owner == ETriadCardOwner.Blue) && (gameData.state == ETriadGameState.InProgressBlue)) ||
                ((owner == ETriadCardOwner.Red) && (gameData.state == ETriadGameState.InProgressRed));

            TriadCard card = cardDeck.GetCard(cardIdx);

            if (bIsAllowedOwner && (boardPos >= 0) && (gameData.board[boardPos] == null) && (card != null))
            {
#if DEBUG
                Stopwatch timer = new Stopwatch();
                timer.Start();
#endif // DEBUG

                gameData.board[boardPos] = new TriadCardInstance(card, owner);
                gameData.numCardsPlaced++;

                if (owner == ETriadCardOwner.Blue)
                {
                    gameData.deckBlue.OnCardPlacedFast(cardIdx);
                    gameData.state = ETriadGameState.InProgressRed;
                }
                else
                {
                    gameData.deckRed.OnCardPlacedFast(cardIdx);
                    gameData.state = ETriadGameState.InProgressBlue;
                }
#if DEBUG
                perfStats.PlaceCardOnPlaced += timer.ElapsedTicks;
                timer.Restart();
#endif // DEBUG
                bResult = true;

                bool bAllowCombo = false;
                if ((modFeatures & TriadGameModifier.EFeature.CardPlaced) != 0)
                {
                    foreach (TriadGameModifier mod in modifiers)
                    {
                        mod.OnCardPlaced(gameData, boardPos);
                        bAllowCombo = bAllowCombo || mod.AllowsCombo();
                    }
                }
#if DEBUG
                perfStats.PlaceCardOnPlacedMods += timer.ElapsedTicks;
                timer.Restart();
#endif // DEBUG

                List <int> comboList    = new List <int>();
                int        comboCounter = 0;
                CheckCaptures(gameData, boardPos, comboList, comboCounter);
#if DEBUG
                perfStats.PlaceCardCaptures += timer.ElapsedTicks;
                timer.Restart();
#endif // DEBUG

                while (bAllowCombo && comboList.Count > 0)
                {
                    List <int> nextCombo = new List <int>();
                    comboCounter++;
                    foreach (int pos in comboList)
                    {
                        CheckCaptures(gameData, pos, nextCombo, comboCounter);
                    }

                    comboList = nextCombo;
                }
#if DEBUG
                perfStats.PlaceCardCapturesCombo += timer.ElapsedTicks;
                timer.Restart();
#endif // DEBUG

                if ((modFeatures & TriadGameModifier.EFeature.PostCapture) != 0)
                {
                    foreach (TriadGameModifier mod in modifiers)
                    {
                        mod.OnPostCaptures(gameData, boardPos);
                    }
                }
#if DEBUG
                perfStats.PlaceCardPostCaptures += timer.ElapsedTicks;
                timer.Restart();
#endif // DEBUG

                if (gameData.numCardsPlaced == gameData.board.Length)
                {
                    OnAllCardsPlaced(gameData);
                }
#if DEBUG
                timer.Stop();
                perfStats.PlaceCardAllPlaced += timer.ElapsedTicks;
#endif // DEBUG
            }

            return(bResult);
        }
示例#7
0
 public TriadCardInstance(TriadCardInstance copyFrom)
 {
     card          = copyFrom.card;
     owner         = copyFrom.owner;
     scoreModifier = copyFrom.scoreModifier;
 }
示例#8
0
 public TriadCardInstance(TriadCard card, ETriadCardOwner owner)
 {
     this.card     = card;
     this.owner    = owner;
     scoreModifier = 0;
 }
示例#9
0
        public override void OnAllCardsPlaced(TriadGameData gameData)
        {
            if (gameData.state == ETriadGameState.BlueDraw && gameData.numRestarts < 3)
            {
                // implement this rule only for manual mode, screen captures get everything automatically
                TriadDeckInstanceManual deckBlueEx = gameData.deckBlue as TriadDeckInstanceManual;
                TriadDeckInstanceManual deckRedEx  = gameData.deckRed as TriadDeckInstanceManual;
                if (deckBlueEx != null && deckRedEx != null)
                {
                    List <TriadCard> blueCards       = new List <TriadCard>();
                    List <TriadCard> redCards        = new List <TriadCard>();
                    List <TriadCard> redUnknownCards = new List <TriadCard>();
                    string           redCardsDebug   = "";

                    for (int Idx = 0; Idx < gameData.board.Length; Idx++)
                    {
                        if (gameData.board[Idx].owner == ETriadCardOwner.Blue)
                        {
                            blueCards.Add(gameData.board[Idx].card);
                        }
                        else
                        {
                            redCards.Add(gameData.board[Idx].card);
                        }

                        gameData.board[Idx] = null;
                    }

                    if (deckBlueEx.numPlaced < deckRedEx.numPlaced)
                    {
                        // blue has cards on hand, all known
                        for (int Idx = 0; Idx < deckBlueEx.deck.knownCards.Count; Idx++)
                        {
                            bool bIsAvailable = !deckBlueEx.IsPlaced(Idx);
                            if (bIsAvailable)
                            {
                                blueCards.Add(deckBlueEx.deck.knownCards[Idx]);
                                break;
                            }
                        }

                        gameData.state = ETriadGameState.InProgressBlue;
                    }
                    else
                    {
                        // red has cards on hand, check known vs unknown
                        for (int Idx = 0; Idx < deckRedEx.deck.knownCards.Count; Idx++)
                        {
                            bool bIsAvailable = !deckRedEx.IsPlaced(Idx);
                            if (bIsAvailable)
                            {
                                redCards.Add(deckRedEx.deck.knownCards[Idx]);
                                redCardsDebug += deckRedEx.deck.knownCards[Idx].Name + ":K, ";
                                break;
                            }
                        }

                        if (redCards.Count < blueCards.Count)
                        {
                            for (int Idx = 0; Idx < deckRedEx.deck.unknownCardPool.Count; Idx++)
                            {
                                int  cardIdx      = Idx + deckRedEx.deck.knownCards.Count;
                                bool bIsAvailable = !deckRedEx.IsPlaced(cardIdx);
                                if (bIsAvailable)
                                {
                                    redUnknownCards.Add(deckRedEx.deck.unknownCardPool[Idx]);
                                    redCardsDebug += deckRedEx.deck.unknownCardPool[Idx].Name + ":U, ";
                                }
                            }
                        }

                        gameData.state = ETriadGameState.InProgressRed;
                    }

                    gameData.deckBlue       = new TriadDeckInstanceManual(new TriadDeck(blueCards));
                    gameData.deckRed        = new TriadDeckInstanceManual(new TriadDeck(redCards, redUnknownCards));
                    gameData.numCardsPlaced = 0;
                    gameData.numRestarts++;

                    for (int Idx = 0; Idx < gameData.typeMods.Length; Idx++)
                    {
                        gameData.typeMods[Idx] = 0;
                    }

                    if (gameData.bDebugRules)
                    {
                        redCardsDebug = (redCardsDebug.Length > 0) ? redCardsDebug.Remove(redCardsDebug.Length - 2, 2) : "(board only)";
                        ETriadCardOwner nextTurnOwner = (gameData.state == ETriadGameState.InProgressBlue) ? ETriadCardOwner.Blue : ETriadCardOwner.Red;
                        Logger.WriteLine(">> " + RuleName + "! next turn:" + nextTurnOwner + ", red:" + redCardsDebug);
                    }
                }
            }
        }