Beispiel #1
0
        private EUpdateFlags DetectSwapOnGameStart()
        {
            EUpdateFlags updateFlags = EUpdateFlags.None;

            deckRed.SetSwappedCard(null, -1);

            for (int Idx = 0; Idx < deckBlue.cards.Length; Idx++)
            {
                if (deckBlue.cards[Idx] == null)
                {
                    Logger.WriteLine("DetectSwapOnGameStart: found empty blue card, skipping");
                    return(updateFlags);
                }
            }

            bool bDetectedSuddenDeath = bHasRestartRule && IsSuddenDeathRestart(deckRed);

            if (bDetectedSuddenDeath)
            {
                Logger.WriteLine(">> ignore swap checks");
                return(updateFlags);
            }

            // store initial blue deck
            {
                if (blueDeckHistory.Count > 10)
                {
                    blueDeckHistory.RemoveAt(0);
                }

                TriadCard[] copyCards = new TriadCard[deckBlue.cards.Length];
                Array.Copy(deckBlue.cards, copyCards, copyCards.Length);

                blueDeckHistory.Add(copyCards);
                Logger.WriteLine("Storing blue deck at[" + blueDeckHistory.Count + "]: " + deckBlue);
            }

            int       blueSwappedCardIdx = -1;
            int       redSwappedCardIdx  = -1;
            TriadCard blueSwappedCard    = null;
            bool      bHasSwappedCard    = FindSwappedCardVisible(deckBlue.cards, gameState.board, deckRed, out blueSwappedCardIdx, out redSwappedCardIdx, out blueSwappedCard);

            if (!bHasSwappedCard)
            {
                bHasSwappedCard = FindSwappedCard(deckBlue.cards, playerDeckPattern, deckRed, out blueSwappedCardIdx, out redSwappedCardIdx, out blueSwappedCard);
                if (!bHasSwappedCard)
                {
                    TriadCard[] commonCards = FindCommonCards(blueDeckHistory);
                    if (commonCards != null)
                    {
                        bHasSwappedCard = FindSwappedCard(deckBlue.cards, commonCards, deckRed, out blueSwappedCardIdx, out redSwappedCardIdx, out blueSwappedCard);
                    }
                }
            }

            if (bHasSwappedCard)
            {
                // deck blue doesn't need updates, it already has all cards visible
                // deck red needs to know which card is not longer available and which one is new
                deckRed.SetSwappedCard(blueSwappedCard, redSwappedCardIdx);
                swappedBlueCardIdx = blueSwappedCardIdx;
                updateFlags       |= EUpdateFlags.SwapHints;
            }
            else
            {
                swappedBlueCardIdx = -1;
                updateFlags       |= EUpdateFlags.SwapWarning;
            }

            return(updateFlags);
        }
