자습서: 수학 퀴즈 WinForms 앱에 타이머 추가

4개 자습서로 구성된 이 시리즈에서는 수학 퀴즈를 빌드합니다. 퀴즈는 퀴즈를 푸는 사람이 지정된 시간 이내에 답변을 시도하는 4가지 난수 수학 문제를 포함합니다.

퀴즈에서 타이머 컨트롤을 사용합니다. 이 컨트롤의 숨김 코드는 경과된 시간을 추적하고 퀴즈를 푸는 사람의 답변을 확인합니다.

이 세 번째 자습서에서는 다음 작업을 수행하는 방법을 알아봅니다.

  • 타이머 컨트롤을 추가합니다.
  • 타이머에 대한 이벤트 처리기를 추가합니다.
  • 사용자의 답변을 확인하고 메시지를 표시하고 정답을 채우는 코드를 작성합니다.

사전 요구 사항

이 자습서는 수학 퀴즈 WinForms 앱 만들기로 시작하는 이전 자습서를 기반으로 작성되었습니다. 이전 자습서를 완료하지 않은 경우 해당 자습서를 먼저 진행합니다.

카운트다운 타이머 추가

퀴즈를 푸는 동안 시간을 추적하려면 타이머 구성 요소를 사용합니다. 또한 남은 시간을 저장할 변수가 필요합니다.

  1. 이전 자습서에서 변수를 선언한 것과 같은 방식으로 timeLeft라는 정수 변수를 추가합니다. timeLeft 선언을 다른 선언 바로 뒤에 배치합니다. 코드는 다음 샘플과 같습니다.

    public partial class Form1 : Form
    {
        // Create a Random object called randomizer 
        // to generate random numbers.
        Random randomizer = new Random();
    
        // These integer variables store the numbers 
        // for the addition problem. 
        int addend1;
        int addend2;
    
        // These integer variables store the numbers 
        // for the subtraction problem. 
        int minuend;
        int subtrahend;
    
        // These integer variables store the numbers 
        // for the multiplication problem. 
        int multiplicand;
        int multiplier;
    
        // These integer variables store the numbers 
        // for the division problem. 
        int dividend;
        int divisor;
    
        // This integer variable keeps track of the 
        // remaining time.
        int timeLeft;
    

중요

이 페이지의 오른쪽 위에 있는 프로그래밍 언어 컨트롤을 사용하여 C# 코드 조각 또는 Visual Basic 코드 조각을 볼 수 있습니다.

Programming language control for Microsoft Learn

  1. Windows Forms 디자이너에서 도구 상자구성 요소 범주에서 Timer 컨트롤을 양식으로 이동합니다. 그러면 디자인 창의 맨 아래에 있는 회색 영역에 이 컨트롤이 표시됩니다.

  2. 양식에서 방금 추가한 timer1 아이콘을 선택하고 간격 속성을 1000으로 설정합니다. 이 간격은 밀리초 단위이므로 값 1000을 설정하면 타이머가 1초마다 Tick 이벤트를 발생시킵니다.

답변 확인

타이머가 1초마다 Tick 이벤트를 발생시키므로 Tick 이벤트 처리기에서 경과된 시간을 확인하는 것이 합리적입니다. 또한 해당 이벤트 처리기에서 답변을 확인하는 것이 타당합니다. 시간이 다 되거나 답변이 올바르면 퀴즈가 종료되어야 합니다.

해당 이벤트 처리기를 작성하기 전에 CheckTheAnswer()라는 메서드를 추가하여 수학 문제에 대한 답변이 올바른지를 확인합니다. 이 메서드는 StartTheQuiz()와 같은 다른 메서드와 비슷해야 합니다. 코드는 다음 샘플과 같습니다.

/// <summary>
/// Check the answers to see if the user got everything right.
/// </summary>
/// <returns>True if the answer's correct, false otherwise.</returns>
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;
}

이 메서드는 수학 문제에 대한 답변을 확인하고 결과를 NumericUpDown 컨트롤의 값과 비교합니다. 이 코드에서는 다음과 같습니다.

  • 이 메서드는 값을 반환하므로 Visual Basic 버전에서는 일반적인 Sub 키워드 대신 Function 키워드를 사용합니다.

  • 키보드를 사용하여 곱하기 기호(×)와 나누기 기호(÷)를 입력하기가 쉽지 않으므로 C# 및 Visual Basic에서는 별표(*)를 곱하기에, 슬래시(/)를 나누기에 각각 사용합니다.

  • C#에서 &&logical and 연산자입니다. Visual Basic에서 이에 해당하는 연산자는 AndAlso입니다. logical and 연산자를 사용하여 둘 이상의 조건이 true인지를 확인합니다. 이 경우 값이 모두 올바르면 메서드는 true 값을 반환합니다. 그렇지 않으면 false를 반환합니다.

  • if 문은 NumericUpDown 컨트롤의 속성을 사용하여 컨트롤의 현재 값에 액세스합니다. 다음 섹션에서는 같은 속성을 사용하여 각 컨트롤의 정답을 표시합니다.

