『Excelでリバーシを作ろう!! マクロ、VBAを1から学ぶ』内で使用しているコードです。
Excelのマクロ(VBA)で「三目並べ」「マインスイーパー」「リバーシ」を作る解説本です!
プログラミングが全くわからない人でも大丈夫! 丁寧な解説と図でしっかり理解しながら楽しくプログラミングを学ぶ事ができます!
値段:300円(Kindle Unlimited対象)
サンプルとして「準備」~「三目並べ」を無料公開しています。
【kindle】
【booth(pdf】
「三目並べ」
https://qiita.com/sano192/items/1f674361711114d57b91
「リバーシ」
https://qiita.com/sano192/items/a9680a3a09d37aad1a17
「マインスイーパー 3」
「マインスイーパー 3」
Sub GameStart()
Dim Grid(16, 16)
Dim N, Gyou, Retu, MineCount
' 地雷個数
N = Cells(2, 19)
' Gridの初期化
For Gyou = 2 To 16
For Retu = 2 To 16
Grid(Gyou, Retu) = 0
Next Retu
Next Gyou
' 地雷個数がN個未満の間
Do While MineCount < N
' 2~16のランダムな数を行,列番号に指定
Gyou = Int((16 - 2 + 1) * Rnd + 2)
Retu = Int((16 - 2 + 1) * Rnd + 2)
' 地雷がまだ置かれていないなら
If Grid(Gyou, Retu) <> -1 Then
' 地雷を置く
Grid(Gyou, Retu) = -1
' 地雷個数をプラス1
MineCount = MineCount + 1
End If
Loop
' 各マスの値をセルに落とす
For Gyou = 2 To 16
For Retu = 2 To 16
Cells(Gyou, Retu) = Grid(Gyou, Retu)
Next Retu
Next Gyou
End Sub
「マインスイーパー 4」
「マインスイーパー 4」
Dim Grid(16, 16)
Sub GameStart()
Dim N, Gyou, Retu, MineCount
' 地雷個数
N = Cells(2, 19)
' Gridの初期化
For Gyou = 2 To 16
For Retu = 2 To 16
Grid(Gyou, Retu) = 0
Next Retu
Next Gyou
' 地雷個数がN個未満の間
Do While MineCount < N
' 2~16のランダムな数を行,列番号に指定
Gyou = Int((16 - 2 + 1) * Rnd + 2)
Retu = Int((16 - 2 + 1) * Rnd + 2)
' 地雷がまだ置かれていないなら
If Grid(Gyou, Retu) <> -1 Then
' 地雷を置く
Grid(Gyou, Retu) = -1
' 地雷個数をプラス1
MineCount = MineCount + 1
End If
Loop
' 各マスごとの数字を確認する
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) <> -1 Then
Grid(Gyou, Retu) = GridNumCalc(Gyou, Retu)
End If
Next Retu
Next Gyou
' 各マスの値をセルに落とす
For Gyou = 2 To 16
For Retu = 2 To 16
Cells(Gyou, Retu) = Grid(Gyou, Retu)
Next Retu
Next Gyou
End Sub
'各マスごとの数字を確認する関数
Function GridNumCalc(Gyou, Retu)
' 地雷個数のカウント
Dim MineCount
MineCount = 0
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If Grid(Gyou + i, Retu + k) = -1 Then
MineCount = MineCount + 1
End If
End If
Next k
Next i
' 値を返す
GridNumCalc = MineCount
End Function
「マインスイーパー 5」
「マインスイーパー 5」
Dim Grid(16, 16)
Sub GameStart()
Dim N, Gyou, Retu, MineCount
' 地雷個数
N = Cells(2, 19)
' Gridの初期化
For Gyou = 2 To 16
For Retu = 2 To 16
Grid(Gyou, Retu) = 0
Next Retu
Next Gyou
' 地雷個数がN個未満の間
Do While MineCount < N
' 2~16のランダムな数を行,列番号に指定
Gyou = Int((16 - 2 + 1) * Rnd + 2)
Retu = Int((16 - 2 + 1) * Rnd + 2)
' 地雷がまだ置かれていないなら
If Grid(Gyou, Retu) <> -1 Then
' 地雷を置く
Grid(Gyou, Retu) = -1
' 地雷個数をプラス1
MineCount = MineCount + 1
End If
Loop
' 各マスごとの数字を確認する
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) <> -1 Then
Grid(Gyou, Retu) = GridNumCalc(Gyou, Retu)
End If
Next Retu
Next Gyou
' 全マスを灰色に塗る
Range("B2", "P16").Interior.Color = RGB(210, 210, 210)
' 各マスの値をセルに落とす
For Gyou = 2 To 16
For Retu = 2 To 16
Cells(Gyou, Retu) = Grid(Gyou, Retu)
Next Retu
Next Gyou
End Sub
'各マスごとの数字を確認する関数
Function GridNumCalc(Gyou, Retu)
' 地雷個数のカウント
Dim MineCount
MineCount = 0
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If Grid(Gyou + i, Retu + k) = -1 Then
MineCount = MineCount + 1
End If
End If
Next k
Next i
' 値を返す
GridNumCalc = MineCount
End Function
'クリックしたときの処理
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim Gyou, Retu
Gyou = Target.Row
Retu = Target.Column
' マス目をはみ出していないかチェック
If 2 <= Gyou And Gyou <= 16 And 2 <= Retu And Retu <= 16 Then
' 背景色を白に変える
Cells(Gyou, Retu).Interior.Color = RGB(255, 255, 255)
' Gridの数字を入力
Cells(Gyou, Retu) = Grid(Gyou, Retu)
End If
End Sub
「マインスイーパー 6」
「マインスイーパー 6」
Dim Grid(16, 16)
Dim EndFlag
Sub GameStart()
Dim N, Gyou, Retu, MineCount
' 「ゲームオーバー」となっているか管理する変数
EndFlag = False
' 地雷個数
N = Cells(2, 19)
' Gridの初期化
For Gyou = 2 To 16
For Retu = 2 To 16
Grid(Gyou, Retu) = 0
Next Retu
Next Gyou
' 地雷個数がN個未満の間
Do While MineCount < N
' 2~16のランダムな数を行,列番号に指定
Gyou = Int((16 - 2 + 1) * Rnd + 2)
Retu = Int((16 - 2 + 1) * Rnd + 2)
' 地雷がまだ置かれていないなら
If Grid(Gyou, Retu) <> -1 Then
' 地雷を置く
Grid(Gyou, Retu) = -1
' 地雷個数をプラス1
MineCount = MineCount + 1
End If
Loop
' 各マスごとの数字を確認する
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) <> -1 Then
Grid(Gyou, Retu) = GridNumCalc(Gyou, Retu)
End If
Next Retu
Next Gyou
' 全マスを灰色に塗る
Range("B2", "P16").Interior.Color = RGB(210, 210, 210)
' 各マスの値をセルに落とす
For Gyou = 2 To 16
For Retu = 2 To 16
Cells(Gyou, Retu) = Grid(Gyou, Retu)
Next Retu
Next Gyou
End Sub
'各マスごとの数字を確認する関数
Function GridNumCalc(Gyou, Retu)
' 地雷個数のカウント
Dim MineCount
MineCount = 0
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If Grid(Gyou + i, Retu + k) = -1 Then
MineCount = MineCount + 1
End If
End If
Next k
Next i
' 値を返す
GridNumCalc = MineCount
End Function
'クリックしたときの処理
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' もしゲームオーバーになっているなら終了
If EndFlag = True Then
Exit Sub
End If
Dim Gyou, Retu
Gyou = Target.Row
Retu = Target.Column
' クリックした箇所がマス目の範囲内なら背景色を白に変える
If 2 <= Gyou And Gyou <= 16 And 2 <= Retu And Retu <= 16 Then
' 地雷を踏んだ場合
If Grid(Gyou, Retu) = -1 Then
EndFlag = True
Call MineColor
' そうでない場合
Else
Cells(Gyou, Retu).Interior.Color = RGB(255, 255, 255)
Cells(Gyou, Retu) = Grid(Gyou, Retu)
End If
End If
End Sub
'地雷を赤色に塗る処理
Function MineColor()
Dim Gyou, Retu
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) = -1 Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 0, 0)
End If
Next Retu
Next Gyou
End Function
「マインスイーパー 7」
「マインスイーパー 7」
Dim Grid(16, 16)
Dim EndFlag
Sub GameStart()
Dim N, Gyou, Retu, MineCount
' 数字を消す
Range("B2", "P16").ClearContents
' 「ゲームオーバー」となっているか管理する変数
EndFlag = False
' 地雷個数
N = Cells(2, 19)
' Gridの初期化
For Gyou = 2 To 16
For Retu = 2 To 16
Grid(Gyou, Retu) = 0
Next Retu
Next Gyou
' 地雷個数がN個未満の間
Do While MineCount < N
' 2~16のランダムな数を行,列番号に指定
Gyou = Int((16 - 2 + 1) * Rnd + 2)
Retu = Int((16 - 2 + 1) * Rnd + 2)
' 地雷がまだ置かれていないなら
If Grid(Gyou, Retu) <> -1 Then
' 地雷を置く
Grid(Gyou, Retu) = -1
' 地雷個数をプラス1
MineCount = MineCount + 1
End If
Loop
' 各マスごとの数字を確認する
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) <> -1 Then
Grid(Gyou, Retu) = GridNumCalc(Gyou, Retu)
End If
Next Retu
Next Gyou
' 全マスを灰色に塗る
Range("B2", "P16").Interior.Color = RGB(210, 210, 210)
' Gridが0のマスとその周りを開ける
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) = 0 Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 255, 255)
Call OpenCells(Gyou, Retu)
End If
Next Retu
Next Gyou
' 各マスの値をセルに落とす
' For Gyou = 2 To 16
' For Retu = 2 To 16
' Cells(Gyou, Retu) = Grid(Gyou, Retu)
' Next Retu
' Next Gyou
End Sub
'各マスごとの数字を確認する関数
Function GridNumCalc(Gyou, Retu)
' 地雷個数のカウント
Dim MineCount
MineCount = 0
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If Grid(Gyou + i, Retu + k) = -1 Then
MineCount = MineCount + 1
End If
End If
Next k
Next i
' 値を返す
GridNumCalc = MineCount
End Function
'クリックしたときの処理
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' もしゲームオーバーになっているなら終了
If EndFlag = True Then
Exit Sub
End If
Dim Gyou, Retu
Gyou = Target.Row
Retu = Target.Column
' クリックした箇所がマス目の範囲内なら背景色を白に変える
If 2 <= Gyou And Gyou <= 16 And 2 <= Retu And Retu <= 16 Then
' 地雷を踏んだ場合
If Grid(Gyou, Retu) = -1 Then
EndFlag = True
Call MineColor
' そうでない場合
Else
Cells(Gyou, Retu).Interior.Color = RGB(255, 255, 255)
Cells(Gyou, Retu) = Grid(Gyou, Retu)
End If
End If
End Sub
'地雷を赤色に塗る処理
Function MineColor()
Dim Gyou, Retu
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) = -1 Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 0, 0)
End If
Next Retu
Next Gyou
End Function
'Gridが0の周りのマスを開く処理
Function OpenCells(Gyou, Retu)
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If 1 <= Grid(Gyou + i, Retu + k) Then
Cells(Gyou + i, Retu + k).Interior.Color = RGB(255, 255, 255)
Cells(Gyou + i, Retu + k) = Grid(Gyou + i, Retu + k)
End If
End If
Next k
Next i
End Function
「マインスイーパー 8」
「マインスイーパー 8」
Dim Grid(16, 16)
Dim EndFlag
Dim ClosedCellsCount, N
Sub GameStart()
Dim Gyou, Retu, MineCount
' 数字を消す
Range("B2", "P16").ClearContents
' 「ゲームオーバー」となっているか管理する変数
EndFlag = False
' 地雷個数
N = Cells(2, 19)
' Gridの初期化
For Gyou = 2 To 16
For Retu = 2 To 16
Grid(Gyou, Retu) = 0
Next Retu
Next Gyou
' 地雷個数がN個未満の間
Do While MineCount < N
' 2~16のランダムな数を行,列番号に指定
Gyou = Int((16 - 2 + 1) * Rnd + 2)
Retu = Int((16 - 2 + 1) * Rnd + 2)
' 地雷がまだ置かれていないなら
If Grid(Gyou, Retu) <> -1 Then
' 地雷を置く
Grid(Gyou, Retu) = -1
' 地雷個数をプラス1
MineCount = MineCount + 1
End If
Loop
' 各マスごとの数字を確認する
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) <> -1 Then
Grid(Gyou, Retu) = GridNumCalc(Gyou, Retu)
End If
Next Retu
Next Gyou
' 全マスを灰色に塗る
Range("B2", "P16").Interior.Color = RGB(210, 210, 210)
' Gridが0のマスとその周りを開ける
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) = 0 Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 255, 255)
Call OpenCells(Gyou, Retu)
End If
Next Retu
Next Gyou
' 「まだ開いていないマスの個数」を確認
ClosedCellsCount = 0
For Gyou = 2 To 16
For Retu = 2 To 16
If Cells(Gyou, Retu).Interior.Color = RGB(210, 210, 210) Then
ClosedCellsCount = ClosedCellsCount + 1
End If
Next Retu
Next Gyou
' 各マスの値をセルに落とす
' For Gyou = 2 To 16
' For Retu = 2 To 16
' Cells(Gyou, Retu) = Grid(Gyou, Retu)
' Next Retu
' Next Gyou
End Sub
'各マスごとの数字を確認する関数
Function GridNumCalc(Gyou, Retu)
' 地雷個数のカウント
Dim MineCount
MineCount = 0
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If Grid(Gyou + i, Retu + k) = -1 Then
MineCount = MineCount + 1
End If
End If
Next k
Next i
' 値を返す
GridNumCalc = MineCount
End Function
'クリックしたときの処理
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' もしゲームオーバーになっているなら終了
If EndFlag = True Then
Exit Sub
End If
Dim Gyou, Retu
Gyou = Target.Row
Retu = Target.Column
' クリックした箇所がマス目の範囲内なら背景色を白に変える
If 2 <= Gyou And Gyou <= 16 And 2 <= Retu And Retu <= 16 Then
' 地雷を踏んだ場合
If Grid(Gyou, Retu) = -1 Then
EndFlag = True
Call MineColor(1)
' そうでない場合
Else
If Cells(Gyou, Retu).Interior.Color = RGB(210, 210, 210) Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 255, 255)
Cells(Gyou, Retu) = Grid(Gyou, Retu)
ClosedCellsCount = ClosedCellsCount - 1
End If
End If
End If
' 「ゲームクリア」の場合
If ClosedCellsCount = N Then
EndFlag = True
Call MineColor(2)
MsgBox "除去完了"
End If
End Sub
'地雷を赤色に塗る処理
Function MineColor(x)
Dim Gyou, Retu
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) = -1 Then
If x = 1 Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 0, 0)
ElseIf x = 2 Then
Cells(Gyou, Retu).Interior.Color = RGB(0, 0, 255)
End If
End If
Next Retu
Next Gyou
End Function
'Gridが0の周りのマスを開く処理
Function OpenCells(Gyou, Retu)
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If 1 <= Grid(Gyou + i, Retu + k) Then
Cells(Gyou + i, Retu + k).Interior.Color = RGB(255, 255, 255)
Cells(Gyou + i, Retu + k) = Grid(Gyou + i, Retu + k)
End If
End If
Next k
Next i
End Function
「マインスイーパー コード全文」
「マインスイーパー コード全文」
Dim Grid(16, 16)
Dim EndFlag
Dim ClosedCellsCount, N
Sub GameStart()
Dim Gyou, Retu, MineCount
' 数字を消す
Range("B2", "P16").ClearContents
' 「ゲームオーバー」となっているか管理する変数
EndFlag = False
' 地雷個数
N = Cells(2, 19)
' Nが整数でない場合
If IsNumeric(N) = False Then
MsgBox "地雷個数は数字を入力してください"
Exit Sub
End If
' Nが1未満 または 100より大きい場合
If N < 1 Or 100 < N Then
MsgBox "地雷個数は1個以上100個以下にしてください"
Exit Sub
End If
' Nが整数でない場合
If Int(N) <> N Then
MsgBox "地雷個数は整数で指定してください"
Exit Sub
End If
' Gridの初期化
For Gyou = 2 To 16
For Retu = 2 To 16
Grid(Gyou, Retu) = 0
Next Retu
Next Gyou
' 地雷個数がN個未満の間
Do While MineCount < N
' 2~16のランダムな数を行,列番号に指定
Gyou = Int((16 - 2 + 1) * Rnd + 2)
Retu = Int((16 - 2 + 1) * Rnd + 2)
' 地雷がまだ置かれていないなら
If Grid(Gyou, Retu) <> -1 Then
' 地雷を置く
Grid(Gyou, Retu) = -1
' 地雷個数をプラス1
MineCount = MineCount + 1
End If
Loop
' 各マスごとの数字を確認する
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) <> -1 Then
Grid(Gyou, Retu) = GridNumCalc(Gyou, Retu)
End If
Next Retu
Next Gyou
' 全マスを灰色に塗る
Range("B2", "P16").Interior.Color = RGB(210, 210, 210)
' Gridが0のマスとその周りを開ける
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) = 0 Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 255, 255)
Call OpenCells(Gyou, Retu)
End If
Next Retu
Next Gyou
' 「まだ開いていないマスの個数」を確認
ClosedCellsCount = 0
For Gyou = 2 To 16
For Retu = 2 To 16
If Cells(Gyou, Retu).Interior.Color = RGB(210, 210, 210) Then
ClosedCellsCount = ClosedCellsCount + 1
End If
Next Retu
Next Gyou
' 各マスの値をセルに落とす
' For Gyou = 2 To 16
' For Retu = 2 To 16
' Cells(Gyou, Retu) = Grid(Gyou, Retu)
' Next Retu
' Next Gyou
End Sub
'各マスごとの数字を確認する関数
Function GridNumCalc(Gyou, Retu)
' 地雷個数のカウント
Dim MineCount
MineCount = 0
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If Grid(Gyou + i, Retu + k) = -1 Then
MineCount = MineCount + 1
End If
End If
Next k
Next i
' 値を返す
GridNumCalc = MineCount
End Function
'クリックしたときの処理
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' もしゲームオーバーになっているなら終了
If EndFlag = True Then
Exit Sub
End If
Dim Gyou, Retu
Gyou = Target.Row
Retu = Target.Column
' クリックした箇所がマス目の範囲内なら背景色を白に変える
If 2 <= Gyou And Gyou <= 16 And 2 <= Retu And Retu <= 16 Then
' 地雷を踏んだ場合
If Grid(Gyou, Retu) = -1 Then
EndFlag = True
Call MineColor(1)
' そうでない場合
Else
If Cells(Gyou, Retu).Interior.Color = RGB(210, 210, 210) Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 255, 255)
Cells(Gyou, Retu) = Grid(Gyou, Retu)
ClosedCellsCount = ClosedCellsCount - 1
End If
End If
End If
' 「ゲームクリア」の場合
If ClosedCellsCount = N Then
EndFlag = True
Call MineColor(2)
MsgBox "除去完了"
End If
End Sub
'地雷を赤色に塗る処理
Function MineColor(x)
Dim Gyou, Retu
For Gyou = 2 To 16
For Retu = 2 To 16
If Grid(Gyou, Retu) = -1 Then
If x = 1 Then
Cells(Gyou, Retu).Interior.Color = RGB(255, 0, 0)
ElseIf x = 2 Then
Cells(Gyou, Retu).Interior.Color = RGB(0, 0, 255)
End If
End If
Next Retu
Next Gyou
End Function
'Gridが0の周りのマスを開く処理
Function OpenCells(Gyou, Retu)
For i = -1 To 1
For k = -1 To 1
' マス目をはみ出していないかチェック
If 2 <= Gyou + i And Gyou + i <= 16 And 2 <= Retu + k And Retu + k <= 16 Then
If 1 <= Grid(Gyou + i, Retu + k) Then
Cells(Gyou + i, Retu + k).Interior.Color = RGB(255, 255, 255)
Cells(Gyou + i, Retu + k) = Grid(Gyou + i, Retu + k)
End If
End If
Next k
Next i
End Function