Weekend Mathematics情報/「プログラミング基礎」の授業


「プログラミング基礎」の授業

「プログラミング基礎」の年間指導計画


第13回・スロットマシーン

川崎北高校の柴田先生の新教科・情報・授業アイデア集にある「スロットマシーン」を参考に今日の授業を組み立てました。

<スロットマシーン>

目標となるスロットマシーンをまずはデモンストレーション。 スロットマシーンの内容は以下のように整理しました。


今回は、ソースコードを一切提示せず、それぞれ模索をしてもらいました。 そうはいってもデモを見ただけでは、とりあえずFormにオブジェクトを配置することはできても、そこから先どうしていいかわからないということで、作成の手順を以下のように提示しました。

作成の手順

  1. スタートボタンが押されると、数字がランダムに動き出す。
    (ヒント:Timerの活用)
  2. ストップボタンが押されると、数字が止まる。
  3. プログラムが動き始めた段階で(FormのLoadイベント)、持ち点を与える。
  4. スタートボタンが押された段階で持ち点から50点をひく。
  5. 数字がそろった場合、そろわなかった場合、それぞれに応じてメッセージを出す。
  6. 数字がそろった場合、持ち点に500点を足す。
  7. 持ち点がなくなった段階でゲーム終了のメッセージをだす。
  8. ストップボタンを押す順番を問わず、きちんと動くようにする。

  1. スタートボタンが押されると、数字がランダムに動き出す。
    スタートボタンと同時にタイマーが動き出す。タイマーイベントで乱数を発生させてそれを表示する、というこの切り分けができずに混乱している生徒が見受けられました。(ボタンのクリックイベントで乱数を出してしまう。)ここをきちんと整理し、具体化するのに時間がかかっていました。タイマーのIntervalは200(ミリ秒)程度。
  2. ストップボタンが押されると、数字が止まる。
    とりあえず止めるだけならば、簡単です、タイマーを止めればいいわけですから。
  3. プログラムが動き始めた段階で(FormのLoadイベント)、持ち点を与える。
    プログラムが動き始めた段階で起こしたいイベントは「FormのLoadイベント」で記述 しましょうということで説明しました。持ち点を記憶させる変数を設定する必要性もありますね。
  4. スタートボタンが押された段階で持ち点から50点をひく。
    スタートボタンのクリックイベントに持ち点をひく記述をします。
  5. 数字がそろった場合、そろわなかった場合、それぞれに応じてメッセージを出す。
    条件分岐を「IF文」で書いていきますが、問題はどこに記述するかです。とりあえず左から順に止めていくと想定して、一番右のストップボタンのクリックイベントに書いていくことにします。
  6. 数字がそろった場合、持ち点に500点を足す。
    持ち点に500点を足すのはいいのですが、検証できません。3つそろう確率は1/1000ですからね! そうしましたら、生徒の1人がタイマーのIntervalを一時的に大きくすることで数字をゆっくりまわし、3つのぞろ目を作って確認していました。なーるほど。
  7. 持ち点がなくなった段階でゲーム終了のメッセージをだす。
    スタートボタンのところで持ち点のチェックをすることにします。
  8. ストップボタンを押す順番を問わず、きちんと動くようにする。
    ストップボタンが押されたときに、他のボタンが既に押された状態であるかどうかを判定すればよいということですね。

50分×2時間の授業なのですが、みな休み時間も休まずに取り組んでいました。 全員がとはいえませんが、ほぼ完成していました。 終わり10分のところで、以下のソースコードを参考までにということで提示しました。

Dim x, y, z, m As Integer Private Sub Command1_Click() If m <= 0 Then Label3.Caption = "持ち点がありません。" Else Timer1.Enabled = True Timer2.Enabled = True Timer3.Enabled = True m = m - 50 Text2.Text = m Label3.Caption = "" End If End Sub Private Sub Command2_Click() Timer1.Enabled = False If Timer3.Enabled = False And Timer2.Enabled = False Then If x = y And y = z Then Label3.Caption = "やったー!" m = m + 500 Text2.Text = m Else Label3.Caption = "残念でした。" End If End If End Sub Private Sub Command3_Click() End End Sub Private Sub Command4_Click() Timer2.Enabled = False If Timer1.Enabled = False And Timer3.Enabled = False Then If x = y And y = z Then Label3.Caption = "やったー!" m = m + 500 Text2.Text = m Else Label3.Caption = "残念でした。" End If End If End Sub Private Sub Command5_Click() Timer3.Enabled = False If Timer1.Enabled = False And Timer2.Enabled = False Then If x = y And y = z Then Label3.Caption = "やったー!" m = m + 500 Text2.Text = m Else Label3.Caption = "残念でした。" End If End If End Sub Private Sub Form_Load() m = 1000 Text2.Text = m End Sub Private Sub Timer1_Timer() x = Int(Rnd(1) * 10) Text1(0).Text = x End Sub Private Sub Timer2_Timer() y = Int(Rnd(1) * 10) Text1(1).Text = y End Sub Private Sub Timer3_Timer() z = Int(Rnd(1) * 10) Text1(2).Text = z End Sub




