Behind Coleus

大学生なのに特別大学で楽しいことが一 つもない。虐待と男子校病のせいにしてみる。→日本脱出しました 今ジャカルタにいます。→ジャカルタから帰ってきました。

テキストベース、バニラ状態

昨日のキューブ整理がバカほど時間かかったので、昼から活動した。

  • 【JP/NM】(089)《永遠の若さ/Forever Young》[ELD] 黒C
  • 【JP/NM】(012)《一心同体/Fight as One》[IKO] 白U
  • 【JP/NM】(202)《戦いの覚悟/Gird for Battle》[J25] 白U
  • 【JP/NM】(142)《癒し手の鷹/Healer's Hawk》[FDN] 白C
  • 【JP/NM】(025)《取り憑かれた山羊/Possessed Goat》[DSK] 白C
  • 【JP/NM】(026)《没収の強行/Requisition Raid》[OTJ] 白U
  • 【JP/NM】(027)《高潔のあかし/Righteousness》[ELD] 白U
  • 【JP/NM】(237)《サバンナ・ライオン/Savannah Lions》[J22] 白U
  • 【JP/NM】《模範的な造り手/Toolcraft Exemplar》[KLD] 白R
  • 【JP/NM】(040)《古参の生存者/Veteran Survivor》[DSK] 白U
  • 【JP/NM】(004)《輝き刃のオコジョ/Brightblade Stoat》[BLB] 白U
  • 【JP/NM】(011)《監視への恐怖/Fear of Surveillance》[DSK] 白C
  • 【JP/NM】(015)《恐れなき雛/Fearless Fledgling》[ZNR] 白U
  • 【JP/NM】(022)《ティアのグレートソード/Greatsword of Tyr》[CLB] 白C
  • 【JP/NM】(026)《獅子の飾緒/Lion Sash》[NEO] 白R
  • 【JP/NM】(027)《災厄の追い返し/Repel Calamity》[BLB] 白U
  • 【JP/NM】(033)《肌裂けの人形/Splitskin Doll》[DSK] 白U
  • 【JP/NM】(031)《暁の暴君、サンダイヤル/Sundial, Dawn Tyrant》[DFT] 白U
  • 【JP/NM】(005)《天界の鎧/Celestial Armor》[FDN] 白R
  • 【JP/NM】(031)《百舌部隊/Shrike Force》[BLB] 白U
  • 【JP/NM】《縄張り持ちの槌頭/Territorial Hammerskull》[XLN] 白C
  • 【JP/NM】《残骸の漂着/Settle the Wreckage》[XLN] 白R
  • 【JP/NM】(038)《薄気味悪い双子/Unsettling Twins》[DSK] 白C
  • 【JP/NM】(048)《怪物縛り/Bind the Monster》[KHM] 青C
  • 【JP/NM】(043)《燭台/Candlestick》[MKM] 青U
  • 【JP/NM】(067)《手練/Sleight of Hand》[WOE] 青C
  • 【JP/NM】《一瞬/Blink of an Eye》[DOM] 青C
  • 【JP/NM】(052)《推理/Deduce》[MKM] 青C
  • 【JP/NM】(058)《孤立への恐怖/Fear of Isolation》[DSK] 青U
  • 【JP/NM】(049)《束の間の反射/Fleeting Reflection》[OTJ] 青U
  • 【JP/NM】(041)《群青の獣縛り/Azure Beastbinder》[BLB] 青R
  • 【JP/NM】(324)《マルカトールの監視者/Malcator's Watcher》[J25] 青C
  • 【JP/NM】《戦凧の匪賊/Warkite Marauder》[RIX] 青R
  • 【JP/NM】(300)《雲族の予見者/Cloudkin Seer》[J25] 青C
  • 【JP/NM】(050)《困惑の謎掛け/Confounding Riddle》[LCI] 青U
  • 【JP/NM】(055)《氷造の歩哨/Icewrought Sentry》[WOE] 青U
  • 【JP/NM】(048)《論破/Refute》[FDN] 青C
  • 【JP/NM】【Foil】(086)《生命ある象形/Zoetic Glyph》[LCI] 青U
  • 【JP/NM】(151)《霊気化/Aetherize》[FDN] 青U
  • 【JP/NM】(073)《水飛沫の殴打者/Splash Lasher》[BLB] 青U
  • 【JP/NM】《奔流の機械巨人/Torrential Gearhulk》[KLD] 青R
  • 【JP/NM】(099)《最後の復讐/Final Vengeance》[DSK] 黒C
  • 【JP/NM】(103)《闇討ち/Slice from the Shadows》[MKM] 黒C
  • 【JP/NM】《才気ある霊基体/Gifted Aetherborn》[AER] 黒U
  • 【JP/NM】(099)《真夜中の騎士団/Order of Midnight》[ELD] 黒U
  • 【JP/NM】(074)《吸血鬼の大食家/Vampire Gourmand》[FDN] 黒U
  • 【JP/NM】(082)《秘密裏の干渉者/Clandestine Meddler》[MKM] 黒U
  • 【JP/NM】(112)《不吉なとげ刺し/Fell Stinger》[VOW] 黒U
  • 【JP/NM】《死に到る霊/Pestilent Spirit》[RNA] 黒R
  • 【JP/NM】(110)《泥岩の鱗/Scales of Shale》[BLB] 黒C
  • 【JP/NM】(503)《吸血鬼の夜鷲/Vampire Nighthawk》[J25] 黒U
  • 【JP/NM】(092)《風下の伏兵/Downwind Ambusher》[BLB] 黒U
  • 【JP/NM】(087)《夜の大臣、ゴンティ/Gonti, Night Minister》[DFT] 黒R
  • 【JP/NM】(097)《ヘイゼルの夜想曲/Hazel's Nocturne》[BLB] 黒U
  • 【JP/NM】(107)《生きるか死ぬか/Live or Die》[DSK] 黒U
  • 【JP/NM】(250)《押し出し+引き抜き/Push+Pull》[MKM] 分U
  • 【JP/NM】(192)《噴出の稲妻/Burst Lightning》[FDN] 赤C
  • 【JP/NM】(130)《機械仕掛けの打楽器奏者/Clockwork Percussionist》[DSK] 赤C
  • 【JP/NM】(147)《戦慄大口の怒り/Dreadmaw's Ire》[LCI] 赤U
  • 【JP/NM】(157)《兎電池/Rabbit Battery》[NEO] 赤U
  • 【JP/NM】(128)《厚顔な収集者/Brazen Collector》[BLB] 赤U
  • 【JP/NM】《戦慄衆の秘儀術師/Dreadhorde Arcanist》[WAR] 赤R
  • 【JP/NM】(140)《祭り壊し/Festival Crasher》[MID] 赤C
  • 【JP/NM】(548)《火付け射手/Firebrand Archer》[J25] 赤C
  • 【JP/NM】(126)《投げ飛ばし/Fling》[ELD] 赤C
  • 【JP/NM】《火による戦い/Fight with Fire》[DOM] 赤U
  • 【JP/NM】(146)《カズールの憤怒/Kazuul's Fury》/《カズールの崖/Kazuul's Cliffs》[ZNR] 赤U
  • 【JP/NM】(146)《地震牙の猪/Quaketusk Boar》[BLB] 赤U
  • 【JP/NM】(377)《セルトランドの投げ飛ばし屋/Surtland Flinger》[KHM] 赤R
  • 【JP/NM】《燎原の火/Wildfire》[MM2] 赤R
  • 【JP/NM】(161)《一歩上へ/Get a Leg Up》[MKM] 緑U
  • 【JP/NM】(164)《痛烈な質問/Hard-Hitting Question》[MKM] 緑U
  • 【JP/NM】(178)《凶暴な一振り/Savage Swipe》[MH1] 緑C
  • 【JP/NM】(167)《翡翠の復讐者/Jade Avenger》[MH2] 緑C
  • 【JP/NM】(191)《怪物的出現/Monstrous Emergence》[DSK] 緑C
  • 【JP/NM】(205)《崖からの転落/Over the Edge》[LCI] 緑C
  • 【JP/NM】(206)《用心深い番犬/Wary Watchdog》[DSK] 緑C
  • 【JP/NM】(249)《橋仕掛けの戦い/Bridgeworks Battle》/《絡み架かりの橋仕掛け/Tanglespan Bridgeworks》[MH3] 緑U
  • 【JP/NM】(286)《永遠の証人/Eternal Witness》[CMM] 緑U
  • 【JP/NM】《蛇の陰影/Snake Umbra》[UMA] 緑U
  • 【JP/NM】(187)《強情なベイロス/Obstinate Baloth》[BRO] 緑U
  • 【JP/NM】《世界を揺るがす者、ニッサ/Nissa, Who Shakes the World》[WAR] 緑R
  • 【JP/NM】(173)《烈風のヘラジカ/Galewind Moose》[BLB] 緑U
  • 【JP/NM】(110)《揺らし歩きのケラトプス/Quakestrider Ceratops》[FDN] 緑U
  • 【JP/NM】(772)《搭載歩行機械/Hangarback Walker》[J22] 茶R
  • 【JP/NM】(235)《市場背負いの歩行機械/Marketback Walker》[DFT] 茶R
  • 【JP/NM】(325)《精神石/Mind Stone》[CLB] 茶U
  • 【JP/NM】《巨大戦車/Juggernaut》[10ED] 茶U
  • 【JP/NM】《始まりの木の管理人/Warden of the First Tree》[FRF] 緑R
  • 【JP/NM】(116)《勇者の頌歌/Anthem of Champions》[FDN] 金R
  • 【JP/NM】(196)《戦闘魔道士の隊長、バルモア/Balmor, Battlemage Captain》[DMU] 金U
  • 【JP/NM】(135)《炎貯えのヤモリ/Flamecache Gecko》[BLB] 赤U
  • 【JP/NM】(233)《優雅な連続技/Slick Sequence》[OTJ] 金U
  • 【JP/NM】(228)《圧倒的洞察/Staggering Insight》[THB] 金U
  • 【JP/NM】《思考消去/Thought Erasure》[GRN] 金U
  • 【JP/NM】(219)■プロモスタンプ付■《悪名高い残虐爪/The Infamous Cruelclaw》[BLB] 金R
  • 【JP/NM】(237)《危険な欲/Treacherous Greed》[MKM] 金R
  • 【JP/NM】(216)《アダルト・ゴールド・ドラゴン/Adult Gold Dragon》[AFR] 金R
  • 【JP/NM】(311)■ショーケース■《殺害の強要/Coerced to Kill》[MKM-BF] 金U
  • 【JP/NM】(248)《空騒ぎ+大騒ぎ/Fuss+Bother》[MKM] 分U
  • 【JP/NM】(165)《砂丘の危険/Hazard of the Dunes》[DFT] 緑C
  • 【JP/NM】《ゴーア族の暴行者/Ghor-Clan Rampager》[GTC] 金U
  • 【JP/NM】《不眠の晒し台/Pillory of the Sleepless》[GK2-WB] 金U
  • 【JP/NM】(211)《スプライトのドラゴン/Sprite Dragon》[IKO] 金U
  • 【JP/NM】《先駆ける者、ナヒリ/Nahiri, the Harbinger》[C20] 金R
  • 【JP/NM】(199)《堕ちた忍び/Fallen Shinobi》[MH1] 金R
  • 【JP/NM】(038)《スレイベンの守護者、サリア/Thalia, Guardian of Thraben》[VOW] 白R
  • 【JP/NM】(277)《毒の濁流/Toxic Deluge》[MH3] 黒R
  • 【JP/NM】(017)《手掛かりトークン/Clue token》[MKM] 茶
  • 【JP/NM】(012)《コピートークン/Copy Token》[ZNR] 無
  • 【EN/NM】(009)《恐竜トークン/Dinosaur Token》[LCI] 赤
  • 【JP/NM】(042)《構築物トークン/Construct Token》[CMM] 茶
  • 【JP/NM】(010)《ドラゴントークン/Dragon Token》[DMU] 赤
  • 【JP/NM】(001)《エレメンタルトークン/Elemental token》[RIX] 赤
  • 【JP/NM】(004)《エレメンタル・鳥トークン/Elemental Bird Token》[M20] 青
  • 【JP/NM】(080/055)《紋章(太陽の勇者、エルズペス)+コピートークン/Emblem Elspeth, Sun's Champion+Copy Token》[CMM] 紋章/無
  • 【JP/NM】(036/033)《エネルギー貯蔵所+霊基装置トークン/Energy Reserve+Servo Token》[MH3] 特殊/茶
  • 【JP/NM】(012)《紋章(空の踊り手、ムー・ヤンリン)[M20]/Emblem Mu Yanling, Sky Dancer》[M20]
  • 【JP/NM】(019)《紋章(世界を揺るがす者、ニッサ)/Emblem Nissa, Who Shakes The World Token》[WAR]
  • 【JP/NM】(013)《紋章(灯の再覚醒、オブ・ニクシリス)/Emblem Ob Nixilis Reignited》[BFZ]
  • 【JP/NM】(003)《兵士トークン/Soldier Token》[DOM] 白
  • 【JP/NM】(005)《兵士トークン/Soldier Token》[CLB] 白
  • 【JP/NM】(011)《蜘蛛トークン/Spider token》[MKM] 金
  • 【JP/NM】(009/011)《飛行機械+宝物トークン/Thopter+Treasure Token》[DFT] 茶/茶
  • 【EN/NM】(003)《侍トークン/Samurai Token》[NEO] 白
  • 【JP/NM】(012)《食物トークン/Food Token》[WOE] 茶
  • 【JP/NM】(011)《食物トークン/Food Token》[WOE] 茶
  • 【JP/NM】(011)《サイ・戦士トークン/Rhino Warrior Token》[SNC] 緑
  • 【JP/NM】(008)《狼トークン/Wolf Token》[M20] 緑
  • 【JP/NM】(006)《ゾンビトークン/Zombie Token》[M20] 黒
  • 【JP/NM】(008)《水飛沫の殴打者トークン/Splash Lasher Token》[BLB] 青
  • 【JP/NM】(007/018)《ラガバン+宝物トークン/Ragavan+Treasure Token》[LCC] 赤/茶


