public void UpdateAvailableCards(TriadCard[] screenCards) { availableCardMask = 0; numPlaced = 0; numUnknownPlaced = 0; Array.Copy(screenCards, cards, 5); int hiddenCardId = TriadCardDB.Get().hiddenCard.Id; for (int Idx = 0; Idx < cards.Length; Idx++) { if (cards[Idx] != null) { if (cards[Idx].Id != hiddenCardId) { availableCardMask |= (1 << Idx); } } else { numPlaced++; } } }
public void Run() { GameDataLists gameDataLists = new GameDataLists(); gameDataLists.Load(@"..\..\..\datasource\export\exd-all\"); bool result = true; result = result && ValidateCardIds(gameDataLists); result = result && ValidateNpcIds(gameDataLists); result = result && gameDataLists.Link(); if (result) { var mapRuleByCodeName = BuildRuleNameMap(); var mapCardTypeByCodeName = BuildCardTypes(); result = result && ExportRuleNames(gameDataLists.rules, mapRuleByCodeName); result = result && ExportCardTypes(gameDataLists.cardTypes, mapCardTypeByCodeName); result = result && UpdateCards(gameDataLists, mapCardTypeByCodeName); result = result && UpdateNpcs(gameDataLists, mapRuleByCodeName); result = result && UpdateTournaments(gameDataLists, mapRuleByCodeName); } if (result) { LocalizationDB.Get().Save(); TriadCardDB.Get().Save(); TriadNpcDB.Get().Save(); TriadTournamentDB.Get().Save(); } Logger.WriteLine(result ? "Done." : "Aborted"); }
public bool Load() { bool bResult = false; string FilePath = AssetManager.Get().CreateFilePath(DBPath); if (File.Exists(FilePath)) { using (StreamReader file = new StreamReader(FilePath)) { string fileContent = file.ReadToEnd(); bResult = LoadFromJson(fileContent); file.Close(); } } TriadCardDB cardDB = TriadCardDB.Get(); starterCards[0] = cardDB.Find("Dodo"); starterCards[1] = cardDB.Find("Sabotender"); starterCards[2] = cardDB.Find("Bomb"); starterCards[3] = cardDB.Find("Mandragora"); starterCards[4] = cardDB.Find("Coeurl"); foreach (TriadCard starterCard in starterCards) { if (!ownedCards.Contains(starterCard)) { ownedCards.Add(starterCard); } } Logger.WriteLine("Loaded player cards: " + ownedCards.Count + ", npcs: " + completedNpcs.Count + ", hashes: " + customHashes.Count); return(bResult); }
public TriadDeck(IEnumerable <int> knownCardIds, IEnumerable <int> unknownCardlIds) { TriadCardDB cardDB = TriadCardDB.Get(); knownCards = new List <TriadCard>(); foreach (int id in knownCardIds) { TriadCard card = cardDB.cards[id]; if (card != null && card.IsValid()) { knownCards.Add(card); } } unknownCardPool = new List <TriadCard>(); foreach (int id in unknownCardlIds) { TriadCard card = cardDB.cards[id]; if (card != null && card.IsValid()) { unknownCardPool.Add(card); } } UpdateDeckId(); }
private bool IsSuddenDeathRestart(TriadDeckInstanceScreen deck) { // sudden death: all red cards visible, not matching npc deck at all int numMismatchedCards = 0; int numVisibleCards = 0; int hiddenCardId = TriadCardDB.Get().hiddenCard.Id; for (int Idx = 0; Idx < deck.cards.Length; Idx++) { int npcCardIdx = deck.deck.GetCardIndex(deck.cards[Idx]); if (npcCardIdx < 0) { numMismatchedCards++; } if (deck.cards[Idx] != null && deck.cards[Idx].Id != hiddenCardId) { numVisibleCards++; } } bool bHasOpenAndMismatched = (numVisibleCards >= 4 && numMismatchedCards > 1); bool bHasOpenAndShouldnt = (numVisibleCards >= 4 && !bHasOpenRule); Logger.WriteLine("IsSuddenDeathRestart? numMismatchedCards:" + numMismatchedCards + ", numVisibleCards:" + numVisibleCards); return(bHasOpenAndMismatched || bHasOpenAndShouldnt); }
private void UpdateAdjustedCard() { int sideU = (int)numericUpDownU.Value; int sideL = (int)numericUpDownL.Value; int sideD = (int)numericUpDownD.Value; int sideR = (int)numericUpDownR.Value; comboBox1.Items.Clear(); TriadCard foundCard = TriadCardDB.Get().Find(sideU, sideL, sideD, sideR); if (foundCard != null) { if (foundCard.SameNumberId < 0) { comboBox1.Items.Add(foundCard); } else { foreach (TriadCard card in TriadCardDB.Get().sameNumberMap[foundCard.SameNumberId]) { comboBox1.Items.Add(card); } } comboBox1.SelectedIndex = 0; } buttonOk.Enabled = comboBox1.Items.Count > 0; }
private void contextMenuStripPickCard_Opened(object sender, EventArgs e) { toolStripComboBoxPick.BeginUpdate(); PlayerSettingsDB playerDB = PlayerSettingsDB.Get(); TriadCardDB cardsDB = TriadCardDB.Get(); int numExpected = toolStripMenuOnlyOwned.Checked ? playerDB.ownedCards.Count : cardsDB.cards.Count; if (numExpected != toolStripComboBoxPick.Items.Count) { toolStripComboBoxPick.Items.Clear(); foreach (TriadCard card in cardsDB.cards) { if (card != null && (!toolStripMenuOnlyOwned.Checked || playerDB.ownedCards.Contains(card))) { toolStripComboBoxPick.Items.Add(new DeckCardPicker(card)); } } } for (int Idx = 0; Idx < toolStripComboBoxPick.Items.Count; Idx++) { DeckCardPicker cardOb = (DeckCardPicker)toolStripComboBoxPick.Items[Idx]; if (cardOb.Card == cardClickOwner.GetCard()) { toolStripComboBoxPick.SelectedIndex = Idx; break; } } toolStripComboBoxPick.EndUpdate(); toolStripComboBoxPick.Focus(); }
public List <ImageHashData> LoadImageHashes(JsonParser.ObjectValue jsonOb) { List <ImageHashData> list = new List <ImageHashData>(); string[] enumArr = Enum.GetNames(typeof(EImageHashType)); foreach (var kvp in jsonOb.entries) { EImageHashType groupType = (EImageHashType)Array.IndexOf(enumArr, kvp.Key); JsonParser.ArrayValue typeArr = (JsonParser.ArrayValue)kvp.Value; foreach (JsonParser.Value value in typeArr.entries) { JsonParser.ObjectValue jsonHashOb = (JsonParser.ObjectValue)value; string idStr = jsonHashOb["id"]; bool hasIdNum = int.TryParse(idStr, out int idNum); bool needsIdNum = (groupType != EImageHashType.Rule); if (hasIdNum != needsIdNum) { continue; } ImageHashData hashEntry = new ImageHashData() { type = groupType, isKnown = true }; switch (groupType) { case EImageHashType.Rule: hashEntry.ownerOb = ParseRule(idStr); break; case EImageHashType.CardImage: hashEntry.ownerOb = TriadCardDB.Get().cards[idNum]; break; default: hashEntry.ownerOb = idNum; break; } if (hashEntry.ownerOb != null) { string descHashTLSH = jsonHashOb["hashC", JsonParser.StringValue.Empty]; string descHashMd5 = jsonHashOb["hashB", JsonParser.StringValue.Empty]; hashEntry.LoadFromString(descHashTLSH, descHashMd5); if (hashEntry.IsValid()) { list.Add(hashEntry); } } } } return(list); }
public ImageHashData LoadHashEntry(XmlElement xmlElem) { ImageHashData result = null; if (xmlElem != null && xmlElem.Name == "hash" && xmlElem.HasAttribute("type") && (xmlElem.HasAttribute("value") || xmlElem.HasAttribute("valueB"))) { string typeName = xmlElem.GetAttribute("type"); string hashValueC = xmlElem.HasAttribute("value") ? xmlElem.GetAttribute("value") : null; string hashValueB = xmlElem.HasAttribute("valueB") ? xmlElem.GetAttribute("valueB") : null; if (typeName.Equals("rule", StringComparison.InvariantCultureIgnoreCase)) { string ruleName = xmlElem.GetAttribute("name"); result = new ImageHashData() { type = EImageHashType.Rule, isKnown = true }; result.ownerOb = ParseRule(ruleName); result.LoadFromString(hashValueC, hashValueB); } else if (typeName.Equals("card", StringComparison.InvariantCultureIgnoreCase)) { string cardIdName = xmlElem.GetAttribute("id"); int cardId = int.Parse(cardIdName); result = new ImageHashData() { type = EImageHashType.CardImage, isKnown = true }; result.ownerOb = TriadCardDB.Get().cards[cardId]; result.LoadFromString(hashValueC, hashValueB); } else if (typeName.Equals("cactpot", StringComparison.InvariantCultureIgnoreCase)) { string numIdName = xmlElem.GetAttribute("id"); result = new ImageHashData() { type = EImageHashType.Cactpot, isKnown = true }; result.ownerOb = int.Parse(numIdName); result.LoadFromString(hashValueC, hashValueB); } } return(result); }
private void toolStripMenuOnlyOwned_CheckedChanged(object sender, EventArgs e) { toolStripComboBoxPick.Items.Clear(); PlayerSettingsDB playerDB = PlayerSettingsDB.Get(); TriadCardDB cardsDB = TriadCardDB.Get(); foreach (TriadCard card in cardsDB.cards) { if (card != null && (!toolStripMenuOnlyOwned.Checked || playerDB.ownedCards.Contains(card))) { toolStripComboBoxPick.Items.Add(new DeckCardPicker(card)); } } }
public ImageHashData LoadHashEntry(XmlElement xmlElem) { ImageHashData result = null; if (xmlElem != null && xmlElem.Name == "hash" && xmlElem.HasAttribute("type") && (xmlElem.HasAttribute("value") || xmlElem.HasAttribute("valueS"))) { string typeName = xmlElem.GetAttribute("type"); string hashValueC = xmlElem.HasAttribute("value") ? xmlElem.GetAttribute("value") : null; string hashValueS = xmlElem.HasAttribute("valueS") ? xmlElem.GetAttribute("valueS") : null; HashCollection hashData = new HashCollection(hashValueC, hashValueS); if (typeName.Equals("rule", StringComparison.InvariantCultureIgnoreCase)) { string ruleName = xmlElem.GetAttribute("name"); TriadGameModifier ruleMod = ParseRule(ruleName); result = new ImageHashData(ruleMod, hashData, EImageHashType.Rule); } else if (typeName.Equals("card", StringComparison.InvariantCultureIgnoreCase)) { string cardIdName = xmlElem.GetAttribute("id"); int cardId = int.Parse(cardIdName); TriadCard cardOb = TriadCardDB.Get().cards[cardId]; result = new ImageHashData(cardOb, hashData, EImageHashType.Card); } else if (typeName.Equals("cactpot", StringComparison.InvariantCultureIgnoreCase)) { string numIdName = xmlElem.GetAttribute("id"); int numId = int.Parse(numIdName); if (numId >= 1 && numId <= 9) { result = new ImageHashData(CactpotGame.hashDB[numId - 1], hashData, EImageHashType.Cactpot); } } } return(result); }
static public List <object> GenerateHashOwnerOptions(ImageHashData hashData) { List <object> list = new List <object>(); switch (hashData.type) { case EImageHashType.Rule: foreach (TriadGameModifier mod in ImageHashDB.Get().modObjects) { list.Add(new HashOwnerItem(mod)); } break; case EImageHashType.CardImage: foreach (TriadCard card in TriadCardDB.Get().sameNumberMap[((TriadCard)hashData.ownerOb).SameNumberId]) { list.Add(new HashOwnerItem(card)); } break; case EImageHashType.CardNumber: for (int number = 1; number <= 10; number++) { list.Add(new HashOwnerItem(number)); } break; case EImageHashType.Cactpot: for (int number = 1; number <= 9; number++) { list.Add(new HashOwnerItem(number)); } break; default: break; } return(list); }
public List <ImageHashData> LoadImageHashes(JsonParser.ObjectValue jsonOb) { List <ImageHashData> list = new List <ImageHashData>(); string[] enumArr = Enum.GetNames(typeof(EImageHashType)); foreach (KeyValuePair <string, JsonParser.Value> kvp in jsonOb.entries) { EImageHashType groupType = (EImageHashType)Array.IndexOf(enumArr, kvp.Key); JsonParser.ArrayValue typeArr = (JsonParser.ArrayValue)kvp.Value; foreach (JsonParser.Value value in typeArr.entries) { JsonParser.ObjectValue jsonHashOb = (JsonParser.ObjectValue)value; string idStr = jsonHashOb["id"]; object hashOwner = null; switch (groupType) { case EImageHashType.Rule: hashOwner = ParseRule(idStr); break; case EImageHashType.Card: hashOwner = TriadCardDB.Get().cards[int.Parse(idStr)]; break; case EImageHashType.Cactpot: hashOwner = CactpotGame.hashDB[int.Parse(idStr) - 1]; break; default: break; } if (hashOwner != null) { HashCollection hashes = new HashCollection(jsonHashOb["hashC", JsonParser.StringValue.Empty], jsonHashOb["hashS", JsonParser.StringValue.Empty]); ImageHashData hashEntry = new ImageHashData(hashOwner, hashes, groupType); list.Add(hashEntry); } } } return(list); }
public void Load(JsonParser.ObjectValue configOb) { string ownerStr = configOb["player"] as JsonParser.StringValue; owner = (ownerStr == "blue") ? ETriadCardOwner.Blue : (ownerStr == "red") ? ETriadCardOwner.Red : ETriadCardOwner.Unknown; boardPos = configOb["pos"] as JsonParser.IntValue; if (configOb.entries.ContainsKey("board")) { string boardCode = configOb["board"] as JsonParser.StringValue; boardCode = boardCode.Replace(" ", ""); expectedState = new ETriadCardOwner[9]; for (int idx = 0; idx < expectedState.Length; idx++) { expectedState[idx] = (boardCode[idx] == 'R') ? ETriadCardOwner.Red : (boardCode[idx] == 'B') ? ETriadCardOwner.Blue : ETriadCardOwner.Unknown; } } var cardName = configOb["card"] as JsonParser.StringValue; if (cardName != null) { card = TriadCardDB.Get().Find(cardName); } else { var cardSides = configOb["card"] as JsonParser.ArrayValue; int numU = cardSides[0] as JsonParser.IntValue; int numL = cardSides[1] as JsonParser.IntValue; int numD = cardSides[2] as JsonParser.IntValue; int numR = cardSides[3] as JsonParser.IntValue; card = TriadCardDB.Get().Find(numU, numL, numD, numR); } }
public bool Load() { try { XmlDocument xdoc = new XmlDocument(); xdoc.Load(AssetManager.Get().GetAsset(DBPath)); foreach (XmlNode npcNode in xdoc.DocumentElement.ChildNodes) { XmlElement npcElem = (XmlElement)npcNode; if (npcElem != null && npcElem.Name == "npc") { try { List <TriadGameModifier> rules = new List <TriadGameModifier>(); List <TriadCard> rewards = new List <TriadCard>(); int[] deckA = new int[5]; int[] deckV = new int[5]; foreach (XmlNode innerNode in npcElem.ChildNodes) { XmlElement testElem = (XmlElement)innerNode; if (testElem != null) { if (testElem.Name == "rule") { int ruleId = int.Parse(testElem.GetAttribute("id")); rules.Add(TriadGameModifierDB.Get().mods[ruleId].Clone()); } else if (testElem.Name == "reward") { int cardId = int.Parse(testElem.GetAttribute("id")); rewards.Add(TriadCardDB.Get().cards[cardId]); } else if (testElem.Name == "deckA") { deckA[0] = int.Parse(testElem.GetAttribute("id0")); deckA[1] = int.Parse(testElem.GetAttribute("id1")); deckA[2] = int.Parse(testElem.GetAttribute("id2")); deckA[3] = int.Parse(testElem.GetAttribute("id3")); deckA[4] = int.Parse(testElem.GetAttribute("id4")); } else if (testElem.Name == "deckV") { deckV[0] = int.Parse(testElem.GetAttribute("id0")); deckV[1] = int.Parse(testElem.GetAttribute("id1")); deckV[2] = int.Parse(testElem.GetAttribute("id2")); deckV[3] = int.Parse(testElem.GetAttribute("id3")); deckV[4] = int.Parse(testElem.GetAttribute("id4")); } } } TriadNpc newNpc = new TriadNpc( int.Parse(npcElem.GetAttribute("id")), rules, rewards, deckA, deckV); newNpc.LocationX = int.Parse(npcElem.GetAttribute("mx")); newNpc.LocationY = int.Parse(npcElem.GetAttribute("my")); while (npcs.Count <= newNpc.Id) { npcs.Add(null); } npcs[newNpc.Id] = newNpc; } catch (Exception ex) { Logger.WriteLine("Loading failed! Exception:" + ex); } } } } catch (Exception ex) { Logger.WriteLine("Loading failed! Exception:" + ex); } Logger.WriteLine("Loaded npcs: " + npcs.Count); return(npcs.Count > 0); }
public bool Load() { List <TriadNpc> loadedNpcs = new List <TriadNpc>(); int maxLoadedId = 0; List <TriadGameModifier> modObjects = new List <TriadGameModifier>(); foreach (Type type in Assembly.GetAssembly(typeof(TriadGameModifier)).GetTypes()) { if (type.IsSubclassOf(typeof(TriadGameModifier))) { modObjects.Add((TriadGameModifier)Activator.CreateInstance(type)); } } try { XmlDocument xdoc = new XmlDocument(); xdoc.Load(AssetManager.Get().GetAsset(DBPath)); foreach (XmlNode npcNode in xdoc.DocumentElement.ChildNodes) { XmlElement npcElem = (XmlElement)npcNode; if (npcElem != null && npcElem.Name == "npc") { try { List <TriadGameModifier> rules = new List <TriadGameModifier>(); List <TriadCard> rewards = new List <TriadCard>(); int[] deckA = new int[5]; int[] deckV = new int[5]; foreach (XmlNode innerNode in npcElem.ChildNodes) { XmlElement testElem = (XmlElement)innerNode; if (testElem != null) { if (testElem.Name == "rule") { rules.Add(ParseRule(testElem.GetAttribute("name"), modObjects)); } else if (testElem.Name == "reward") { int cardId = int.Parse(testElem.GetAttribute("id")); rewards.Add(TriadCardDB.Get().cards[cardId]); } else if (testElem.Name == "deckA") { deckA[0] = int.Parse(testElem.GetAttribute("id0")); deckA[1] = int.Parse(testElem.GetAttribute("id1")); deckA[2] = int.Parse(testElem.GetAttribute("id2")); deckA[3] = int.Parse(testElem.GetAttribute("id3")); deckA[4] = int.Parse(testElem.GetAttribute("id4")); } else if (testElem.Name == "deckV") { deckV[0] = int.Parse(testElem.GetAttribute("id0")); deckV[1] = int.Parse(testElem.GetAttribute("id1")); deckV[2] = int.Parse(testElem.GetAttribute("id2")); deckV[3] = int.Parse(testElem.GetAttribute("id3")); deckV[4] = int.Parse(testElem.GetAttribute("id4")); } } } TriadNpc newNpc = new TriadNpc( int.Parse(npcElem.GetAttribute("id")), WebUtility.HtmlDecode(npcElem.GetAttribute("name")), WebUtility.HtmlDecode(npcElem.GetAttribute("location")), rules, rewards, deckA, deckV); loadedNpcs.Add(newNpc); maxLoadedId = Math.Max(maxLoadedId, newNpc.Id); } catch (Exception ex) { Logger.WriteLine("Loading failed! Exception:" + ex); } } } } catch (Exception ex) { Logger.WriteLine("Loading failed! Exception:" + ex); } if (loadedNpcs.Count > 0) { while (npcs.Count < (maxLoadedId + 1)) { npcs.Add(null); } foreach (TriadNpc npc in loadedNpcs) { npcs[npc.Id] = npc; } } Logger.WriteLine("Loaded npcs: " + npcs.Count); return(loadedNpcs.Count > 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 rootOb = JsonParser.ParseJson(configText); if (rootOb["type"] != "Screen") { return; } ScannerTriad.VerifyConfig configData = new ScannerTriad.VerifyConfig(); configData.Load(rootOb); // setup npc & modifiers TriadNpc testNpc = TriadNpcDB.Get().Find(configData.npc); if (testNpc == null) { string exceptionMsg = string.Format("Test {0} failed! Can't find npc: {1}", testName, configData.npc); throw new Exception(exceptionMsg); } ScannerTriad.GameState screenGame = new ScannerTriad.GameState(); 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) { screenGame.mods.Add(mapValidationRules[modName]); } 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); }; bool needsLockedBlue = false; for (int idx = 0; idx < 5; idx++) { screenGame.blueDeck[idx] = ConvertToTriadCard(configData.deckBlue[idx]); screenGame.redDeck[idx] = ConvertToTriadCard(configData.deckRed[idx]); if (configData.deckBlue[idx].state == ScannerTriad.ECardState.Locked) { needsLockedBlue = true; } } if (needsLockedBlue) { for (int idx = 0; idx < 5; idx++) { if (configData.deckBlue[idx].state == ScannerTriad.ECardState.Visible) { screenGame.forcedBlueCard = screenGame.blueDeck[idx]; break; } } } for (int idx = 0; idx < 9; idx++) { screenGame.board[idx] = ConvertToTriadCard(configData.board[idx]); screenGame.boardOwner[idx] = configData.board[idx].state == ScannerTriad.ECardState.PlacedBlue ? ETriadCardOwner.Blue : configData.board[idx].state == ScannerTriad.ECardState.PlacedRed ? ETriadCardOwner.Red : ETriadCardOwner.Unknown; } TriadGameScreenMemory screenMemory = new TriadGameScreenMemory { logScan = false }; screenMemory.OnNewScan(screenGame, testNpc); screenMemory.gameSession.SolverFindBestMove(screenMemory.gameState, out int solverBoardPos, out TriadCard solverTriadCard, out TriadGameResultChance bestChance); if (bestChance.expectedResult == ETriadGameState.BlueLost && bestChance.winChance <= 0.0f && bestChance.drawChance <= 0.0f) { string exceptionMsg = string.Format("Test {0} failed! Can't find move!", testName); throw new Exception(exceptionMsg); } }
private bool FindSwappedCardVisible(TriadCard[] screenCards, TriadCardInstance[] board, TriadDeckInstanceScreen otherDeck, out int swappedCardIdx, out int swappedOtherIdx, out TriadCard swappedCard) { swappedCardIdx = -1; swappedOtherIdx = -1; swappedCard = null; int numDiffs = 0; int numOnHand = 0; int hiddenCardId = TriadCardDB.Get().hiddenCard.Id; for (int Idx = 0; Idx < otherDeck.cards.Length; Idx++) { if (otherDeck.cards[Idx] != null && otherDeck.cards[Idx].Id != hiddenCardId) { // find in source deck, not in instance int cardIdx = otherDeck.deck.GetCardIndex(otherDeck.cards[Idx]); if (cardIdx < 0) { swappedOtherIdx = Idx; swappedCard = otherDeck.cards[Idx]; for (int ScreenIdx = 0; ScreenIdx < screenCards.Length; ScreenIdx++) { cardIdx = otherDeck.deck.GetCardIndex(screenCards[ScreenIdx]); if (cardIdx >= 0) { swappedCardIdx = ScreenIdx; numDiffs++; } } } } numOnHand += (otherDeck.cards[Idx] != null) ? 1 : 0; } bool bBoardMode = false; if (numOnHand < screenCards.Length) { for (int Idx = 0; Idx < board.Length; Idx++) { if (board[Idx] != null && board[Idx].owner == ETriadCardOwner.Red) { // find in source deck, not in instance int cardIdx = otherDeck.deck.GetCardIndex(board[Idx].card); if (cardIdx < 0) { swappedCard = board[Idx].card; swappedOtherIdx = 100; // something way outside, it's not going to be used directly as card was already placed for (int ScreenIdx = 0; ScreenIdx < screenCards.Length; ScreenIdx++) { cardIdx = otherDeck.deck.GetCardIndex(screenCards[ScreenIdx]); if (cardIdx >= 0) { swappedCardIdx = ScreenIdx; bBoardMode = true; numDiffs++; } } } } } } bool bHasSwapped = (numDiffs == 1); Logger.WriteLine("FindSwappedCardVisible: blue[" + swappedCardIdx + "]:" + (swappedCardIdx >= 0 ? screenCards[swappedCardIdx].Name : "??") + " <=> red[" + swappedOtherIdx + "]:" + (swappedCard != null ? swappedCard.Name : "??") + ", boardMode:" + bBoardMode + ", diffs:" + numDiffs + " => " + (bHasSwapped ? "SWAP" : "ignore")); return(bHasSwapped); }
private void UpdateAvailableRedCards(TriadDeckInstanceScreen redDeck, TriadCard[] screenCardsRed, TriadCard[] screenCardsBlue, TriadCard[] screenBoard, TriadCard[] prevCardsBlue, TriadCardInstance[] prevBoard, bool bContinuePrevState) { bool bDebugMode = false; int hiddenCardId = TriadCardDB.Get().hiddenCard.Id; int numVisibleCards = deckRed.cards.Length; redDeck.numPlaced = 0; if (!bContinuePrevState) { redDeck.numUnknownPlaced = 0; } int maxUnknownToUse = redDeck.cards.Length - redDeck.deck.knownCards.Count; int firstUnknownPoolIdx = redDeck.cards.Length + redDeck.deck.knownCards.Count; if (redDeck.deck.unknownCardPool.Count > 0) { redDeck.unknownPoolMask = ((1 << redDeck.deck.unknownCardPool.Count) - 1) << firstUnknownPoolIdx; for (int Idx = 0; Idx < screenCardsRed.Length; Idx++) { if ((screenCardsRed[Idx] != null) && (screenCardsRed[Idx].Id != hiddenCardId) && redDeck.deck.unknownCardPool.Contains(screenCardsRed[Idx])) { redDeck.unknownPoolMask |= (1 << Idx); } } } int allDeckAvailableMask = ((1 << (redDeck.deck.knownCards.Count + redDeck.deck.unknownCardPool.Count)) - 1) << numVisibleCards; bool bCanCompareWithPrevData = (screenCardsRed.Length == redDeck.cards.Length) && (screenCardsBlue.Length == prevCardsBlue.Length) && (screenBoard.Length == prevBoard.Length); if (bCanCompareWithPrevData && !bContinuePrevState) { // special case: 1st turn int numCardsOnBoard = 0; for (int Idx = 0; Idx < screenBoard.Length; Idx++) { if (screenBoard[Idx] != null) { numCardsOnBoard++; } } if (numCardsOnBoard <= 1) { bCanCompareWithPrevData = true; prevBoard = new TriadCardInstance[screenBoard.Length]; prevCardsBlue = new TriadCard[numVisibleCards]; deckRed.cards = new TriadCard[numVisibleCards]; deckRed.availableCardMask = allDeckAvailableMask; deckRed.numPlaced = 0; deckRed.numUnknownPlaced = 0; } else { bCanCompareWithPrevData = false; } } if (bDebugMode) { Logger.WriteLine("Red deck update, diff mode check... " + "bContinuePrevState:" + bContinuePrevState + ", cards(screen:" + screenCardsRed.Length + ", prev:" + deckRed.cards.Length + ")=" + ((screenCardsRed.Length == deckRed.cards.Length) ? "ok" : "nope") + ", other(screen:" + screenCardsBlue.Length + ", prev:" + prevCardsBlue.Length + ")=" + ((screenCardsBlue.Length == prevCardsBlue.Length) ? "ok" : "nope") + ", board(screen:" + screenBoard.Length + ", prev:" + prevBoard.Length + ")=" + ((screenBoard.Length == prevBoard.Length) ? "ok" : "nope")); } if (bCanCompareWithPrevData) { // create diffs, hopefully prev state comes from last turn and is just 2 cards away List <int> usedCardsIndices = new List <int>(); List <TriadCard> usedCardsOther = new List <TriadCard>(); int numKnownOnHand = 0; int numUnknownOnHand = 0; int numHidden = 0; int numOnHand = 0; for (int Idx = 0; Idx < deckRed.cards.Length; Idx++) { if (screenCardsRed[Idx] == null) { TriadCard prevCard = deckRed.cards[Idx]; if ((prevCard != null) && (prevCard.Id != hiddenCardId)) { if (bDebugMode) { Logger.WriteLine(" card[" + Idx + "]:" + prevCard.Name + " => mark as used, disappeared from prev state"); } usedCardsIndices.Add(Idx); } deckRed.availableCardMask &= ~(1 << Idx); deckRed.numPlaced++; } else { if (screenCardsRed[Idx].Id != hiddenCardId) { bool bIsUnknown = (deckRed.unknownPoolMask & (1 << Idx)) != 0; numUnknownOnHand += bIsUnknown ? 1 : 0; numKnownOnHand += bIsUnknown ? 0 : 1; numOnHand++; deckRed.availableCardMask |= (1 << Idx); int knownCardIdx = deckRed.deck.knownCards.IndexOf(screenCardsRed[Idx]); int unknownCardIdx = deckRed.deck.unknownCardPool.IndexOf(screenCardsRed[Idx]); if (knownCardIdx >= 0) { deckRed.availableCardMask &= ~(1 << (knownCardIdx + deckRed.cards.Length)); } else if (unknownCardIdx >= 0) { deckRed.availableCardMask &= ~(1 << (unknownCardIdx + deckRed.cards.Length + deckRed.deck.knownCards.Count)); } if (bDebugMode) { TriadCard cardOb = screenCardsRed[Idx]; Logger.WriteLine(" card[" + Idx + "]:" + (cardOb != null ? cardOb.Name : "??") + " => numUnknown:" + numUnknownOnHand + ", numKnown:" + numKnownOnHand + ", numHidden:" + numHidden); } } else { numHidden++; } } } for (int Idx = 0; Idx < prevCardsBlue.Length; Idx++) { if ((prevCardsBlue[Idx] != null) && (screenCardsBlue[Idx] == null)) { usedCardsOther.Add(prevCardsBlue[Idx]); if (bDebugMode) { Logger.WriteLine(" blue[" + Idx + "]:" + prevCardsBlue[Idx].Name + " => mark as used"); } } } for (int Idx = 0; Idx < prevBoard.Length; Idx++) { TriadCard testCard = screenBoard[Idx]; if ((prevBoard[Idx] == null || prevBoard[Idx].card == null) && (testCard != null)) { int testCardIdx = deckRed.GetCardIndex(testCard); if (!usedCardsOther.Contains(testCard) && (testCardIdx >= 0)) { usedCardsIndices.Add(testCardIdx); if (bDebugMode) { Logger.WriteLine(" card[" + testCardIdx + "]:" + testCard.Name + " => mark as used, appeared on board[" + Idx + "], not used by blue"); } } } } Array.Copy(screenCardsRed, deckRed.cards, 5); for (int Idx = 0; Idx < usedCardsIndices.Count; Idx++) { int cardMask = 1 << usedCardsIndices[Idx]; deckRed.availableCardMask &= ~cardMask; bool bIsUnknownPool = (deckRed.unknownPoolMask & cardMask) != 0; if (bIsUnknownPool) { deckRed.numUnknownPlaced++; } if (bDebugMode) { TriadCard cardOb = deckRed.GetCard(usedCardsIndices[Idx]); Logger.WriteLine(" card[" + usedCardsIndices[Idx] + "]:" + (cardOb != null ? cardOb.Name : "??") + " => used"); } } if ((numHidden == 0) && ((numOnHand + deckRed.numPlaced) == numVisibleCards)) { deckRed.availableCardMask &= (1 << numVisibleCards) - 1; if (bDebugMode) { Logger.WriteLine(" all cards are on hand and visible"); } } else if ((deckRed.numUnknownPlaced + numUnknownOnHand) >= maxUnknownToUse || ((numKnownOnHand >= (numVisibleCards - maxUnknownToUse)) && (numHidden == 0))) { deckRed.availableCardMask &= (1 << (numVisibleCards + deckRed.deck.knownCards.Count)) - 1; if (bDebugMode) { Logger.WriteLine(" removing all unknown cards, numUnknownPlaced:" + deckRed.numUnknownPlaced + ", numUnknownOnHand:" + numUnknownOnHand + ", numKnownOnHand:" + numKnownOnHand + ", numHidden:" + numHidden + ", maxUnknownToUse:" + maxUnknownToUse); } } } else { // TriadDeckInstanceScreen is mostly stateless (created from scratch on screen capture) // this makes guessing which cards were placed hard, especially when there's no good // history data to compare with. // Ignore board data here, cards could be placed by blue and are still available for red deck deckRed.UpdateAvailableCards(screenCardsRed); deckRed.availableCardMask = allDeckAvailableMask; } if (bDebugMode) { redDeck.LogAvailableCards("Red deck"); } }
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); } } }
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); }
private bool UpdateCards(GameDataLists gameDataLists, Dictionary <string, ETriadCardType> mapCardTypes) { Logger.WriteLine("Updating card list..."); TriadCardDB cardDB = TriadCardDB.Get(); foreach (var cardData in gameDataLists.cards) { TriadCard cardOb = (cardData.Id < cardDB.cards.Count) ? cardDB.cards[cardData.Id] : null; if (cardOb != null) { // ensure side numbers are the same if (cardOb.Sides[0] != cardData.sideTop || cardOb.Sides[1] != cardData.sideLeft || cardOb.Sides[2] != cardData.sideBottom || cardOb.Sides[3] != cardData.sideRight) { Logger.WriteLine("FAILED card update, id:{0} name:{1} is not matching side numbers!", cardData.Id, cardData.LinkedName.Name.GetCodeName()); return(false); } } else { while (cardDB.cards.Count <= cardData.Id) { cardDB.cards.Add(null); } int iconId = 82500 + cardData.Id; string iconPath = iconId.ToString("000000") + ".png"; cardOb = new TriadCard(cardData.Id, iconPath, (ETriadCardRarity)(cardData.rarityIdx - 1), mapCardTypes[cardData.LinkedType == null ? "" : cardData.LinkedType.Type.GetCodeName()], cardData.sideTop, cardData.sideBottom, cardData.sideLeft, cardData.sideRight, cardData.sortOrder, cardData.uiGroup); Logger.WriteLine(">> adding new card: " + cardOb.ToString()); cardDB.cards[cardData.Id] = cardOb; } cardOb.Name.Text = cardData.LinkedName.Name.Text; } for (int idx = 0; idx < cardDB.cards.Count; idx++) { TriadCard cardOb = cardDB.cards[idx]; if (cardOb != null) { var matchingCardData = gameDataLists.cards.Find(x => (x.Id == cardOb.Id)); if (matchingCardData == null) { Logger.WriteLine(">> removing card: " + cardOb.ToString()); cardDB.cards[idx] = null; continue; } if (cardOb.Id != idx) { Logger.WriteLine("FAILED card update, index mismatch for card[{0}].Id:{1}, Name:{2}", idx, cardOb.Id, cardOb.Name.GetCodeName()); return(false); } } } return(true); }
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); }
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 bool UpdateCards(Dictionary <int, TriadCard> cardMap) { TriadCardDB cardDB = TriadCardDB.Get(); int newCardId = cardDB.cards[cardDB.cards.Count - 1].Id + 1; bool hasChanges = false; foreach (KeyValuePair <int, TriadCard> kvp in cardMap) { if (kvp.Key > 285) { int a = 1; a++; } if (kvp.Key >= newCardId) { kvp.Value.Id = kvp.Key; newCardId = kvp.Key + 1; while (cardDB.cards.Count < newCardId) { cardDB.cards.Add(null); } cardDB.cards[kvp.Value.Id] = kvp.Value; Logger.WriteLine("Newly added card: " + kvp.Value.ToShortString()); hasChanges = true; continue; } TriadCard cardMatch = cardDB.Find(kvp.Value.Name); if (cardMatch == null) { foreach (TriadCard testCard in cardDB.cards) { if (testCard != null && testCard.Rarity == kvp.Value.Rarity && testCard.Type == kvp.Value.Type && testCard.Sides[0] == kvp.Value.Sides[0] && testCard.Sides[1] == kvp.Value.Sides[1] && testCard.Sides[2] == kvp.Value.Sides[2] && testCard.Sides[3] == kvp.Value.Sides[3]) { Logger.WriteLine("Card name remap: " + testCard.ToShortString() + " => " + kvp.Value.Name); cardMatch = testCard; hasChanges = true; break; } } } if (cardMatch != null) { kvp.Value.Id = cardMatch.Id; cardDB.cards[kvp.Value.Id] = kvp.Value; } else { TriadCard otherCard = cardDB.cards[kvp.Key]; Logger.WriteLine("Missing card match: " + kvp.Value.ToString() + "! Will replace existing Id: " + (otherCard != null ? otherCard.ToString() : "??")); kvp.Value.Id = kvp.Key; cardDB.cards[kvp.Value.Id] = kvp.Value; hasChanges = true; } } if (hasChanges) { cardDB.Save(); } return(hasChanges); }
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); }