Bash를 사용하여 텍스트 기반 퀴즈를 구현하는 방법은 무엇입니까?

Bash를 사용하여 텍스트 기반 퀴즈를 구현하는 방법은 무엇입니까?

질문이 매번 무작위로 지정되고 사용자의 다양한 응답(맞음, 틀림, 합격)이 기록된 다음 퀴즈가 끝날 때 제공되는 Bash에서 퀴즈를 구현하는 적절한 방법이 있습니까?

배열을 사용하여 퀴즈 질문과 답변을 저장할 수 있고, 퀴즈 질문 자체를 한동안 또는 루프 내에서 질문할 수 있으며, 마지막 질문에 도달할 때까지 다양한 질문을 증가시킨 다음 사용자의 성과를 평가할 수 있다고 가정합니다. 다양한 조건문을 사용하여?


점에 유의하시기 바랍니다이 오래된 질문그래픽 퀴즈 소프트웨어에 대해 논의하고 사운드/그래픽 등에 대해 명시적으로 언급했지만 저는 명령줄 텍스트 기반 퀴즈에 대해서만 이야기하고 있습니다.

(아래에 내 질문에 대한 답변이 있습니다...하지만 Bash의 퀴즈에 대한 다른 프레임워크가 있는 사람이 있으면 게시해 주세요.)

답변1

제가 생각해낸 퀴즈 프레임워크는 아래와 같습니다.GitHub(원래 사용자 GitHub 페이지는 더 이상 존재하지 않습니다).

다소 복잡해 보이기 때문에 작동 방식에 대해 설명하는 것이 좋습니다.

스크립트에는 지금까지의 모든 릴리스의 Ubuntu 버전과 코드명이 두 개의 배열에 저장되어 있습니다. 그런 다음 변수가 초기화됩니다.밖의C 스타일 표기법을 사용하여 루프에서 필요에 따라 증가할 수 있습니다 (( var++ )).

그런 다음 질문 번호에 대한 또 다른 배열을 만듭니다. 이 경우 19개 질문에 대해 0부터 18까지 포함해야 합니다.

questions_order=(15 4 1 10 8 3 13 0 11 16 2 7 5 17 6 9 14 18 12)

그런 다음 shuf새 배열을 사용하여 섞고 이를 특정 스크립트 실행에 사용합니다.

shuffled_order=( $(shuf -n19 -e ${questions_order[@]}) )

이 작업을 수행해야 합니다.밖의루프는 한 번만 실행되기를 원하기 때문입니다.

즉, 현재 질문 수가 변수와 같아질 때까지 루프가 실행되고 "${target_questions}"결과가 제공됩니다.

사용자가 질문에 응답하면 해당 내용은 설명문의 다양한 조건에 따라 해석됩니다 case. 미답(공백), 오답, 정답, 합격을 모두 감지하여 응답을 받으며, 다양한 변수가 모두 증가됩니다(예: 오답의 경우 (( wrong++ ))).

마지막 질문에 대한 답변이 완료되면 정답, 오답 및 합격 횟수(있는 경우)가 전달되고 소요 시간도 제공되는 사용자의 성과가 평가됩니다.

이것은 간단한 설명이지만 스크립트 자체에는 작업을 명확하게 만드는 다양한 주석이 있습니다! 수도나 국가 등 다른 유형의 퀴즈에도 적용할 수 있습니다.

스크립트를 파일에 복사한 후 실행 가능하게 만들고( chmod u+x), 실행하거나 폴더 ./scriptname에 넣고 ~/bin다른 프로그램처럼 이름으로 호출 ~/bin합니다 PATH.

#!/usr/bin/env bash

# by mik, aka Exactus29, https://github.com/Exactus29
# 
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

######### 

# Requires at least bash 3.1. As it makes extensive use of arrays, it would be a pain to 
# try to write it to be sh compatible, but it may be possible.

# arrays for questions and answers
codenames=("Warty Wharthog" "Hoary Hedgehog" "Breezy Badger" "Dapper Drake" "Edgy Eft" "Feisty Fawn" 
"Gutsy Gibbon" "Hardy Heron" "Intrepid Ibex" "Jaunty Jackalope" "Karmic Koala" "Lucid Lynx" "Maverick Meerkat" 
"Natty Narwahl" "Oneric Ocelot" "Precise Pangolin" "Quantal Quentzal" "Raring Ringtail" "Saucy Salamander")
versions=(4.10 5.04 5.10 6.06 6.10 7.04 7.10 8.04 8.10 9.04 9.10 10.04 10.10 
11.04 11.10 12.04 12.10 13.04 13.10)

# must intialize quest_index at -1 so we can use array index 0
quest_index=-1
target_questions=19
# we start question counter at 0, so we can increment it to the value in number_questions
questions=0 
# the other variables below will all be incremented as necessary in the quiz
correct=0 
wrong=0
no_response=0
pass=0

