陽が暮れるまで心が赴くままに

ボードゲーム制作サークル「遊陽ゲームズ」のブログ

ボドゲ制作するときに使えそうな「3枚のカードの組合せ全網羅リスト」を取得できるプログラムを書きました

セットコレクションのメカニクスを持つゲームを作っていると、任意のカード3枚の全組合せを網羅したリストが欲しくなりませんか? 「別に欲しくない」という人の方が多い気がしますが僕は欲しかったので続けます。

経緯

今作っているゲームは3枚のカードの組合せで戦うのですが、「役」の強さはカードに記載された数字の合計で、3枚の色を揃えているとボーナス点が入るような仕組みになっています。カードは15枚全てがユニークです。

どれくらいの強さの役がどの程度の頻度で出現するかは、通常ならばカードをパターン分けして、高校の数学で習う「場合の数」なんかを駆使してスマートに出したりするのでしょう。けれど、パターン自体が一定以上多くなってくるともはや絶対間違える全パターン作って出現率を弾いた方が楽だったりします。(※表計算ソフトが扱える程度のパターン数であれば)

全パターンが手に入ってしまえば、それぞれのカードのパラメータを展開して前述のボーナスなどを加味した点数を計算するのは楽勝です。今回は15C3=455パターンしかないことも分かっているので安心です。

結果

というわけで早速書いたコードがこちら。

コピペできるようにコードも貼っておきます。このコードはそのまま Go Playground で実行して結果を取得できます。
また、A~O の文字列がカード一枚一枚に対応しています。この要素リストを増減させればカードの総枚数(種類数)を調整できます。

package main

import (
    "fmt"
    "sort"
)

func main() {
    // 結果を格納する連想配列
    result := make(map[string]int,0)
 
    // 15個数の要素のリスト
    list := [...] string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"}
 
    // 1枚目のドロー
    for i, _ := range [15]int{} {
        // 2枚目のドロー
        for j, _ := range [15]int{} {
            // 1枚目と2枚目が同じならスキップ
            if (i==j) {
                continue
            }

            // 3枚目のドロー
            for k, _ := range [15]int{} {
                // 1枚目と3枚目、2枚目と3枚目が同じならスキップ
                if (k==i || k==j) {
                    continue
                }
             
                // 文字列をソート
                arr := [] string { list[i], list[j], list[k] }
                sort.Slice(arr, func(l, n int) bool { return arr[l] < arr[n] })
             
                // 文字列を結合
                str := arr[0] + arr[1] + arr[2]
                 
                // 連想配列に入れる
                if _, ok := result[str]; ok {
                    // 既に入っていたら抜ける
                    continue
                }
             
                result[str] = 1
            }
        }
    }
 
    // 結果出力
    fmt.Printf("要素数: %d\n",len(result))
    fmt.Println("===== 以下、生成結果 =====")
    for key, _ := range result {
        fmt.Println(key)
    }
 
}

出力結果が以下のように三文字のアルファベットで出るので、予め作っておいたアルファベットとカードの対応表を使えばデータを加工していけます。

f:id:susabi-games:20200822190947p:plain

エクセルやスプレッドシートで頑張る場合

実はプログラム書く前に一度スプレッドシートを駆使して欲しいリストを得ることができていました。

何やらテクニカルなことをしてリストを生成していますが、説明は省きます。ちなみにデータの加工がすごくめんどくさかったのでオススメしません。

まとめ

3枚の組合せ全網羅リストを取得するプログラムを作りました。15枚のユニークカードを前提としたプログラムになっていますが、要素リストの行を書き換えることで枚数は調整できます。

3枚のセットコレクションはかなりたくさんのゲームで使われている仕組みですし、今後もそういうゲームが多く生まれるのではないでしょうか。そんなゲームを作るときには、このブログ記事を思い出して前述のプログラムをぶん回してもらえば良いかと思います。

一応、個人利用の範囲内で使って頂き、使ってお役に立てたならこの記事についてツイートしたりメンションくれたりするとぼくが喜びます。