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
「たべっ子どうぶつ」は袋入りのビスケットで、それぞれのビスケットに動物の英語名が焼き付けられています。
常に全種類入っているのかどうかまでは知らないのですが、これならわざわざビンゴマシーンを使わなくても、袋から取り出しながらビンゴゲームをやって、ついでに食べちゃってもいいでしょう。
同じ種類が複数入っていますが、そこはまぁゲームですから。
他にも特定のテーマに属すキャラクターやモノでビンゴゲームを作るのも面白そうです。