早い生徒は、発展課題「数字ではなく、10種類の絵を表示させる。」に挑戦していました。 10枚の画像を配列にして、1〜10の乱数に応じた画像を表示させればいいわけですね。

Private Sub Timer1_Timer() x = Int(Rnd(1) * 10) Image2.Picture = Image1(x).Picture End Sub








第14回・もぐらたたき

<もぐらたたき>

今回も2時間をかけて、もぐらたたき(もぐらでなく、くま?)を模索しながら作ってもらいました。完成品をデモして、内容をまとめます。


まずは、Form上にオブジェクトを並べ、プロパティの設定をしていきます。 実行したところでは見えませんが、タイマーが2つ使われています。なぜ2つ必要か? と問うてみました。1つは、もぐら(くま?)の表示を制御する、もう1つは30秒を計測するという答えが返ってきました、OK。
前回同様、ソースコードは一切提示せず、作成の手順だけをヒントとして与え、1から作ってもらいました。

作成の手順

  1. 一定の時間間隔で、もぐらをランダムに表示させるにはどうしたらよいか。
  2. もぐらのランダム表示を、一定時間(30秒)で終わらせるにはどうしたらいいか。
  3. もぐらのランダム表示の時間間隔を(初級、中級、上級に応じて)変えるにはどうしたらよいか。
  4. もぐらをクリックできたら、得点を加算していくにはどうしたらいいか。

  1. 一定の時間間隔で、もぐらをランダムに表示させるにはどうしたらよいか。
    9つ(個数は生徒によっていろいろでした)のもぐら(くま?)をImageの配列で並べておき、プロパティ(初期値)では「Visible = False」とする。乱数を出して、それに応じて「Visible = True」にするという考え方が主流でした。中には、Pictureオブジェクトを使ってやってみようという生徒もいました。
    試しに実行してみて気づくこと、前に表示されたもぐらが残ってしまいます。ですからタイマー1のタイマーイベントは、前のもぐらを消した後に、乱数に応じて次ぎのもぐらを表示させるという手順を踏む必要性があることに思いいたります。
  2. もぐらのランダム表示を、一定時間(30秒)で終わらせるにはどうしたらいいか。
    タイマー2を用いて30秒を計測します。「IF文」による条件分岐で、30秒を越えたら終了処理をします。
  3. もぐらのランダム表示の時間間隔を(初級、中級、上級に応じて)変えるにはどうしたらよいか。
    タイマー1のIntervalを適当に設定していけばいいわけです。
    生徒の1人が「最初の段階で、例えば初級のところが選択された状態にしたい。」と言い出しました。 それはそうですね、確かに。どうしたらいいか模索をして、結局その生徒自身が解決しました。

    Private Sub Form_Load() Option1.Value = True End Sub


  4. もぐらをクリックできたら、得点を加算していくにはどうしたらいいか。
    もぐらの絵(Image1)のクリックイベントで得点を加算します。 でもそれだけではだめです、その得点を表示させなければね!

早い生徒には発展課題として、
  得点に応じて終了のメッセージを変える。
  同時に2つの絵を表示させる。
  その他、どうしたらゲームがおもしろくなるか考える
を示しました。ほとんどの生徒が2時間でほぼ完成、最後に1つの例として以下のものを提示しました。

Option Explicit Dim Ten As Integer Dim x As Integer Private Sub Command1_Click() Command1.Enabled = False Option1.Enabled = False Option2.Enabled = False Option3.Enabled = False Ten = 0 Text1.Text = Str(Ten) Timer1.Enabled = True Timer2.Enabled = True End Sub Private Sub Command2_Click() End End Sub Private Sub Image1_Click(Index As Integer) Image1(Index).Enabled = False Image1(Index).Visible = False Ten = Ten + 1 Text1.Text = Str(Ten) End Sub Private Sub Option1_Click() Timer1.Interval = 1500 End Sub Private Sub Option2_Click() Timer1.Interval = 1250 End Sub Private Sub Option3_Click() Timer1.Interval = 1000 End Sub Private Sub Timer1_Timer() Image1(x).Enabled = False Image1(x).Visible = False x = Int(9 * Rnd()) Image1(x).Enabled = True Image1(x).Visible = True End Sub Private Sub Timer2_Timer() Static Time As Integer Time = Time + 1 If Time < 30 Then Exit Sub End If Timer1.Enabled = False Timer2.Enabled = False MsgBox "Game Over" Time = 0 Command1.Enabled = True Image1(x).Enabled = False Image1(x).Visible = False Option1.Enabled = True Option2.Enabled = True Option3.Enabled = True End Sub








