コード例 #1
0
ファイル: TriadGame.cs プロジェクト: MgAl2O4/FFTriadBuddy
        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 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 && forcedBlueCard != null)
            {
                int forcedBlueCardIdx = useDeck.GetCardIndex(forcedBlueCard);
                availCardsMask = 1 << forcedBlueCardIdx;
            }
            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);
        }