#!/usr/bin/env ruby # -*- coding: utf-8 -*- # 通常バージョンです # 改良しようとしたけどやばいことになったのでやばい方は避難させといた require 'csv' require 'roo' ods = Roo::Spreadsheet.open("quizod.ods") #odsをもってくる neta = CSV.parse(ods.to_csv, :headers => true) #odsをcsvにする fuseikai = 0 def wrong() puts"不正解!" sleep(0.5) end # ans = answer,opt = row["オプション"],san = santaku,seikai = row["答え"],fu = fuseikaiと書きたいけど無理だった def isRightAns(ans,opt,san,seikai,fu) ansIsA = (ans == san[0]) # この変数群 ansIsB = (ans == san[1]) # カッコ付きはTF、カッコ無しはその他の値 ansIsC = (ans == san[2]) # A,B,Cは選択肢の文字を仮で表している alreadySantaku = (fu >= 3) ansIs1 = (ans == "1") ansIs2 = (ans == "2") ansIs3 = (ans == "3") ansAry = ans.chars ansIsEmpty = (ansAry.empty?) ansLength = ans.length santakuNumbers = ["1","2","3"] santakuTotalLength = san.join.length ansHasA = (ans.include?(san[0]))if san[0] # sanにnilがあるとinclude?で ansHasB = (ans.include?(san[1]))if san[1] # エラーになるのでこうなった ansHasC = (ans.include?(san[2]))if san[2] # ansIs123わかりにくくてすいません。回答に123が1個ずつあればOKを表しています ansIs123 = ((ansAry + santakuNumbers).tally == {"1" =>2,"2" =>2,"3" =>2}) ansIsABC = (ansHasA && ansHasB && ansHasC && ansLength == santakuTotalLength) #ansIs順不同 selectNumber = (ans.to_i)-1 select = san[selectNumber] #文字で答えた場合 || 番号で答えた場合 if opt =~/(すべて)/ return (ansIsABC) || (ansIs123 && alreadySantaku) elsif opt =~ /(どれかひとつ)/ return ([ansIsA,ansIsB,ansIsC].one?) || ([ansIs1,ansIs2,ansIs3].one?) else #通常の三択 return false if ans == "" return (ans == seikai) || (select == seikai && alreadySantaku) end end def putAnswer(row,santaku) if row["答え"] != nil # 正解表示(通常) printf("正解は%sでした。\n",row["答え"]) return end # 以下では row["答え"] = nil if row["オプション"] =~ /(すべて)/ # 正解表示(すべて) printf("正解は%s,%s,%sすべてでした。\n",santaku[0],santaku[1],santaku[2]) return elsif row["オプション"] =~ /(どれかひとつ)/ # 正解表示(どれか) printf("正解は%s,%s,%sの中からひとつでした。\n",santaku[0],santaku[1],santaku[2]) return end end setumei = ["カスタムクイズ", " 説明", "専用のodsを使うことで、自由にクイズを作ることができます。", "odsでつくったクイズが出題されるクイズです。", "選択肢を出す場合、今は出せる選択肢は3つのみとなっております。", "odsでの操作はodsに書いているのでそちらを見てください。", "enterを押すと始まります。" ] for i in setumei puts i end gets countAns = 0 countRight = 0 count = 0 # 今何問目なのか print("\e[2J") print("\e[H") startTime = Time.now.to_i neta.each{|row| if row["オプション"] == "表示物" printf("%s\n",row["問題"]) gets print("--------------------------\n") next end count += 1 dasita = 0 comeback = 0 printf("第%d問\n",count) printf("%s\n", row["問題"]) santaku = [row["三択1"], row["三択2"], row["三択3"]] fuseikai = 0 # fuseikai >= 3で三択表示 kaitou = nil while true #入力と三択システム if comeback == 1 wrong end if row["オプション"] =~ /(三択なし)/ # 意地悪問題がいい人へ dasita = 1 elsif ( fuseikai == 3 || row["オプション"] =~ /(三択)/ ) && dasita != 1 if row["オプション"] =~ /(三択)/ fuseikai = 3 end num = 1 # 選択肢の番号 for i in santaku printf("%d => %s\n",num,i) num += 1 end dasita = 1 # dasitaが1 =「三択出した」 2回以上の三択表示を防ぐ end print"答えを入力..." kaitou = gets.chomp countAns += 1 if row["オプション"] !~ /(判定なし)/ if isRightAns(kaitou,row["オプション"],santaku,row["答え"],fuseikai) puts"正解!!" countRight += 1 sleep(0.5) break else fuseikai += 1 wrong if row["オプション"] !~ /(1回だけ)/ print("\e[2A") # 2行上 print("\e[J") # 下のやつを消す end end end if row["オプション"] =~ /(正解を出す)/ putAnswer(row,santaku) end if row["オプション"] =~ /(1回だけ|判定なし)/ break end end if row["解説"] printf("%s\n",row["解説"]) gets print"\e[1A" end print("--------------------------\n") #何個でもいい仕切りの機能 } # 終了時演出の変数の準備 finishTime = Time.now.to_i text = neta["変更テキスト"][0] finish = neta["終了時演出"][0] seitouritu = (((countRight.to_f)/(countAns.to_f))*100).truncate(1) keikajikan = (finishTime - startTime) heikinjikan = ((keikajikan.to_f)/(count.to_f)).truncate(1) # 終了時演出の表示 printf("正解数: %d回/%d回中 ",countRight,countAns)if finish =~ /(結果表示)/ printf("正答率: #{seitouritu}%% ")if finish =~ /(正答率)/ print"\n" if finish =~ /(正解表示|正答率)/ printf("経過時間: %d秒 ",keikajikan)if finish =~ /(経過時間)/ printf("平均回答時間: #{heikinjikan}秒 ")if finish =~ /(平均時間)/ print"\n" if text printf("%s\n",text)if text != "なし" else puts"終了!!おつかれさまでした!" end # おつかれさまでした!!