はじめに
この記事は「おもしろ科学まつり2025」で配布したパンフレットと連動した内容です。パンフレットの手順に従ってExcelファイルを作成したら、このページでプログラムの仕組みを詳しく学びましょう!
パンフレットには「作り方の手順」が載っていますが、この記事では**「なぜこのコードで動くのか」「どんな仕組みなのか」**をわかりやすく解説します。
どんなゲーム?
10×10のマス目のどこかに宝が隠れています。
- 好きなマスを選んで「箱を開ける」ボタンを押す
- 「右下」「左上」などの方向のヒントが出る
- ヒントを頼りに探して、宝を見つけたらクリア!
📜 完全なソースコード
パンフレットの手順で作ったExcelに、下のコードをそのままコピー&ペーストしてください。
Sub setTreasure()
' ゲーム画面をリセットするためのプログラム
Dim treasure_i As Integer
Dim treasure_j As Integer
' Int(Rnd * 10) は「0〜9の整数」になるので +1 して「1〜10」にしている
treasure_i = Int(Rnd * 10) + 1 ' 宝の「たて」の場所
treasure_j = Int(Rnd * 10) + 1 ' 宝の「よこ」の場所
' 宝の場所を覚えておくために、目立たないところ(100行目)にメモしておく
Cells(100, 1) = treasure_i
Cells(100, 2) = treasure_j
' 宝箱の代わりに ?? を表示する
Range("A1:J10") = "??"
End Sub
Sub openBox()
' 箱を開けるためのプログラム
Dim treasure_i As Integer ' 宝のたて位置
Dim treasure_j As Integer ' 宝のよこ位置
Dim selection_i As Integer ' クリックしたマスのたて位置
Dim selection_j As Integer ' クリックしたマスのよこ位置
Dim vertical_diff As Integer ' たてのずれ
Dim horizontal_diff As Integer ' よこのずれ
Dim diff_msg As String ' ヒントのメッセージ(上・下・左・右など)
' 選択したマスを調べる
selection_i = Selection.Row
selection_j = Selection.Column
' 宝の場所を(さっき100行目に保存しておいた場所から)読み取る
treasure_i = Cells(100, 1)
treasure_j = Cells(100, 2)
' クリックした場所が宝の場所と同じだったら
If selection_i = treasure_i And selection_j = treasure_j Then
MsgBox ("お宝を見つけた!")
Else
' ちがうマスだったら、宝がどっちのほうにあるかヒントを出す
' たて・よこのずれを計算する
horizontal_diff = treasure_j - selection_j
vertical_diff = treasure_i - selection_i
If horizontal_diff = 0 Then
diff_msg = "" ' 同じ列ならヒントなし
ElseIf horizontal_diff > 0 Then
diff_msg = "右" ' 宝は右の方にある
Else
diff_msg = "左" ' 宝は左の方にある
End If
' たてのずれからヒントを追加する
If vertical_diff = 0 Then
diff_msg = diff_msg + "" ' 同じ行ならヒントなし
ElseIf vertical_diff > 0 Then
diff_msg = diff_msg + "下" ' 宝は下の方にある
Else
diff_msg = diff_msg + "上" ' 宝は上の方にある
End If
' 上下左右のヒントを表示する
MsgBox (diff_msg)
End If
End Sub
プログラムの全体像
このプログラムは大きく2つの部分に分かれています。
| 名前 | 何をするの? | どのボタンに結びついてる? |
|---|---|---|
setTreasure |
宝をどこかに隠す | 「スタート」ボタン |
openBox |
選んだマスを開けてヒントを出す | 「箱を開ける」ボタン |
ボタンとプログラムの関係
Excel画面に作った2つのボタン(「スタート」と「箱を開ける」)は、それぞれのプログラムと結びついています。
- 「スタート」ボタンを押すと →
setTreasureが動く - 「箱を開ける」ボタンを押すと →
openBoxが動く
この結びつけ方は、パンフレットの「ゲーム画面にボタンを設置」のページに書いてあります。まだその部分を読んでいなくても大丈夫です。今はプログラムの中身を理解していきましょう!
ゲームの流れ:
- 「スタート」ボタンを押す →
setTreasureが動いて、宝がどこかに隠れる - マスを選んで「箱を開ける」ボタンを押す →
openBoxが動いて、ヒントが表示される - 宝が見つかるまで2を繰り返す
setTreasure の解説 - 宝を隠す部分
使う変数(データを入れる箱)
Dim treasure_i As Integer
Dim treasure_j As Integer
プログラムでは、数字や文字を「変数」という箱に入れて使います。
-
treasure_i→ 宝の「たて位置」を入れる箱 -
treasure_j→ 宝の「よこ位置」を入れる箱
Excelのセルは「たて(行)」と「よこ(列)」の2つの数字で場所を表すので、2つの箱が必要です。
ランダムな場所を決める
treasure_i = Int(Rnd * 10) + 1
treasure_j = Int(Rnd * 10) + 1
この式で、1〜10のどれかの数字がランダムに決まります。分解して見てみましょう。
Rnd - ランダムな数字を作る
Rnd は、0〜1の間のでたらめな小数を作ります。
例: 0.234、0.789、0.012 など
Rnd * 10 - 10倍にする
0.234 × 10 = 2.34
0.789 × 10 = 7.89
0.012 × 10 = 0.12
Int(...) - 小数点を消す
Int(2.34) = 2
Int(7.89) = 7
Int(0.12) = 0
これで 0〜9 の整数になります。
+ 1 - 1を足す
2 + 1 = 3
7 + 1 = 8
0 + 1 = 1
最終的に 1〜10の数字 ができます!
なぜ 1〜10 なのか?
ゲームのマス目が A1〜J10(1〜10行目、1〜10列目)だからです。
宝の場所をメモしておく
Cells(100, 1) = treasure_i
Cells(100, 2) = treasure_j
Cells(行, 列) でExcelのセルを指定できます。
-
Cells(100, 1)→ 100行目のA列 -
Cells(100, 2)→ 100行目のB列
なぜ100行目にメモするの?
画面には見えない場所に、宝の位置をこっそりメモしておくためです。
プログラムは実行が終わると、変数の中身を忘れてしまいます。例えば:
-
setTreasureで「宝は5行目」と決まる -
setTreasureが終わる → 変数が消える - 次に
openBoxを実行 → 「宝の場所がわからない!」
だから、Excelのセルに書いておくことで、次のプログラムでも宝の場所を思い出せるようにしています。
ゲーム盤を用意する
Range("A1:J10") = "??"
A1からJ10までの全部のマスに「??」を表示します。これで宝箱が並んでいるように見えます!
openBox の解説 - 箱を開ける部分
使う変数(データを入れる箱)
Dim treasure_i As Integer
Dim treasure_j As Integer
Dim selection_i As Integer
Dim selection_j As Integer
Dim vertical_diff As Integer
Dim horizontal_diff As Integer
Dim diff_msg As String
7つの箱を用意します。
| 変数名 | 何を入れる? |
|---|---|
treasure_i |
宝のたて位置 |
treasure_j |
宝のよこ位置 |
selection_i |
クリックしたマスのたて位置 |
selection_j |
クリックしたマスのよこ位置 |
vertical_diff |
たてのずれ |
horizontal_diff |
よこのずれ |
diff_msg |
ヒントの言葉(「右下」など) |
クリックした場所を調べる
selection_i = Selection.Row
selection_j = Selection.Column
Selection は「今選んでいるセル」という意味です。
-
.Row→ 何行目? -
.Column→ 何列目?
列番号について
Excelの列(A, B, C...)は、プログラムの中では数字で表されます。
| 列 | 番号 |
|---|---|
| A | 1 |
| B | 2 |
| C | 3 |
| D | 4 |
| E | 5 |
| ... | ... |
| J | 10 |
例:D5のセルを選んでいたら
-
selection_i = 5(5行目) -
selection_j = 4(D列=4列目)
宝の場所を思い出す
treasure_i = Cells(100, 1)
treasure_j = Cells(100, 2)
さっき setTreasure で100行目にメモしておいた場所を読みます。
宝を見つけたか調べる
If selection_i = treasure_i And selection_j = treasure_j Then
MsgBox ("お宝を見つけた!")
ここで If-Then という「条件分岐」を使っています。これはプログラミングでとても大切な考え方なので、丁寧に見ていきましょう。
If-Then(条件分岐)とは?
If 〜 Then は日本語で言うと「もし〜なら」という意味です。
もし(雨が降っている)なら
傘を持っていく
これをプログラムで書くと:
If 雨が降っている Then
傘を持っていく
End If
このゲームでは:
If selection_i = treasure_i And selection_j = treasure_j Then
MsgBox ("お宝を見つけた!")
End If
And(両方とも)の意味
And は「かつ」「両方とも」という意味です。
| 条件1 | 条件2 | 結果 |
|---|---|---|
selection_i = treasure_i |
たて位置が同じ | |
selection_j = treasure_j |
よこ位置が同じ | |
| And で結ぶ | → 両方合っていたら | 宝の場所! |
例えば:
- たて位置は合ってるけど、よこ位置が違う → 宝じゃない
- よこ位置は合ってるけど、たて位置が違う → 宝じゃない
- 両方とも合ってる → 宝発見!
MsgBox(メッセージを表示)
MsgBox ("お宝を見つけた!")
画面にポップアップでメッセージを表示する命令です。ここでは「お宝を見つけた!」という文字が表示されます。
ヒントを計算する(宝じゃなかった場合)
Else
horizontal_diff = treasure_j - selection_j
vertical_diff = treasure_i - selection_i
Else(そうじゃなかったら)とは?
さっきの If の続きです。Else は「そうじゃなかったら」という意味です。
全体の構造を見てみましょう:
If 宝を見つけた Then
「お宝を見つけた!」と表示
Else
ヒントを表示
End If
つまり:
- 宝を見つけた場合 → 「お宝を見つけた!」
- 宝じゃなかった場合 → ヒントを計算して表示
この If-Else の組み合わせで、「場合によって違うことをする」というプログラムが書けます。
ずれを計算する
宝じゃなかったときは、「どっちの方向にあるか」のヒントを出すために、ずれを計算します。
よこのずれ
horizontal_diff = treasure_j - selection_j
引き算で「どっちの方向に、どれくらいずれているか」がわかります。
| 例 | 計算 | 結果 | 意味 |
|---|---|---|---|
| 宝がG列(7)、選択がD列(4) | 7 - 4 | +3 | 宝は右に3マス |
| 宝がC列(3)、選択がF列(6) | 3 - 6 | -3 | 宝は左に3マス |
| 宝がE列(5)、選択がE列(5) | 5 - 5 | 0 | 同じ列 |
たてのずれ
vertical_diff = treasure_i - selection_i
| 例 | 計算 | 結果 | 意味 |
|---|---|---|---|
| 宝が8行目、選択が3行目 | 8 - 3 | +5 | 宝は下に5マス |
| 宝が2行目、選択が6行目 | 2 - 6 | -4 | 宝は上に4マス |
| 宝が5行目、選択が5行目 | 5 - 5 | 0 | 同じ行 |
よこのヒントを作る
If horizontal_diff = 0 Then
diff_msg = ""
ElseIf horizontal_diff > 0 Then
diff_msg = "右"
Else
diff_msg = "左"
End If
これは3つの場合分けです。
horizontal_diff = 0 → 同じ列なので何も言わない
horizontal_diff > 0 → プラスなので「右」
それ以外 → マイナスなので「左」
ElseIf は「そうじゃなくて、もし〜なら」という意味です。
たてのヒントを追加する
If vertical_diff = 0 Then
diff_msg = diff_msg + ""
ElseIf vertical_diff > 0 Then
diff_msg = diff_msg + "下"
Else
diff_msg = diff_msg + "上"
End If
さっき作った diff_msg(「右」や「左」)に、たてのヒント(「上」や「下」)をくっつけます。
文字をくっつける
"右" + "下" = "右下"
"左" + "上" = "左上"
"" + "下" = "下"(よこのずれが0の場合)
これで「右下」「左上」「下」などの方向ができます!
ヒントを表示する
MsgBox (diff_msg)
作ったヒントを画面に表示します。
実際にゲームをプレイしたら?
例として、宝がG8(7列目8行目)にあるとき、プレイヤーがどうやって見つけるかを見てみましょう。
1回目:C3を選んだ
- 選んだ場所:C3(3列目3行目)
- 宝の場所:G8(7列目8行目)
- 宝じゃない!
- よこのずれ:7 - 3 = 4(右に4マス)→ ヒント「右」
- たてのずれ:8 - 3 = 5(下に5マス)→ ヒント「下」
- 表示されるヒント:「右下」
2回目:H9を選んだ
- 選んだ場所:H9(8列目9行目)
- 宝の場所:G8(7列目8行目)
- 宝じゃない!
- よこのずれ:7 - 8 = -1(左に1マス)→ ヒント「左」
- たてのずれ:8 - 9 = -1(上に1マス)→ ヒント「上」
- 表示されるヒント:「左上」
3回目:G8を選んだ
- 選んだ場所:G8(7列目8行目)
- 宝の場所:G8(7列目8行目)
- 同じ場所!
- 「お宝を見つけた!」
このプログラムで学べること
1. 変数 - データを覚えておく
変数は「数字や文字を入れる箱」です。
treasure_i = 5
これは「treasure_i という箱に 5 という数字を入れる」という意味です。
2. ランダム - でたらめな動きを作る
Int(Rnd * 10) + 1
ゲームには「毎回違う動き」が必要です。ランダムな数字を使うことで、毎回違う場所に宝が隠れるゲームが作れます。
3. 条件分岐 - 場合によって違うことをする
If 条件 Then
Aをする
Else
Bをする
End If
「もし〜ならAをする、そうじゃなければBをする」という判断をコンピュータにさせることができます。
4. 引き算で方向を計算する
horizontal_diff = treasure_j - selection_j
引き算で「ずれ」を計算することで、どっちの方向にあるかわかります。この考え方は、ゲームやロボットの制御でよく使われます。
5. データを保存する
Cells(100, 1) = treasure_i
プログラムが終わっても消えない場所にデータを保存することで、次に使うときにも情報を使えます。
改造のアイデア
基本のゲームができたら、自分でアレンジしてみよう!
盤面を大きくする
' 20×20の大きなマス目にする
treasure_i = Int(Rnd * 20) + 1
treasure_j = Int(Rnd * 20) + 1
Range("A1:T20") = "??"
難しくなります!
開けた箱に×印をつける
' openBox の Else の最初に追加
Selection.Value = "×"
どこを探したか記録できます。
何回で見つけたか数える
' setTreasure の最後に追加(カウンターをリセット)
Cells(102, 1) = 0
' openBox の最初に追加(1回増やす)
Cells(102, 1) = Cells(102, 1) + 1
' 宝を見つけたときのメッセージを変更
MsgBox ("お宝を見つけた!" & Cells(102, 1) & "回で見つけました")
スコアが表示されます!
宝を2つにする
' setTreasure で2つ目の宝も配置
treasure2_i = Int(Rnd * 10) + 1
treasure2_j = Int(Rnd * 10) + 1
Cells(101, 1) = treasure2_i
Cells(101, 2) = treasure2_j
' openBox で2つ目の宝もチェック
treasure2_i = Cells(101, 1)
treasure2_j = Cells(101, 2)
If (selection_i = treasure_i And selection_j = treasure_j) Or _
(selection_i = treasure2_i And selection_j = treasure2_j) Then
MsgBox ("お宝を見つけた!")
よくある問題と解決方法
「マクロが見つかりません」と出る
解決方法:
- ボタンを右クリック → 「マクロの登録」
-
setTreasureまたはopenBoxを選ぶ
ヒントが表示されない
確認すること:
- マスを選んでから「箱を開ける」ボタンを押していますか?
- 最初に「スタート」ボタンを押しましたか?
宝が見つからない
確認すること:
- 一度「スタート」ボタンを押してゲームを始める
- 100行目のA列とB列に1〜10の数字が入っているか見る
次のステップ
このゲームができたら、次はこんなプログラムに挑戦してみよう!
かんたん
- 数当てゲーム - 1〜100の数字を当てる(「もっと大きい」「もっと小さい」のヒント)
- じゃんけんゲーム - コンピュータとじゃんけん
ちょっと難しい
- 神経衰弱 - カードをめくって同じ絵を探す
- マインスイーパー - 爆弾を避けながらマスを開ける
難しい
- オセロ - 2人で対戦するゲーム
- 迷路作り - ランダムな迷路を自動で作る
プログラミングコンテスト
中学生・高校生向けのコンテストもあります!
おわりに
この宝探しゲームは、50行くらいのコードで作れますが、プログラミングで大切な考え方がたくさん入っています。
- 変数 でデータを覚える
- ランダム ででたらめな動きを作る
- 条件分岐 で場合によって違うことをする
- 引き算 で方向を計算する
- 保存 で情報を残す
コードを読んで理解すること、そして自分で変えてみることが、プログラミングが上手になる一番の方法です。
ぜひこのゲームを改造して、自分だけのゲームを作ってみてください!
質問や「こんな風に改造したよ!」という報告は、コメント欄で待っています。
タグ: VBA Excel プログラミング教育 初心者向け 中学生
関連リンク:
- パンフレット配布元:おもしろ科学まつり2025