Exemple #1
0
        public TriadGameData StartGame(TriadDeck deckBlue, TriadDeck deckRed, ETriadGameState state)
        {
            TriadGameData gameData = new TriadGameData
            {
                state    = state,
                deckBlue = new TriadDeckInstanceManual(deckBlue),
                deckRed  = new TriadDeckInstanceManual(deckRed)
            };

            currentProgress = 0;

            return(gameData);
        }
Exemple #2
0
        public TriadGameData()
        {
            board           = new TriadCardInstance[boardSize * boardSize];
            typeMods        = new int[Enum.GetNames(typeof(ETriadCardType)).Length];
            state           = ETriadGameState.InProgressBlue;
            resolvedSpecial = ETriadGameSpecialMod.None;
            numCardsPlaced  = 0;
            numRestarts     = 0;
            bDebugRules     = false;

            for (int Idx = 0; Idx < typeMods.Length; Idx++)
            {
                typeMods[Idx] = 0;
            }
        }
Exemple #3
0
        private int GetDeckScore(TriadGameSession solver, TriadDeck testDeck, Random randomGen, int numGamesDiv)
        {
            int deckScore = 0;

            int maxGames = (numGamesToPlay / numGamesDiv) / 2;

            for (int IdxGame = 0; IdxGame < maxGames; IdxGame++)
            {
                TriadGameData   gameDataR  = solver.StartGame(testDeck, npc.Deck, ETriadGameState.InProgressRed);
                ETriadGameState gameRState = solver.SolverPlayRandomGame(gameDataR, randomGen);
                deckScore += (gameRState == ETriadGameState.BlueWins) ? 2 : (gameRState == ETriadGameState.BlueDraw) ? 1 : 0;

                TriadGameData   gameDataB  = solver.StartGame(testDeck, npc.Deck, ETriadGameState.InProgressBlue);
                ETriadGameState gameBState = solver.SolverPlayRandomGame(gameDataB, randomGen);
                deckScore += (gameBState == ETriadGameState.BlueWins) ? 2 : (gameBState == ETriadGameState.BlueDraw) ? 1 : 0;
            }

            return(deckScore);
        }
Exemple #4
0
        public TriadGameResultChance(float winChance, float drawChance)
        {
            this.winChance  = winChance;
            this.drawChance = drawChance;

            if (winChance < 0.25f && drawChance < 0.25f)
            {
                compScore      = winChance / 10.0f;
                expectedResult = ETriadGameState.BlueLost;
            }
            else if (winChance < drawChance)
            {
                compScore      = drawChance;
                expectedResult = ETriadGameState.BlueDraw;
            }
            else
            {
                compScore      = winChance + 10.0f;
                expectedResult = ETriadGameState.BlueWins;
            }
        }
Exemple #5
0
        public TriadGameData(TriadGameData copyFrom)
        {
            board = new TriadCardInstance[copyFrom.board.Length];
            for (int Idx = 0; Idx < board.Length; Idx++)
            {
                board[Idx] = (copyFrom.board[Idx] == null) ? null : new TriadCardInstance(copyFrom.board[Idx]);
            }

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

            deckBlue        = copyFrom.deckBlue.CreateCopy();
            deckRed         = copyFrom.deckRed.CreateCopy();
            state           = copyFrom.state;
            numCardsPlaced  = copyFrom.numCardsPlaced;
            numRestarts     = copyFrom.numRestarts;
            resolvedSpecial = copyFrom.resolvedSpecial;
            // bDebugRules not copied, only first step needs it
        }
Exemple #6
0
        private TriadGameResultChance SolverFindWinningProbability(TriadGameData gameData)
        {
            int numWinningWorkers = 0;
            int numDrawingWorkers = 0;

            Parallel.For(0, solverWorkers, workerIdx =>
                         //for (int workerIdx = 0; workerIdx < solverWorkers; workerIdx++)
            {
                TriadGameData gameDataCopy = new TriadGameData(gameData);
                Random randomGen           = new Random(workerIdx);
                ETriadGameState gameResult = SolverPlayRandomGame(gameDataCopy, randomGen);

                if (gameResult == ETriadGameState.BlueWins)
                {
                    Interlocked.Add(ref numWinningWorkers, 1);
                }
                else if (gameResult == ETriadGameState.BlueDraw)
                {
                    Interlocked.Add(ref numDrawingWorkers, 1);
                }
            });

            return(new TriadGameResultChance((float)numWinningWorkers / (float)solverWorkers, (float)numDrawingWorkers / (float)solverWorkers));
        }
