0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

リストのシャッフル (応用編~ビンゴカード)

0
Last updated at Posted at 2025-12-08

Tcl/Tk Advent Calendar 2025の7日目です。

相変わらず昨日の続きネタです。

昨日はshuffle関数の応用でビンゴマシーンを作りましたので、今日はビンゴカードを作ってみたいと思います。

WikiPediaの「ビンゴ」の縦横5マスのビンゴカードの配置ルールを参考にしました。

proc make_bingo_card {shuffle center_is_free args} {
    set width [llength $args]

    foreach arg $args {
        lappend min_args [llength $arg]
    }
    set lowest [expr min([join $min_args ,])]

    if {$width > $lowest} {
        error "length of each arg should be equal or larger than # of args."
    }

    set tail [expr {$width - 1}]
    for {set key 0} {$key < $width} {incr key} {
        set arg [lindex $args $key]
        set column($key) [lrange [$shuffle $arg] 0 $tail]
    }

    set card [list]
    for {set i 0} {$i < $width} {incr i} {
        for {set key 0} {$key < $width} {incr key} {
            lappend card [lindex $column($key) $i]
        }
    }

    if {$center_is_free} {
        set length [llength $card]
        if {$length % 2} {
            set center [expr {int($length / 2)}]
            set card [lreplace $card $center $center {}]
        }
    }

    return [list $width $card]
}

はい!できました。

ただmake_bingo_cardコマンドだけでは見にくいので表示用のshow_cardコマンドも作っておきましょう。

proc show_card {width card} {
    foreach str $card {
        lappend max_args [string length $str]
    }
    set longest [expr max([join $max_args ,])]
    
    for {set i 0} {$i < $width} {incr i} {
        set left [expr {$width * $i}]
        set right [expr {$width * ($i + 1) - 1}]
        set row ""
        for {set j $left} {$j <= $right} {incr j} {
            append row [format "%${longest}s " [lindex $card $j]]
        }
        puts $row
    }
}

あ、あとTcl/Tk Advent Calendar 2025の最初の数日間で作ったshuffleコマンドも必要です。

さて、使い方ですが、まずは列リストを定義します。

for {set i 1} {$i <= 15} {incr i} {
    lappend B $i
}
for {set i 16} {$i <= 30} {incr i} {
    lappend I $i
}
for {set i 31} {$i <= 45} {incr i} {
    lappend N $i
}
for {set i 46} {$i <= 60} {incr i} {
    lappend G $i
}
for {set i 61} {$i <= 75} {incr i} {
    lappend O $i
}

ちなみにTcl9.0からはlseqコマンドが追加されたので以下で済みます。

set B [lseq 1 to 15]
set I [lseq 16 to 30]
set N [lseq 31 to 45]
set G [lseq 46 to 60]
set O [lseq 61 to 75]

では作ってみましょう。結果表示は#=> に続けて記載します。

show_card {*}[make_bingo_card shuffle 1 $B $I $N $G $O]
#=>  9 17 39 56 66 
#=>  6 23 40 47 75 
#=>  5 19    50 73 
#=>  4 29 45 60 67 
#=> 14 30 42 58 69 

show_card {*}[make_bingo_card shuffle 1 $B $I $N $G $O]
#=>  3 28 44 50 71 
#=>  2 30 37 57 74 
#=> 15 20    59 72 
#=> 14 17 35 54 62 
#=>  1 23 36 53 75 

show_card {*}[make_bingo_card shuffle 1 $B $I $N $G $O]
#=>  3 24 41 56 75 
#=> 10 17 44 50 69 
#=>  5 26    57 61 
#=>  6 23 45 59 67 
#=>  2 29 42 58 66 

列は数字である必要はありません。文字列でも大丈夫です。

例として、ギンビス・マーケットの「たべっ子どうぶつ」のビンゴカードを作ってみましょう。

set B {
    LION
    GIRAFFE
    MONKEY
    HIPPO
    RABBIT
    CROCODILE
    CAT
    ELEPHANT
    CHICK
    BAT
    BEAR
}

set I {
    CAMEL
    COW
    DEER
    DOG
    DUCK
    EAGLE
    FOX
    FURSEAL
    GOAT
    GORILLA
    HAWK
}

set N {
    HEN
    HORN-OWL
    HORSE
    KANGAROO
    KOALA
    LEOPARD
    LYNX
    MACAW
    M,DUCK
    MOLE
    MOUSE
}

set G {
    OX
    PANDA
    PARROT
    PEAFOWL
    PELICAN
    PENGUIN
    PIG
    PIGEON
    POLAR BEAR
    PORCUPINE
    RACCOON
}

set O {
    RHINOCEROS
    ROOSTER
    SEAL
    SHEEP
    SPARROW
    SQUIRREL
    TAPIR
    TIGER
    TORTOISE
    WILD BOAR
    WOLF
    ZEBRA
}

show_card {*}[make_bingo_card shuffle 1 $B $I $N $G $O]
#=>        BAT       GOAT       LYNX     PARROT       WILD 
#=>   ELEPHANT       DEER    LEOPARD    PENGUIN   TORTOISE 
#=>       BEAR    GORILLA                  BEAR    SPARROW 
#=>        CAT        DOG     M,DUCK         OX      ZEBRA 
#=>      HIPPO       DUCK        HEN        PIG RHINOCEROS 

show_card {*}[make_bingo_card shuffle 1 $B $I $N $G $O]
#=>       CAT     EAGLE      LYNX        OX     ZEBRA 
#=> CROCODILE      DEER       HEN     PANDA      BOAR 
#=>     HIPPO       DOG             RACCOON      SEAL 
#=>      LION   FURSEAL  KANGAROO   PEAFOWL     TAPIR 
#=>      BEAR   GORILLA  HORN-OWL    PIGEON   SPARROW 

show_card {*}[make_bingo_card shuffle 1 $B $I $N $G $O]
#=>     RABBIT      CAMEL   HORN-OWL     PIGEON   SQUIRREL 
#=>      CHICK      EAGLE      MACAW    PELICAN   TORTOISE 
#=>   ELEPHANT    FURSEAL               PEAFOWL RHINOCEROS 
#=>        BAT        DOG        HEN      PANDA       SEAL 
#=>        CAT        FOX      HORSE      POLAR      SHEEP 

「たべっ子どうぶつ」は袋入りのビスケットで、それぞれのビスケットに動物の英語名が焼き付けられています。

常に全種類入っているのかどうかまでは知らないのですが、これならわざわざビンゴマシーンを使わなくても、袋から取り出しながらビンゴゲームをやって、ついでに食べちゃってもいいでしょう。

同じ種類が複数入っていますが、そこはまぁゲームですから。

他にも特定のテーマに属すキャラクターやモノでビンゴゲームを作るのも面白そうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?