Excelマクロ・VBA 練習に最適な課題1 じゃんけんゲーム

マクロ・VBAを練習する課題として

じゃんけんゲームを紹介します。

筆者がプログラミングの専門学校で、

実際に学んだ物の例題でもあります。

(ソースなどゼロから作成してあります)

マクロ・VBAやプログラミングの

重要要素である変数と判断(IF)の

学習に最適な課題です。

ソースコードを紹介するため

是非、作成することをお勧めします。

なおコピー&ペーストでなく

意味を考えながらタイピングすると

学習効果が高いです。

サンプルファイル

ゲーム内容

※セキュリティの警告が出る場合は有効化してください。(解除方法↓)

グー、チョキ、パーの手のボタンがあり

何れかを押すとコンピュータと勝負します。

じゃんけんゲームの画面
じゃんけんゲームの画面
勝負の結果
勝負の結果

勝負の結果は上の表に

カウントされていきます。

勝負の結果は上の表にカウント

この結果は「勝敗リセット」ボタンで

全てが0に戻ります。

サンプルソース

Option Explicit
'定数設定
Const グー As Integer = 1
Const チョキ As Integer = 2
Const パー As Integer = 3
Const 勝ち数セル As String = "D3"
Const 負け数セル As String = "G3"
Const あいこ数セル As String = "J3"
Function 手の定数を手の名前に変換(手) As String
    
    If 手 = グー Then
        手の定数を手の名前に変換 = "グー"
    ElseIf 手 = チョキ Then
        手の定数を手の名前に変換 = "チョキ"
    ElseIf 手 = パー Then
        手の定数を手の名前に変換 = "パー"
    End If
    
End Function
Sub グーボタン()
    Call ゲーム開始(グー)
End Sub
Sub チョキボタン()
    Call ゲーム開始(チョキ)
End Sub
Sub パーボタン()
    Call ゲーム開始(パー)
End Sub
Function ゲーム開始(プレイヤーの手 As Integer)
    Dim コンピュータの手 As Integer
    Dim メッセージ As String
    
    コンピュータの手 = コンピュータが手を選ぶ()
    If プレイヤーの手 = グー Then
    
        If コンピュータの手 = グー Then
            メッセージ = "あいこです。"
            Range(あいこ数セル).Value = Range(あいこ数セル).Value + 1
            
        ElseIf コンピュータの手 = チョキ Then
            メッセージ = "プレイヤーの勝ちです。"
            Range(勝ち数セル).Value = Range(勝ち数セル).Value + 1
            
        ElseIf コンピュータの手 = パー Then
            メッセージ = "プレイヤーの負けです。"
            Range(負け数セル).Value = Range(負け数セル).Value + 1
            
        End If
    End If
    If プレイヤーの手 = チョキ Then
        
        If コンピュータの手 = グー Then
            メッセージ = "プレイヤーの負けです。"
            Range(負け数セル).Value = Range(負け数セル).Value + 1
            
        ElseIf コンピュータの手 = チョキ Then
            メッセージ = "あいこです。"
            Range(あいこ数セル).Value = Range(あいこ数セル).Value + 1
            
        ElseIf コンピュータの手 = パー Then
            メッセージ = "プレイヤーの勝ちです。"
            Range(勝ち数セル).Value = Range(勝ち数セル).Value + 1
            
        End If
    End If
    
    If プレイヤーの手 = パー Then
        
        If コンピュータの手 = グー Then
            メッセージ = "プレイヤーの勝ちです。"
            Range(勝ち数セル).Value = Range(勝ち数セル).Value + 1
            
        ElseIf コンピュータの手 = チョキ Then
            メッセージ = "プレイヤーの負けです。"
            Range(負け数セル).Value = Range(負け数セル).Value + 1
            
        ElseIf コンピュータの手 = パー Then
            メッセージ = "あいこです。"
            Range(あいこ数セル).Value = Range(あいこ数セル).Value + 1
            
        End If
    End If
    
    MsgBox (メッセージ + "プレイヤー:" + 手の定数を手の名前に変換(プレイヤーの手) + "。コンピューター:" + 手の定数を手の名前に変換(コンピュータの手))
End Function
Function コンピュータが手を選ぶ() As Integer
    Randomize   '乱数系列初期化。ランダムの数字を使うために必要
    コンピュータが手を選ぶ = Int(3 * Rnd() + 1) '1~3のランダム
End Function
Sub 勝敗リセット()
    Range(勝ち数セル).Value = 0
    Range(負け数セル).Value = 0
    Range(あいこ数セル).Value = 0
End Sub

解説

Option Explicit

Dimによる変数宣言をしないと

変数を使えないようにする設定です。

(変数とはデータを格納する箱に

 名前を付けたものと認識するのが一般的です)

宣言していない変数を使用すると

構文エラーとなりプログラムが

動かなくなります。

一見、不便に感じますが

実際には作成効率が良くなります。

変数名を間違えて打ち込んでしまった際、

この設定をしていれば

構文エラーで検出が出来ますが、

そうでない場合、新しい空の変数となってしまい

プログラムの挙動がおかしくなります。

よって初心者の方ほどOption Explicitを

設定することを推奨します。

定数設定

定数とは最初に値を設定して以降、

プログラム中で変更しない変数です。

セルのアドレスなどプログラム中で

多用するものを設定します。

定数にするとプログラム中で

間違えて中身を変えることを

防ぐことが出来ます。

またシートの内容を変更して

セルの場所が変わった場合、

定数にしておくと定数の宣言文だけ

替えればよいですが、

そうでない場合、アドレスの使用箇所を

全て変える必要が発生し、手間と

