なんか…カードバトルできそう…(ハチワレ)

# 【0. まえがき】
こんにちは！くつしたすきぞうです！
アドベントカレンダー2本目の記事となる今回はかなりガチめな仕組み解説です！
タイトルはズバリ「カードバトルの作り方」です。

というのも、直近で作ったカードバトル2作品は特に色々考えて作ったので、
何も説明せず終わらせるのはもったいないと思っていたところでした。
紹介がてら全部見せちゃいましょう！

見終わった頃にはこう思うでしょう…

__<font color="Blue">「なんか…カードバトルできそう…」</font><font color="Silver">「エ～?」</font>__
![ngnchiikawa-1360202257199894530-img3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/512ddcf5-1471-effa-d12b-1226e3bb5122.jpeg)
出典:[ちいかわ](https://twitter.com/ngnchiikawa/status/1360202257199894530?s=20&t=P88XU9qFe1BcvoHeZRac6Q)

お遊びはここまでです！振り落とされないように気を付けてくださいね。
では行くぞ！

# 【1.自作ゲーム紹介 す～ぱ～干支ポーカー】
まずご紹介するのはこちらのゲームです。
トランプのスピードを十二支で再現してみよう、という試みでした。
CPUと渡り合うためのテストプレイがとにかく大変だった印象があります。

https://twitter.com/KutsusitaSukizo/status/1583730513923432448?s=20&t=RshITV9bsm16hvYtHqhO9g

## 【1.1 ゲームの裏側】
(解説の内容をより詳しく理解するために、まずは一度プレイされることをおすすめします。)

動画用に一部配置を変更したり見えないものを見えるようにしたりしてますが、
使用しているパーツはこんな感じです。

![スクリーンショット 2022-12-05 233846.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/869a0fa9-ccf3-5a0b-15f8-0cb23aa06a5b.png)


| No. |名前 | 説明 |
|:-:|:-:|:--|
| ①|デッキワープ入口(デッキ部)|タイトル画面で見えてるとこ。実はデザインとデッキの機能を兼ねています。|
| ② |デッキワープ出口(手札部)|ゲーム中メインで動かすとこ。場に直接カードを出す時は干渉回避のため下がります。|
| ③ |識別部|後ほど解説します。   |

動画で見るとこんな感じです。

ワープ入口部分が振動しているのは、ランダムノードンで1~360°までの角度を与えているためです。
ワープ入口ノードンの「中心に近いものからワープする」という特性を活かし、シャッフル状態を作り出しています。

<iframe width="560" height="315" src="https://www.youtube.com/embed/xPP5TKRqmBM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## 【1.2 カードを区別する方法】
そもそも、はじプロ上で見た目が同じものを区別するためにはどうすればいいでしょうか？

レッスンを受けた方は覚えているかもしれませんが、見た目が同じものを区別する方法として、見えないオシャレなモノノードンを連結してさわっているセンサーに感知させる「秘技:見えないオシャレ」という方法がありましたね。
![2022120609130500-1DC473CEFCA17AB42EE8681FFF996D70.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/759231b0-0c6c-e4f7-c5ed-ec39e636d7f7.png)


ただしこの方法には弱点があります。
オシャレなモノノードンは1作品あたり32枚までしか使用できないのです。
干支ポーカーでは12種類x各4枚=48枚のカードを使用する予定のため、オシャレなモノの配置上限を余裕でオーバーしてしまいます。
よって、はじプロでカードゲームのようなものを作るのは難しいと考えていました。

そんな問題を解決する記事を見つけてしまいました！
https://pochitto.hatenadiary.jp/entry/2022/06/29/140748

「上海ソリティア」を制作したpochittoさんのブログです。
麻雀も多くの牌を区別しなければならないという点でカードゲームに似たような点がありますね。

ともかく、pochittoさんがどのように麻雀牌を区別したかをざっくり説明すると、
識別させたいモノに球や円柱などのシンプルなモノノードンを連結させ、その大きさに応じたさわっているセンサーで識別させているのです。
これは自分にとっての天啓でした！

さっそく自分のゲームにも適用した動画がこちらになります。
先程の動画も、実はカードに連結されている円柱を識別部で読み取っていたんですね。
具体的な識別方法は次で解説します。

<iframe width="560" height="315" src="https://www.youtube.com/embed/jkDxxHrXjDE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## 【1.3 影の立役者 角度の差ノードン】
スピードのルール上、手札を場に出すための条件として｢手札と場の札が隣同士のカードかどうか｣を判断する必要があります。

![記事用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/9ec0dc13-0960-8ee0-4247-845b57cce59a.png)

先程のpochitto式を適応し、上の図のように各カードに1から12までの数字を割り当てたと仮定します。
これであればくらべるノードンなどを使って数字が隣り合っているかどうかを判定すればよさそうに考えられます。
ですが、1または12のカードが場にある場合はそう単純にはいきません。
場札が12なら11または1を出せるように、場札が1なら12または2を出せるように場合分けする必要があります。

ただしその処理のために3パターンの場合分けを作るのは、面倒だし見た目的にも美しくないですよね。
そこで役に立つのが角度の差ノードンです。

![記事用2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/0c456ad1-9567-d040-0622-df69f1e9e542.png)

まず各カードに対し、1から12ではなく上の図のように数字(角度)を割り当てます。
次に場札の数字と手札の数字を角度の差ノードンに入力します。
こうすると「__出そうとしている手札が場札に対し±30°である__」という条件だけ満たしていれば、細かい場合分けを指定しなくても12と1を行き来できるようになるのです。
![20221216_194008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/369ec96e-bf4c-b503-a59f-20cf14e5bbbb.jpeg)

15°と345°の引き算でもきちんと30°で出力してくれます。
この循環性を1ノードンで完結できる角度の差ノードンって地味にすごくないですか？

(ちなみに0°からスタートしないのは、何もカードが置かれていない状態と区別するためです。)

ちなみに先程のpochitto式の識別部の仕組みはこのようになっております。
さわっているセンサーをマッピンッグに接続すると、図のように角度で示せるようになっているんですね。

![2022120522011500-1DC473CEFCA17AB42EE8681FFF996D70d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/bf7220b1-d913-2d02-5efc-75884faa633a.png)


## 【1.4 反省点】
仕組み的には上手く落とし込んだつもりだしデザインも気に入ってる今作でしたが、プレイヤー側からは「難しすぎる」との声が多く聞こえてきました。
作者がテストプレイに慣れすぎて適切な難易度調整が出来ない典型ですね💦
あと干支を逆順で覚えることって普段絶対ありませんからね。
この反省は次の作品に生かしました。

今度余力あれば普通のトランプバージョンで作るかもしれませんね。
13種類の角度の輪を作り直す必要がありますが…

# 【2.自作ゲーム紹介 異世界ルイージのいかさまポーカー】
干支スピードを完成させてからも、カードゲームを作りたい欲は収まりませんでした。
むしろ干支スピードを作ったことにより基本システムが完成したため、別のカードゲームにアイデアを展開させようという意欲が湧き出ていました。
とっつきづらさを感じさせずにみんなに遊んでもらうには、キャッチーで見覚えのある、ピッタリな題材がありますよね!
そう、ルイージカジノのポーカーです。
(若い子へ：DSのマリオにそういうミニゲームがあったのじゃよ。)
子供の頃はこれだけでマジで時間が溶けましたよね～。

https://twitter.com/KutsusitaSukizo/status/1592508674513469441?s=20&t=nu9FGwaOja-LI87wJxW-6Q

## 【2.1 ゲームの裏側】
(解説の内容をより詳しく理解するために、まずは一度プレイされることをおすすめします。)
先ほどと同様、動画用に一部配置を変更したり見えないものを見えるようにしたりしてます。

| No. |名前 | 説明 |
|:-:|:-:|:--|
| ①|デッキワープ入口(デッキ部)|干支スピードとだいたい同じ。|
| ② |デッキワープ出口(手札部)|プレイヤー側も相手側も同じワープ出口でカードを配っています。|
| ③ |捨て札エリア(ワープ出口)|ワープ入口の表記は省略してますが各手札位置に一つずつ配置されてます。|
| ④ |回収用ワープ入口|すべての場のカードをデッキに戻すため、このワープだけは「ゼロ以外の時ずっと」です。|
| ⑤ |回収用ワープ出口|回転でカードをバラけさせて次の手札抽選がなるべくランダムになるようにしてます。|

![スクリーンショット 2022-12-10 093140.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/0b117b90-2611-08d9-cd5e-9cfb880310f7.png)


動画はこちら
<iframe width="560" height="315" src="https://www.youtube.com/embed/I9jWCUe-58o" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

ゲームの流れはこの様になっています。
1. 山札エリアからプレイヤーとCOMにカードを配る。(ワープ<font color="Red">赤</font>)
1. プレイヤーは交換するカードにフラグを立てる。同時にCOMは自分の手札の中で重複していないカードにフラグを立てる。
1. 交換フラグの立っているカードを捨て札エリアに送る。(ワープ<font color="Blue">青</font>)
1. カードが置かれていない箇所に山札エリアからカードを配る。(ワープ<font color="Red">赤</font>)
1. 得点計算により勝敗判定を決める。(後述)
1. 勝敗を発表する。プレイヤーが勝っていた場合配当を還元する。
1. プレイヤー、相手、捨て札エリアのカードを全て山札エリアに戻す。(ワープ<font color="Yellow">黄色</font>)
1. 以下繰り返し

## 【2.2 役判定の仕組み】
カードは6種類あるため先程のpochitto式を適用して1-6までの番号で識別しました。
(ゲームのルール的に角度換算は必要ないのでここはシンプルに決めました。)

カードに紐づいた数字はそのまま強さに連動しています。
これは後々勝敗判定に利用することになります。
(余談ですが、なんとなくカバって最強そうじゃないですか?さわっている君最弱は満場一致ですよね。そんな感じの人選です。)

![記事用3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/cff5e2d3-8212-08c0-af1f-3e84fb7bcb00.png)

手札が配られたら5枚の数値をカウンターで記録してマーカーにぶち込み、スポイトと重なっている量でペアやスリーカードが揃っているかを判定しています。
![2022120311283300-1DC473CEFCA17AB42EE8681FFF996D70.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/e876a948-eefc-3772-88fe-c8e6c34149d2.png)
具体的にはこんな感じです。
ここ大事なトコですが、最初の読み取りでは __スポイトはほんのちょっとだけマーカーに重ねる__ ようにします。

スポイトノードンはマーカーと重なっている量を0-1までの数値で出力しますが、マーカーと重なっている量が体感2割くらいを超えると、すぐに1に到達してしまいます。
スポイトとマーカーをガッツリ重ねてしまうと、例えばカバのカードが2枚揃ってようが、3枚揃っていようがスポイトから1が出力されてしまいますね!
これでは役を正確に判別することができません。
だから、重なっているかどうかの微妙なラインで重ねています。

3パターンほどお見せしますので、ご参考まで。
![2022120311283300-1DC473CEFCA17AB42EE8681FFF996D70.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/e876a948-eefc-3772-88fe-c8e6c34149d2.png)
![2022120311284500-1DC473CEFCA17AB42EE8681FFF996D70.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/987dd064-5748-e684-31b7-451ebc4f62aa.png)
![2022120311290300-1DC473CEFCA17AB42EE8681FFF996D70.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/32c95b71-42e3-e730-4908-d806995a94d1.png)

## 【2.3 勝敗判定の仕組み】
ここまで手札から役を判別する仕組みを作りましたが、勝敗判定はどのように行うのでしょうか。
仕組み自体はとても単純です！役に得点を割り当て、プレイヤーと相手で獲得した得点を比較した結果によって勝敗を判別しています。
得点は下記のとおりです。

|役名|得点|
|:-:|:-:|
|ワンペア|10|
|ツーペア|20|
|スリーカード|30|
|フルハウス|40|
|フォーカード|50|
|ファイブカード|60|

(ゲームを進めると隠し役も登場しますが、ここでは割愛します。)


ですが、これだけでは相手と同じ役だった場合に、マークの強弱に関わらず引き分けになってしまいます。
同じツーペアでも、カブのペアの方がさわっている君のペアより強い、というように強弱の情報を数字に付与する必要があります。

![記事用4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/35894b87-5d73-b8c8-2eda-cc02bb1b0a2a.png)


そのために、読み取り部②に追加パーツを取り付けました。2Dマーカーノードンくんです。
2Dマーカーノードンには、他のマーカーと重なった時に信号を出力するポートがあります。
重なったときのカードの数字を2桁まで記録することができます。

![スクリーンショット 2022-12-10 183322.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/9174b502-c9a9-4df0-11d1-c3d76fa8df4d.png)

この2Dマーカーが右下から左上に移動していきながら、途中で重なった数字をカウンターに記録していきます。
どのような動きになるのかは、実際に動画で見ていただいたほうがわかりやすいかと思います。
ツーペアのパターンで実演したものが以下です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/u75FZe7kKNI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

一回目に重なった数字は __4__ 、二回目に重なった数字は __1__ となりました。
このあと、一回目の数字を得点の一の位として、二回目の数字を少数第一位として先程の役の得点に追加します。
ツーペアの役の得点は20点なので、手札の合計点数は __24.1__ となります。
これであれば相手が同じツーペアであっても、一の位以下の数字の比較で勝敗を判定することができますね！

![記事用5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/dc215925-6f0d-8b8b-4f54-22336fd281d2.png)

![記事用6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953004/1076cb74-8558-7625-1d7d-2359bcf87a07.png)
(↑フルハウス同士の得点計算のサンプル)

この仕組みさえできていれば、ゲームの進捗によって解放されるイカサマ(手札を6枚に増やしたり、役を増やしたり)は、応用でなんとでもできます。


# 【3. 最後に】
長々と書き連ねましたがお付き合いいただきありがとうございました！

はじプロ発売から1年半が経ち、そろそろ皆さんオリジナリティという名の手癖に慣れ始めていませんか？
開拓してみませんか？カードゲームという新しい地平！
質問などあれば、コメント欄、Twitterのリプ欄などで遠慮なく送ってきてください。

このように自分のプログラミングの考えを話せる場を用意していただき楽しかったです！
ではまた！