Exemple #1
0
        public void UpdatePlayerDeckForNpc(TriadNpc npc, TriadDeck deck)
        {
            if (npc != null && deck != null && deck.knownCards.Count == 5)
            {
                bool bIsStarterDeck = true;
                for (int Idx = 0; Idx < starterCards.Length; Idx++)
                {
                    bIsStarterDeck = bIsStarterDeck && (starterCards[Idx] == deck.knownCards[Idx]);
                }

                if (!bIsStarterDeck)
                {
                    bool bChanged = true;
                    if (lastDeck.ContainsKey(npc))
                    {
                        if (lastDeck[npc].Equals(deck))
                        {
                            bChanged = false;
                        }
                        else
                        {
                            lastDeck.Remove(npc);
                        }
                    }

                    if (bChanged)
                    {
                        TriadCard[] deckCardsCopy = deck.knownCards.ToArray();
                        lastDeck.Add(npc, new TriadDeck(deckCardsCopy));
                        MarkDirty();
                    }
                }
            }
        }
Exemple #2
0
 public TriadDeckInstanceManual(TriadDeck deck)
 {
     this.deck         = deck;
     numUnknownPlaced  = 0;
     numPlaced         = 0;
     availableCardMask = (1 << (deck.knownCards.Count + deck.unknownCardPool.Count)) - 1;
 }
Exemple #3
0
        // special logic, covered by GUI
        public static void StaticSwapCards(TriadGameData gameData, TriadCard swapFromBlue, int blueSlotIdx, TriadCard swapFromRed, int redSlotIdx)
        {
            // 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)
            {
                bool bIsRedFromKnown = redSlotIdx < deckRedEx.deck.knownCards.Count;
                if (gameData.bDebugRules)
                {
                    TriadGameModifierSwap DummyOb = new TriadGameModifierSwap();
                    Logger.WriteLine(">> " + DummyOb.RuleName + "! blue[" + blueSlotIdx + "]:" + swapFromBlue.Name +
                                     " <-> red[" + redSlotIdx + (bIsRedFromKnown ? "" : ":Opt") + "]:" + swapFromRed.Name);
                }

                TriadDeck blueDeckSwapped = new TriadDeck(deckBlueEx.deck.knownCards, deckBlueEx.deck.unknownCardPool);
                TriadDeck redDeckSwapped  = new TriadDeck(deckRedEx.deck.knownCards, deckRedEx.deck.unknownCardPool);

                // ignore order in red deck
                redDeckSwapped.knownCards.Add(swapFromBlue);
                redDeckSwapped.knownCards.Remove(swapFromRed);
                redDeckSwapped.unknownCardPool.Remove(swapFromRed);

                // preserve order in blue deck
                blueDeckSwapped.knownCards[blueSlotIdx] = swapFromRed;

                gameData.deckBlue = new TriadDeckInstanceManual(blueDeckSwapped);
                gameData.deckRed  = new TriadDeckInstanceManual(redDeckSwapped);
            }
        }
Exemple #4
0
        public static void RunSolverStressTest()
        {
            int numIterations = 1000 * 1000;

            Logger.WriteLine("Solver testing start, numIterations:" + numIterations);

            Stopwatch timer = new Stopwatch();

            timer.Start();

            TriadDeck testDeck   = new TriadDeck(new int[] { 10, 20, 30, 40, 50 });
            TriadNpc  testNpc    = TriadNpcDB.Get().Find("Garima");
            Random    randStream = new Random();

            TriadGameSession solver = new TriadGameSession();

            solver.modifiers.AddRange(testNpc.Rules);
            solver.UpdateSpecialRules();

            for (int Idx = 0; Idx < numIterations; Idx++)
            {
                TriadGameData testData    = solver.StartGame(testDeck, testNpc.Deck, ETriadGameState.InProgressBlue);
                Random        sessionRand = new Random(randStream.Next());
                solver.SolverPlayRandomGame(testData, sessionRand);
            }

            timer.Stop();
            Logger.WriteLine("Solver testing finished, time taken:" + timer.ElapsedMilliseconds + "ms");

            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
        }
