fork download
  1. namespace PokePoke
  2. {
  3. internal static class Program
  4. {
  5. #region <共通メソッド>
  6. public static List<Card> Deck;
  7.  
  8. /// <summary>
  9. /// カードの定義
  10. /// </summary>
  11. public class Card
  12. {
  13. public CardType Type;
  14. public bool IsBottom = false;
  15. public bool IsTane = false;
  16. public bool IsPsychic = false;
  17.  
  18. public override string ToString()
  19. {
  20. return this.Type.ToString();
  21. }
  22. }
  23.  
  24. /// <summary>
  25. /// 初期ドロー
  26. /// </summary>
  27. /// <returns></returns>
  28. public static List<Card> FirstDraw()
  29. {
  30. // 枚数調整
  31. Deck = CreateDeck();
  32.  
  33. // 初期ドロー
  34. Random random = new Random();
  35. List<Card> hand = new List<Card>();
  36. for (int i = 0; i < 5; i++)
  37. {
  38. int index = random.Next(Deck.Count); // 山札からランダムなインデックスを取得
  39. hand.Add(Deck[index]); // カードを手札に追加
  40. Deck.RemoveAt(index); // 山札からそのカードを削除
  41. }
  42.  
  43. // マリガン
  44. if (hand.Any(h => h.IsTane))
  45. {
  46. return hand;
  47. }
  48. else
  49. {
  50. return FirstDraw();
  51. }
  52. }
  53.  
  54. /// <summary>
  55. /// 一枚引く
  56. /// </summary>
  57. /// <param name="hand"></param>
  58. /// <returns></returns>
  59. public static List<Card> DrawOne(List<Card> hand)
  60. {
  61. // ドロー
  62. Random random = new Random();
  63.  
  64. // 一枚引く
  65. while (true)
  66. {
  67. int index = random.Next(Deck.Count); // 山札からランダムなインデックスを取得
  68. if (!Deck[index].IsBottom)
  69. {
  70. hand.Add(Deck[index]); // カードを手札に追加
  71. Deck.RemoveAt(index); // 山札からそのカードを削除
  72. break;
  73. }
  74. else
  75. {
  76. continue;
  77. }
  78. }
  79.  
  80. // モンスターボール使用
  81. hand = MonsterBall(hand);
  82.  
  83. // 幻の石板使用
  84. hand = MysticalTablet(hand);
  85.  
  86. // オーキド使用
  87. hand = Okid(hand);
  88.  
  89. // モンスターボール使用
  90. hand = MonsterBall(hand);
  91.  
  92. // 幻の石板使用
  93. hand = MysticalTablet(hand);
  94.  
  95. return hand;
  96. }
  97.  
  98. /// <summary>
  99. /// オーキド博士の使用
  100. /// </summary>
  101. /// <param name="hand"></param>
  102. /// <returns></returns>
  103. public static List<Card> Okid(List<Card> hand)
  104. {
  105. Random random = new Random();
  106.  
  107. List<Card> result = new List<Card>();
  108.  
  109. bool Okided = false;
  110.  
  111. // ドロー
  112. foreach (Card card in hand)
  113. {
  114. if (card.Type == CardType.Okido && Okided == false)
  115. {
  116. while (true)
  117. {
  118. int index = random.Next(Deck.Count); // 山札からランダムなインデックスを取得
  119. // 底でなかったら
  120. if (!Deck[index].IsBottom)
  121. {
  122. result.Add(Deck[index]); // カードを手札に追加
  123. Deck.RemoveAt(index); // 山札からそのカードを削除
  124. index = random.Next(Deck.Count);
  125. result.Add(Deck[index]); // カードを手札に追加
  126. Deck.RemoveAt(index); // 山札からそのカードを削除
  127. Okided = true;
  128. break;
  129. }
  130. else
  131. {
  132. continue;
  133. }
  134. }
  135.  
  136. }
  137. else
  138. {
  139. result.Add(card);
  140. }
  141. }
  142.  
  143. return result;
  144. }
  145.  
  146. /// <summary>
  147. /// モンスターボールの使用
  148. /// </summary>
  149. /// <param name="hand"></param>
  150. /// <returns></returns>
  151. public static List<Card> MonsterBall(List<Card> hand)
  152. {
  153. Random random = new Random();
  154.  
  155. List<Card> result = new List<Card>();
  156.  
  157. // ドロー
  158. foreach (Card card in hand)
  159. {
  160. if (card.Type == CardType.PokeBall && Deck.Any(card => card.IsTane))
  161. {
  162. while (true)
  163. {
  164. int index = random.Next(Deck.Count); // 山札からランダムなインデックスを取得
  165. if (Deck[index].IsTane)
  166. {
  167. result.Add(Deck[index]); // カードを手札に追加
  168. Deck.RemoveAt(index); // 山札からそのカードを削除
  169. break;
  170. }
  171. else
  172. {
  173. continue;
  174. }
  175. }
  176. }
  177. else
  178. {
  179. result.Add(card);
  180. }
  181. }
  182.  
  183. // 底フラグの解除
  184. foreach(Card card in Deck)
  185. {
  186. card.IsBottom = false;
  187. }
  188.  
  189. return result;
  190. }
  191.  
  192. /// <summary>
  193. /// 幻の石板
  194. /// </summary>
  195. /// <param name="hand"></param>
  196. /// <returns></returns>
  197. public static List<Card> MysticalTablet(List<Card> hand)
  198. {
  199. Random random = new Random();
  200.  
  201. List<Card> result = new List<Card>();
  202.  
  203. // ドロー
  204. foreach (Card card in hand)
  205. {
  206. if (card.Type == CardType.MysticalTablet)
  207. {
  208. int index = random.Next(Deck.Count); // 山札からランダムなインデックスを取得
  209. if (Deck[index].IsPsychic)
  210. {
  211. result.Add(Deck[index]); // カードを手札に追加
  212. Deck.RemoveAt(index); // 山札からそのカードを削除
  213. }
  214. else
  215. {
  216. Deck[index].IsBottom = true; // 底フラグを設定
  217. }
  218. }
  219. else
  220. {
  221. result.Add(card);
  222. }
  223. }
  224.  
  225. return result;
  226. }
  227.  
  228. /// <summary>
  229. /// 判定条件
  230. /// </summary>
  231. public class CheckPoint
  232. {
  233. public CheckPoint(int count) { this.Count = count; }
  234. public int Count { get; set; }
  235. public double Fullfill = 0;
  236. public bool IsFullFilled = false;
  237. public virtual bool IsFullfill() { throw new NotImplementedException(); }
  238. public void Update()
  239. {
  240. this.IsFullFilled = this.IsFullfill();
  241. if (this.IsFullFilled)
  242. {
  243. this.Fullfill++;
  244. }
  245. }
  246. public void Update(bool fullfill)
  247. {
  248. this.IsFullFilled = fullfill;
  249. if (this.IsFullFilled)
  250. {
  251. this.Fullfill++;
  252. }
  253. }
  254. public virtual void Reset() { throw new NotImplementedException(); }
  255. public double GetResult() { return Math.Round((this.Fullfill / this.Count) * 100, 2); }
  256. public virtual string ToName() { throw new NotImplementedException(); }
  257. public string ToResultString() { return this.ToName() + "確率 " + this.GetResult() + " %"; }
  258. }
  259.  
  260. /// <summary>
  261. /// 種ポケモン初手の例
  262. /// </summary>
  263. public class FastestOne : CheckPoint
  264. {
  265. public FastestOne(int count) : base(count) { }
  266. public bool FirstTime { get; set; }
  267. public override bool IsFullfill()
  268. {
  269. return this.FirstTime;
  270. }
  271. public override void Reset()
  272. {
  273. this.FirstTime = false;
  274. }
  275. public override string ToName()
  276. {
  277. return "種ポケモンが初手で来る";
  278. }
  279. }
  280.  
  281. /// <summary>
  282. /// 最速2進化の例
  283. /// </summary>
  284. public class FastestStage2 : CheckPoint
  285. {
  286. public FastestStage2(int count) : base(count) { }
  287. public bool FirstTimeTane { get; set; }
  288. public bool SecondTimeStage1 { get; set; }
  289. public bool ThirdTimeStage2 { get; set; }
  290. public override bool IsFullfill()
  291. {
  292. return this.FirstTimeTane && this.SecondTimeStage1 && this.ThirdTimeStage2;
  293. }
  294. public override void Reset()
  295. {
  296. this.FirstTimeTane = this.SecondTimeStage1 = this.ThirdTimeStage2 = false;
  297. }
  298. public override string ToName()
  299. {
  300. return "2進化ポケモンが最速で完成する";
  301. }
  302. }
  303.  
  304. /// <summary>
  305. /// 一枚引く
  306. /// </summary>
  307. /// <param name="hands"></param>
  308. /// <param name="type"></param>
  309. /// <returns></returns>
  310. public static bool HaveOne(this List<Card> hands, CardType type)
  311. {
  312. return hands.Any(h => h.Type == type);
  313. }
  314. /// <summary>
  315. /// 二枚引く
  316. /// </summary>
  317. /// <param name="hands"></param>
  318. /// <param name="type"></param>
  319. /// <returns></returns>
  320. public static bool HaveTwo(this List<Card> hands, CardType type)
  321. {
  322. return hands.Count(h => h.Type == type) == 2;
  323. }
  324. #endregion
  325.  
  326. #region <デッキごとに変える>
  327. /// <summary>
  328. /// カード種別
  329. /// </summary>
  330. public enum CardType
  331. {
  332. // セレビィ
  333. Celebi,
  334. // ジャローダ
  335. Tsutaja,
  336. Jaropi,
  337. Jaroda,
  338. // ナッシー
  339. Tamatama,
  340. Nassy,
  341. // ミュウ
  342. Mew,
  343. // ミュウツー
  344. Mewtwo,
  345. // サーナイト
  346. Rartos,
  347. Kirlia,
  348. Sernight,
  349. //
  350. Okido,
  351. PokeBall,
  352. MysticalTablet,
  353. Other,
  354. }
  355. /// <summary>
  356. /// デッキの作成
  357. /// </summary>
  358. /// <returns></returns>
  359. public static List<Card> CreateDeck()
  360. {
  361. List<Card> Deck = new List<Card>
  362. {
  363. // ミュウ
  364. new Card { Type = CardType.Mew, IsPsychic = true, IsTane = true },
  365. // ミュウツー
  366. new Card { Type = CardType.Mewtwo, IsPsychic = true, IsTane = true },
  367. new Card { Type = CardType.Mewtwo, IsPsychic = true, IsTane = true },
  368. // サーナイト
  369. new Card { Type = CardType.Rartos, IsPsychic = true, IsTane = true },
  370. new Card { Type = CardType.Rartos, IsPsychic = true, IsTane = true },
  371. new Card { Type = CardType.Kirlia, IsPsychic = true },
  372. new Card { Type = CardType.Kirlia, IsPsychic = true },
  373. new Card { Type = CardType.Sernight, IsPsychic = true },
  374. new Card { Type = CardType.Sernight, IsPsychic = true },
  375. // 石板
  376. new Card { Type = CardType.MysticalTablet },
  377. new Card { Type = CardType.MysticalTablet },
  378. //
  379. new Card { Type = CardType.Okido },
  380. new Card { Type = CardType.Okido },
  381. new Card { Type = CardType.PokeBall },
  382. new Card { Type = CardType.PokeBall },
  383. };
  384. while (Deck.Count() < 20)
  385. {
  386. Deck.Add(new Card { Type = CardType.Other });
  387. }
  388.  
  389. return Deck;
  390. }
  391. #endregion
  392.  
  393. #region <条件ごとに変える>
  394. public class FastestSernight : FastestStage2
  395. {
  396. public FastestSernight(int count) : base(count) { }
  397. public override string ToName()
  398. {
  399. return "サーナイトが最速で完成する";
  400. }
  401. }
  402. public class FastestMewtow : FastestOne
  403. {
  404. public FastestMewtow(int count) : base(count) { }
  405. public override string ToName()
  406. {
  407. return "ミュウツーが初手で来る";
  408. }
  409. }
  410. public class FastestSernightAndMewtow : CheckPoint
  411. {
  412. public FastestSernightAndMewtow(int count) : base(count) { }
  413. public override string ToName()
  414. {
  415. return "ミュウツーが初手で来てサーナイトも最速で完成する";
  416. }
  417. }
  418. #endregion
  419.  
  420. static void Main(string[] args)
  421. {
  422. // 試行回数
  423. int count = 100000;
  424.  
  425. #region <チェック項目のリスト>
  426. FastestSernight fastestSernight = new FastestSernight(count);
  427. FastestMewtow fastestMewtow = new FastestMewtow(count);
  428. FastestSernightAndMewtow fastestSernightAndMewtow = new FastestSernightAndMewtow(count);
  429. #endregion
  430.  
  431. for (int i = 0; i < count; i++)
  432. {
  433. #region <初期リセット>
  434. Deck = CreateDeck(); // 山札をリセット
  435. List<Card> hands = FirstDraw();
  436. #endregion
  437.  
  438. #region <チェック項目のリセット>
  439. fastestSernight.Reset();
  440. fastestMewtow.Reset();
  441. #endregion
  442.  
  443. // 1ターン目
  444. hands = DrawOne(hands);
  445. #region <チェック項目の更新>
  446. fastestSernight.FirstTimeTane = hands.HaveOne(CardType.Rartos);
  447. fastestMewtow.FirstTime = hands.HaveOne(CardType.Mewtwo);
  448. #endregion
  449.  
  450. // 2ターン目
  451. hands = DrawOne(hands);
  452. #region <チェック項目の更新>
  453. fastestSernight.SecondTimeStage1 = hands.HaveOne(CardType.Kirlia);
  454. #endregion
  455.  
  456. // 3ターン目
  457. hands = DrawOne(hands);
  458. #region <チェック項目の更新>
  459. fastestSernight.ThirdTimeStage2 = hands.HaveOne(CardType.Sernight);
  460. #endregion
  461.  
  462. // 4ターン目
  463. hands = DrawOne(hands);
  464.  
  465. #region <チェック項目の更新>
  466. fastestSernight.Update();
  467. fastestMewtow.Update();
  468. fastestSernightAndMewtow.Update(fastestSernight.IsFullFilled && fastestMewtow.IsFullFilled);
  469. #endregion
  470. }
  471.  
  472. #region <結果の出力>
  473. Console.WriteLine(fastestSernightAndMewtow.ToResultString());
  474. #endregion
  475. }
  476. }
  477. }
  478.  
Success #stdin #stdout 3.31s 36540KB
stdin
Standard input is empty
stdout
ミュウツーが初手で来てサーナイトも最速で完成する確率 35.48 %