■お題
コンピューターが選んだ数字(1~1000)を10回以内に当てるゲーム。答えた際に予想した数字が答えより低かったら「もっと上」逆なら「もっと下」等のヒントを出すこと。
コンピューターが選んだ数字(1~1000)を10回以内に当てるゲーム。答えた際に予想した数字が答えより低かったら「もっと上」逆なら「もっと下」等のヒントを出すこと。
■解答例
まずは、乱数を用いてコンピュータが1~1000の数字を選ぶところから作り始める。いきなり1~1000ではなく0~3を出すコードを考えてみる。
Randomizeについてですが、ExcelVBAではこれを指定しないとRnd関数は、Excelを開く度にに同じ値を返してしまいます。
Rnd関数が0以上1未満の連続する値であることから、それを4倍して整数部だけにすると0以上4未満の整数になるので0~3を出すのは問題なさそう。
次に1~1000にすることを考える。
同様の考えをすると(Int(Rnd() * 1000)で0~999の整数値が得られるので、+1をしてあげると1~1000の整数値が得られる。
乱数部分完成。まずは、こんな感じに書いてみる。
次に、ゲームの流れを考えると・・・
ユーザーが答えを入力する→コンピュータの値と比べる→間違える→ヒントを出す→
ユーザーが答えを入力する→コンピュータの値と比べる→間違える→ヒントを出す→
ユーザーが答えを入力する→コンピュータの値と比べる→間違える→ヒントを出す→
ユーザーが答えを入力する→コンピュータの値と比べる→正解する
という流れを見るとループで上記部分を作ればよさそう。そして、コンピュータの値と比べる行為が1サイクルのうち途中に 来ているのでループ文の最初の部分(Doのすぐ後)に判定をするわけにも最後の部分(Loopのすぐ後)で判定するわけにもいかない。 よって、途中にIf文でユーザー入力値と比較して正解していればExit Doでループを抜けるとよさそう。
ひとまず、テストすることを考えて間違ってたら答えを表示するようにしました。
次に、ユーザーから予想値をInputBoxにて受け取る
ここまでで実際に動かしてチェックしてみることにします。
どうやら問題なさそうです。
あとは、10回でゲームを終了させる部分と、間違っていた時のヒントを表示する部分を作ります。
まずは、ヒント部分から。間違ってたらヒントを出すわけなので、IF文のElse内でユーザーの入力値と 答えを比較して大きい場合と小さい場合でメッセージを表示します。
完成
と言いたいところですが、二つ問題があります。
共にInputBox関数の話です。
一つは、InputBoxで値が入力されずキャンセルもしくは右上の×印を押されたらどうなるか?
もう一つは、InputBoxの返す値の型です。InputBox自体文字列を入力することも考えると返ってくる値の型はStringです。
たまたま今回は数字しか入力していないことと、内部的にInteger型に変換してくれていたので問題がなかったものの もし、ユーザーが数字以外を入力したらどうなるか?ということです。
共にエラーになりますよね。
本来なら入力ミスをミスと捕らえてそのままゲームを進行してもいいのですが今回は必ず何かしらの数字を入力してもらうという形にしてみます。
(完成形)
まずは、乱数を用いてコンピュータが1~1000の数字を選ぶところから作り始める。いきなり1~1000ではなく0~3を出すコードを考えてみる。
Option Explicit
Sub TestCode1()
Randomize
Debug.Print (Int(Rnd() * 4))
End Sub
Randomizeについてですが、ExcelVBAではこれを指定しないとRnd関数は、Excelを開く度にに同じ値を返してしまいます。
Rnd関数が0以上1未満の連続する値であることから、それを4倍して整数部だけにすると0以上4未満の整数になるので0~3を出すのは問題なさそう。
次に1~1000にすることを考える。
Option Explicit
Sub TestCode2()
Randomize
Debug.Print (Int(Rnd() * 1000)) + 1
End Sub
同様の考えをすると(Int(Rnd() * 1000)で0~999の整数値が得られるので、+1をしてあげると1~1000の整数値が得られる。
乱数部分完成。まずは、こんな感じに書いてみる。
Option Explicit
Sub MainCode()
Randomize
Dim Answer As Integer
Answer = (Int(Rnd() * 1000)) + 1 '1~1000の整数
End Sub
次に、ゲームの流れを考えると・・・
ユーザーが答えを入力する→コンピュータの値と比べる→間違える→ヒントを出す→
ユーザーが答えを入力する→コンピュータの値と比べる→間違える→ヒントを出す→
ユーザーが答えを入力する→コンピュータの値と比べる→間違える→ヒントを出す→
ユーザーが答えを入力する→コンピュータの値と比べる→正解する
という流れを見るとループで上記部分を作ればよさそう。そして、コンピュータの値と比べる行為が1サイクルのうち途中に 来ているのでループ文の最初の部分(Doのすぐ後)に判定をするわけにも最後の部分(Loopのすぐ後)で判定するわけにもいかない。 よって、途中にIf文でユーザー入力値と比較して正解していればExit Doでループを抜けるとよさそう。
Option Explicit
Sub MainCode()
Randomize
Dim Answer As Integer
Answer = (Int(Rnd() * 1000)) + 1 '1~1000の整数
Dim UserInputData As Integer
Do
If UserInputData = Answer Then
'当たった時の処理
MsgBox ("正解です")
Exit Do
Else
'はずれた時の処理
MsgBox ("はずれです" & "[" & Answer & "]")
End If
Loop
End Sub
ひとまず、テストすることを考えて間違ってたら答えを表示するようにしました。
次に、ユーザーから予想値をInputBoxにて受け取る
Option Explicit
Sub MainCode()
Randomize
Dim Answer As Integer
Answer = (Int(Rnd() * 1000)) + 1 '1~1000の整数
Dim UserInputData As Integer
Do
UserInputData = InputBox("1~1000の間の整数値を入力してね")
If UserInputData = Answer Then
'当たった時の処理
MsgBox ("正解です")
Exit Do
Else
'はずれた時の処理
MsgBox ("はずれです" & "[" & Answer & "]")
End If
Loop
End Sub
ここまでで実際に動かしてチェックしてみることにします。
どうやら問題なさそうです。
あとは、10回でゲームを終了させる部分と、間違っていた時のヒントを表示する部分を作ります。
まずは、ヒント部分から。間違ってたらヒントを出すわけなので、IF文のElse内でユーザーの入力値と 答えを比較して大きい場合と小さい場合でメッセージを表示します。
Option Explicit
Sub MainCode()
Randomize
Dim Answer As Integer
Answer = (Int(Rnd() * 1000)) + 1 '1~1000の整数
Dim UserInputData As Integer
Do
UserInputData = InputBox("1~1000の間の整数値を入力してね")
If UserInputData = Answer Then
'当たった時の処理
MsgBox ("正解です")
Exit Do
Else
'はずれた時の処理
If UserInputData < Answer Then
MsgBox ("はずれです" & vbCrLf & _
"答えはもっと大きいです!")
Else
MsgBox ("はずれです" & vbCrLf & _
"答えはもっと小さいです!")
End If
End If
Loop
End Sub
後は、10回で終了させるようにしましょう。 Option Explicit
Sub MainCode()
Randomize
Dim GameCount As Integer
GameCount = 10 '何回でゲーム終了とするか設定する
Dim Answer As Integer
Answer = (Int(Rnd() * 1000)) + 1 '1~1000の整数
Dim UserInputData As Integer
Do
UserInputData = InputBox("1~1000の間の整数値を入力してね")
GameCount = GameCount - 1 '入力後にゲームカウントを減らす
If UserInputData = Answer Then
'当たった時の処理
MsgBox ("正解です")
Exit Do
Else
''はずれた時の処理
'ゲーム続行できるか判定する
If GameCount = 0 Then
MsgBox ("GameOver" & vbCrLf & _
"答えは「" & Anwser & "」でした")
Exit Do
End If
If UserInputData < Answer Then
MsgBox ("はずれです" & vbCrLf & _
"答えはもっと大きいです!")
Else
MsgBox ("はずれです" & vbCrLf & _
"答えはもっと小さいです!")
End If
End If
Loop
End Sub
ひとまず、最低限の仕様は、満たしてますね。ただし、これだとあと何回間違えると おしまいなのかとかわからないので、もうちょっとゲームらしく必要な情報を与えることにします。 Option Explicit
Sub MainCode()
Randomize
Dim GameCount As Integer
GameCount = 10 '何回でゲーム終了とするか設定する
Dim Answer As Integer
Answer = (Int(Rnd() * 1000)) + 1 '1~1000の整数
Dim UserInputData As Integer
Do
UserInputData = InputBox("あと" & GameCount & "回答えれます!" & vbCrLf & _
"1~1000の間の整数値を入力してね")
GameCount = GameCount - 1 '入力後にゲームカウントを減らす
If UserInputData = Answer Then
'当たった時の処理
MsgBox (Answer & "で正解です!!" & vbCrLf & _
10 - GameCount & "回で正解しました")
Exit Do
Else
''はずれた時の処理
'ゲーム続行できるか判定する
If GameCount = 0 Then
MsgBox ("GameOver" & vbCrLf & _
"答えは「" & Answer & "」でした")
Exit Do
End If
If UserInputData < Answer Then
MsgBox ("はずれです" & vbCrLf & _
"答えはもっと大きいです!" & vbCrLf & _
"あと" & GameCount & "回")
Else
MsgBox ("はずれです" & vbCrLf & _
"答えはもっと小さいです!" & vbCrLf & _
"あと" & GameCount & "回")
End If
End If
Loop
End Sub
MsgBox内を調整してみました。完成
と言いたいところですが、二つ問題があります。
共にInputBox関数の話です。
一つは、InputBoxで値が入力されずキャンセルもしくは右上の×印を押されたらどうなるか?
もう一つは、InputBoxの返す値の型です。InputBox自体文字列を入力することも考えると返ってくる値の型はStringです。
たまたま今回は数字しか入力していないことと、内部的にInteger型に変換してくれていたので問題がなかったものの もし、ユーザーが数字以外を入力したらどうなるか?ということです。
共にエラーになりますよね。
本来なら入力ミスをミスと捕らえてそのままゲームを進行してもいいのですが今回は必ず何かしらの数字を入力してもらうという形にしてみます。
(完成形)
Option Explicit
Sub MainCode()
Randomize
Dim GameCount As Integer
GameCount = 10 '何回でゲーム終了とするか設定する
Dim Answer As Integer
Answer = (Int(Rnd() * 1000)) + 1 '1~1000の整数
Dim UserInputData As String 'InputBoxからの値はString型
Do
Do '必ず何かしらの数字を入力してもらう
UserInputData = InputBox("あと" & GameCount & "回答えれます!" & vbCrLf & _
"1~1000の間の整数値を入力してね")
Loop Until IsNumeric(UserInputData)
GameCount = GameCount - 1 '入力後にゲームカウントを減らす
If CInt(UserInputData) = Answer Then
'当たった時の処理
MsgBox (Answer & "で正解です!!" & vbCrLf & _
10 - GameCount & "回で正解しました")
Exit Do
Else
''はずれた時の処理
'ゲーム続行できるか判定する
If GameCount = 0 Then
MsgBox ("GameOver" & vbCrLf & _
"答えは「" & Answer & "」でした")
Exit Do
End If
If CInt(UserInputData) < Answer Then
MsgBox ("はずれです" & vbCrLf & _
"答えはもっと大きいです!" & vbCrLf & _
"あと" & GameCount & "回")
Else
MsgBox ("はずれです" & vbCrLf & _
"答えはもっと小さいです!" & vbCrLf & _
"あと" & GameCount & "回")
End If
End If
Loop
End Sub
0 件のコメント:
コメントを投稿