Beispiel #2
0
        public EUpdateFlags OnNewScan(ScreenshotAnalyzer.GameStateTriad screenGame, TriadNpc selectedNpc)
        {
            EUpdateFlags updateFlags = EUpdateFlags.None;

            // check if game from screenshot can be continuation of cached one
            // is current state a continuation of last one?
            // ideally each blue turn is a capture until game resets = any card disappears from board
            // guess work for adding sense of persistence to screen decks
            bool bContinuesPrevState = (deckRed.deck == selectedNpc.Deck) && (lastScanNpc == selectedNpc);

            if (bContinuesPrevState)
            {
                for (int Idx = 0; Idx < gameState.board.Length; Idx++)
                {
                    bool bWasNull = gameState.board[Idx] == null;
                    bool bIsNull  = screenGame.board[Idx] == null;

                    if (!bWasNull && bIsNull)
                    {
                        bContinuesPrevState = false;
                        Logger.WriteLine("Can't continue previous state: board[" + Idx + "] disappeared ");
                    }
                }
            }
            else
            {
                Logger.WriteLine("Can't continue previous state: npc changed");
            }

            bool bModsChanged = (gameSession.modifiers.Count != screenGame.mods.Count) || !gameSession.modifiers.All(screenGame.mods.Contains);

            if (bModsChanged)
            {
                bHasSwapRule    = false;
                bHasRestartRule = false;
                bHasOpenRule    = false;
                gameSession.modifiers.Clear();
                gameSession.modifiers.AddRange(screenGame.mods);
                gameSession.specialRules = ETriadGameSpecialMod.None;
                gameSession.modFeatures  = TriadGameModifier.EFeature.None;
                foreach (TriadGameModifier mod in gameSession.modifiers)
                {
                    gameSession.modFeatures |= mod.GetFeatures();

                    // swap rule is bad for screenshot based analysis, no good way of telling what is out of place
                    if (mod is TriadGameModifierSwap)
                    {
                        bHasSwapRule = true;
                    }
                    else if (mod is TriadGameModifierSuddenDeath)
                    {
                        bHasRestartRule = true;
                    }
                    else if (mod is TriadGameModifierAllOpen)
                    {
                        bHasOpenRule = true;
                    }
                }

                updateFlags        |= EUpdateFlags.Modifiers;
                bContinuesPrevState = false;
                Logger.WriteLine("Can't continue previous state: modifiers changed");

                deckRed.SetSwappedCard(null, -1);
            }

            // wipe blue deck history when playing with new npc (or region modifiers have changed)
            bool bRemoveBlueHistory = bModsChanged || (lastScanNpc != selectedNpc);

            if (bRemoveBlueHistory)
            {
                blueDeckHistory.Clear();
                if (bHasSwapRule)
                {
                    Logger.WriteLine("Blue deck history cleared");
                }
            }

            bool bRedDeckChanged = (lastScanNpc != selectedNpc) || !IsDeckMatching(deckRed, screenGame.redDeck) || (deckRed.deck != selectedNpc.Deck);

            if (bRedDeckChanged)
            {
                updateFlags |= EUpdateFlags.RedDeck;
                deckRed.deck = selectedNpc.Deck;
                lastScanNpc  = selectedNpc;

                // needs to happen before any changed to board (gameState)
                UpdateAvailableRedCards(deckRed, screenGame.redDeck, screenGame.blueDeck,
                                        screenGame.board, deckBlue.cards, gameState.board, bContinuesPrevState);
            }

            bool bBlueDeckChanged = !IsDeckMatching(deckBlue, screenGame.blueDeck);

            if (bBlueDeckChanged)
            {
                updateFlags |= EUpdateFlags.BlueDeck;
                deckBlue.UpdateAvailableCards(screenGame.blueDeck);
            }

            gameSession.forcedBlueCard = screenGame.forcedBlueCard;
            gameState.state            = ETriadGameState.InProgressBlue;
            gameState.deckBlue         = deckBlue;
            gameState.deckRed          = deckRed;
            gameState.numCardsPlaced   = 0;

            bool bBoardChanged = false;

            for (int Idx = 0; Idx < gameState.board.Length; Idx++)
            {
                bool bWasNull = gameState.board[Idx] == null;
                bool bIsNull  = screenGame.board[Idx] == null;

                if (bWasNull && !bIsNull)
                {
                    bBoardChanged        = true;
                    gameState.board[Idx] = new TriadCardInstance(screenGame.board[Idx], screenGame.boardOwner[Idx]);
                    Logger.WriteLine("  board update: [" + Idx + "] " + gameState.board[Idx].owner + ": " + gameState.board[Idx].card.Name);
                }
                else if (!bWasNull && bIsNull)
                {
                    bBoardChanged        = true;
                    gameState.board[Idx] = null;
                }
                else if (!bWasNull && !bIsNull)
                {
                    if (gameState.board[Idx].owner != screenGame.boardOwner[Idx] ||
                        gameState.board[Idx].card != screenGame.board[Idx])
                    {
                        bBoardChanged        = true;
                        gameState.board[Idx] = new TriadCardInstance(screenGame.board[Idx], screenGame.boardOwner[Idx]);
                    }
                }

                gameState.numCardsPlaced += (gameState.board[Idx] != null) ? 1 : 0;
            }

            if (bBoardChanged)
            {
                updateFlags |= EUpdateFlags.Board;

                foreach (TriadGameModifier mod in gameSession.modifiers)
                {
                    mod.OnScreenUpdate(gameState);
                }
            }

            // start of game, do additional checks when swap rule is active
            if (bHasSwapRule && gameState.numCardsPlaced <= 1)
            {
                updateFlags |= DetectSwapOnGameStart();
            }

            Logger.WriteLine("OnNewScan> board:" + (bBoardChanged ? "changed" : "same") +
                             ", blue:" + (bBlueDeckChanged ? "changed" : "same") +
                             ", red:" + (bRedDeckChanged ? "changed" : "same") +
                             ", mods:" + (bModsChanged ? "changed" : "same") +
                             ", continuePrev:" + bContinuesPrevState +
                             " => " + ((updateFlags != EUpdateFlags.None) ? ("UPDATE[" + updateFlags + "]") : "skip"));

            return(updateFlags);
        }