最初の1時間はアドビアクロバットで、カードの効果をテキストで抽出できないかなと思ったんだけど、アドビアクロバットでテキスト抽出はできなかった。

そのあと、あきらめてコードを何回か書き直させて進捗を産もうとしたんだけど、bevyの部分が入っていると全然うまくいかなくて、rustだけで書き直させたら結構うまくいった。



以下の情報をもとにゲームをプログラミングしてください。
カードのデータベースを、G:\extreme_fantsia_itch\assets\cards.jsonから読み込みます。
デッキ二つ分のデータベースを、G:\extreme_fantsia_itch\deck_recipes\deck1.json G:\extreme_fantsia_itch\deck_recipes\deck2.jsonから読み込みます。
以上の3つは以下の様なファイルになっています。

[
        {
            "id": "XFSD01-1",
            "pictures_path": null,
            "name": "リトルナイト",
            "furigana": "りとるないと",
            "card_type": "FIGHTER",
            "tags": ["#ダウィの騎士団"],
            "energy": 1,
            "power": 1000,
            "class": "軽量級",
            "skills": null,
            "required_energy": null,
            "effects": null,
            "flavor_text": "この世界のすべての命をつかさどる、世界樹。生まれる命、朽ちる命、そのリンネは世界樹のもとで繰り返される。その世界樹を守り、大地を守護する戦士たち。それがダウィの騎士団である。",
            "element": "NATURE",
            "pack_info": "XFSD01",
            "rarity": 1,
            "energy_color": null,
            "rising_from": null
        },
        {
            "id": "XFSD01-2",
            "pictures_path": null,
            "name": "なまけ騎士 ハームゥ",
            "furigana": "なまけきし はーむぅ",
            "card_type": "FIGHTER",
            "tags": ["#ダウィの騎士団"],
            "energy": 0,
            "power": 500,
            "class": "軽量級",
            "skills": null,
            "required_energy": null,
            "effects": "【Fゾーンにいる時】自分の他のファイターが場に出た時、このファイターをSゾーンにに置く。【Sゾーンにいる時】このファイターのエナジーを+1",
            "flavor_text": "はい・・・お腹が痛いので今日の戦いはお休みします。次は行きますんで・・・。本当にごめんなさい・・・。",
            "element": "NATURE",
            "pack_info": "XFSD01",
            "rarity": 1,
            "energy_color": null,
            "rising_from": null
      },以下100枚以上続く
{
    "first_energy": {
        "name": "勇敢のエナジー"
    },
    "deck": [
        {"name": "リトルナイト", "count": 3},
        {"name": "なまけ騎士 ハームゥ", "count": 2},
        {"name": "アサシン・タイクーン", "count": 2},
        {"name": "騎士ニャタタ・ビィ", "count": 3},
        {"name": "密林の騎士リンキー", "count": 2},
        {"name": "ワンダフルウィザード・ワッチチ", "count": 3},
        {"name": "ワンダフル・ウィザード ドギィ", "count": 1},
        {"name": "ワンダフル・ウィザード ゴン", "count": 2},
        {"name": "三剣士のトランスロ", "count": 2},
        {"name": "三剣士のソードホーク", "count": 1},
        {"name": "師範マスター・ゼブラ", "count": 1},
        {"name": "若き英雄 ナポ", "count": 2},
        {"name": "アサシン・ロー", "count": 1},
        {"name": "雷の戦士ポーラ", "count": 1},
        {"name": "疾風の騎士ゴート・パラディン", "count": 1},
        {"name": "エナジーベリー", "count": 3},
        {"name": "ハームゥのラッパ", "count": 2},
        {"name": "反撃の剣撃", "count": 1},
        {"name": "ふんわりトルネート", "count": 2},
        {"name": "あつあつフレア", "count": 2},
        {"name": "ホキュウムッシ", "count": 2}
    ]
}

デッキリストにはファーストエナジーと、デッキのカードの枚数と名前が記されています。
ここから、以下の機能を持った、ゲームを作ってください。

・カードリストのjsonファイルから全てのカードリストを読み込む そのログをつける
・プレイヤー1とプレイヤー2のデッキリストjsonファイルから現在のデッキリストを読み込む。そのログをつける。
デッキリスト二つの情報を解析しdeckキーを持つカードの名前を読み込み、それを参照して、カードリストからカードの情報全てを取得する。プレイヤー1のデッキリストを山札1に格納する。その際、count要素も読み込んで、同じカードをcountの数値分読み込む。(今回の場合は40枚)そのログをつける。同様に、プレイヤー2のデッキリストを山札2に格納する。そのログをつける。
・読み込んだ山札1と2の順番をランダムに入れ替える。そのログをつける
・プレイヤー1のデッキリストのfirst_energyキーを持つカードの情報を解析し、その名前からカードリストを検索し、その情報を取得する。それらすべてをSゾーン1に裏側状態で置く。そのログをつける。同様にプレイヤー1のデッキリストのfirst_energyキーを持つカードの情報を解析し、その名前からカードリストを検索し、その情報を取得する。それらすべてをSゾーン2に裏側状態で置く。そのログをつける。
・プレイヤー1は山札の上から5枚を手札に加える。その手札を表示する。
・プレイヤー1からの入力を受け付け、望むなら山札1と手札1を加えてシャッフルし、5枚を手札に加える操作をする。なお、そのたび、引き直した手札を表示する。 それは2回まで可能である。

プレイヤー2からの入力を受け付け、望むなら山札2と手札2を加えてシャッフルし、5枚を手札に加える操作をする。なお、そのたび、引き直した手札を表示する。それは、2回まで可能である。

・プレイヤー1が2回引き直すことを選んでいた場合、プレイヤー2はカードを山札から1枚引く
・プレイヤー2が2回引き直すことを選んでいた場合、プレイヤー1はカードを山札から1枚引く

・プレイヤー1と2の入力をそれぞれ受け付け、じゃんけんを行う。勝った方のプレイヤーが先行か後攻かを選択する。

・プレイヤー1と2のSゾーンにある、裏向きのファーストエナジーカードを表向きにし、ファーストエナジー、オープン!」と表示する。

・先行を選んだプレイヤーをターンプレイヤー、そうでないプレイヤーを非ターンプレイヤーとしてゲームを開始する。この時の二人のGiven in hand という情報として記録する。

・先行を選んだプレイヤーをターンプレイヤー、そうでないプレイヤーを非ターンプレイヤーとしてゲームを開始する。
・以下ターン進行ループと以上ターン進行ループの間をどちらかのプレイヤーのXゾーンのカードが6枚以上になるまで、ループさせる。

以下ターン進行ループ

・ターンスタートと表示して、ターンプレイヤーの自分のターンであることのフラグを作る。

・準備フェーズと表示する。ドロータイムと表示して、山札からカードを1枚引く

なお、先行を選んだプレイヤーの1ターン目はカードを引くことはできない。

・ターンプレイヤーのFゾーンのスピン状態のカードすべてをリスピン状態にする。

この際、Fゾーンのカード全てを、召喚酔いをしていない状態にする。

・ターンプレイヤーのSゾーンのスピン状態のカードすべてをリスピン状態にする。


・撤退フェーズと表示し、ターンプレイヤーのFゾーンにカードがある場合以下の処理を行う。まず、Sゾーンにあるカードのエナジーの値の合計Aを計算する。その後、ターンプレイヤーのFゾーンのカード1,2,3...のエナジーB_1,B_2,B_3,...をそれぞれ読み込む。A+B_nを計算し、その和が10以下になるようなFゾーンのカードnを全て表示する。(なお、この計算が出来ればよいので、AやBという代数を使う必要はない)また、撤退しないという選択肢も表示する。プレイヤーからの入力を受け付け、条件を満たしたFゾーンのカードが選ばれた場合、そのカードをSゾーンに表向き裏向き、召喚酔い、スピンリスピン状態の情報を維持したままで移動する。撤退しないという選択肢が表示された場合、次の処理に進む。

・ターンプレイヤーのXゾーンのカードの枚数をカウントし、0枚なら、次の処理に、進む。そうでないなら、Xフェーズと表示し、Xスキルを使うか使わないかの選択肢を表示し、プレイヤーからの入力を受け付ける。使わないを選択した場合は、次の処理に移動する。使うを選択した場合、使いましたと表示して、次の処理に移動します。

・メインフェーズを開始したと表示し、メインフェーズであることのフラグを作成する。フリー状態に移行する。

メインフェーズは複雑なので以下の様に1, 2, 3の区分分けを行う。
1が基本の状態で、2、3に繰り返し遷移し、4でループを抜けるという構造である。

1フリー状態 この状態になる度、ターンプレイヤーのFゾーン、Sゾーン、Xゾーンのカードを読み込み表示する。ターンプレイヤーのSゾーンのリスピン状態のカードのエナジーをエレメントごとに読み込む。
そして、Sゾーンのリスピン状態のカードのエナジーの合計をNATURE, FIRE, AQUA, DARK, FENE毎に計算して、それぞれをA, B, C, D, Eとおく。そして、A+E, B+E, C+E, D+Eを計算し、保存しておく。さらに、ターンプレイヤーのFゾーンのカードの状態(カード名、スピンリスピン状態と、召喚酔いの情報、パワー等)を読み込んでおく。

手札のカード1,2,3,...kについてそれぞれのエレメントF_nとエナジーH_nを確認し、F_nがNATUREだった場合H_nをA+Eと、FIREだった場合B+Eと、AQUAだった場合はC+Eと、DARKだった場合はD+Eと比較する。H_nが比較した値以下になるような、手札nの一覧を表示する。(代数は、この計算が出来ればいいのでこのような文字である必要はない。)その際{カード名}{F_n}{H_n}エナジーのカードを使用しますか?という選択肢を条件を満たすカードそれぞれの分表示(選択肢列a)する。

そして、Fゾーンのカードに、リスピン状態で、召喚酔いをしていないカードnがあった場合は、それぞれにおいて、{nのカード名}パワー{nのパワー}で攻撃しますか??と、表示する(選択肢列b)。

そして、ターンを終了する。という選択肢cを表示する。

プレイヤーからの入力を受け付け、選択肢列aが選ばれた場合は、2の処理に移動する。
選択肢列bが選ばれた場合は、3の処理に移動する。

選択肢列cが選ばれた場合は、4の処理に移行する。

2エナジー選択状態 
選択したカードがファイターカードだった場合は、2-1に移行する
選択したカードがタクティクスカードだった場合は、2-2に移行する
2-1
選択したカードのエレメントとエナジーをAとBとする。Sゾーンにあるリスピン状態のカードのうち、Aと同じであるか、FENEであるカードのカード名とエナジーの値をすべて表示する。複数チェックリスト方式で選択できるようにしておく。プレイヤーからの入力を受け付け選択されたら、選択されたカードのエナジーの合計を計算し、それ以上であれば、決定という選択肢を表示させる。その選択したカードを手札からFゾーンに召喚酔いした状態で移動させる。その場合2-1-1に移行する
2-1の操作や入力全般において、やっぱりやめるという選択肢を置いておき、それが選択された場合には、1に移行するようにする。

2-1-1 召喚時の処理
召喚されたと表示する。
選択されたカードが手札から召喚されたというフラグを作成する。
1に移行する

2-2

選択したカードのエレメントと必要エナジーをAとBとする。Sゾーンにあるリスピン状態のカードのうち、Aと同じであるか、FENEであるカードのカード名とエナジーの値をすべて表示する。複数チェックリスト方式で選択できるようにしておく。プレイヤーからの入力を受け付け選択されたら、選択されたカードのエナジーの合計を計算し、それ以上であれば、決定という選択肢を表示させる。その選択したカードを手札からSゾーンにリスピン状態で移動する。
その後、Sゾーンのカードのエナジーの合計を計算し、10を超えていたら、2-2-1, そうでないなら、2-3に移行する。

2-2-1エナジーの調整
自分のSゾーンの合計エナジーが10以下になるように、自分のSゾーンのカードを自分のXゾーンに裏側で移動させる。その際に、SゾーンにあるカードSゾーンに送るカードの枚数は最小でなければならない。2-2-2に移行する。
2-2-2 タクティクスカード効果の処理
選択されていたカードを発動したと表示する。
手札から発動時というフラグを作成する。
1に戻る

3アタック状態
非ターンプレイヤーのFゾーンのスピン状態のカードすべてと、非ターンプレイヤーのSゾーンのカード全てを読み込み選択肢として表示させる。すべてのカード名と、パワー(存在すれば)を表示する、またやっぱりやめるという選択肢を置く。ターンプレイヤーに入力させる。
そして、1で選択したファイターをスピンさせる。攻撃時というフラグを作成する。
その後、非ターンプレイヤーFゾーンにリスピン状態の、ガードスキルを持つファイターがいた場合、それぞれのガードを持つカードの名前とパワーを表示し、非ターンプレイヤーにどのファイターでガードをするのか、それともしないのか入力を求める。
ガードを宣言した場合、そのファイターをスピンさせる。

ターンプレイヤーが選択したカードが、Fゾーンのカードだった場合、若しくは、ガードを宣言された場合3-1Sゾーンのファイターだった場合、3-2Sゾーンのタクティクスだった場合、3-3Sゾーンのファーストエナジーだった場合、3-4
やっぱりやめた場合、1に移行する。
3-1
バトルのフラグを作成する
攻撃ファイターのパワーと、ガードを宣言された場合はガードファイターとを比べる。ガードを宣言されていない場合は、ターンプレイヤーが攻撃したファイターのパワーとを比較する。
その際、パワーが同じ場合は、お互いのファイターをバトルで破壊する。パワーが違う場合は、大きい方がバトルに勝利し、小さいほうがバトルで破壊する。


その後、バトルで破壊されたファイターがいる場合、ターンプレイヤー優先で以下の処理をします。
バトルで破壊されたファイターのコントローラーのSゾーンのカードのエナジーの合計Aを計算する。その後、破壊されたファイターのエナジーBとの合計A+Bを計算し、和が10より大きくなるならば、選択肢を表示せずにバトルで破壊されたファイターを自動的に墓地に移動させる。その和が10以下になるならば、撤退をするか、それとも墓地に送るかという選択肢を表示する。
撤退を選んだ場合、バトルで破壊されたファイターをSゾーンに移動する。
バトルのフラグを回収する。
1に戻る

3-2
バトルのフラグを作成する。
攻撃ファイターのパワーと、ターンプレイヤーが攻撃したファイターのパワーとを比較する。
その際、パワーが同じかそれ以上の場合は、非ターンプレイヤーのファイターをバトルで破壊します。パワーが小さい場合は、何も起きません。
バトルで破壊された非ターンプレイヤーのファイターはその持ち主のXゾーンに裏側で送られます。
バトルのフラグを回収する。

1に戻る
3-3
バトルのフラグを作成する。

攻撃したタクティクスカードをバトルで破壊する。
バトルで破壊されたタクティクスカードは、自動的にXゾーンに裏側で移動する。
バトルのフラグを回収する。
1に戻る
3-4
非ターンプレイヤーの山札の1番上から1枚目を1枚Xゾーンに移動する。
1に戻る


・メインフェーズを終了メインフェーズのフラグを回収し、次の処理に移行する。
・自分のターンであるというフラグを回収する。ターンプレイヤーを非ターンプレイヤーに移行し、非ターンプレイヤーをターンプレイヤーに移行する

以上ターンループ


・Xゾーンが6枚以上になったプレイヤーのSゾーンにあるファーストエナジーのカードを、Xゾーンに移動させる。
・Xゾーンにファーストエナジーが送られたプレイヤーは敗北する。
・ゲームを終了する。

use std::io::{self, Write, BufReader}; // Writeトレイトを使用するために追加
use std::collections::HashMap;

// 以前のコードに続く...
use serde::{Deserialize, Serialize};
use serde_json::Result;
use std::fs::File;
use rand::seq::SliceRandom; // 乱数用

#[derive(Debug, Serialize, Deserialize, Clone)]
struct Card {
    //id: String,
    name: String,
    /*card_type: String,
    energy: Option<u32>,
    power: Option<u32>,
    effects: Option<String>,
    flavor_text: Option<String>,
    element: String,
    // 他のフィールド...*/
}

#[derive(Debug, Serialize, Deserialize)]
struct DeckList {
    first_energy: FirstEnergy,
    deck: Vec<DeckCard>,
}

#[derive(Debug, Serialize, Deserialize)]
struct FirstEnergy {
    name: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct DeckCard {
    name: String,
    count: u32,
}

fn read_json_file<T: for<'de> Deserialize<'de>>(filepath: &str) -> Result<T> {
    let file = File::open(filepath).expect("Unable to open file");
    let reader = BufReader::new(file);
    let data = serde_json::from_reader(reader)?;
    Ok(data)
}

fn main() -> io::Result<()> {
    // カードリストを読み込む
    let card_list: Vec<Card> = read_json_file("G:\\extreme_fantsia_itch\\assets\\cards.json").expect("Error reading cards.json");
    println!("Loaded card list: {:?}", card_list);

    // プレイヤーのデッキリストを読み込む
    let deck1: DeckList = read_json_file("G:\\extreme_fantsia_itch\\deck_recipes\\deck1.json").expect("Error reading deck1.json");
    let deck2: DeckList = read_json_file("G:\\extreme_fantsia_itch\\deck_recipes\\deck2.json").expect("Error reading deck2.json");
   
    println!("Player 1 deck: {:?}", deck1);
    println!("Player 2 deck: {:?}", deck2);

    // 山札を作成する
    let mut deck1_cards = create_deck(&deck1, &card_list);
    let mut deck2_cards = create_deck(&deck2, &card_list);
   
    // 山札をシャッフルする
    deck1_cards.shuffle(&mut rand::thread_rng());
    deck2_cards.shuffle(&mut rand::thread_rng());

    // 手札を作成
    let mut hand1 = draw_hand(&mut deck1_cards, 5);
    let mut hand2 = draw_hand(&mut deck2_cards, 5);
   
    println!("Player 1 hand: {:?}", hand1);
    println!("Player 2 hand: {:?}", hand2);

    // 引き直し処理
    for i in 1..=2 {
        let player_num = if i == 1 { "1" } else { "2" };
        let deck_cards = if i == 1 { &mut deck1_cards } else { &mut deck2_cards };
        let hand = if i == 1 { &mut hand1 } else { &mut hand2 };

        for _ in 0..2 {
            println!("Player {}: 引き直しますか? (y/n)", player_num);
            let choice = get_user_input();
            if choice.to_lowercase() == "y" {
                *hand = draw_hand(deck_cards, 5);
                println!("Player {} hand after reshuffle: {:?}", player_num, hand);
            } else {
                break;
            }
        }
       
        // 相手のプレイヤーが2回引き直した場合、1枚引く
        if hand.len() == 5 {
            if i == 1 {
                println!("Player 2 draws a card from the deck.");
                if let Some(card) = deck2_cards.pop() {
                    hand2.push(card);
                    println!("Player 2 hand: {:?}", hand2);
                }
            } else {
                println!("Player 1 draws a card from the deck.");
                if let Some(card) = deck1_cards.pop() {
                    hand1.push(card);
                    println!("Player 1 hand: {:?}", hand1);
                }
            }
        }
    }
    // 最終手札表示
    println!("Player 1 hand: {:?}", hand1);
    println!("Player 2 hand: {:?}", hand2);
    // じゃんけん
    let (turn_player, non_turn_player) = janken();
    println!("Turn Player: Player {}, Non-Turn Player: Player {}", turn_player, non_turn_player);    
    // ファーストエナジーを表向きにする
    let energy1 = card_info_from_name(&deck1.first_energy.name, &card_list);
    let energy2 = card_info_from_name(&deck2.first_energy.name, &card_list);

    println!("Player 1 First Energy: {:?}", energy1);
    println!("Player 2 First Energy: {:?}", energy2);
    // ゲームの進行...
   
    Ok*1 == Some(&player2_choice.as_str()) {
        println!("Player 1の勝ちです!");
        1 // Player 1 の勝ち
    } else {
        println!("Player 2の勝ちです!");
        2 // Player 2 の勝ち
    };

    // 勝者からの入力を受け付ける
    let winner_choice = if winner == 1 {
        println!("Player 1: 先行または後攻を選んでください。(1: 先行, 2: 後攻)");
        get_user_input()
    } else {
        println!("Player 2: 先行または後攻を選んでください。(1: 先行, 2: 後攻)");
        get_user_input()
    };

    // ターンプレイヤーと非ターンプレイヤーの設定
    let (turn_player, non_turn_player) = match winner_choice.as_str() {
        "1" => {
            println!("勝者は先行を選びました。");
            (winner, 3 - winner) // 1が勝者ならturn_playerはwinner、non_turn_playerは対戦相手
        },
        "2" => {
            println!("勝者は後攻を選びました。");
            (3 - winner, winner) // 2が勝者ならturn_playerは対戦相手、non_turn_playerはwinner
        },
        _ => {
            println!("無効な選択肢です。");
            return (0, 0); // 無効な場合はゼロを返す
        },
    };

    (turn_player, non_turn_player) // ターンプレイヤーと非ターンプレイヤーを返す
}


とりあえず、このコードで、ゲーム前最初のところは完成した。



・カードの構造体を設定する
カードのデータは、後に紹介するカードリストjsonファイルから読み込みます。

id    pictures_path    name    furigana    card_type    tags    energy    power     class    skills    required_energy    effects    flavor_text    element    pack_info    rarity    energy_color    rising_from
以上の属性を追加する。
id picures_path card_type 半角の文字列を一つ格納する
tags skills全角の文字列を格納する。それは、複数持つことも、一つも持たないこともある。
rising_from name furigana flavor_text effects class全角の文字列を格納する。一つ持つか一つも持たない。
power energy rarity required_energy数字を一つ格納するか、一つも持たない。
energy_color     文字列を格納する 一つも持たないか一つ格納する。
element    pack_info 半角の文字列を一つも持たないか一つ格納する

以下がカードリストのjsonファイルの一例です。

        {
            "id": "XFSD01-1",
            "pictures_path": null,
            "name": "リトルナイト",
            "furigana": "りとるないと",
            "card_type": "FIGHTER",
            "tags": ["#ダウィの騎士団"],
            "energy": 1,
            "power": 1000,
            "class": "軽量級",
            "skills": null,
            "required_energy": null,
            "effects": null,
            "flavor_text": "この世界のすべての命をつかさどる、世界樹。生まれる命、朽ちる命、そのリンネは世界樹のもとで繰り返される。その世界樹を守り、大地を守護する戦士たち。それがダウィの騎士団である。",
            "element": "NATURE",
            "pack_info": "XFSD01",
            "rarity": 1,
            "energy_color": null,
            "rising_from": null
        },

・プレイに使われる領域を設定する。プレイヤーは二人いてそれぞれが、以下の5つの領域を管理する。プレイヤー1は、Fゾーン1Sゾーン1Xゾーン1山札1手札1墓地1を持つ。同様にプレイヤー2は、Fゾーン2Sゾーン2Xゾーン2山札2手札2墓地2を持つ。

・カードの状態を設定する。カードにはそれぞれ、裏向き状態、表向き状態(同時に片方しか持てない)と、スピンとリスピン状態(同時に片方しか持てない)召喚酔いを持つ。
・ゲーム内の処理のいくつかの定型文を作る。 カードを1枚引く:これは山札の1番上のカードを手札に加える操作である。 攻撃する:攻撃する対象を選択し、攻撃ファイターをスピンさせる。 ガードする:ガードを持つファイターをスピンさせ、攻撃対象を変更させる。 
撤退する:これは条件を満たしたFゾーンのカードが選ばれた場合、そのカードをSゾーンに表向き裏向き、召喚酔い、スピンリスピン状態の情報を維持したままで移動する。 X:TREME MODE :これはXゾーンのカードが4枚以上になった場合に、フラグを立てる。


以下はゲームの機能である。データベースとして用いる、jsonファイルは3つある。カードの情報が格納された、cards.json つぎに、プレイヤー1のデッキリストを表す、deck1.jsonプレイヤー2のデッキリストを表すdeck2.jsonだ。
deck1やdeck2の書式は以下の様であり、数字はカードの枚数、名前はそのカードのcards.json上でのname 要素を表す。

{
    "first_energy": {
        "name": "勇敢のエナジー"
    },
    "deck": [
        {"name": "リトルナイト", "count": 3},
        {"name": "なまけ騎士 ハームゥ", "count": 2},
        {"name": "アサシン・タイクーン", "count": 2},
        {"name": "騎士ニャタタ・ビィ", "count": 3},
        {"name": "密林の騎士リンキー", "count": 2},
        {"name": "ワンダフルウィザード・ワッチチ", "count": 3},
        {"name": "ワンダフル・ウィザード ドギィ", "count": 1},
        {"name": "ワンダフル・ウィザード ゴン", "count": 2},
        {"name": "三剣士のトランスロ", "count": 2},
        {"name": "三剣士のソードホーク", "count": 1},
        {"name": "師範マスター・ゼブラ", "count": 1},
        {"name": "若き英雄 ナポ", "count": 2},
        {"name": "アサシン・ロー", "count": 1},
        {"name": "雷の戦士ポーラ", "count": 1},
        {"name": "疾風の騎士ゴート・パラディン", "count": 1},
        {"name": "エナジーベリー", "count": 3},
        {"name": "ハームゥのラッパ", "count": 2},
        {"name": "反撃の剣撃", "count": 1},
        {"name": "ふんわりトルネート", "count": 2},
        {"name": "あつあつフレア", "count": 2},
        {"name": "ホキュウムッシ", "count": 2}
    ]
}


・カードリストのjsonファイルから全てのカードリストを読み込む そのログをつける
・プレイヤー1とプレイヤー2のデッキリストjsonファイルから現在のデッキリストを読み込む。そのログをつける。
デッキリスト二つの情報を解析しdeckキーを持つカードの名前を読み込み、それを参照して、カードリストからカードの情報全てを取得する。プレイヤー1のデッキリストを山札1に格納する。その際、count要素も読み込んで、同じカードをcountの数値分読み込む。(今回の場合は40枚)そのログをつける。同様に、プレイヤー2のデッキリストを山札2に格納する。そのログをつける。
・読み込んだ山札1と2の順番をランダムに入れ替える。そのログをつける
・プレイヤー1のデッキリストのfirst_energyキーを持つカードの情報を解析し、その名前からカードリストを検索し、その情報を取得する。それらすべてをSゾーン1に裏側状態で置く。そのログをつける。同様にプレイヤー1のデッキリストのfirst_energyキーを持つカードの情報を解析し、その名前からカードリストを検索し、その情報を取得する。それらすべてをSゾーン2に裏側状態で置く。そのログをつける。
・プレイヤー1は山札の上から5枚を手札に加える。その手札を表示する。
・プレイヤー1からの入力を受け付け、望むなら山札1と手札1を加えてシャッフルし、5枚を手札に加える操作をする。なお、そのたび、引き直した手札を表示する。 それは2回まで可能である。

プレイヤー2からの入力を受け付け、望むなら山札2と手札2を加えてシャッフルし、5枚を手札に加える操作をする。なお、そのたび、引き直した手札を表示する。それは、2回まで可能である。

・プレイヤー1が2回引き直すことを選んでいた場合、プレイヤー2はカードを山札から1枚引く
・プレイヤー2が2回引き直すことを選んでいた場合、プレイヤー1はカードを山札から1枚引く

・プレイヤー1と2の入力をそれぞれ受け付け、じゃんけんを行う。勝った方のプレイヤーが先行か後攻かを選択する。

・プレイヤー1と2のSゾーンにある、裏向きのファーストエナジーカードを表向きにし、ファーストエナジー、オープン!」と表示する。

・先行を選んだプレイヤーをターンプレイヤー、そうでないプレイヤーを非ターンプレイヤーとしてゲームを開始する。

ターンの進行は、ターンスタート、準備フェーズ、撤退フェーズ、Xフェーズ、メインフェーズ、ターンエンド、ターンプレイヤーを入れ替える。を繰り返す。
・以下ターン進行ループと以上ターン進行ループの間をどちらかのプレイヤーのXゾーンのカードが6枚以上になるまで、もしくは、カードを引こうとして、山札が0枚だった時になるまで、ループさせる。

以下ターン進行ループ

・ターンスタートと表示して、ターンプレイヤーの自分のターンであることのフラグを作る。

・(準備フェーズ)準備フェーズと表示する。ドロータイムと表示して、山札からカードを1枚引く

なお、先行を選んだプレイヤーの1ターン目はカードを引くことはできない。

・ターンプレイヤーのFゾーンのスピン状態のカードすべてをリスピン状態にする。

この際、Fゾーンのカード全てを、召喚酔いをしていない状態にする。

・ターンプレイヤーのSゾーンのスピン状態のカードすべてをリスピン状態にする。


・(撤退フェーズ)撤退フェーズと表示し、ターンプレイヤーのFゾーンにカードがある場合以下の処理を行う。まず、Sゾーンにあるカードのエナジーの値の合計Aを計算する。その後、ターンプレイヤーのFゾーンのカード1,2,3...のエナジーB_1,B_2,B_3,...をそれぞれ読み込む。A+B_nを計算し、その和が10以下になるようなFゾーンのカードnを全て表示する。(なお、この計算が出来ればよいので、AやBという代数を使う必要はない)また、撤退しないという選択肢も表示する。プレイヤーからの入力を受け付け、条件を満たしたFゾーンのカードが選ばれた場合、そのカードをSゾーンに表向き裏向き、召喚酔い、スピンリスピン状態の情報を維持したままで移動する。撤退しないという選択肢が表示された場合、次の処理に進む。

・ターンプレイヤーのXゾーンのカードの枚数をカウントし、0枚なら、次の処理に、進む。そうでないなら、Xフェーズと表示し、Xスキルを使うか使わないかの選択肢を表示し、プレイヤーからの入力を受け付ける。使わないを選択した場合は、次の処理に移動する。使うを選択した場合、使いましたと表示して、次の処理に移動します。

・(メインフェーズ)メインフェーズを開始したと表示し、メインフェーズであることのフラグを作成する。フリー状態に移行する。

メインフェーズは複雑なので以下の様に1, 2, 3の区分分けを行う。
1が基本の状態で、入力を受け付け2,3 に遷移し、必要な入力が終われば、1に戻る。 1で入力を受け付け、ターンエンドに遷移する。このような構造になっている。

1フリー状態 この状態になる度、ターンプレイヤーのSゾーンのリスピン状態のカードのエナジーをエレメントごとに読み込む。
そして、Sゾーンのリスピン状態のカードのエナジーの合計をNATURE, FIRE, AQUA, DARK, FENE毎に計算して、それぞれをA, B, C, D, Eとおく。そして、A+E, B+E, C+E, D+Eを計算し、保存しておく。さらに、ターンプレイヤーのFゾーンのカードの状態(カード名、スピンリスピン状態と、召喚酔いの情報、パワー等)を読み込んでおく。

手札のカード1,2,3,...kについてそれぞれのエレメントF_nとエナジーH_nを確認し、F_nがNATUREだった場合H_nをA+Eと、FIREだった場合B+Eと、AQUAだった場合はC+Eと、DARKだった場合はD+Eと比較する。H_nが比較した値以下になるような、手札nの一覧を表示する。(代数は、この計算が出来ればいいのでこのような文字である必要はない。)その際{カード名}{F_n}{H_n}エナジーのカードを使用しますか?という選択肢を条件を満たすカードそれぞれの分表示(選択肢列a)する。

そして、Fゾーンのカードに、リスピン状態で、召喚酔いをしていないカードnがあった場合は、それぞれにおいて、{nのカード名}パワー{nのパワー}で攻撃しますか??と、表示する(選択肢列b)。

そして、ターンを終了する。という選択肢cを表示する。

プレイヤーからの入力を受け付け、選択肢列aが選ばれた場合は、2の処理に移動する。
選択肢列bが選ばれた場合は、3の処理に移動する。

選択肢列cが選ばれた場合は、4の処理に移行する。

2エナジー選択状態 
選択したカードがファイターカードだった場合は、2-1に移行する
選択したカードがタクティクスカードだった場合は、2-2に移行する
2-1
選択したカードのエレメントとエナジーをAとBとする。Sゾーンにあるリスピン状態のカードのうち、Aと同じであるか、FENEであるカードのカード名とエナジーの値をすべて表示する。複数チェックリスト方式で選択できるようにしておく。プレイヤーからの入力を受け付け選択されたら、選択されたカードのエナジーの合計を計算し、それ以上であれば、決定という選択肢を表示させる。その選択したカードを手札からFゾーンに召喚酔いした状態で移動させる。その場合2-1-1に移行する
2-1の操作や入力全般において、やっぱりやめるという選択肢を置いておき、それが選択された場合には、1に移行するようにする。

2-1-1 召喚時の処理
召喚されたと表示する。
選択されたカードが手札から召喚されたというフラグを作成する。
1に移行する

2-2

選択したカードのエレメントと必要エナジーをAとBとする。Sゾーンにあるリスピン状態のカードのうち、Aと同じであるか、FENEであるカードのカード名とエナジーの値をすべて表示する。複数チェックリスト方式で選択できるようにしておく。プレイヤーからの入力を受け付け選択されたら、選択されたカードのエナジーの合計を計算し、それ以上であれば、決定という選択肢を表示させる。その選択したカードを手札からSゾーンにリスピン状態で移動する。
その後、Sゾーンのカードのエナジーの合計を計算し、10を超えていたら、2-2-1, そうでないなら、2-3に移行する。

2-2-1エナジーの調整
自分のSゾーンの合計エナジーが10以下になるように、自分のSゾーンのカードを自分のXゾーンに裏側で移動させる。その際に、SゾーンにあるカードSゾーンに送るカードの枚数は最小でなければならない。2-2-2に移行する。
2-2-2 タクティクスカード効果の処理
選択されていたカードを発動したと表示する。
手札から発動時というフラグを作成する。
1に戻る

3アタック状態
非ターンプレイヤーのFゾーンのスピン状態のカードすべてと、非ターンプレイヤーのSゾーンのカード全てを読み込み選択肢として表示させる。すべてのカード名と、パワー(存在すれば)を表示する、またやっぱりやめるという選択肢を置く。ターンプレイヤーに入力させる。
そして、1で選択したファイターをスピンさせる。攻撃時というフラグを作成する。
その後、非ターンプレイヤーFゾーンにリスピン状態の、ガードスキルを持つファイターがいた場合、それぞれのガードを持つカードの名前とパワーを表示し、非ターンプレイヤーにどのファイターでガードをするのか、それともしないのか入力を求める。
ガードを宣言した場合、そのファイターをスピンさせる。

ターンプレイヤーが選択したカードが、Fゾーンのカードだった場合、若しくは、ガードを宣言された場合3-1Sゾーンのファイターだった場合、3-2Sゾーンのタクティクスだった場合、3-3Sゾーンのファーストエナジーだった場合、3-4
やっぱりやめた場合、1に移行する。
3-1
バトルのフラグを作成する
攻撃ファイターのパワーと、ガードを宣言された場合はガードファイターとを比べる。ガードを宣言されていない場合は、ターンプレイヤーが攻撃したファイターのパワーとを比較する。
その際、パワーが同じ場合は、お互いのファイターをバトルで破壊します。パワーが違う場合は、大きい方がバトルに勝利し、小さいほうがバトルで破壊されます。


その後、バトルで破壊されたファイターがいる場合、ターンプレイヤー優先で以下の処理をします。
バトルで破壊されたファイターのコントローラーのSゾーンのカードのエナジーの合計Aを計算する。その後、破壊されたファイターのエナジーBとの合計A+Bを計算し、その和が10以下になるならば、撤退をするか、それとも墓地に送るかという選択肢を表示する。和が10より大きくなるならば、選択肢を表示せずにバトルで破壊されたファイターを自動的に墓地に移動する。
撤退を選んだ場合、バトルで破壊されたファイターをSゾーンに移動する。
バトルのフラグを回収する。
1に戻る

3-2
バトルのフラグを作成する。
攻撃ファイターのパワーと、ターンプレイヤーが攻撃したファイターのパワーとを比較する。
その際、パワーが同じかそれ以上の場合は、非ターンプレイヤーのファイターをバトルで破壊します。パワーが小さい場合は、何も起きません。
バトルで破壊された非ターンプレイヤーのファイターはその持ち主のXゾーンに裏側で送られます。
バトルのフラグを回収する。

1に戻る
3-3
バトルのフラグを作成する。

攻撃したタクティクスカードをバトルで破壊する。
バトルで破壊されたタクティクスカードは、自動的にXゾーンに裏側で移動する。
バトルのフラグを回収する。
1に戻る
3-4
非ターンプレイヤーの山札の1番上から1枚目を1枚Xゾーンに移動する。
1に戻る


・メインフェーズを終了メインフェーズのフラグを回収し、次の処理に移行する。
・自分のターンであるというフラグを回収する。ターンプレイヤーを非ターンプレイヤーに移行し、非ターンプレイヤーをターンプレイヤーに移行する

以上ターンループ


・Xゾーンが6枚以上になったプレイヤーのSゾーンにあるファーストエナジーのカードを、Xゾーンに移動させる。
・Xゾーンにファーストエナジーが送られたプレイヤーは敗北する。山札を引けなかったプレイヤーも敗北する。
・ゲームを終了する。
・勝敗を記録する。

 

*1:))

}
fn create_deck(deck_list: &DeckList, card_list: &[Card]) -> Vec<Card> {
    let mut deck = Vec::new();
    for card in &deck_list.deck {
        for _ in 0..card.count {
            if let Some(card_info) = card_info_from_name(&card.name, card_list) {
                deck.push(card_info);
            }
        }
    }
    deck
}

