using System; using System.Collections.Generic; using System.Linq; using UnityEngine; [System.Serializable] public class DeckData { public static int m = 256; public static int n = 256; public static int log_n_m = (int)Mathf.Log(m, n); public static int maxCardKind = 37000; public static int CardKindCellLength = (int)Math.Ceiling(Mathf.Log(maxCardKind, m)); #region コンストラクタ public DeckData(string DeckCode) { List _DeckCardIDs = new List(); List _DigitamaDeckCardIDs = new List(); //コンマで区切り string[] parseByComma = DeckCode.Split(','); List DistinctDeckCardIDs = new List(); List DistinctDeckCardCounts = new List(); List DistinctDigitamaDeckCardIDs = new List(); List DistinctDigitamaDeckCardCounts = new List(); for (int i = 0; i < parseByComma.Length; i++) { //デッキ名 if (i == 0) { DeckName = parseByComma[i]; } //デッキのカード(重複なし) else if (i == 1) { //2文字ごとに区切り string[] SplitText = SplitClass.Split(parseByComma[i], CardKindCellLength); for (int j = 0; j < SplitText.Length; j++) { DistinctDeckCardIDs.Add(ConvertBinaryNumber.NStringToInt(SplitText[j], m)); } } //カード各種の枚数 else if (i == 2) { //m進数の文字列 string x_m = parseByComma[i]; if (!string.IsNullOrEmpty(x_m)) { //m進数をn進数に変換 string x_n = ConvertBinaryNumber.NKStringToNString(x_m, n, log_n_m); //n進数の文字列を1文字ずつ区切り string[] Split_x_n = SplitClass.Split(x_n, 1); for (int j = 0; j < Split_x_n.Length; j++) { //n進数をintに変換 DistinctDeckCardCounts.Add(ConvertBinaryNumber.NStringToInt(Split_x_n[j], n) + 1); } } } //デジタマデッキのカード(重複なし) else if (i == 3) { //2文字ごとに区切り string[] SplitText = SplitClass.Split(parseByComma[i], CardKindCellLength); for (int j = 0; j < SplitText.Length; j++) { DistinctDigitamaDeckCardIDs.Add(ConvertBinaryNumber.NStringToInt(SplitText[j], m)); } } //カード各種の枚数 else if (i == 4) { //m進数の文字列 string x_m = parseByComma[i]; if (!string.IsNullOrEmpty(x_m)) { //m進数をn進数に変換 string x_n = ConvertBinaryNumber.NKStringToNString(x_m, n, log_n_m); //n進数の文字列を1文字ずつ区切り string[] Split_x_n = SplitClass.Split(x_n, 1); for (int j = 0; j < Split_x_n.Length; j++) { //n進数をintに変換 DistinctDigitamaDeckCardCounts.Add(ConvertBinaryNumber.NStringToInt(Split_x_n[j], n) + 1); } } } //キーカードID else if (i == 5) { if (int.TryParse(parseByComma[i], out int value)) { KeyCardId = value; } } } for (int i = 0; i < DistinctDeckCardIDs.Count; i++) { if (i < DistinctDeckCardCounts.Count) { for (int j = 0; j < DistinctDeckCardCounts[i]; j++) { _DeckCardIDs.Add(DistinctDeckCardIDs[i]); } } } for (int i = 0; i < DistinctDigitamaDeckCardIDs.Count; i++) { if (i < DistinctDigitamaDeckCardCounts.Count) { for (int j = 0; j < DistinctDigitamaDeckCardCounts[i]; j++) { _DigitamaDeckCardIDs.Add(DistinctDigitamaDeckCardIDs[i]); } } } DeckCardIDs = _DeckCardIDs; DigitamaDeckCardIDs = _DigitamaDeckCardIDs; } #endregion #region デッキ名 string _deckName = ""; public string DeckName { get { if (string.IsNullOrEmpty(_deckName)) { return "NewDeck"; } return _deckName; } set { _deckName = value; } } #endregion #region デッキに含まれるカードリスト public List DeckCards() { List deckCards = new List(); if (DeckCardIDs != null) { foreach (int DeckCardID in DeckCardIDs) { CEntity_Base cEntity_Base = ContinuousController.instance.getCardEntityByCardID(DeckCardID); if (cEntity_Base != null) { deckCards.Add(cEntity_Base); } } } return deckCards; } #endregion #region デジタマデッキに含まれるカードリスト public List DigitamaDeckCards() { List deckCards = new List(); foreach (int DeckCardID in DigitamaDeckCardIDs) { CEntity_Base cEntity_Base = ContinuousController.instance.getCardEntityByCardID(DeckCardID); if (cEntity_Base != null) { deckCards.Add(cEntity_Base); } } return deckCards; } #endregion #region デッキの全カード public List AllDeckCards() { List AllDeckCards = new List(); foreach (CEntity_Base cEntity_Base in DigitamaDeckCards()) { AllDeckCards.Add(cEntity_Base); } foreach (CEntity_Base cEntity_Base in DeckCards()) { AllDeckCards.Add(cEntity_Base); } return AllDeckCards; } #endregion #region キーカード public int KeyCardId { get; set; } = -1; public CEntity_Base KeyCard { get { if (KeyCardId >= 0) { foreach (CEntity_Base Card in ContinuousController.instance.CardList) { if (Card.CardIndex == KeyCardId) { return Card; } } } if (DeckCards().Count >= 1) { List deckCards = new List(); foreach (CEntity_Base cEntity_Base in DeckCards()) { deckCards.Add(cEntity_Base); } deckCards = deckCards .OrderBy(value => Array.IndexOf(DataBase.cardKinds, value.cardKind)) .ThenByDescending(value => value.Level) .ThenBy(value => Array.IndexOf(DataBase.cardColors, value.cardColors[0])) .ThenByDescending(value => value.PlayCost) .ThenByDescending(value => value.DP) .ThenBy(value => value.CardIndex) .ToList(); return deckCards[0]; } else if (DigitamaDeckCards().Count >= 1) { return DigitamaDeckCards()[0]; } return null; } } #endregion #region デッキに含まれるカードIDリスト public List DeckCardIDs { get; set; } = new List(); public List DigitamaDeckCardIDs { get; set; } = new List(); #region カードを追加する public void AddCard(CEntity_Base cEntity_Base) { if (cEntity_Base.cardKind == CardKind.DigiEgg) { AddDigitamaDeckCard(cEntity_Base); } else { AddDeckCard(cEntity_Base); } } #endregion #region カードを除く public void RemoveCard(CEntity_Base cEntity_Base) { if (cEntity_Base.cardKind == CardKind.DigiEgg) { RemoveDigitamaDeckCard(cEntity_Base); } else { RemoveDeckCard(cEntity_Base); } } #endregion #region デッキにカードを追加する void AddDeckCard(CEntity_Base cEntity_Base) { List _DeckCards = DeckCards(); _DeckCards.Add(cEntity_Base); _DeckCards = SortedDeckCardsList(_DeckCards); DeckCardIDs = GetDeckCardCodes(_DeckCards); } #endregion #region デッキからカードを抜く void RemoveDeckCard(CEntity_Base cEntity_Base) { List _DeckCards = DeckCards(); _DeckCards.Remove(cEntity_Base); _DeckCards = SortedDeckCardsList(_DeckCards); DeckCardIDs = GetDeckCardCodes(_DeckCards); } #endregion #region デジタマデッキにカードを追加する void AddDigitamaDeckCard(CEntity_Base cEntity_Base) { List _DeckCards = DigitamaDeckCards(); _DeckCards.Add(cEntity_Base); _DeckCards = SortedDeckCardsList(_DeckCards); DigitamaDeckCardIDs = GetDeckCardCodes(_DeckCards); } #endregion #region デジタマデッキからカードを抜く void RemoveDigitamaDeckCard(CEntity_Base cEntity_Base) { List _DeckCards = DigitamaDeckCards(); _DeckCards.Remove(cEntity_Base); _DeckCards = SortedDeckCardsList(_DeckCards); DigitamaDeckCardIDs = GetDeckCardCodes(_DeckCards); } #endregion #region カードリストからカードIDリストを取得 public static List GetDeckCardCodes(List DeckCards) { List _DeckCardCodes = new List(); foreach (CEntity_Base DeckCard in DeckCards) { _DeckCardCodes.Add(DeckCard.CardIndex); } return _DeckCardCodes; } #endregion #endregion #region カードリストをソート public static List SortedDeckCardsList(List DeckCards) { List DeckCards1 = new List(); foreach (CEntity_Base cEntity_Base in DeckCards) { DeckCards1.Add(cEntity_Base); } DeckCards1 = DeckCards1 .OrderBy(value => Array.IndexOf(DataBase.cardKinds, value.cardKind)) .ThenBy(value => value.Level) .ThenBy(value => Array.IndexOf(DataBase.cardColors, value.cardColors[0])) .ThenByDescending(value => value.PlayCost) .ThenByDescending(value => value.DP) .ThenBy(value => value.CardIndex) .ToList(); return DeckCards1; } public static List SortedCardPoolList(List DeckCards) { List DeckCards1 = new List(); foreach (CEntity_Base cEntity_Base in DeckCards) { DeckCards1.Add(cEntity_Base); } DeckCards1 = DeckCards1 .OrderBy(value => Array.IndexOf(DataBase.SetIDs, value.SetID)) .ThenBy(value => Array.IndexOf(DataBase.cardColors, value.cardColors[0])) .ThenBy(value => value.CardID) .ThenBy(value => value.CardIndex) .ToList(); return DeckCards1; } public static List SortedCardsList(List DeckCards) { List DeckCards1 = new List(); foreach (CardSource cardSource in DeckCards) { DeckCards1.Add(cardSource); } DeckCards1 = DeckCards1 .OrderBy(value => value.SetID) .ThenBy(value => Array.IndexOf(DataBase.cardKinds, value.CardKind)) .ThenBy(value => Array.IndexOf(DataBase.cardColors, value.BaseCardColorsFromEntity[0])) .ThenByDescending(value => value.BaseEvoCostsFromEntity.Count) .ThenByDescending(value => value.CardDP) .ThenBy(value => value.CardEntityIndex) .ToList(); return DeckCards1; } #endregion #region 256進数のデッキコードを取得 #region デッキ名とデッキのカードから256進数のデッキコードを取得 public static string GetDeckCode(string _DeckName, List _DeckCards, List _DigitamaDeckCards, CEntity_Base keyCard) { string _DeckDataString = null; //デッキ名 _DeckDataString += _DeckName + ","; SetDeckCard(_DeckCards); SetDeckCard(_DigitamaDeckCards); if (keyCard != null) { _DeckDataString += $"{keyCard.CardIndex},"; } else { _DeckDataString += $"-1,"; } //Debug.Log($"生デッキコード:{_DeckDataString}"); void SetDeckCard(List cEntity_Bases) { //カードリストを重複なしリストにする List DistinctDeckCards = cEntity_Bases.Distinct().ToList(); //重複なしのカードIDリストを登録 foreach (CEntity_Base cardData in DistinctDeckCards) { _DeckDataString += cardData.CardIndex_String; } _DeckDataString += ","; //各カードの種類のカード枚数を保存(1減らす) List _DistinctDeckCardCounts = new List(); foreach (CEntity_Base cardData in DistinctDeckCards) { _DistinctDeckCardCounts.Add(cEntity_Bases.Count((_CardData) => _CardData == cardData) - 1); } string x_n = null; //デッキ内のカード枚数をn進数に変換 for (int i = 0; i < _DistinctDeckCardCounts.Count; i++) { x_n += ConvertBinaryNumber.IntToNString(_DistinctDeckCardCounts[i], n); } //桁数がlog(n)m桁になるように0埋め if (x_n != null) { while (x_n.Count() % log_n_m != 0) { x_n += "0"; } } //n進数をm進数に変換 if (x_n != null) { string x_m = ConvertBinaryNumber.NStringToNKString(x_n, n, log_n_m); _DeckDataString += x_m; } _DeckDataString += ","; } return _DeckDataString; } #endregion #region このデッキのデッキコードを取得 public string GetThisDeckCode() { return DeckData.GetDeckCode(DeckName, DeckCards(), DigitamaDeckCards(), KeyCard); } #endregion #endregion #region その文字列がデッキコードとして適するか public static bool IsValidDeckCode(string DeckCode) { if (!DeckCode.Contains(",")) { return false; } string[] parseByComma = DeckCode.Split(','); if (parseByComma.Length != 5 && parseByComma.Length != 6) { return false; } if (!string.IsNullOrEmpty(parseByComma[1])) { string[] SplitText = SplitClass.Split(parseByComma[1], 1); for (int j = 0; j < SplitText.Length; j++) { if (ConvertBinaryNumber.NStringToInt(SplitText[j], m) == 114514) { return false; } } } else { return false; } if (!string.IsNullOrEmpty(parseByComma[2])) { //256進数の文字列 string x_m = parseByComma[2]; //256進数をn進数に変換 string x_n = ConvertBinaryNumber.NKStringToNString(x_m, n, log_n_m); if (x_n == "114514") { Debug.Log("[2]:114514"); return false; } } else { return false; } if (!string.IsNullOrEmpty(parseByComma[3])) { string[] SplitText = SplitClass.Split(parseByComma[3], 1); for (int j = 0; j < SplitText.Length; j++) { if (ConvertBinaryNumber.NStringToInt(SplitText[j], m) == 114514) { return false; } } } if (!string.IsNullOrEmpty(parseByComma[4])) { //256進数の文字列 string x_m = parseByComma[4]; //256進数をn進数に変換 string x_n = ConvertBinaryNumber.NKStringToNString(x_m, n, log_n_m); if (x_n == "114514") { Debug.Log("[4]:114514"); return false; } } if (parseByComma.Length >= 6) { if (!string.IsNullOrEmpty(parseByComma[5])) { if (!int.TryParse(parseByComma[5], out int value)) { return false; } } } return true; } #endregion #region このデッキデータが対戦に使えるかどうか public bool IsValidDeckData() { //デッキ枚数はちょうど50枚 if (DeckCards().Count != 50) { return false; } if (DigitamaDeckCards().Count > 5) { return false; } foreach (CEntity_Base cEntity_Base in DeckCards()) { if (!cEntity_Base.IsStandardValid) { return false; } } foreach (CEntity_Base cEntity_Base in DigitamaDeckCards()) { if (!cEntity_Base.IsStandardValid) { return false; } } return true; } #endregion #region 空白のデッキコード public static DeckData EmptyDeckData() { return new DeckData(""); } #endregion #region インポートしたデッキデータを修正 public DeckData ModifiedDeckData() { List deckCards = new List(); List digitamaDeckCards = new List(); foreach (CEntity_Base cEntity_Base in AllDeckCards()) { if (cEntity_Base.cardKind != CardKind.DigiEgg) { deckCards.Add(cEntity_Base); } else { digitamaDeckCards.Add(cEntity_Base); } } List modifiedDeckCards = modifiedList(deckCards); List modifiedDigitamaDeckCards = modifiedList(digitamaDeckCards); List modifiedList(List cEntity_Bases) { //カードリストを重複なしのリストにする List DistinctDeckCards = cEntity_Bases.Distinct().ToList(); List DistinctDeckCards1 = new List(); foreach (CEntity_Base cEntity_Base in DistinctDeckCards) { if (DistinctDeckCards1.Count((cEntity_Base1) => cEntity_Base.CardID == cEntity_Base1.CardID) == 0) { DistinctDeckCards1.Add(cEntity_Base); } } List deckCards = new List(); foreach (CEntity_Base cEntity_Base in cEntity_Bases) { deckCards.Add(cEntity_Base); } //規定枚数以上のカードを抜く foreach (CEntity_Base cEntity_Base in DistinctDeckCards1) { while (cEntity_Base.SameCardIDCount(deckCards) > cEntity_Base.MaxCountInDeck) { CEntity_Base removeCard = null; foreach (CEntity_Base cEntity_Base1 in deckCards) { if (cEntity_Base1.CardID == cEntity_Base.CardID) { removeCard = cEntity_Base1; break; } } if (removeCard != null) { deckCards.Remove(removeCard); } } } return deckCards; } DeckData deckData = new DeckData(GetDeckCode(ValidateDeckName(this._deckName), modifiedDeckCards, modifiedDigitamaDeckCards, KeyCard)); if (!deckData.AllDeckCards().Contains(deckData.KeyCard)) { deckData.KeyCardId = -1; } DeckData deckData1 = DeckBuildingRule.ModifiedDeckData(deckData); return deckData1; } #endregion #region デッキ名を修正 public static string ValidateDeckName(string deckName) { if (String.IsNullOrEmpty(deckName)) { return deckName; } List ErrorLetters = new List() { ",", "_", "*", "/", }; foreach (string error in ErrorLetters) { deckName = deckName.Replace(error, ""); } return deckName; } #endregion } #region 文字列を分割 public static class SplitClass { public static string[] Split(this string str, int count) { var list = new List(); int length = (int)Math.Ceiling((double)str.Length / count); for (int i = 0; i < length; i++) { int start = count * i; if (str.Length <= start) { break; } if (str.Length < start + count) { list.Add(str.Substring(start)); } else { list.Add(str.Substring(start, count)); } } return list.ToArray(); } } #endregion