4章:チュートリアル 3: 計算クイズの作成

    作成2013.04.09

  1. 参照元情報
     チュートリアル 3: 計算クイズの作成
    「チュートリアル 3: 計算クイズの作成」にジャンプする
     作成方法の詳細は上記を参照願います。


  2. チュートリアル 3: 計算クイズの作成の完成ファイル
     チュートリアル 3: 計算クイズの作成の解説とおりに作業を実施すると、プロジェクトファイル群が完成しますがVBからC#に変換したほうが簡単です。
     完成ファイルは以下からダウンロードできます。
     ダウンロード後は解凍してから使用してください。
      [ チュートリアル 3: 計算クイズの作成]をダウンロードする。
     解凍すると「4Math Quiz」フォルダーがあります。
    注(1)「4Math Quiz」フォルダーの「Math Quiz.sln」ファイルをダブルクリックすると「Express 2012 for Windows Desktop」が起動します。
    注(2)メニューの「ウインド」_「ウインドレイアウトのリセット」で標準に戻ります。
    注(3)「ソリューションエクスプローラ」ウインドウ内の「Form1.cs」をダブルクリックすると「デザイン」が表示されます。
    注(4)メニューの「表示」_「コード」を選択するとコードが表示されます。
    注(5)「Graphics.sln」の動作確認は「デバッグ」_「デバッグ開始」で実行します。デバッグ機能を用いて動作確認を行います。


  3. Math Quiz.slnの実行
    (1)「Express 2012 for Windows Desktop」のデバッグ機能を使用します。
    (2)「デバッグ」_「デバッグ開始」を選択します。
    (3)クイズスタート前の画面が表示されます。
    (4)Start the quizボタンを押すと問題と残り時間が表示されます。
    (5)+解答欄にカーソルを移し、値をキーボード入力して、リターンします。
    (6)次に-、×、÷の順で解答します。
    (7)制限時間内の全問正解すれば成功です。
    (8)クローズボックスでプログラムを終了します。


  4. 新規プロジェクトの作成
    (1)Form1のデザイン設定
     新規プロジェクトを作成すると「デザイナー」にはForm1が自動生成されます。Form1のデザイン設定はVBのForm1のコピー&ペーストで完成します。

    (2) Form1コード
     基本コードが自動生成されます。


  5. Form1の全コード
    using System;using System;
    using System.Windows.Forms;
    
    namespace Math_Quiz
    {
        public partial class Form1 : Form
        {
            Random randomizer = new Random();
            int addend1;
            int addend2;
            int minuend;
            int subtrahend;
            int multiplicand;
            int multiplier;
            int dividend;
            int divisor;
            int timeLeft;
    
            public Form1()
            {
                InitializeComponent(); 
            }
    
            public void StartTheQuiz()
            {
                // Fill in the addition problem.
                addend1 = randomizer.Next(51);
                addend2 = randomizer.Next(51);
                plusLeftLabel.Text = addend1.ToString();
                plusRightLabel.Text = addend2.ToString();
                sum.Value = 0;
    
                // Fill in the subtraction problem.
                minuend = randomizer.Next(1, 101);
                subtrahend = randomizer.Next(1, minuend);
                minusLeftLabel.Text = minuend.ToString();
                minusRightLabel.Text = subtrahend.ToString();
                difference.Value = 0;
    
                // Fill in the multiplication problem.
                multiplicand = randomizer.Next(2, 11);
                multiplier = randomizer.Next(2, 11);
                timesLeftLabel.Text = multiplicand.ToString();
                timesRightLabel.Text = multiplier.ToString();
                product.Value = 0;
    
                // Fill in the division problem.
                divisor = randomizer.Next(2, 11);
                int temporaryQuotient = randomizer.Next(2, 11);
                dividend = divisor * temporaryQuotient;
                dividedLeftLabel.Text = dividend.ToString();
                dividedRightLabel.Text = divisor.ToString();
                quotient.Value = 0;
    
                // Start the timer.
                timeLeft = 30;
                timeLabel.Text = "30 seconds";
                Timer1.Start();
            }
    
            private void startButton_Click(object sender, EventArgs e)
            {
                StartTheQuiz();
                startButton.Enabled = false; 
            }
    
            private void Timer1_Tick(object sender, EventArgs e)
            {
                if (CheckTheAnswer())
                {
                    // If the user got the answer right, stop the timer 
                    // and show a MessageBox.
                    Timer1.Stop();
                    MessageBox.Show("You got all the answers right!",
                                    "Congratulations");
                    startButton.Enabled = true;
                }
                else if (timeLeft > 0)
                {
                    // Decrease the time left by one second and display 
                    // the new time left by updating the Time Left label.
                    timeLeft--;
                    timeLabel.Text = timeLeft + " seconds";
                }
                else
                {
                    // If the user ran out of time, stop the timer, show
                    // a MessageBox, and fill in the answers.
                    Timer1.Stop();
                    timeLabel.Text = "Time's up!";
                    MessageBox.Show("You didn't finish in time.", "Sorry");
                    sum.Value = addend1 + addend2;
                    difference.Value = minuend - subtrahend;
                    product.Value = multiplicand * multiplier;
                    quotient.Value = dividend / divisor;
                    startButton.Enabled = true;
                }
            }
    
            private bool CheckTheAnswer()
            {
                if ((addend1 + addend2 == sum.Value)
            && (minuend - subtrahend == difference.Value)
            && (multiplicand * multiplier == product.Value)
            && (dividend / divisor == quotient.Value))
                    return true;
                else
                    return false;
            }
    
            private void answer_Enter(object sender, EventArgs e)
            {
                NumericUpDown answerBox = sender as NumericUpDown;
    
                if (answerBox != null)
                {
                    int lengthOfAnswer = answerBox.Value.ToString().Length;
                    answerBox.Select(0, lengthOfAnswer);
                }
            }
        }
    }
    


  6. Form1コードの解説
    (1)Random randomizer = new Random();で変数randomizerをRandom()型で生成します。
    (2)public void StartTheQuiz()で乱数を使用して計算問題を作成します。
    (3)Timer1.Start();でタイマーを起動します。
    (4)private void startButton_ClickでStartTheQuiz()を起動します。
    (5)private void Timer1_Tickで1秒ごとの状態を確認します。
    (6)CheckTheAnswer()がOKの場合、タイマーを停止、メーセージを出し、スタートボタンを有効にします。
    (7)CheckTheAnswer()がNGで制限時間内の場合、残り時間を1秒減少し、残り時間を表示します。
    (8)CheckTheAnswer()がNGで制限時間外の場合、タイマーを停止、メーセージを出し、解答を表示スタートボタンを有効にします。
    (9)private bool CheckTheAnswer()では全問正解の場合trueを返し、そうでない場合falseを返します。
    (10)private void answer_EnterはVBでは不要なルーチンでした。しかしC#では、このルーチンを削除するとエラーとなります。
    (11)private void answer_Enterの内部の処理は結果的に何も行っていません。内部の処理だけ削除して、中身が空のprivate void answer_Enterルーチンを記載すると正常に動作します。
    (不思議?な現象です。理解できません。)


    感想:
    (1)private void answer_Enterルーチンを記載の問題は不思議な現象です。中身が空のprivate void answer_Enterルーチンを記載する必要があるのは、Express 2012 for Windows Desktopのバグである可能性が強く疑われます。
    (2)VBからC#への変換において、このような問題は重大な混乱を与える可能性があることを示しています。
    (3)理屈では理解できないことが、しばしば起こる可能性があります。実際に動作するサンプルコードをまねするのが賢い方法です。







5章:チュートリアル 4: 絵合わせゲームの作成に行く。

トップページに戻る。