타이머에 이벤트 처리기 추가

이제 답변을 확인하는 방법이 마련되었으므로 Tick 이벤트 처리기의 코드를 작성할 수 있습니다. 이 코드는 타이머가 Tick 이벤트를 발생시킨 후 1초마다 실행됩니다. 이 이벤트 처리기는 CheckTheAnswer()를 호출하여 퀴즈를 푸는 사람의 답변을 확인합니다. 또한 퀴즈에서 경과된 시간을 확인합니다.

  1. 양식에서 타이머 컨트롤을 두 번 클릭하거나, 이 컨트롤을 선택한 후 Enter 키를 선택합니다. 이러한 작업은 Tick 이벤트 처리기를 타이머에 추가합니다. 코드 편집기가 나타나고 Tick 처리기의 메서드가 표시됩니다.

  2. 새 이벤트 처리기 메서드에 다음 문을 추가합니다.

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (CheckTheAnswer())
        {
            // If CheckTheAnswer() returns true, then 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)
        {
            // If CheckTheAnswer() returns false, keep counting
            // down. Decrease the time left by one second and 
            // display the new time left by updating the 
            // Time Left label.
            timeLeft = timeLeft - 1;
            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;
        }
    }
    

퀴즈를 푸는 동안 1초마다 이 메서드가 실행됩니다. 이 코드는 먼저 CheckTheAnswer()에서 반환하는 값을 확인합니다.

  • 모든 답변이 올바르면 해당 값은 true이고 퀴즈가 종료됩니다.

    • 타이머가 중지됩니다.
    • 축하 메시지가 표시됩니다.
    • 퀴즈를 푸는 사람이 다른 퀴즈를 시작할 수 있도록 startButton 컨트롤의 Enabled 속성이 true로 설정됩니다.
  • CheckTheAnswer()에서 false를 반환하면 코드에서 timeLeft 값을 확인합니다.

    • 이 변수가 0보다 크면 타이머가 timeLeft에서 1을 뺍니다. 또한 퀴즈를 푸는 사람에게 남은 시간(초)을 표시하도록 timeLabel 컨트롤의 텍스트 속성을 업데이트합니다.
    • 남은 시간이 없으면 타이머가 중지되고 timeLabel 텍스트가 Time's up!으로 변경됩니다. 퀴즈가 종료되었음을 알리는 메시지 상자가 나타나고 답변이 표시됩니다. 시작 단추를 다시 사용할 수 있습니다.

타이머 시작

퀴즈가 시작될 때 타이머를 시작하려면 다음 샘플과 같이 StartTheQuiz() 메서드의 끝에 세 줄을 추가합니다.

/// <summary>
/// Start the quiz by filling in all of the problem 
/// values and starting the timer. 
/// </summary>
public void StartTheQuiz()
{
    // Fill in the addition problem.
    // Generate two random numbers to add.
    // Store the values in the variables 'addend1' and 'addend2'.
    addend1 = randomizer.Next(51);
    addend2 = randomizer.Next(51);

    // Convert the two randomly generated numbers
    // into strings so that they can be displayed
    // in the label controls.
    plusLeftLabel.Text = addend1.ToString();
    plusRightLabel.Text = addend2.ToString();

    // 'sum' is the name of the NumericUpDown control.
    // This step makes sure its value is zero before
    // adding any values to it.
    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();
}

퀴즈를 시작하면 이 코드가 timeLeft 변수를 30으로 설정하고 timeLabel 컨트롤의 텍스트 속성을 30초로 설정합니다. 그런 다음, Timer 컨트롤의 Start() 메서드가 카운트다운을 시작합니다.

앱을 실행합니다.

  1. 프로그램을 저장하고 실행합니다.

  2. Start the quiz를 선택합니다. 타이머가 카운트다운을 시작합니다. 시간이 다 되면 퀴즈가 종료되고 답변이 표시됩니다.

  3. 다른 퀴즈를 시작하고 수학 문제에 대한 정답을 제공합니다. 시간 제한 이내에 올바르게 답변하면 메시지 상자가 열리고 시작 단추를 사용할 수 있으며 타이머가 중지됩니다.

    Screenshot that shows a completed quiz with 19 seconds remaining. The Start the quiz button is available.

다음 단계

수학 퀴즈를 사용자 지정하는 방법을 알아볼 수 있는 다음 자습서를 진행합니다.