Exemple #5
0
        public bool Equals(TriadDeck otherDeck)
        {
            if ((knownCards.Count != otherDeck.knownCards.Count) ||
                (unknownCardPool.Count != otherDeck.unknownCardPool.Count))
            {
                return(false);
            }

            for (int Idx = 0; Idx < knownCards.Count; Idx++)
            {
                if (!knownCards[Idx].Equals(otherDeck.knownCards[Idx]))
                {
                    return(false);
                }
            }

            for (int Idx = 0; Idx < unknownCardPool.Count; Idx++)
            {
                if (!unknownCardPool[Idx].Equals(otherDeck.unknownCardPool[Idx]))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #6
0
 public void SetDeck(TriadDeck deck)
 {
     if (this.deck == null || deck == null || !this.deck.Equals(deck))
     {
         this.deck = deck;
         CalcWinChance();
     }
 }
Exemple #7
0
 public TriadNpc(int id, List <TriadGameModifier> rules, List <TriadCard> rewards, TriadDeck deck)
 {
     Id          = id;
     Name        = LocalizationDB.Get().FindOrAddLocString(ELocStringType.NpcName, id);
     LocationMap = LocalizationDB.Get().FindOrAddLocString(ELocStringType.NpcLocation, id);
     Rules       = rules;
     Rewards     = rewards;
     Deck        = deck;
 }
Exemple #8
0
 public TriadNpc(int id, List <TriadGameModifier> rules, List <TriadCard> rewards, int[] cardsAlways, int[] cardsPool)
 {
     Id          = id;
     Name        = LocalizationDB.Get().FindOrAddLocString(ELocStringType.NpcName, id);
     LocationMap = LocalizationDB.Get().FindOrAddLocString(ELocStringType.NpcLocation, id);
     Rules       = rules;
     Rewards     = rewards;
     Deck        = new TriadDeck(cardsAlways, cardsPool);
 }
Exemple #9
0
 public TriadNpc(int id, string name, string location,
                 List <TriadGameModifier> rules, List <TriadCard> rewards, int[] cardsAlways, int[] cardsPool)
 {
     Id       = id;
     Name     = name;
     Location = location;
     Rules    = rules;
     Rewards  = rewards;
     Deck     = new TriadDeck(cardsAlways, cardsPool);
 }
Exemple #10
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 #11
0
        // shared with three open
        public static void StaticMakeKnown(TriadGameData gameData, List <int> redIndices)
        {
            const int deckSize = 5;

            TriadDeckInstanceManual deckRedEx = gameData.deckRed as TriadDeckInstanceManual;

            if (deckRedEx != null && redIndices.Count <= deckSize)
            {
                if (gameData.bDebugRules)
                {
                    Logger.WriteLine(">> Open:{0}! red indices:{1}", redIndices.Count, string.Join(", ", redIndices));
                }

                TriadDeck redDeckVisible = new TriadDeck(deckRedEx.deck.knownCards, deckRedEx.deck.unknownCardPool);
                for (int idx = 0; idx < redIndices.Count; idx++)
                {
                    int cardIdx = redIndices[idx];
                    if (cardIdx < deckRedEx.deck.knownCards.Count)
                    {
                        // already known, ignore
                    }
                    else
                    {
                        int idxU   = cardIdx - deckRedEx.deck.knownCards.Count;
                        var cardOb = deckRedEx.deck.unknownCardPool[idxU];
                        redDeckVisible.knownCards.Add(cardOb);
                        redDeckVisible.unknownCardPool.Remove(cardOb);
                    }
                }

                // safety for impossible state
                for (int idx = 0; (idx < redDeckVisible.knownCards.Count) && (redDeckVisible.knownCards.Count > deckSize); idx++)
                {
                    var cardOb = redDeckVisible.knownCards[idx];
                    int orgIdx = deckRedEx.GetCardIndex(cardOb);
                    if (!redIndices.Contains(orgIdx))
                    {
                        redDeckVisible.knownCards.RemoveAt(idx);
                        idx--;
                    }
                }

                gameData.deckRed = new TriadDeckInstanceManual(redDeckVisible);
            }
        }
Exemple #12
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 #13
0
        public void InitDeck(int slotIdx, TriadDeck copyFrom, ImageList cardImages, ImageList cardTypes, ImageList cardRarity)
        {
            this.slotIdx = slotIdx;

            PlayerSettingsDB playerDB = PlayerSettingsDB.Get();

            if (slotIdx < playerDB.favDecks.Count)
            {
                deck           = playerDB.favDecks[slotIdx];
                buttonAdd.Text = "Update";
            }
            else
            {
                deck      = new TriadDeckNamed(copyFrom);
                deck.Name = "Fav #" + (slotIdx + 1).ToString();
            }

            deckCtrl1.SetImageLists(cardImages, cardTypes, cardRarity);
            deckCtrl1.SetDeck(deck);
            textBox1.Text = deck.Name;
        }
Exemple #14
0
        public static void RunSolverStressTest()
        {
#if DEBUG
            int numIterations = 1000 * 100;
            Logger.WriteLine("Solver testing start, numIterations:" + numIterations);
            perfStats = new SolverPerfStats();

            Stopwatch timer = new Stopwatch();
            timer.Start();

            TriadDeck testDeck   = new TriadDeck(new int[] { 10, 20, 30, 40, 50 });
            TriadNpc  testNpc    = TriadNpcDB.Get().Find("Garima");
            Random    randStream = new Random();

            TriadGameSession solver = new TriadGameSession();
            solver.modifiers.AddRange(testNpc.Rules);
            solver.UpdateSpecialRules();

            for (int Idx = 0; Idx < numIterations; Idx++)
            {
                TriadGameData testData    = solver.StartGame(testDeck, testNpc.Deck, ETriadGameState.InProgressBlue);
                Random        sessionRand = new Random(randStream.Next());
                solver.SolverPlayRandomGame(testData, sessionRand);
            }

            timer.Stop();
            Logger.WriteLine("Solver testing finished, time taken:" + timer.ElapsedMilliseconds + "ms");

            float TicksToMs = 1000.0f / Stopwatch.Frequency;
            Logger.WriteLine(">> PlayRandomTurn.SelectSpot: " + (perfStats.PlayRandomTurnSelectSpot * TicksToMs) + "ms");
            Logger.WriteLine(">> PlayRandomTurn.SelectCard: " + (perfStats.PlayRandomTurnSelectCard * TicksToMs) + "ms");
            Logger.WriteLine(">> PlayRandomTurn.PlaceCard: " + (perfStats.PlayRandomTurnPlaceCard * TicksToMs) + "ms");
            Logger.WriteLine("  >> PlaceCard.OnPlaced: " + (perfStats.PlaceCardOnPlaced * TicksToMs) + "ms");
            Logger.WriteLine("  >> PlaceCard.OnPlacedMods: " + (perfStats.PlaceCardOnPlacedMods * TicksToMs) + "ms");
            Logger.WriteLine("  >> PlaceCard.Captures: " + (perfStats.PlaceCardCaptures * TicksToMs) + "ms");
            Logger.WriteLine("  >> PlaceCard.CapturesCombo: " + (perfStats.PlaceCardCapturesCombo * TicksToMs) + "ms");
            Logger.WriteLine("  >> PlaceCard.PostCaptures: " + (perfStats.PlaceCardPostCaptures * TicksToMs) + "ms");
            Logger.WriteLine("  >> PlaceCard.AllPlaced: " + (perfStats.PlaceCardAllPlaced * TicksToMs) + "ms");
#endif // DEBUG
        }
Exemple #15
0
        public void SetDeck(TriadDeck deck)
        {
            if ((clickAction == EDeckCtrlAction.Highlight) && (cardClickOwner != null))
            {
                cardClickOwner.SetHighlighted(false);
                cardClickOwner = null;
            }

            if (cardCtrls != null)
            {
                int prevCtrlCount = cardCtrls.Length;
                int numCards      = deck.knownCards.Count + deck.unknownCardPool.Count;
                if (prevCtrlCount == numCards)
                {
                    this.deck = null;
                    for (int Idx = 0; Idx < cardCtrls.Length; Idx++)
                    {
                        setDeckCard(Idx, deck.GetCard(Idx), true);
                    }

                    this.deck = deck;
                    return;
                }
            }

            if (deck.unknownCardPool.Count == 0)
            {
                SetDeck(deck.knownCards);
            }
            else
            {
                List <TriadCard> allCards = new List <TriadCard>();
                allCards.AddRange(deck.knownCards);
                allCards.AddRange(deck.unknownCardPool);
                SetDeck(allCards);
            }

            this.deck = deck;
        }
Exemple #16
0
 public TriadDeckNamed(TriadDeck copyFrom) : base(copyFrom.knownCards)
 {
 }
Exemple #17
0
 public void UpdatePlayerDeck(TriadDeck playerDeck)
 {
     playerDeckPattern = playerDeck.knownCards.ToArray();
 }
Exemple #18
0
        private void FindDecksScored(TriadGameModifier[] regionMods, List <TriadCard> lockedCards)
        {
            PlayerSettingsDB playerDB = PlayerSettingsDB.Get();
            //TriadCardDB playerDB = TriadCardDB.Get();

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            TriadGameSession solver = new TriadGameSession();

            solver.modifiers.AddRange(npc.Rules);
            solver.modifiers.AddRange(regionMods);
            solver.UpdateSpecialRules();

            bool bIsOrderImportant = false;

            foreach (TriadGameModifier mod in solver.modifiers)
            {
                bIsOrderImportant = bIsOrderImportant || mod.IsDeckOrderImportant();
            }

            List <TriadCard> rareList   = new List <TriadCard>();
            List <TriadCard> commonList = new List <TriadCard>();

            FindCardsToUse(playerDB.ownedCards, solver.modifiers, rareList, commonList);

            ETriadCardRarity rareThreshold = GetRareThreshold(playerDB.ownedCards);

            ECardSlotState[] cardSlots = BuildCardSlots(lockedCards, rareList.Count, commonList.Count, rareThreshold, bIsOrderImportant);

            object    lockOb    = new object();
            int       bestScore = 0;
            TriadDeck bestDeck  = new TriadDeck(PlayerSettingsDB.Get().starterCards);

            List <TriadCard>[] slotLists = new List <TriadCard> [cardSlots.Length];
            int numLocked    = 0;
            int numRareSlots = 0;

            for (int Idx = 0; Idx < slotLists.Length; Idx++)
            {
                switch (cardSlots[Idx])
                {
                case ECardSlotState.Common:
                    slotLists[Idx] = commonList;
                    break;

                case ECardSlotState.Rare:
                    slotLists[Idx] = rareList;
                    numRareSlots++;
                    break;

                default:
                    slotLists[Idx] = new List <TriadCard>()
                    {
                        lockedCards[Idx]
                    };
                    numLocked++;
                    break;
                }
            }

            if (numLocked > 0)
            {
                // slower when ran for all 5 slots
                UpdatePossibleDeckCount(rareList.Count, commonList.Count, cardSlots, bIsOrderImportant);

                //for (int IdxS0 = 0; IdxS0 < slotLists[0].Count; IdxS0++)
                Parallel.For(0, slotLists[0].Count, IdxS0 =>
                {
                    if (!bAbort)
                    {
                        //for (int IdxS1 = 0; IdxS1 < slotLists[1].Count; IdxS1++)
                        Parallel.For(0, slotLists[1].Count, IdxS1 =>
                        {
                            if (!bAbort)
                            {
                                //for (int IdxS2 = 0; IdxS2 < slotLists[2].Count; IdxS2++)
                                Parallel.For(0, slotLists[2].Count, IdxS2 =>
                                {
                                    if (!bAbort)
                                    {
                                        //for (int IdxS3 = 0; IdxS3 < slotLists[3].Count; IdxS3++)
                                        Parallel.For(0, slotLists[3].Count, IdxS3 =>
                                        {
                                            if (!bAbort)
                                            {
                                                //for (int IdxS4 = 0; IdxS4 < slotLists[4].Count; IdxS4++)
                                                Parallel.For(0, slotLists[4].Count, IdxS4 =>
                                                {
                                                    if (!bAbort)
                                                    {
                                                        TriadCard[] testDeckCards = new TriadCard[] { slotLists[0][IdxS0], slotLists[1][IdxS1], slotLists[2][IdxS2], slotLists[3][IdxS3], slotLists[4][IdxS4] };
                                                        if (testDeckCards[0] != testDeckCards[1] &&
                                                            testDeckCards[0] != testDeckCards[2] &&
                                                            testDeckCards[0] != testDeckCards[3] &&
                                                            testDeckCards[0] != testDeckCards[4] &&
                                                            testDeckCards[1] != testDeckCards[2] &&
                                                            testDeckCards[1] != testDeckCards[3] &&
                                                            testDeckCards[1] != testDeckCards[4] &&
                                                            testDeckCards[2] != testDeckCards[3] &&
                                                            testDeckCards[2] != testDeckCards[4] &&
                                                            testDeckCards[3] != testDeckCards[4])
                                                        {
                                                            Random randomGen = GetRandomStream(IdxS0, IdxS1, IdxS2, IdxS3, IdxS4);
                                                            // TODO: custom permutation lookup
                                                            {
                                                                TriadDeck testDeck = new TriadDeck(testDeckCards);
                                                                int testScore      = GetDeckScore(solver, testDeck, randomGen, 1);
                                                                if (testScore > bestScore)
                                                                {
                                                                    lock (lockOb)
                                                                    {
                                                                        bestScore = testScore;
                                                                        bestDeck  = testDeck;
                                                                        OnFoundDeck.Invoke(testDeck);
                                                                    }
                                                                }
                                                            }
                                                        }

                                                        lock (lockOb)
                                                        {
                                                            numTestedDecks++;
                                                        }
                                                    }
                                                });
                                            }
                                        });
                                    }
                                });
                            }
                        });
                    }
                });
            }
            else
            {
                // faster loops when nothing is locked
                // A: single rare slot, most common case
                if (numRareSlots == 1)
                {
                    UpdatePossibleDeckCount(rareList.Count, commonList.Count, lockedCards, bIsOrderImportant);

                    Parallel.For(0, rareList.Count, IdxR0 =>
                    {
                        if (!bAbort)
                        {
                            Parallel.For(0, commonList.Count, IdxC1 =>
                            {
                                if (!bAbort)
                                {
                                    for (int IdxC2 = IdxC1 + 1; IdxC2 < commonList.Count; IdxC2++)
                                    {
                                        for (int IdxC3 = IdxC2 + 1; IdxC3 < commonList.Count; IdxC3++)
                                        {
                                            for (int IdxC4 = IdxC3 + 1; IdxC4 < commonList.Count; IdxC4++)
                                            {
                                                TriadCard[] testDeckCards = new TriadCard[] { rareList[IdxR0], commonList[IdxC1], commonList[IdxC2], commonList[IdxC3], commonList[IdxC4] };
                                                Random randomGen          = GetRandomStream(IdxR0, IdxC1, IdxC2, IdxC3, IdxC4);

                                                if (bIsOrderImportant)
                                                {
                                                    if (bAllowPermutationChecks)
                                                    {
                                                        for (int IdxP = 0; IdxP < permutationList.Length; IdxP++)
                                                        {
                                                            int[] UseOrder            = permutationList[IdxP];
                                                            TriadCard[] permDeckCards = new TriadCard[] { testDeckCards[UseOrder[0]], testDeckCards[UseOrder[1]], testDeckCards[UseOrder[2]], testDeckCards[UseOrder[3]], testDeckCards[UseOrder[4]] };
                                                            TriadDeck permDeck        = new TriadDeck(permDeckCards);
                                                            int testScore             = GetDeckScore(solver, permDeck, randomGen, 10);
                                                            if (testScore > bestScore)
                                                            {
                                                                lock (lockOb)
                                                                {
                                                                    bestScore = testScore;
                                                                    bestDeck  = permDeck;
                                                                    OnFoundDeck.Invoke(permDeck);
                                                                }
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        testDeckCards = new TriadCard[] { commonList[IdxC1], rareList[IdxR0], commonList[IdxC2], commonList[IdxC3], commonList[IdxC4] };
                                                    }
                                                }

                                                {
                                                    TriadDeck testDeck = new TriadDeck(testDeckCards);
                                                    int testScore      = GetDeckScore(solver, testDeck, randomGen, 1);
                                                    if (testScore > bestScore)
                                                    {
                                                        lock (lockOb)
                                                        {
                                                            bestScore = testScore;
                                                            bestDeck  = testDeck;
                                                            OnFoundDeck.Invoke(testDeck);
                                                        }
                                                    }
                                                }

                                                lock (lockOb)
                                                {
                                                    numTestedDecks++;
                                                    if (bAbort)
                                                    {
                                                        IdxC2 = commonList.Count;
                                                        IdxC3 = commonList.Count;
                                                        IdxC4 = commonList.Count;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            });
                        }
                    });
                }
                else if (numRareSlots == 0)
                {
                    // remove part of common list for faster procesing, normally it would use 1 rare slot (smaller pool)
                    // randomly for all thta matters...
                    int    maxCommonToUse = commonList.Count * 80 / 100;
                    Random pruneRng       = new Random();

                    while (commonList.Count > maxCommonToUse)
                    {
                        int idxToRemove = pruneRng.Next(0, commonList.Count);
                        commonList.RemoveAt(idxToRemove);
                    }

                    // call simpler version of max possible combinations, 1 list in use
                    UpdatePossibleDeckCount(maxCommonToUse, bIsOrderImportant);
                    OnUpdateMaxSearchDecks?.Invoke(numPossibleDecks.ToString());

                    Parallel.For(0, commonList.Count, IdxC1 =>
                    {
                        if (!bAbort)
                        {
                            for (int IdxC2 = IdxC1 + 1; IdxC2 < commonList.Count; IdxC2++)
                            {
                                for (int IdxC3 = IdxC2 + 1; IdxC3 < commonList.Count; IdxC3++)
                                {
                                    for (int IdxC4 = IdxC3 + 1; IdxC4 < commonList.Count; IdxC4++)
                                    {
                                        for (int IdxC5 = IdxC4 + 1; IdxC5 < commonList.Count; IdxC5++)
                                        {
                                            TriadCard[] testDeckCards = new TriadCard[] { commonList[IdxC1], commonList[IdxC2], commonList[IdxC3], commonList[IdxC4], commonList[IdxC5] };
                                            Random randomGen          = GetRandomStream(IdxC1, IdxC2, IdxC3, IdxC4, IdxC5);

                                            if (bIsOrderImportant && bAllowPermutationChecks)
                                            {
                                                for (int IdxP = 0; IdxP < permutationList.Length; IdxP++)
                                                {
                                                    int[] UseOrder            = permutationList[IdxP];
                                                    TriadCard[] permDeckCards = new TriadCard[] { testDeckCards[UseOrder[0]], testDeckCards[UseOrder[1]], testDeckCards[UseOrder[2]], testDeckCards[UseOrder[3]], testDeckCards[UseOrder[4]] };
                                                    TriadDeck permDeck        = new TriadDeck(permDeckCards);
                                                    int testScore             = GetDeckScore(solver, permDeck, randomGen, 10);
                                                    if (testScore > bestScore)
                                                    {
                                                        lock (lockOb)
                                                        {
                                                            bestScore = testScore;
                                                            bestDeck  = permDeck;
                                                            OnFoundDeck.Invoke(permDeck);
                                                        }
                                                    }
                                                }
                                            }

                                            {
                                                TriadDeck testDeck = new TriadDeck(testDeckCards);
                                                int testScore      = GetDeckScore(solver, testDeck, randomGen, 1);
                                                if (testScore > bestScore)
                                                {
                                                    lock (lockOb)
                                                    {
                                                        bestScore = testScore;
                                                        bestDeck  = testDeck;
                                                        OnFoundDeck.Invoke(testDeck);
                                                    }
                                                }
                                            }

                                            lock (lockOb)
                                            {
                                                numTestedDecks++;
                                                if (bAbort)
                                                {
                                                    IdxC2 = commonList.Count;
                                                    IdxC3 = commonList.Count;
                                                    IdxC4 = commonList.Count;
                                                    IdxC5 = commonList.Count;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    });
                }
                else
                {
                    Logger.WriteLine("Unexpected slot setup: " + string.Join(", ", cardSlots) + ", bailing out");
                }
            }

            stopwatch.Stop();
            Logger.WriteLine("Building list of decks: " + stopwatch.ElapsedMilliseconds + "ms, num:" + numPossibleDecks);
            optimizedDeck = bestDeck;
        }
Exemple #19
0
        private void FindDecks(TriadGameModifier[] regionMods)
        {
            PlayerSettingsDB playerDB = PlayerSettingsDB.Get();
            //TriadCardDB playerDB = TriadCardDB.Get();

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            ETriadCardRarity RarityLimitThr =
                (playerDB.ownedCards.Count < 30) ? ETriadCardRarity.Uncommon :
                (playerDB.ownedCards.Count < 60) ? ETriadCardRarity.Rare :
                ETriadCardRarity.Epic;

            TriadGameSession solver = new TriadGameSession();

            solver.modifiers.AddRange(npc.Rules);
            solver.modifiers.AddRange(regionMods);
            solver.UpdateSpecialRules();

            bool bIsOrderImportant = false;

            foreach (TriadGameModifier mod in solver.modifiers)
            {
                bIsOrderImportant = bIsOrderImportant || mod.IsDeckOrderImportant();
            }

            object    lockOb    = new object();
            int       bestScore = 0;
            TriadDeck bestDeck  = new TriadDeck(PlayerSettingsDB.Get().starterCards);

            Parallel.For(1, playerDB.ownedCards.Count, Idx1 =>
            {
                Parallel.For(Idx1 + 1, playerDB.ownedCards.Count, Idx2 =>
                {
                    int rareCounterLv2 =
                        ((playerDB.ownedCards[Idx1].Rarity >= RarityLimitThr) ? 1 : 0) +
                        ((playerDB.ownedCards[Idx2].Rarity >= RarityLimitThr) ? 1 : 0);
                    if (rareCounterLv2 <= 1)
                    {
                        Parallel.For(Idx2 + 1, playerDB.ownedCards.Count, Idx3 =>
                        {
                            int rareCounterLv3 =
                                ((playerDB.ownedCards[Idx1].Rarity >= RarityLimitThr) ? 1 : 0) +
                                ((playerDB.ownedCards[Idx2].Rarity >= RarityLimitThr) ? 1 : 0) +
                                ((playerDB.ownedCards[Idx3].Rarity >= RarityLimitThr) ? 1 : 0);

                            if (rareCounterLv3 <= 1)
                            {
                                Parallel.For(Idx3 + 1, playerDB.ownedCards.Count, Idx4 =>
                                {
                                    int rareCounterLv4 =
                                        ((playerDB.ownedCards[Idx1].Rarity >= RarityLimitThr) ? 1 : 0) +
                                        ((playerDB.ownedCards[Idx2].Rarity >= RarityLimitThr) ? 1 : 0) +
                                        ((playerDB.ownedCards[Idx3].Rarity >= RarityLimitThr) ? 1 : 0) +
                                        ((playerDB.ownedCards[Idx4].Rarity >= RarityLimitThr) ? 1 : 0);
                                    if (rareCounterLv4 <= 1)
                                    {
                                        for (int Idx5 = Idx4 + 1; Idx5 < playerDB.ownedCards.Count; Idx5++)
                                        {
                                            int rareCounterLv5 = rareCounterLv4 +
                                                                 ((playerDB.ownedCards[Idx5].Rarity >= RarityLimitThr) ? 1 : 0);
                                            if (rareCounterLv5 <= 1)
                                            {
                                                TriadCard[] testDeckCards = new TriadCard[] { playerDB.ownedCards[Idx1], playerDB.ownedCards[Idx2], playerDB.ownedCards[Idx3], playerDB.ownedCards[Idx4], playerDB.ownedCards[Idx5] };
                                                Random randomGen          = GetRandomStream(Idx1, Idx2, Idx3, Idx4, Idx5);

                                                if (bIsOrderImportant)
                                                {
                                                    if (bAllowPermutationChecks)
                                                    {
                                                        for (int IdxP = 0; IdxP < permutationList.Length; IdxP++)
                                                        {
                                                            int[] UseOrder     = permutationList[IdxP];
                                                            TriadDeck permDeck = new TriadDeck(new TriadCard[] { testDeckCards[UseOrder[0]], testDeckCards[UseOrder[1]], testDeckCards[UseOrder[2]], testDeckCards[UseOrder[3]], testDeckCards[UseOrder[4]] });

                                                            int testScore = GetDeckScore(solver, permDeck, randomGen, 10);
                                                            if (testScore > bestScore)
                                                            {
                                                                lock (lockOb)
                                                                {
                                                                    bestScore = testScore;
                                                                    bestDeck  = permDeck;
                                                                }
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        int fixedRareSlot = 2;
                                                        for (int TestSlotIdx = 0; TestSlotIdx < testDeckCards.Length; TestSlotIdx++)
                                                        {
                                                            if (testDeckCards[TestSlotIdx].Rarity > testDeckCards[fixedRareSlot].Rarity)
                                                            {
                                                                TriadCard swapOb             = testDeckCards[TestSlotIdx];
                                                                testDeckCards[TestSlotIdx]   = testDeckCards[fixedRareSlot];
                                                                testDeckCards[fixedRareSlot] = swapOb;
                                                            }
                                                        }
                                                    }
                                                }

                                                {
                                                    TriadDeck testDeck = new TriadDeck(testDeckCards);
                                                    int testScore      = GetDeckScore(solver, testDeck, randomGen, 1);
                                                    if (testScore > bestScore)
                                                    {
                                                        lock (lockOb)
                                                        {
                                                            bestScore = testScore;
                                                            bestDeck  = testDeck;
                                                        }
                                                    }
                                                }
                                            }

                                            numTestedDecks++;
                                        }
                                    }
                                    else
                                    {
                                        numTestedDecks += playerDB.ownedCards.Count - Idx4;
                                    }
                                });
                            }
                            else
                            {
                                numTestedDecks += (playerDB.ownedCards.Count - Idx3) * (playerDB.ownedCards.Count - Idx3 - 1);
                            }
                        });
                    }
                    else
                    {
                        numTestedDecks += (playerDB.ownedCards.Count - Idx2) * (playerDB.ownedCards.Count - Idx2 - 1) * (playerDB.ownedCards.Count - Idx2 - 2);
                    }
                });
            });

            stopwatch.Stop();
            Logger.WriteLine("Building list of decks: " + stopwatch.ElapsedMilliseconds + "ms, num:" + numPossibleDecks);
            optimizedDeck = bestDeck;
        }
Exemple #20
0
        public bool LoadFromJson(string jsonStr)
        {
            TriadCardDB cardDB = TriadCardDB.Get();
            TriadNpcDB  npcDB  = TriadNpcDB.Get();

            ownedCards.Clear();
            completedNpcs.Clear();
            lastDeck.Clear();
            favDecks.Clear();

            try
            {
                JsonParser.ObjectValue jsonOb = JsonParser.ParseJson(jsonStr);

                JsonParser.ObjectValue uiOb = (JsonParser.ObjectValue)jsonOb["ui", null];
                if (uiOb != null)
                {
                    JsonParser.Value BoolTrue  = new JsonParser.BoolValue(true);
                    JsonParser.Value BoolFalse = new JsonParser.BoolValue(false);

                    useXInput      = (JsonParser.BoolValue)uiOb["xInput", BoolTrue];
                    alwaysOnTop    = (JsonParser.BoolValue)uiOb["onTop", BoolFalse];
                    forcedLanguage = (JsonParser.StringValue)uiOb["lang", null];

                    TryGettingFloatValue(uiOb, "fontSize", ref fontSize);
                    TryGettingFloatValue(uiOb, "markerCard", ref markerDurationCard);
                    TryGettingFloatValue(uiOb, "markerSwap", ref markerDurationSwap);
                    TryGettingFloatValue(uiOb, "markerCactpot", ref markerDurationCactpot);

                    TryGettingIntValue(uiOb, "lastNpcId", ref lastNpcId);
                    TryGettingFloatValue(uiOb, "lastWidth", ref lastWidth);
                    TryGettingFloatValue(uiOb, "lastHeight", ref lastHeight);

                    fontSize = Math.Min(Math.Max(fontSize, 10), 40);
                }

                JsonParser.ObjectValue cloudOb = (JsonParser.ObjectValue)jsonOb["cloud", null];
                if (cloudOb != null)
                {
                    useCloudStorage = (JsonParser.BoolValue)cloudOb["use", JsonParser.BoolValue.Empty];
                    cloudToken      = (JsonParser.StringValue)cloudOb["token", null];
                }

                JsonParser.ArrayValue cardsArr = (JsonParser.ArrayValue)jsonOb["cards", JsonParser.ArrayValue.Empty];
                foreach (JsonParser.Value value in cardsArr.entries)
                {
                    int cardId = (JsonParser.IntValue)value;
                    ownedCards.Add(cardDB.cards[cardId]);
                }

                JsonParser.ArrayValue npcsArr = (JsonParser.ArrayValue)jsonOb["npcs", JsonParser.ArrayValue.Empty];
                foreach (JsonParser.Value value in npcsArr.entries)
                {
                    int npcId = (JsonParser.IntValue)value;
                    completedNpcs.Add(npcDB.npcs[npcId]);
                }

                JsonParser.ArrayValue decksArr = (JsonParser.ArrayValue)jsonOb["decks", JsonParser.ArrayValue.Empty];
                foreach (JsonParser.Value value in decksArr.entries)
                {
                    JsonParser.ObjectValue deckOb = (JsonParser.ObjectValue)value;
                    int npcId = (JsonParser.IntValue)deckOb["id"];

                    TriadNpc npc = TriadNpcDB.Get().npcs[npcId];
                    if (npc != null)
                    {
                        TriadDeck deckCards = new TriadDeck();

                        cardsArr = (JsonParser.ArrayValue)deckOb["cards", JsonParser.ArrayValue.Empty];
                        foreach (JsonParser.Value cardValue in cardsArr.entries)
                        {
                            int cardId = (JsonParser.IntValue)cardValue;
                            deckCards.knownCards.Add(cardDB.cards[cardId]);
                        }

                        lastDeck.Add(npc, deckCards);
                    }
                }

                JsonParser.ArrayValue favDecksArr = (JsonParser.ArrayValue)jsonOb["favDecks", JsonParser.ArrayValue.Empty];
                foreach (JsonParser.Value value in favDecksArr.entries)
                {
                    JsonParser.ObjectValue deckOb    = (JsonParser.ObjectValue)value;
                    TriadDeckNamed         deckCards = new TriadDeckNamed();

                    cardsArr = (JsonParser.ArrayValue)deckOb["cards", JsonParser.ArrayValue.Empty];
                    foreach (JsonParser.Value cardValue in cardsArr.entries)
                    {
                        int cardId = (JsonParser.IntValue)cardValue;
                        deckCards.knownCards.Add(cardDB.cards[cardId]);
                    }

                    if (deckCards.knownCards.Count > 0)
                    {
                        deckCards.Name = deckOb["name", JsonParser.StringValue.Empty];
                        favDecks.Add(deckCards);
                    }
                }

                JsonParser.ObjectValue imageHashesOb = (JsonParser.ObjectValue)jsonOb["images", null];
                if (imageHashesOb != null)
                {
                    customHashes = ImageHashDB.Get().LoadImageHashes(imageHashesOb);
                    ImageHashDB.Get().hashes.AddRange(customHashes);
                }
            }
            catch (Exception ex)
            {
                Logger.WriteLine("Loading failed! Exception:" + ex);
            }

            Logger.WriteLine("Loaded player cards: " + ownedCards.Count + ", npcs: " + completedNpcs.Count + ", hashes: " + customHashes.Count);
            return(ownedCards.Count > 0);
        }
Exemple #21
0
        public static void RunTest(string configPath, bool debugMode)
        {
            string testName = System.IO.Path.GetFileNameWithoutExtension(configPath);

            string configText = System.IO.File.ReadAllText(configPath);

            JsonParser.ObjectValue configOb = JsonParser.ParseJson(configText);
            if (configOb["type"] != "Solver")
            {
                return;
            }

            TriadGameSession testSession = new TriadGameSession();

            // intial state
            ScannerTriad.VerifyConfig configData = new ScannerTriad.VerifyConfig();
            configData.Load(configOb);

            if (mapValidationRules == null)
            {
                mapValidationRules = new Dictionary <string, TriadGameModifier>();
                foreach (TriadGameModifier mod in ImageHashDB.Get().modObjects)
                {
                    mapValidationRules.Add(mod.GetCodeName(), mod);
                }
            }

            foreach (string modName in configData.rules)
            {
                testSession.modifiers.Add(mapValidationRules[modName]);
            }

            testSession.UpdateSpecialRules();
            TriadGameData testGameData = new TriadGameData()
            {
                bDebugRules = debugMode
            };

            if (configData.board.Length > 0)
            {
                Func <ScannerTriad.VerifyCard, TriadCard> ConvertToTriadCard = configCard =>
                {
                    if (configCard.state == ScannerTriad.ECardState.None)
                    {
                        return(null);
                    }
                    if (configCard.state == ScannerTriad.ECardState.Hidden)
                    {
                        return(TriadCardDB.Get().hiddenCard);
                    }

                    TriadCard matchingCard = !string.IsNullOrEmpty(configCard.name) ?
                                             TriadCardDB.Get().Find(configCard.name) :
                                             TriadCardDB.Get().Find(configCard.sides[0], configCard.sides[1], configCard.sides[2], configCard.sides[3]);

                    if (matchingCard == null)
                    {
                        string exceptionMsg = string.Format("Test {0} failed! Can't match validation card: '{1}' [{2},{3},{4},{5}]", testName,
                                                            configCard.name, configCard.sides[0], configCard.sides[1], configCard.sides[2], configCard.sides[3]);
                        throw new Exception(exceptionMsg);
                    }

                    return(matchingCard);
                };

                for (int idx = 0; idx < configData.board.Length; idx++)
                {
                    var configState = configData.board[idx].state;
                    if (configState != ScannerTriad.ECardState.None)
                    {
                        testGameData.board[idx] = new TriadCardInstance(ConvertToTriadCard(configData.board[idx]),
                                                                        (configState == ScannerTriad.ECardState.PlacedBlue) ? ETriadCardOwner.Blue :
                                                                        (configState == ScannerTriad.ECardState.PlacedRed) ? ETriadCardOwner.Red :
                                                                        ETriadCardOwner.Unknown);
                    }
                }
            }

            var deckRed  = new TriadDeck();
            var deckBlue = new TriadDeck();

            testGameData.deckBlue = new TriadDeckInstanceManual(deckBlue);
            testGameData.deckRed  = new TriadDeckInstanceManual(deckRed);

            JsonParser.ArrayValue moveArr = configOb.entries["moves"] as JsonParser.ArrayValue;
            for (int idx = 0; idx < moveArr.entries.Count; idx++)
            {
                var move = new VerifyMove();
                move.Load(moveArr.entries[idx] as JsonParser.ObjectValue);

                var useDeck = (move.owner == ETriadCardOwner.Blue) ? deckBlue : deckRed;
                useDeck.knownCards.Add(move.card);
                if (idx == 0)
                {
                    testGameData.state = (move.owner == ETriadCardOwner.Blue) ? ETriadGameState.InProgressBlue : ETriadGameState.InProgressRed;
                }

                if (debugMode)
                {
                    Logger.WriteLine("move[{0}]: [{1}] {2}: {3}", idx, move.boardPos, move.owner, move.card);
                }

                bool result = testSession.PlaceCard(testGameData, move.card, move.owner, move.boardPos);
                if (!result)
                {
                    string exceptionMsg = string.Format("Test {0} failed! Can't place card!", testName);
                    throw new Exception(exceptionMsg);
                }

                result = move.VerifyState(testGameData, debugMode);
                if (!result)
                {
                    string exceptionMsg = string.Format("Test {0} failed! Finished with bad state!", testName);
                    throw new Exception(exceptionMsg);
                }
            }
        }
Exemple #22
0
        public bool LoadFromJson(string jsonStr)
        {
            TriadCardDB cardDB = TriadCardDB.Get();
            TriadNpcDB  npcDB  = TriadNpcDB.Get();

            try
            {
                JsonParser.ObjectValue jsonOb = JsonParser.ParseJson(jsonStr);

                JsonParser.ObjectValue uiOb = (JsonParser.ObjectValue)jsonOb["ui", null];
                if (uiOb != null)
                {
                    useAutoScan = (JsonParser.BoolValue)uiOb["autoScan", JsonParser.BoolValue.Empty];
                }

                JsonParser.ObjectValue cloudOb = (JsonParser.ObjectValue)jsonOb["cloud", null];
                if (cloudOb != null)
                {
                    useCloudStorage = (JsonParser.BoolValue)cloudOb["use", JsonParser.BoolValue.Empty];
                    cloudToken      = (JsonParser.StringValue)cloudOb["token", null];
                }

                JsonParser.ArrayValue cardsArr = (JsonParser.ArrayValue)jsonOb["cards", JsonParser.ArrayValue.Empty];
                foreach (JsonParser.Value value in cardsArr.entries)
                {
                    int cardId = (JsonParser.IntValue)value;
                    ownedCards.Add(cardDB.cards[cardId]);
                }

                JsonParser.ArrayValue npcsArr = (JsonParser.ArrayValue)jsonOb["npcs", JsonParser.ArrayValue.Empty];
                foreach (JsonParser.Value value in npcsArr.entries)
                {
                    int npcId = (JsonParser.IntValue)value;
                    completedNpcs.Add(npcDB.npcs[npcId]);
                }

                JsonParser.ArrayValue decksArr = (JsonParser.ArrayValue)jsonOb["decks", JsonParser.ArrayValue.Empty];
                foreach (JsonParser.Value value in decksArr.entries)
                {
                    JsonParser.ObjectValue deckOb = (JsonParser.ObjectValue)value;
                    int npcId = (JsonParser.IntValue)deckOb["id"];

                    TriadNpc npc = TriadNpcDB.Get().npcs[npcId];
                    if (npc != null)
                    {
                        TriadDeck deckCards = new TriadDeck();

                        cardsArr = (JsonParser.ArrayValue)deckOb["cards", JsonParser.ArrayValue.Empty];
                        foreach (JsonParser.Value cardValue in cardsArr.entries)
                        {
                            int cardId = (JsonParser.IntValue)cardValue;
                            deckCards.knownCards.Add(cardDB.cards[cardId]);
                        }

                        lastDeck.Add(npc, deckCards);
                    }
                }

                JsonParser.ArrayValue favDecksArr = (JsonParser.ArrayValue)jsonOb["favDecks", JsonParser.ArrayValue.Empty];
                foreach (JsonParser.Value value in favDecksArr.entries)
                {
                    JsonParser.ObjectValue deckOb    = (JsonParser.ObjectValue)value;
                    TriadDeckNamed         deckCards = new TriadDeckNamed();

                    cardsArr = (JsonParser.ArrayValue)deckOb["cards", JsonParser.ArrayValue.Empty];
                    foreach (JsonParser.Value cardValue in cardsArr.entries)
                    {
                        int cardId = (JsonParser.IntValue)cardValue;
                        deckCards.knownCards.Add(cardDB.cards[cardId]);
                    }

                    if (deckCards.knownCards.Count > 0)
                    {
                        deckCards.Name = deckOb["name", JsonParser.StringValue.Empty];
                        favDecks.Add(deckCards);
                    }
                }

                JsonParser.ObjectValue imageHashesOb = (JsonParser.ObjectValue)jsonOb["images", null];
                if (imageHashesOb != null)
                {
                    customHashes = ImageHashDB.Get().LoadImageHashes(imageHashesOb);
                }

                JsonParser.ArrayValue digitHashesArr = (JsonParser.ArrayValue)jsonOb["digits", null];
                if (digitHashesArr != null)
                {
                    customDigits = ImageHashDB.Get().LoadDigitHashes(digitHashesArr);
                }
            }
            catch (Exception ex)
            {
                Logger.WriteLine("Loading failed! Exception:" + ex);
            }

            return(ownedCards.Count > 0);
        }
        private void FindDecksScored(TriadGameModifier[] regionMods, List <TriadCard> lockedCards)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            if (currentPool.commonList == null && currentPool.priorityLists == null)
            {
                stopwatch.Stop();
                Logger.WriteLine("Skip deck building, everything was locked");

                optimizedDeck = new TriadDeck(lockedCards);
                return;
            }

            object    lockOb    = new object();
            int       bestScore = 0;
            TriadDeck bestDeck  = new TriadDeck(PlayerSettingsDB.Get().starterCards);

            // no more flexible slot count after this point => loop land
            const int numSlots = 5;

            TriadCard[][] slotLists = new TriadCard[numSlots][];
            for (int idx = 0; idx < numSlots; idx++)
            {
                slotLists[idx] =
                    (currentPool.deckSlotTypes[idx] == DeckSlotCommon) ? currentPool.commonList :
                    (currentPool.deckSlotTypes[idx] >= 0) ? currentPool.priorityLists[currentPool.deckSlotTypes[idx]] :
                    new TriadCard[1] {
                    lockedCards[idx]
                };
            }

            Func <int, int, int, int, int, int> FindLoopStart = (SlotIdx, IdxS0, IdxS1, IdxS2, IdxS3) =>
            {
                if (bAbort)
                {
                    return(slotLists[SlotIdx].Length);
                }
                if (currentPool.deckSlotTypes[SlotIdx] != DeckSlotCommon)
                {
                    return(0);
                }

                if (SlotIdx >= 4 && currentPool.deckSlotTypes[3] == DeckSlotCommon)
                {
                    return(IdxS3 + 1);
                }
                if (SlotIdx >= 3 && currentPool.deckSlotTypes[2] == DeckSlotCommon)
                {
                    return(IdxS2 + 1);
                }
                if (SlotIdx >= 2 && currentPool.deckSlotTypes[1] == DeckSlotCommon)
                {
                    return(IdxS1 + 1);
                }
                if (SlotIdx >= 1 && currentPool.deckSlotTypes[0] == DeckSlotCommon)
                {
                    return(IdxS0 + 1);
                }

                return(0);
            };

            Parallel.For(0, slotLists[0].Length, IdxS0 =>
                         //for (int IdxS0 = 0; IdxS0 < slotLists[0].Length; IdxS0++)
            {
                int startS1 = FindLoopStart(1, IdxS0, -1, -1, -1);
                Parallel.For(startS1, slotLists[1].Length, IdxS1 =>
                             //for (int IdxS1 = startS1; IdxS1 < slotLists[1].Length; IdxS1++)
                {
                    int startS2 = FindLoopStart(2, IdxS0, IdxS1, -1, -1);
                    Parallel.For(startS2, slotLists[2].Length, IdxS2 =>
                                 //for (int IdxS2 = startS2; IdxS2 < slotLists[2].Length; IdxS2++)
                    {
                        int startS3 = FindLoopStart(3, IdxS0, IdxS1, IdxS2, -1);
                        for (int IdxS3 = startS3; IdxS3 < slotLists[3].Length; IdxS3++)
                        {
                            int startS4 = FindLoopStart(4, IdxS0, IdxS1, IdxS2, IdxS3);
                            for (int IdxS4 = startS4; IdxS4 < slotLists[4].Length; IdxS4++)
                            {
                                TriadCard[] testDeckCards = new TriadCard[] { slotLists[0][IdxS0], slotLists[1][IdxS1], slotLists[2][IdxS2], slotLists[3][IdxS3], slotLists[4][IdxS4] };
                                if (testDeckCards[0] != testDeckCards[1] &&
                                    testDeckCards[0] != testDeckCards[2] &&
                                    testDeckCards[0] != testDeckCards[3] &&
                                    testDeckCards[0] != testDeckCards[4] &&
                                    testDeckCards[1] != testDeckCards[2] &&
                                    testDeckCards[1] != testDeckCards[3] &&
                                    testDeckCards[1] != testDeckCards[4] &&
                                    testDeckCards[2] != testDeckCards[3] &&
                                    testDeckCards[2] != testDeckCards[4] &&
                                    testDeckCards[3] != testDeckCards[4])
                                {
                                    Random randomGen = GetRandomStream(IdxS0, IdxS1, IdxS2, IdxS3, IdxS4);
                                    // TODO: custom permutation lookup
                                    {
                                        TriadDeck testDeck = new TriadDeck(testDeckCards);
                                        int testScore      = GetDeckScore(currentSolver, testDeck, randomGen, 1);
                                        if (testScore > bestScore)
                                        {
                                            lock (lockOb)
                                            {
                                                bestScore = testScore;
                                                bestDeck  = testDeck;
                                                OnFoundDeck.Invoke(testDeck);
                                            }
                                        }
                                    }
                                }

                                lock (lockOb)
                                {
                                    numTestedDecks++;
                                }
                            }
                        }
                    });
                });
            });

            stopwatch.Stop();
            Logger.WriteLine("Building list of decks: " + stopwatch.ElapsedMilliseconds + "ms, num:" + numPossibleDecks);
            optimizedDeck = bestDeck;
        }
Exemple #24
0
 public void UpdatePlayerDeck(TriadDeck activeDeck)
 {
     screenMemory.UpdatePlayerDeck(activeDeck);
 }
Exemple #25
0
        private bool UpdateNpcs(GameDataLists gameDataLists, Dictionary <string, TriadGameModifier> mapRuleNames)
        {
            Logger.WriteLine("Updating npc list...");

            TriadCardDB cardDB       = TriadCardDB.Get();
            TriadNpcDB  npcDB        = TriadNpcDB.Get();
            var         validDeckIds = new List <string>();

            foreach (var npcData in gameDataLists.npcs)
            {
                if (npcData.LinkedNpcId == null)
                {
                    continue;
                }

                if (npcData.LinkedNpcId.LinkedName == null || npcData.LinkedNpcId.LinkedLocation == null)
                {
                    continue;
                }

                TriadDeck npcDataDeck = new TriadDeck();
                foreach (var cardData in npcData.LinkedCardsFixed)
                {
                    npcDataDeck.knownCards.Add(cardDB.cards[cardData.Id]);
                }
                foreach (var cardData in npcData.LinkedCardsVariable)
                {
                    npcDataDeck.unknownCardPool.Add(cardDB.cards[cardData.Id]);
                }
                npcDataDeck.UpdateDeckId();
                validDeckIds.Add(npcDataDeck.deckId);

                // mistakes were made...
                TriadNpc npcOb = npcDB.FindByDeckId(npcDataDeck.deckId);
                int      npcId = (npcOb == null) ? npcDB.npcs.Count : npcOb.Id;

                if (npcOb != null)
                {
                    // ensure decks are the same
                    if (!npcOb.Deck.Equals(npcDataDeck))
                    {
                        Logger.WriteLine("FAILED npc update, id:{0} name:{1} is not matching cards!", npcId, npcData.LinkedNpcId.LinkedName.Name.GetCodeName());
                        return(false);
                    }
                }
                else
                {
                    while (npcDB.npcs.Count <= npcId)
                    {
                        npcDB.npcs.Add(null);
                    }

                    var listMods = new List <TriadGameModifier>();
                    foreach (var ruleData in npcData.LinkedRules)
                    {
                        listMods.Add(mapRuleNames[ruleData.Name.GetCodeName()]);
                    }

                    var listRewards = new List <TriadCard>();
                    foreach (var rewardData in npcData.LinkedRewards)
                    {
                        listRewards.Add(cardDB.cards[rewardData.LinkedCard.Id]);
                    }

                    npcOb = new TriadNpc(npcId, listMods, listRewards, npcDataDeck);

                    Logger.WriteLine(">> adding new npc: " + npcOb.ToString());
                    npcDB.npcs[npcId] = npcOb;
                }

                var linkedLoc = npcData.LinkedNpcId.LinkedLocation;
                linkedLoc.LinkedMap.GetCoords(linkedLoc.ScaledPosX, linkedLoc.ScaledPosZ, out npcOb.LocationX, out npcOb.LocationY);

                npcOb.Name.Text        = npcData.LinkedNpcId.LinkedName.Name.Text;
                npcOb.LocationMap.Text = npcData.LinkedNpcId.LinkedLocation.LinkedMap.LinkedPlace.Name.Text;
            }

            for (int idx = 0; idx < npcDB.npcs.Count; idx++)
            {
                TriadNpc npcOb = npcDB.npcs[idx];
                if (npcOb != null)
                {
                    if (!validDeckIds.Contains(npcOb.Deck.deckId))
                    {
                        Logger.WriteLine(">> removing npc: " + npcOb.ToString() + ", deck:" + npcOb.Deck.ToString());
                        npcDB.npcs[idx] = null;
                        continue;
                    }

                    if (npcOb.Id != idx)
                    {
                        Logger.WriteLine("FAILED npc update, index mismatch for npc[{0}].Id:{1}, Name:{2}", idx, npcOb.Id, npcOb.Name.GetCodeName());
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemple #26
0
        public bool LoadFromXmlStream(Stream stream)
        {
            TriadCardDB cardDB = TriadCardDB.Get();
            TriadNpcDB  npcDB  = TriadNpcDB.Get();

            try
            {
                XmlDocument xdoc = new XmlDocument();
                xdoc.Load(stream);

                foreach (XmlNode testNode in xdoc.DocumentElement.ChildNodes)
                {
                    try
                    {
                        XmlElement testElem = (XmlElement)testNode;
                        if (testElem != null && testElem.Name == "ui")
                        {
                            int autoScanNum = int.Parse(testElem.GetAttribute("autoScan"));
                            useAutoScan = (autoScanNum == 1);
                        }
                        else if (testElem != null && testElem.Name == "cloud")
                        {
                            int useNum = int.Parse(testElem.GetAttribute("use"));
                            useCloudStorage = (useNum == 1);
                            cloudToken      = testElem.HasAttribute("token") ? testElem.GetAttribute("token") : null;
                        }
                        else if (testElem != null && testElem.Name == "card")
                        {
                            int cardId = int.Parse(testElem.GetAttribute("id"));
                            ownedCards.Add(cardDB.cards[cardId]);
                        }
                        else if (testElem != null && testElem.Name == "npc")
                        {
                            int npcId = int.Parse(testElem.GetAttribute("id"));
                            completedNpcs.Add(npcDB.npcs[npcId]);
                        }
                        else if (testElem != null && testElem.Name == "deck")
                        {
                            int      npcId = int.Parse(testElem.GetAttribute("id"));
                            TriadNpc npc   = TriadNpcDB.Get().npcs[npcId];
                            if (npc != null)
                            {
                                TriadDeck deckCards = new TriadDeck();
                                foreach (XmlAttribute attr in testElem.Attributes)
                                {
                                    if (attr.Name.StartsWith("card"))
                                    {
                                        string cardNumStr = attr.Name.Substring(4);
                                        int    cardNum    = int.Parse(cardNumStr);
                                        while (deckCards.knownCards.Count < (cardNum + 1))
                                        {
                                            deckCards.knownCards.Add(null);
                                        }

                                        int cardId = int.Parse(attr.Value);
                                        deckCards.knownCards[cardNum] = TriadCardDB.Get().cards[cardId];
                                    }
                                }

                                lastDeck.Add(npc, deckCards);
                            }
                        }
                        else
                        {
                            ImageHashData customHash = ImageHashDB.Get().LoadHashEntry(testElem);
                            if (customHash != null)
                            {
                                customHashes.Add(customHash);
                            }
                            else
                            {
                                ImagePatternDigit customDigit = ImageHashDB.Get().LoadDigitEntry(testElem);
                                if (customDigit.Value > 0)
                                {
                                    customDigits.Add(customDigit);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.WriteLine("Loading failed! Exception:" + ex);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteLine("Loading failed! Exception:" + ex);
            }

            return(ownedCards.Count > 0);
        }
        private void FindDecksScored(TriadGameModifier[] regionMods, List <TriadCard> lockedCards)
        {
            PlayerSettingsDB playerDB = PlayerSettingsDB.Get();
            //TriadCardDB playerDB = TriadCardDB.Get();

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            TriadGameSession solver = new TriadGameSession();

            solver.modifiers.AddRange(npc.Rules);
            solver.modifiers.AddRange(regionMods);
            solver.UpdateSpecialRules();

            bool bIsOrderImportant = false;

            foreach (TriadGameModifier mod in solver.modifiers)
            {
                bIsOrderImportant = bIsOrderImportant || mod.IsDeckOrderImportant();
            }

            List <TriadCard> rareList   = new List <TriadCard>();
            List <TriadCard> commonList = new List <TriadCard>();

            FindCardsToUse(playerDB.ownedCards, solver.modifiers, rareList, commonList);

            ETriadCardRarity rareThreshold = GetRareThreshold(playerDB.ownedCards);

            ECardSlotState[] cardSlots = BuildCardSlots(lockedCards, rareList.Count, commonList.Count, rareThreshold, bIsOrderImportant);

            object    lockOb    = new object();
            int       bestScore = 0;
            TriadDeck bestDeck  = new TriadDeck(PlayerSettingsDB.Get().starterCards);

            List <TriadCard>[] slotLists = new List <TriadCard> [cardSlots.Length];
            int numLocked = 0;

            for (int Idx = 0; Idx < slotLists.Length; Idx++)
            {
                switch (cardSlots[Idx])
                {
                case ECardSlotState.Common: slotLists[Idx] = commonList; break;

                case ECardSlotState.Rare: slotLists[Idx] = rareList; break;

                default:
                    slotLists[Idx] = new List <TriadCard>()
                    {
                        lockedCards[Idx]
                    };
                    numLocked++;
                    break;
                }
            }

            if (numLocked > 0)
            {
                // slower when ran for all 5 slots
                UpdatePossibleDeckCount(rareList.Count, commonList.Count, cardSlots, bIsOrderImportant);

                //for (int IdxS0 = 0; IdxS0 < slotLists[0].Count; IdxS0++)
                Parallel.For(0, slotLists[0].Count, IdxS0 =>
                {
                    if (!bAbort)
                    {
                        //for (int IdxS1 = 0; IdxS1 < slotLists[1].Count; IdxS1++)
                        Parallel.For(0, slotLists[1].Count, IdxS1 =>
                        {
                            if (!bAbort)
                            {
                                //for (int IdxS2 = 0; IdxS2 < slotLists[2].Count; IdxS2++)
                                Parallel.For(0, slotLists[2].Count, IdxS2 =>
                                {
                                    if (!bAbort)
                                    {
                                        //for (int IdxS3 = 0; IdxS3 < slotLists[3].Count; IdxS3++)
                                        Parallel.For(0, slotLists[3].Count, IdxS3 =>
                                        {
                                            if (!bAbort)
                                            {
                                                //for (int IdxS4 = 0; IdxS4 < slotLists[4].Count; IdxS4++)
                                                Parallel.For(0, slotLists[4].Count, IdxS4 =>
                                                {
                                                    if (!bAbort)
                                                    {
                                                        TriadCard[] testDeckCards = new TriadCard[] { slotLists[0][IdxS0], slotLists[1][IdxS1], slotLists[2][IdxS2], slotLists[3][IdxS3], slotLists[4][IdxS4] };
                                                        if (testDeckCards[0] != testDeckCards[1] &&
                                                            testDeckCards[0] != testDeckCards[2] &&
                                                            testDeckCards[0] != testDeckCards[3] &&
                                                            testDeckCards[0] != testDeckCards[4] &&
                                                            testDeckCards[1] != testDeckCards[2] &&
                                                            testDeckCards[1] != testDeckCards[3] &&
                                                            testDeckCards[1] != testDeckCards[4] &&
                                                            testDeckCards[2] != testDeckCards[3] &&
                                                            testDeckCards[2] != testDeckCards[4] &&
                                                            testDeckCards[3] != testDeckCards[4])
                                                        {
                                                            Random randomGen = GetRandomStream(IdxS0, IdxS1, IdxS2, IdxS3, IdxS4);
                                                            // TODO: custom permutation lookup
                                                            {
                                                                TriadDeck testDeck = new TriadDeck(testDeckCards);
                                                                int testScore      = GetDeckScore(solver, testDeck, randomGen, 1);
                                                                if (testScore > bestScore)
                                                                {
                                                                    lock (lockOb)
                                                                    {
                                                                        bestScore = testScore;
                                                                        bestDeck  = testDeck;
                                                                        OnFoundDeck.Invoke(testDeck);
                                                                    }
                                                                }
                                                            }
                                                        }

                                                        lock (lockOb)
                                                        {
                                                            numTestedDecks++;
                                                        }
                                                    }
                                                });
                                            }
                                        });
                                    }
                                });
                            }
                        });
                    }
                });
            }
            else
            {
                // faster loops when nothing is locked
                UpdatePossibleDeckCount(rareList.Count, commonList.Count, lockedCards, bIsOrderImportant);

                Parallel.For(0, rareList.Count, IdxR0 =>
                {
                    if (!bAbort)
                    {
                        Parallel.For(0, commonList.Count, IdxC1 =>
                        {
                            if (!bAbort)
                            {
                                for (int IdxC2 = IdxC1 + 1; IdxC2 < commonList.Count; IdxC2++)
                                {
                                    for (int IdxC3 = IdxC2 + 1; IdxC3 < commonList.Count; IdxC3++)
                                    {
                                        for (int IdxC4 = IdxC3 + 1; IdxC4 < commonList.Count; IdxC4++)
                                        {
                                            TriadCard[] testDeckCards = new TriadCard[] { rareList[IdxR0], commonList[IdxC1], commonList[IdxC2], commonList[IdxC3], commonList[IdxC4] };
                                            Random randomGen          = GetRandomStream(IdxR0, IdxC1, IdxC2, IdxC3, IdxC4);

                                            if (bIsOrderImportant)
                                            {
                                                if (bAllowPermutationChecks)
                                                {
                                                    for (int IdxP = 0; IdxP < permutationList.Length; IdxP++)
                                                    {
                                                        int[] UseOrder            = permutationList[IdxP];
                                                        TriadCard[] permDeckCards = new TriadCard[] { testDeckCards[UseOrder[0]], testDeckCards[UseOrder[1]], testDeckCards[UseOrder[2]], testDeckCards[UseOrder[3]], testDeckCards[UseOrder[4]] };
                                                        TriadDeck permDeck        = new TriadDeck(permDeckCards);
                                                        int testScore             = GetDeckScore(solver, permDeck, randomGen, 10);
                                                        if (testScore > bestScore)
                                                        {
                                                            lock (lockOb)
                                                            {
                                                                bestScore = testScore;
                                                                bestDeck  = permDeck;
                                                                OnFoundDeck.Invoke(permDeck);
                                                            }
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    testDeckCards = new TriadCard[] { commonList[IdxC1], rareList[IdxR0], commonList[IdxC2], commonList[IdxC3], commonList[IdxC4] };
                                                }
                                            }

                                            {
                                                TriadDeck testDeck = new TriadDeck(testDeckCards);
                                                int testScore      = GetDeckScore(solver, testDeck, randomGen, 1);
                                                if (testScore > bestScore)
                                                {
                                                    lock (lockOb)
                                                    {
                                                        bestScore = testScore;
                                                        bestDeck  = testDeck;
                                                        OnFoundDeck.Invoke(testDeck);
                                                    }
                                                }
                                            }

                                            lock (lockOb)
                                            {
                                                numTestedDecks++;
                                                if (bAbort)
                                                {
                                                    IdxC2 = commonList.Count;
                                                    IdxC3 = commonList.Count;
                                                    IdxC4 = commonList.Count;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        });
                    }
                });
            }

            stopwatch.Stop();
            Logger.WriteLine("Building list of decks: " + stopwatch.ElapsedMilliseconds + "ms, num:" + numPossibleDecks);
            optimizedDeck = bestDeck;
        }