Exemple #7
0
        public void UpdateScreenState(ScreenshotAnalyzer screenReader, bool bDebugMode = false)
        {
            checkBoxDetails_CheckedChanged(null, null);

            if (screenReader.GetCurrentState() != ScreenshotAnalyzer.EState.NoErrors)
            {
                Logger.WriteLine("Capture failed: " + screenReader.GetCurrentState());
                bHasValidMarkerDeck  = false;
                bHasValidMarkerBoard = false;
                UpdateStatusDescription();
                return;
            }

            scanId++;
            labelScanId.Text = "Scan Id: " + scanId;
            Logger.WriteLine("Capture " + labelScanId.Text);

            // multi monitor setup: make sure that overlay and game and on the same monitor
            Rectangle gameWindowRect = screenReader.GetGameWindowRect();

            if (gameWindowRect.Width > 0)
            {
                Rectangle gameScreenBounds = Screen.GetBounds(gameWindowRect);
                Point     centerPt         = new Point((Left + Right) / 2, (Top + Bottom) / 2);
                if (!gameScreenBounds.Contains(centerPt))
                {
                    Location = gameScreenBounds.Location;
                    Size     = gameScreenBounds.Size;
                    bCanAdjustSummaryLocation = true;
                }
            }

            TriadGameScreenMemory.EUpdateFlags updateFlags = TriadGameScreenMemory.EUpdateFlags.None;
            if (screenReader.GetCurrentGameType() == ScreenshotAnalyzer.EGame.TripleTriad)
            {
                // update overlay locations
                if (bCanAdjustSummaryLocation)
                {
                    Rectangle gridRect = screenReader.GetGridRect();
                    if ((gridRect.Width > 0) && (gameWindowRect.Width > 0))
                    {
                        bCanAdjustSummaryLocation = false;
                        screenReader.ConvertToScaledScreen(ref gridRect);

                        UpdateOverlayLocation(gameWindowRect.Left + ((gridRect.Left + gridRect.Right) / 2) - (panelSummary.Width / 2), gameWindowRect.Top + gridRect.Bottom + 50);
                    }
                }

                // solver logic
                updateFlags = screenMemory.OnNewScan(screenReader.currentTriadGame, npc);
                if (updateFlags != TriadGameScreenMemory.EUpdateFlags.None)
                {
                    int markerDeckPos  = -1;
                    int markerBoardPos = -1;

                    FindNextMove(out markerDeckPos, out markerBoardPos, out TriadGameResultChance bestChance);
                    ETriadGameState expectedResult = bestChance.expectedResult;

                    TriadCard suggestedCard = screenMemory.deckBlue.GetCard(markerDeckPos);
                    Logger.WriteLine("  suggested move: [" + markerBoardPos + "] " + ETriadCardOwner.Blue + " " + (suggestedCard != null ? suggestedCard.Name : "??") + " (expected: " + expectedResult + ")");

                    bHasValidMarkerDeck  = false;
                    bHasValidMarkerBoard = false;
                    if (markerDeckPos >= 0 && markerBoardPos >= 0)
                    {
                        try
                        {
                            Rectangle rectDeckPos  = screenReader.GetBlueCardRect(markerDeckPos);
                            Rectangle rectBoardPos = screenReader.GetBoardCardRect(markerBoardPos);
                            rectDeckPos.Offset(gameWindowRect.Location);
                            rectBoardPos.Offset(gameWindowRect.Location);

                            screenReader.ConvertToScaledScreen(ref rectDeckPos);
                            screenReader.ConvertToScaledScreen(ref rectBoardPos);
                            rectDeckPos.Inflate(10, 10);
                            rectBoardPos.Inflate(10, 10);

                            panelMarkerDeck.Bounds     = rectDeckPos;
                            panelMarkerBoard.Bounds    = rectBoardPos;
                            panelMarkerBoard.BackColor =
                                (expectedResult == ETriadGameState.BlueWins) ? Color.Lime :
                                (expectedResult == ETriadGameState.BlueDraw) ? Color.Gold :
                                Color.Red;

                            bHasValidMarkerDeck  = true;
                            bHasValidMarkerBoard = true;
                        }
                        catch (Exception) { }
                    }
                }
            }
            else if (screenReader.GetCurrentGameType() == ScreenshotAnalyzer.EGame.MiniCactpot)
            {
                // update overlay locations
                if (bCanAdjustSummaryLocation)
                {
                    Rectangle boardRect = screenReader.GetCactpotBoardRect();
                    if ((boardRect.Width > 0) && (gameWindowRect.Width > 0))
                    {
                        screenReader.ConvertToScaledScreen(ref boardRect);

                        bCanAdjustSummaryLocation = false;
                        UpdateOverlayLocation(gameWindowRect.Left + ((boardRect.Left + boardRect.Right) / 2) - (panelSummary.Width / 2), gameWindowRect.Top + boardRect.Bottom + 50);
                    }
                }

                // solver logic
                if (screenReader.currentCactpotGame.numRevealed > 3)
                {
                    bHasValidMarkerBoard = false;

                    CactpotGame.FindBestLine(screenReader.currentCactpotGame.board, out int fromIdx, out int toIdx);
                    Logger.WriteLine("  suggested line: [" + fromIdx + "] -> [" + toIdx + "]");

                    if (fromIdx >= 0 && toIdx >= 0)
                    {
                        Rectangle fromBox = screenReader.GetCactpotCircleBox(fromIdx);
                        Rectangle toBox   = screenReader.GetCactpotCircleBox(toIdx);
                        fromBox.Offset(gameWindowRect.Location);
                        toBox.Offset(gameWindowRect.Location);
                        screenReader.ConvertToScaledScreen(ref fromBox);
                        screenReader.ConvertToScaledScreen(ref toBox);
                        fromBox.Inflate(10, 10);
                        toBox.Inflate(10, 10);

                        ShowCactpotLine(fromBox, toBox);
                    }
                }
                else
                {
                    int markerPos = CactpotGame.FindNextCircle(screenReader.currentCactpotGame.board);
                    Logger.WriteLine("  suggested move: [" + markerPos + "]");

                    bHasValidMarkerBoard = (markerPos >= 0);
                    if (bHasValidMarkerBoard)
                    {
                        Rectangle rectBoardPos = screenReader.GetCactpotCircleBox(markerPos);
                        rectBoardPos.Offset(gameWindowRect.Location);
                        screenReader.ConvertToScaledScreen(ref rectBoardPos);
                        rectBoardPos.Inflate(10, 10);

                        panelMarkerBoard.Bounds    = rectBoardPos;
                        panelMarkerBoard.BackColor = Color.Lime;
                    }
                }

                for (int Idx = 0; Idx < screenReader.currentCactpotGame.board.Length; Idx++)
                {
                    int numInCircle = screenReader.currentCactpotGame.board[Idx];
                    cactpotBoard[Idx].Text = (numInCircle == 0) ? "" : numInCircle.ToString();
                }
            }

            // update what's needed
            if ((updateFlags & TriadGameScreenMemory.EUpdateFlags.Modifiers) != TriadGameScreenMemory.EUpdateFlags.None)
            {
                string desc = "";
                foreach (TriadGameModifier mod in screenMemory.gameSession.modifiers)
                {
                    desc += mod.ToString() + ", ";
                }

                labelRules.Text = "Rules: " + ((desc.Length > 2) ? desc.Remove(desc.Length - 2, 2) : "unknown");
            }

            if ((updateFlags & TriadGameScreenMemory.EUpdateFlags.BlueDeck) != TriadGameScreenMemory.EUpdateFlags.None)
            {
                deckCtrlBlue.SetDeck(screenReader.currentTriadGame.blueDeck);
            }

            if ((updateFlags & TriadGameScreenMemory.EUpdateFlags.RedDeck) != TriadGameScreenMemory.EUpdateFlags.None)
            {
                deckCtrlRed.SetDeck(screenReader.currentTriadGame.redDeck);
                UpdateRedDeckDetails(screenMemory.deckRed);
            }

            if ((updateFlags & TriadGameScreenMemory.EUpdateFlags.Board) != TriadGameScreenMemory.EUpdateFlags.None)
            {
                for (int Idx = 0; Idx < screenMemory.gameState.board.Length; Idx++)
                {
                    boardControls[Idx].SetCard(screenMemory.gameState.board[Idx]);
                }
            }

            if ((updateFlags & TriadGameScreenMemory.EUpdateFlags.SwapWarning) != TriadGameScreenMemory.EUpdateFlags.None)
            {
                Rectangle ruleRect = screenReader.GetRuleBoxRect();
                if (gameWindowRect.Width > 0 && ruleRect.Width > 0)
                {
                    Rectangle warningBounds = new Rectangle(ruleRect.Left, ruleRect.Top - panelSwapWarning.Height - 10, 0, 0);
                    warningBounds.Offset(gameWindowRect.Location);
                    screenReader.ConvertToScaledScreen(ref warningBounds);

                    panelSwapWarning.Location = warningBounds.Location;
                    panelSwapWarning.Visible  = true;
                    timerHideSwapWarning.Stop();
                    timerHideSwapWarning.Start();
                }
            }

            if ((updateFlags & TriadGameScreenMemory.EUpdateFlags.SwapHints) != TriadGameScreenMemory.EUpdateFlags.None)
            {
                Rectangle rectDeckPos = screenReader.GetBlueCardRect(screenMemory.swappedBlueCardIdx);
                rectDeckPos.Offset(gameWindowRect.Location);
                screenReader.ConvertToScaledScreen(ref rectDeckPos);
                rectDeckPos.Inflate(-10, -10);

                panelMarkerSwap.Bounds  = rectDeckPos;
                panelMarkerSwap.Visible = true;
            }

            bCanStopTurnScan = false;
            bCanAutoCapture  = false;

            timerFadeMarkers.Enabled = bHasValidMarkerDeck || bHasValidMarkerBoard || panelMarkerSwap.Visible || panelMarkerLine.Visible;
            panelMarkerDeck.Visible  = bHasValidMarkerDeck;
            panelMarkerBoard.Visible = bHasValidMarkerBoard;

            timerTurnScan.Enabled = true;
            timerTurnScan_Tick(null, null);
        }