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?

Excel VBAで作る宝探しゲーム - プログラム解説

Last updated at Posted at 2025-10-31

はじめに

この記事は「おもしろ科学まつり2025」で配布したパンフレットと連動した内容です。パンフレットの手順に従ってExcelファイルを作成したら、このページでプログラムの仕組みを詳しく学びましょう!

パンフレットには「作り方の手順」が載っていますが、この記事では**「なぜこのコードで動くのか」「どんな仕組みなのか」**をわかりやすく解説します。

どんなゲーム?

10×10のマス目のどこかに宝が隠れています。

  1. 好きなマスを選んで「箱を開ける」ボタンを押す
  2. 「右下」「左上」などの方向のヒントが出る
  3. ヒントを頼りに探して、宝を見つけたらクリア!

📜 完全なソースコード

パンフレットの手順で作った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 が動く

この結びつけ方は、パンフレットの「ゲーム画面にボタンを設置」のページに書いてあります。まだその部分を読んでいなくても大丈夫です。今はプログラムの中身を理解していきましょう!

ゲームの流れ:

  1. 「スタート」ボタンを押す → setTreasure が動いて、宝がどこかに隠れる
  2. マスを選んで「箱を開ける」ボタンを押す → openBox が動いて、ヒントが表示される
  3. 宝が見つかるまで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行目にメモするの?
画面には見えない場所に、宝の位置をこっそりメモしておくためです。

プログラムは実行が終わると、変数の中身を忘れてしまいます。例えば:

  1. setTreasure で「宝は5行目」と決まる
  2. setTreasure が終わる → 変数が消える
  3. 次に 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を選んだ

  1. 選んだ場所:C3(3列目3行目)
  2. 宝の場所:G8(7列目8行目)
  3. 宝じゃない!
  4. よこのずれ:7 - 3 = 4(右に4マス)→ ヒント「右」
  5. たてのずれ:8 - 3 = 5(下に5マス)→ ヒント「下」
  6. 表示されるヒント:「右下」

2回目:H9を選んだ

  1. 選んだ場所:H9(8列目9行目)
  2. 宝の場所:G8(7列目8行目)
  3. 宝じゃない!
  4. よこのずれ:7 - 8 = -1(左に1マス)→ ヒント「左」
  5. たてのずれ:8 - 9 = -1(上に1マス)→ ヒント「上」
  6. 表示されるヒント:「左上」

3回目:G8を選んだ

  1. 選んだ場所:G8(7列目8行目)
  2. 宝の場所:G8(7列目8行目)
  3. 同じ場所!
  4. 「お宝を見つけた!」

このプログラムで学べること

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 ("お宝を見つけた!")

よくある問題と解決方法

「マクロが見つかりません」と出る

解決方法

  1. ボタンを右クリック → 「マクロの登録」
  2. setTreasure または openBox を選ぶ

ヒントが表示されない

確認すること

  • マスを選んでから「箱を開ける」ボタンを押していますか?
  • 最初に「スタート」ボタンを押しましたか?

宝が見つからない

確認すること

  1. 一度「スタート」ボタンを押してゲームを始める
  2. 100行目のA列とB列に1〜10の数字が入っているか見る

次のステップ

このゲームができたら、次はこんなプログラムに挑戦してみよう!

かんたん

  • 数当てゲーム - 1〜100の数字を当てる(「もっと大きい」「もっと小さい」のヒント)
  • じゃんけんゲーム - コンピュータとじゃんけん

ちょっと難しい

  • 神経衰弱 - カードをめくって同じ絵を探す
  • マインスイーパー - 爆弾を避けながらマスを開ける

難しい

  • オセロ - 2人で対戦するゲーム
  • 迷路作り - ランダムな迷路を自動で作る

プログラミングコンテスト

中学生・高校生向けのコンテストもあります!

おわりに

この宝探しゲームは、50行くらいのコードで作れますが、プログラミングで大切な考え方がたくさん入っています。

  • 変数 でデータを覚える
  • ランダム ででたらめな動きを作る
  • 条件分岐 で場合によって違うことをする
  • 引き算 で方向を計算する
  • 保存 で情報を残す

コードを読んで理解すること、そして自分で変えてみることが、プログラミングが上手になる一番の方法です。

ぜひこのゲームを改造して、自分だけのゲームを作ってみてください!

質問や「こんな風に改造したよ!」という報告は、コメント欄で待っています。


タグ: VBA Excel プログラミング教育 初心者向け 中学生

関連リンク:

  • パンフレット配布元:おもしろ科学まつり2025
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?