第15回・実技テスト

2学期に学習した内容を確認する意味で、実技テストを実施しました。
問題は5題用意し、完成形をひととおり説明した後、 どれでもできるものから取り組んでもらいました。 課題以上に工夫した点も評価をするとしました。 30分ほどの時間設定で、早い生徒は4題めに取りかかっていました。
以下に問題と、終了後に示した解答例を紹介します。



1.メッセージ
ボタンを押すとメッセージが表示される。

解答例

Private Sub Command1_Click() Label1.Caption = "Merry Christmas!!" End Sub Private Sub Command2_Click() End End Sub







2.画像の切り替え
ボタンに応じて画像が切り替わる。(画像は提供)

解答例

Private Sub Command1_Click(Index As Integer) Image1.Picture = Image2(0).Picture End Sub Private Sub Command2_Click() Image1.Picture = Image2(1).Picture End Sub Private Sub Command3_Click() Image1.Picture = Image2(2).Picture End Sub Private Sub Command4_Click() Image1.Picture = Image2(3).Picture End Sub Private Sub Command5_Click() Image1.Picture = Image2(4).Picture End Sub Private Sub Command6_Click() Image1.Picture = Image2(5).Picture End Sub Private Sub Command7_Click() Image1.Picture = Image2(6).Picture End Sub Private Sub Command8_Click() Image1.Picture = Image2(7).Picture End Sub Private Sub Command9_Click() End End Sub







3.タイマー
秒数を指定してスタートボタンを押す。指定時間が経過したらメッセージを出す。

解答例

Private Sub Command1_Click() Timer1.Enabled = True End Sub Private Sub Command2_Click() End End Sub Private Sub Timer1_Timer() time = time + 1 If time >= Text1.Text Then Timer1.Enabled = False MsgBox "時間でーす。" Beep End If End Sub







4.さいころ
「さいころをふる」と書かれたボタンを押すと、1〜6の数字のいずれかが表示される。

解答例

Dim x As Integer Private Sub Command1_Click() Picture1.Cls x = Int(Rnd() * 6) + 1 Picture1.Print x End Sub Private Sub Command2_Click() End End Sub







5.図形の描画
ボタンを押すと、以下のような時計の絵が表示される。

解答例

Private Sub Command1_Click() Picture1.Circle (1500, 1500), 1000 Picture1.Circle (1500, 1500), 10 Picture1.Line (1500, 1500)-(1500, 800) Picture1.Line (1500, 1500)-(2100, 1500) End Sub Private Sub Command2_Click() End End Sub








第16回・じゃんけん

<じゃんけん>

早いもので、最終回となりました。 この際だからゲームに徹してしまおうということで、じゃんけんゲームを作ってもらうことにしました。 自分の手の出し方はもちろん自分の意志通り、そして相手(コンピュータ)の手の出し方は予測はできません。 連勝記録をとり、新記録と比較して更新していくというものです。
何らかのゲームを作る時に、自分の意志で決まるもの、自分の意志で決まらないもの、そしてスコアを記録していくことが多かれ少なかれ必要だろうと思い、それの要素を盛り込んだわけです。
いつものように完成品をデモして、その内容を確認します。


作成の手順をヒントとして示しました。

