カードドロー&山札シャッフル|手札管理の実装テク

シミュレーションゲームの作り方

カードドローシステムは、カードゲームの核心です。

山札の生成とシャッフルを実装すれば、ランダム性が確保できます。

この記事では、実装方法を詳しく解説します。

この記事でわかること

  • 山札生成の実装
  • シャッフルアルゴリズムの実装
  • 手札ドローの実装
  • 墓地処理の実装
  • 実装例とコード
ゲーム開発講師
ゲーム開発講師

カードドローシステムは、山札生成から始めましょう。デッキから山札を作成すれば、ゲームが開始できます。

ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
ゲームを「遊ぶ側」から「作る側」へ

あなたのオリジナルゲーム、今年こそ完成させませんか?

RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。

Unity入門の森|永久会員チケット

永久会員チケット|Unity入門の森

全講座ラインナップを見てみる

実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。

山札生成の実装

card-draw-system-001

山札生成は、ゲーム開始時にデッキの内容を元に、実際に使用する山札を作成する処理です。

デッキと山札を分けて管理することで、ゲーム進行中にカードを引いたり、捨てたりしても、
元のデッキ構成を保持できます。

ここでは、デッキ情報をコピーして山札を生成し、初期状態でシャッフルを行う基本的な実装方法を紹介します。

山札生成システム

InitializeDrawPile()では、デッキのリストをそのまま使わず、新しいリストとしてコピーしています。

これは、ゲーム中に山札の内容が変化しても、元のデッキデータに影響を与えないためです。

また、山札生成と同時にシャッフルを行うことで、ゲーム開始時点からランダム性が確保されます。

シャッフルには、偏りの少ないFisher-Yatesシャッフルを採用しています。

この構成により、山札・手札・墓地を明確に分離した、扱いやすいカード管理システムを実装できます。

ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる

シャッフルアルゴリズムの実装

card-draw-system-002

シャッフルアルゴリズムは、カードの順序をランダム化し、ゲームの公平性と再現性のなさを担保する重要な処理です。

実装方法を誤ると、特定のカードが出やすくなるなど、プレイ体験に大きな影響を与えます。

ここでは、カードゲームで最も標準的に使われているFisher-Yatesシャッフルを、再利用しやすい形で実装します。

Fisher-Yatesシャッフル

Shuffle()は、元のリストを変更せずに、新しいシャッフル済みリストを返すメソッドです。

「元データを保持したい場面」や「安全に処理したい場合」に適しています。

一方、ShuffleInPlace()は、渡されたリスト自体を書き換えるメソッドです。

山札や墓地など、状態として管理しているリストを直接シャッフルしたい場合に向いています。

このように用途に応じてメソッドを分けておくことで、カード管理処理を柔軟かつ安全に再利用できます。

ゲーム開発講師
ゲーム開発講師

Fisher-Yatesシャッフルは、すべての並び順が等確率になることが数学的に保証されています。
そのため、カードゲームやガチャシステムなど、公平性が求められる場面で広く使われています。

ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる

手札ドローの実装

card-draw-system-003

手札ドローは、山札からカードを引いて手札に加える処理です。

単純にカードを1枚引くだけでなく、山札切れ・手札上限・再シャッフルなど、ゲーム進行上のルールをまとめて管理する必要があります。

ここでは、カードゲームで一般的な挙動を想定した、安全に使えるドローシステムを実装します。

ドローシステム

DrawCard()では、カードを引く前に必ずドロー可能かどうかを判定しています。

この順序でチェックすることで、想定外の状態でもエラーを起こさずに処理できます。

  • 山札が空の場合は、墓地を戻して再シャッフル
  • それでも山札が空なら、ドロー不可として処理終了
  • 手札が上限に達している場合も、ドローを中断

カードは山札の先頭から取得し、手札に追加します。

この処理により、山札 → 手札というカードの流れが明確になります。

また、DrawCards()を用意することで、初期手札配布や複数枚ドローなどの処理を簡潔に記述できます。

このようにドロー処理を1か所にまとめておくことで、ルール変更や演出追加にも対応しやすい設計になります。

ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる

墓地処理の実装

card-draw-system-004

墓地処理は、使用したカードを管理します。 実装方法を紹介します。

墓地管理システム

墓地は、使用済みカードを一時的に保管するための領域です。

単なる「捨て場」ではなく、山札切れ時の再利用やゲームルールの制御に直結する重要な要素になります。

ここでは、手札からカードを墓地に送る処理と、墓地を山札に戻す基本的な管理システムを実装します。

DiscardCard()は、カード使用時や効果解決後に、特定のカードだけを墓地に送る場合に使用します。