# declare questions_order array and then shuffle it and use that for this run of the script.
# must be declared outside of the loop, as only want it executed once
questions_order=(15 4 1 10 8 3 13 0 11 16 2 7 5 17 6 9 14 18 12)
shuffled_order=( $(shuf -n19 -e ${questions_order[@]}) )

printf "\nPress 0 to exit the quiz at any time.\n"
printf "You can ignore case in your answers, but correct spelling of the Ubuntu codenames is crucial.\n"
printf "Please enter the word pass if you don't know the answer.\n\n\n"


timer_begin=$SECONDS


until (( questions == target_questions )); do
 
(( questions++ ))

(( quest_index++ ))

new_index=$( echo ${shuffled_order[$quest_index]})

# alternate style of questions, separate odd and even 

    if (( questions % 2 > 0 )); then 
        new_question="${codenames[$new_index]}"
        ans="${versions[$new_index]}"
        question_text="Ubuntu release had the development codename"
    else
        new_question="${versions[$new_index]}"
        ans="${codenames[$new_index]}"
        question_text="was the Ubuntu development codename (both adjective and animal) for release"
    fi

read -p "(${questions}) What ${question_text} ${new_question}? " response 

# necessary to switch on nocasematch to cover if the answer is in capitals, as can't use normal [Mm] in case statement
shopt -s nocasematch

    case $response in 
    "$ans") 
          printf "Well done, correct answer. " 
          (( correct++ ))
          if (( questions < target_questions )); then 
              printf "Next question.\n\n" 
          else
              printf "\nHowever, the quiz has now finished. Let us calculate your performance...\n"
              sleep 1
          fi
       ;; 
       0) 
          printf "\nOk, time to finish with the quiz.\n"
          break
       ;;
    "pass")
         (( pass++ ))
         printf "Ok, you passed on this one..."
         if (( pass >= 10 )); then 
            printf "The passes are mounting, as you have now had ${pass} passes.\n"
         elif (( pass >= 2 )); then
            printf "Please try to give an answer, as you have now had ${pass} passes.\n" 
         fi
            
         if (( questions < target_questions )); then 
            printf "Let us try another question.\n\n"
         else
            printf "\nHowever, the quiz has now finished. Let us calculate your performance.....\n"
            sleep 1
         fi
         
       ;;
       *) 
          if [[ -z ${response} ]]; then
              printf "Please provide an answer, as a blank answer is counted as a wrong answer; "
              (( no_response++ ))
              (( wrong++ ))
                if (( no_response == 1  )); then
                    printf "${no_response} blank response has been given so far. \n"
                elif (( no_response > 1 )); then
                    printf "${no_response} blank responses have been given so far. \n"   
                fi
          else
              (( wrong++ ))
                if  (( questions % 2 > 0 )); then
                    printf "That is incorrect..."
                else 
                    printf "That is incorrect, ${response} was not the codename of ${new_question}. \n"
                fi
          fi
           
         if (( questions < target_questions )); then 
            printf "Let us try another question.\n\n"
         else
            printf "\nHowever, the quiz has now finished. Let us calculate your performance.....\n"
            sleep 1
         fi
       ;;
    esac

done

quiz_duration=$(( SECONDS - timer_begin ))
# could further process the $quiz_duration if it is over 60 seconds, and output the total in
# minutes and seconds using bc or awk

# checking against target_questions here, i.e. all of the questions
if (( questions == target_questions )); then 
    if (( correct == target_questions )); then
        printf "\nYou got them all right in ${quiz_duration} seconds, well done!\n\n"
    elif (( no_response == target_questions )); then 
        printf "\nYou gave ${no_response} blank responses, and so effectively gave ${no_response} wrong answers.\n\n"                
    elif (( wrong == target_questions )); then
        printf "\nYou got them all wrong in ${quiz_duration} seconds, oh dear!\n\n"
    elif (( pass == target_questions )); then 
        printf "\nYou passed on all the questions. Was this just a trial run?\n\n"             
    else
        printf "\nOut of ${target_questions} questions, you got "
        # have to do this now because we have added the pass option, as you can have none wrong/correct,
        # some correct/wrong, and some passes
        (( wrong > 0 )) && printf "${wrong} wrong and "
        (( correct > 0 )) && printf "${correct} correct "
        
        if (( pass == 0 )); then
            printf "with no passess at all in a time of ${quiz_duration} seconds.\n "
        elif (( pass == 1 )); then 
            printf "with 1 pass in a time of ${quiz_duration} seconds.\n "
        elif (( pass > 1 )); then
            printf "with ${pass} passes in a time of ${quiz_duration} seconds.\n"
        fi
    fi
fi

exit 

무작위 질문이 포함된 실제 퀴즈:

여기에 이미지 설명을 입력하세요

관련 정보