間違える危険性が発生します。

変数定数
宣言DimConst
値の変更プログラム中のどこでも可能宣言時のみ可能

Asはデータ型(データの種類)の宣言です。

Integerは整数、Stringが文字列です。

他にも多数あります。

'定数設定
Const グー As Integer = 1
Const チョキ As Integer = 2
Const パー As Integer = 3
Const 勝ち数セル As String = "D3"
Const 負け数セル As String = "G3"
Const あいこ数セル As String = "J3"

手の定数を手の名前に変換Function

Functionはプロシージャの一つで

コードを一まとめにして

名前を付ける機能です。

他の言語では関数やメソッド、

サブプログラムなど様々な呼び方があります。

何度も使用するコードや長いコード、

シートから呼び出す場合に使用します。

プロシージャにはFunctionとSubがあります。

Function
(ファンクション)
Sub
(サブ)
戻り値(結果)返す返さない
セルの数式から
ユーザ定義関数として実行
可能不可能
ボタンなどの
オブジェクトから実行
不可能可能

手の定数を手の名前に変換Function

先述の定数で定義した数値の手を

人にわかる表現にするFunctionです。

プロシージャにする必要性は低いのですが

テストしやすくするためにFunctionにしています。

Function 手の定数を手の名前に変換(手) As String
    
    If 手 = グー Then
        手の定数を手の名前に変換 = "グー"
    ElseIf 手 = チョキ Then
        手の定数を手の名前に変換 = "チョキ"
    ElseIf 手 = パー Then
        手の定数を手の名前に変換 = "パー"
    End If
    
End Function

Functionであればセルの数式で

ユーザ定義関数として実行できます。

手の定数を手の名前に変換Functionの実行例
手の定数を手の名前に変換Functionの実行例

Functionは下記のように作成します。

黄色のマーカーの箇所は

作成者が自由に決める部分です。

Function ファンクション名(引数) As データ型
     ファンクション名 = 戻り値
End Function 

ファンクション名や引数名は

可能な限りファンクションや引数の

役割を表す名前にしましょう。

ファンクション名に値を入れると

入れた値が戻り値となります。

(多くの言語ではreturn句が多いです)

引数やデータ型は省略可能です。

手のボタンSub

シート上のボタンから呼び出すための

プロシージャです。

それぞれ対応する手を引数に

ゲーム開始Functionを実行します。

戻り値のないプロシージャを

実行する場合はCallを使用します。

Sub グーボタン()
    Call ゲーム開始(グー)
End Sub

Sub チョキボタン()
    Call ゲーム開始(チョキ)
End Sub
Sub パーボタン()
    Call ゲーム開始(パー)
End Sub

作成したらボタンから

マクロの登録を行います。

Subを呼び出すボタン
Subを呼び出すボタン

ゲーム開始Function

Function宣言

 Function ゲーム開始(プレイヤーの手 As Integer) 

引数として「プレイヤーの手」を受けます。

前述の手のボタンSubから呼び出され

プレイヤーの手に1(グー)か

2(チョキ)か3(パー)が

引数として格納されます。

IF文による勝敗判定

「プレイヤーによる手」ごとに

勝敗判定のIF文を作ります。

下記はグーを選ぶ場合のIFです。

If プレイヤーの手 = グー Then
    If コンピュータの手 = グー Then
        メッセージ = "あいこです。"
        Range(あいこ数セル).Value = Range(あいこ数セル).Value + 1
        
    ElseIf コンピュータの手 = チョキ Then
        メッセージ = "プレイヤーの勝ちです。"
        Range(勝ち数セル).Value = Range(勝ち数セル).Value + 1
        
    ElseIf コンピュータの手 = パー Then
        メッセージ = "プレイヤーの負けです。"
        Range(負け数セル).Value = Range(負け数セル).Value + 1
        
    End If
End If

一番、上位のIFで「プレイヤーの手」の

判定をして、その中のIFで

「コンピュータの手」と

突き合わせます。

「プレイヤーの手」と「コンピュータの手」を

で一致するパターンがあれば

表示するメッセージ設定

勝敗セルへの値設定を行います。

この構文は指定セルの値を

1つカウントアップする構文です。

Range(セルアドレス).Value = Range(セルアドレス).Value + 1

同様のIF文の入れ子をチョキとパーの

バージョンで作りMsgBoxで

結果をプレイヤーに提示します。

コンピュータが手を選ぶFunction

Function コンピュータが手を選ぶ() As Integer
    Randomize   '乱数系列初期化。ランダムの数字を使うために必要
    コンピュータが手を選ぶ = Int(3 * Rnd() + 1) '1~3のランダム
End Function

1,2,3の値をランダム(乱数)で

返すFunctionです。

「Randomize」は乱数を使うために

必要な構文です。

Rnd()は0~0.999…のうち

何れかの値を返します。

これに3を掛けることで

0~2.999…の何れかになります。

そこに1を足すと1~3.999…になります。

Intは小数点以下を切り捨てて

整数にするFunctionです。

これにより1か2か3になります。

勝敗リセットSub

Sub 勝敗リセット()
    Range(勝ち数セル).Value = 0
    Range(負け数セル).Value = 0
    Range(あいこ数セル).Value = 0
End Sub

Subプロシージャのため

ボタンから呼び出す処理です。

このSubは勝敗リセットボタンに

マクロ登録をします。

勝敗リセットボタンにマクロ登録
Range(セルアドレス).Value = 値

はセルに値を設定するコードです。

逆に書くとセルから値を

取得するコードになります。

変数 = Range(セルアドレス).Value

関連記事

マクロ・VBA 自動化講座の導入部分

フォローする