DiscardHand()は、ターン終了時やラウンド終了時など、手札を一括でリセットしたい場面で役立ちます。

ShuffleDiscardIntoDraw()は、山札が尽きた際に、墓地を山札へ戻してゲームを継続するための処理です。

この処理を分離しておくことで、再シャッフルのタイミングをルールごとに柔軟に制御できます。

墓地管理を独立したシステムとして実装しておくと、カード効果による回収や除外などの拡張も容易になります。

ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる

確率のブレを抑える工夫

card-draw-system-005

カードゲームでは、理論上は同じ確率でも、短期的には極端な結果が続くことがあります。

これをそのまま採用すると、「全然出ない」「不公平に感じる」といったプレイヤー体験の低下につながる場合があります。

そこで一部のゲームでは、確率そのものを変えずに、結果の偏りだけを緩和する仕組みが採用されています。

いわゆる「天井システム」や「救済処理」です。

ここでは、その一例として、指定回数引いても出なかった場合にのみ保証する仕組みを実装します。

確率調整システム

この処理では、まず通常のドローを繰り返し、指定した回数以内に目的のカードが出るかを確認します。

途中で目的のカードが出た場合は、その時点で処理を終了します。

規定回数引いても出なかった場合のみ、山札の中から対象カードを検索し、強制的に取得します。

これにより、理論確率を大きく崩さずに救済処理を実現できます。

なお、この仕組みはすべてのカードゲームに適しているわけではありません。

対戦型TCGなど完全なランダム性が求められるゲームでは、使用を避けるべきです。

一方で、ソロプレイ中心のゲームやガチャ要素を含むゲームでは、プレイヤー体験を安定させるための有効な選択肢になります。

確率調整は「ズル」ではなく、どの体験を提供したいかに応じた設計判断として慎重に導入することが重要です。

ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる

実装例:完全なカードドローシステム

card-draw-system-006

ここまで紹介してきた各システムを組み合わせることで、実際のゲームでそのまま使えるカードドローシステム一式を構築できます。

この実装例では、山札生成・シャッフル・ドロー・墓地管理といった個別の責務を分離したまま、ゲーム開始時の初期化処理をまとめています。

StartGame()では、ゲーム開始時に必要な処理のみをまとめています。

ここで山札を初期化し、初期手札を配ることで、カードゲームとしてのスタート状態を簡潔に構築できます。

各機能はそれぞれ専用のクラスに分かれているため、カード効果やルールが増えても、特定のシステムだけを拡張すれば対応できます。

例えば、ターン終了時の手札破棄は DiscardSystem に、特殊ドローや確率補正は ProbabilityControlSystem に追加するなど、責務ごとに機能を増やせる構成になっています。

このように、システムを疎結合に設計しておくことで、小規模なカードゲームから本格的なデッキ構築型ゲームまで、柔軟に対応できる土台を作ることができます。

ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる

よくある質問(FAQ)

card-draw-system-007

Q: シャッフルアルゴリズムはどれを使えばいいですか?
A: Fisher-Yatesシャッフルが標準です。均等なランダム性を提供します。
Q: 手札の最大枚数はどう設定すればいいですか?
A: 7枚が標準です。多すぎると複雑になり、少なすぎると選択肢が少なくなります。
Q: 山札が空になったらどうすればいいですか?
A: 墓地を山札に戻してシャッフルしましょう。これにより、ゲームが続行できます。
Q: 確率のブレを抑える工夫は必須ですか?
A:
必須ではありませんが、強く推奨します。天井システムなどで、公平性が保たれます。
Q:
カードドローシステムのパフォーマンスはどう最適化すればいいですか?

A: リスト操作を最小限にしましょう。また、不要なカードは早めに削除します。
ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
ゲームを「遊ぶ側」から「作る側」へ

あなたのオリジナルゲーム、今年こそ完成させませんか?

RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。

Unity入門の森|永久会員チケット

永久会員チケット|Unity入門の森

全講座ラインナップを見てみる

実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。

まとめ

card-draw-system-008
カードドローシステムは、山札生成から始めましょう。
デッキから山札を作成し、シャッフルすれば、ゲームが開始できます。

今日から始める3ステップ

  • ステップ1:山札生成システムを実装する(所要2時間)
  • ステップ2:シャッフルアルゴリズムを実装する(所要1時間)
  • ステップ3:手札ドローシステムを実装する(所要2時間)

本格的にUnityを学びたい方は、Unity入門の森で実践的なスキルを身につけましょう。
あなたのペースで、少しずつ進めていけば大丈夫です。

ゲーム制作をゼロから学びたいあなたへ
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる

コメント

タイトルとURLをコピーしました