作成の手順

  1. じゃんけん(自分は選んだボタンによる、コンピュータは乱数を使う。)
  2. じゃんけんの結果を判定して、メッセージをだす。
  3. 連勝回数を記憶するための変数(i:integer)と新記録を記憶するための変数(j:integer)を設定する。
  4. 勝った場合は、連勝回数を増やす。
  5. 負けた場合、これまでの連勝回数が新記録を更新するかどうか判定する。

  1. じゃんけん(自分は選んだボタンによる、コンピュータは乱数を使う。)
    自分の手を出す方は、割合簡単に仕上げていました。ボタンが押されたら、それに対応する画像を表示させればいいわけです。
    問題はコンピュータの方です。じゃんけんの手は3手あるわけですから、乱数を3つに振り分ければいいわけです。たとえば、「x = Int(Rnd() * 3)」とすれば、xの値として考えられるのは{0,1,2}ですから、それぞれに3手をあてはめればいいわけです。
  2. じゃんけんの結果を判定して、メッセージをだす。
    自分の手とコンピュータの手の組み合わせは9通りあります。 それぞれの場合に応じてメッセージを出せばいいわけです。 場合分けについては、「If文」を使っている生徒と「Select Case文」を使っている生徒とがいました。
  3. 連勝回数を記憶するための変数(i:integer)と新記録を記憶するための変数(j:integer)を設定する。
    変数が2つ必要だということを理解しなければなりません。 どちらも初期値0を「Form_Load()」で表示させます。
  4. 勝った場合は、連勝回数を増やす。
    9つの場合わけのうち、勝った場合は、「i」の値を1増やし、「i」を表示です。 案外この「i」を表示するというのを忘れがちです。 値を増やしただけでは、ユーザーに伝わりません。
  5. 負けた場合、これまでの連勝回数が新記録を更新するかどうか判定する。
    負けた場合、その時点での「i」の値と「j」の値を比較し、「i」の方が大きい場合は「j」の値を更新します。


12人いる生徒のうち、2名はほぼ自力で完成に近いところまでできました。

解答例として以下のものを提示しました。しかし、 解答例を示されても、それをそのまま自分のものにはあてはめることはできません。 オブジェクトの内容と番号が違うからです。 コードを分析して、それぞれの命令文の意味を理解し、自分のものと見比べなければなりません。
この解答例で、工夫している点を説明しました。 ひとつは、じゃんけんの3手の画像を配列にしていることです。(Image2(0)〜Image2(2)) そうすると、乱数で出したx={0,1,2}と番号が対応するのでわかりやすいということ。 実際、生徒の中には、ぐー、ちょき、ぱーがどれがどれだか混乱している人がいました。
もう1つは、サブプロシージャを定義していることです。 じゃんけんに負けた場合、新記録を更新できたかどうかの判定をしなければなりません。 これはじゃんけんの9通りの中の3通りについて、全く同じ処理をします。 従って、場合分けの中で書いていくとすると、同じことを3回記述することになります。 そこでその部分を独立させたということです。
実は勝った場合の処理(i = i + 1;Text1.Text = i)についても同じことが言えますね。

Dim i As Integer Dim j As Integer Private Sub Command1_Click() Image1.Picture = Image2(0).Picture x = Int(Rnd() * 3) If x = 0 Then Image3.Picture = Image2(0).Picture Label4.Caption = "あいこ もう1回" ElseIf x = 1 Then Image3.Picture = Image2(1).Picture Label4.Caption = "やったね!" i = i + 1 Text1.Text = i Else Image3.Picture = Image2(2).Picture Label4.Caption = "残念でした。" Hantei End If End Sub Private Sub Command2_Click() Image1.Picture = Image2(1).Picture x = Int(Rnd() * 3) If x = 1 Then Image3.Picture = Image2(1).Picture Label4.Caption = "あいこ もう1回" ElseIf x = 2 Then Image3.Picture = Image2(2).Picture Label4.Caption = "やったね!" i = i + 1 Text1.Text = i Else Image3.Picture = Image2(0).Picture Label4.Caption = "残念でした。" Hantei End If End Sub Private Sub Command3_Click() Image1.Picture = Image2(2).Picture x = Int(Rnd() * 3) If x = 2 Then Image3.Picture = Image2(2).Picture Label4.Caption = "あいこ もう1回" ElseIf x = 0 Then Image3.Picture = Image2(0).Picture Label4.Caption = "やったね!" i = i + 1 Text1.Text = i Else Image3.Picture = Image2(1).Picture Label4.Caption = "残念でした。" Hantei End If End Sub Private Sub Command4_Click() i = 0 Text1.Text = i End Sub Private Sub Command5_Click() End End Sub Private Sub Form_Load() Text1.Text = i Text2.Text = j End Sub Private Sub Hantei() If i > j Then j = i Text2.Text = j MsgBox "でも、新記録です!!" i = 0 Text1.Text = i Else MsgBox "新記録達成ならず" i = 0 Text1.Text = i End If End Sub








1年間を終えて

初めての試みでしたので、どうなることかと不安の中で取り組んだ授業でしたが、何とか1年間終えることができました。生徒たち、よくついてきてくれたと思います。プログラミングのおもしろさがわかってもらえたかな? 私自身もとてもいい勉強になりました。

最終回、簡単なアンケートに答えてもらいました。


授業で扱う言語について、本校の情報処理室の環境などの制限などもありVBを扱いましたが、生徒が自宅で復習できるものの方が望ましいと思いました。

1年間生徒たちが作ってきたファイルはそれぞれCDに焼いて持って帰ってもらいました。





戻る