fn card_info_from_name(name: &str, card_list: &[Card]) -> Option<Card> {
    card_list.iter().find(|card| card.name == name).cloned()
}

fn draw_hand(deck: &mut Vec<Card>, count: usize) -> Vec<Card> {
    let mut hand = Vec::new();
    for _ in 0..count {
        if let Some(card) = deck.pop() {
            hand.push(card);
        }
    }
    hand
}
fn get_user_input() -> String {
    let mut input = String::new();
    print!("> ");
    io::stdout().flush().unwrap(); // 出力をフラッシュしてプロンプトを表示
    io::stdin().read_line(&mut input).expect("Failed to read line");
    input.trim().to_string()
}

fn janken() -> (u32, u32) { // 戻り値を変更して、ターンプレイヤーと非ターンプレイヤーを返す
    println!("じゃんけんをします。Player 1: グー、チョキ、パーのいずれかを選択してください。");
    let player1_choice = get_user_input();
   
    println!("Player 2: グー、チョキ、パーのいずれかを選択してください。");
    let player2_choice = get_user_input();

    let outcomes: HashMap<&str, &str> = [
        ("グー", "チョキ"),
        ("チョキ", "パー"),
        ("パー", "グー"),
    ].iter().cloned().collect();

    let winner = if player1_choice == player2_choice {
        println!("あいこです。");
        return (0, 0); // あいこ
    } else if outcomes.get(player1_choice.as_str(