#!/usr/bin/env ruby # -*- coding: utf-8 -*- myIntro = [ "こんにちは。澤田 羽衣です。", "私の自己紹介ということで、何にしようかなーなんて思いましたが、結局クイズになってしまいました。。", "単なるクイズではつまらないので、カスタマイズができるようにしました。", "どうも柔軟に対応させるのは難しいようで、まだまだ改良点があり、", "一時的な成果のようなものになってしまいましたが、", "三択クイズとしてはそれなりのものになっているかとおもいます。", "話が長いと思いましたか?実は、skipと入力してからenterを押してくれれば本題に入りますよ。", "もっとも、もっと話を聞きたいならこのままでいいのですが。", "さて、話は変わりますが。", "ある時、見つけてしまったのです。", "「わかりやすいプログラム」というやつを。", "もう一目惚れですよ。こんなん書けたらもう最高じゃないか、なんて。", "そして、思いました。", "プログラミングにも、絵のように、「画力」があるのではないか、と。", "うまく伝わるかわかりませんが、今思うと絵に似てるんです。", "昔に書いたものを、すごく見たくないんです、", "「うわぁ...」ってなるんです。でもこれがすごく大事で、こうなるってことは、", "「画力が向上してる」んですよね。", "というわけで(?)、今自分にある技術の中で一番読みやすいプログラムにしました。", "時々ローマ字なのは単語力の問題です。勉強しときます。", "他にも「ん?」ってなる部分があれば指摘していただけると励みになります。", "まあそんな感じで、やんわ〜り触れましたが、私は物心ついたときから絵の練習をしています。", "人物を描き始めたのはつい最近です。小6くらいですね、今が中3だから、2018年頃ですかね。", "私の大好きな白猫プロジェクトというゲームで勉強をしています。", "もちろん今も勉強中です。", "まあ、自己流なので勉強に見えないかもしれないのですが。。", "と、長々と喋っている通り、私は論点の定まらない話をするのが好きです。", "でもこのままではずっと書き続けてしまいそうなので、そろそろ本題へ。" ] hondai = [ "さて、前置きが長くなってしまいましたが、本題のプログラムですね。", "ちょっとしたクイズでしかありませんが、こだわりました。", "よかったら、遊んでみてください。どこまでわかるかな?", ] thankYou = [ "どうでしょう。楽しめたでしょうか。", "今回は提出用に、豪快にプログラムをくっつけたような感じになっていますが、", "本来はクイズ単体で動作します。このままだとカスタマイズしたときにも、余計に私の文章が入り込んで来ますが、", "クイズの本来のプログラムはRubyディレクトリのcsquizですので、興味があったら覗いてみてください。", ] def putStory(dasu) for str in dasu puts str isSkip = gets.chomp return if isSkip == "skip" end end putStory(myIntro) # 分かれているのはskip後にきりのいいところから進行を putStory(hondai) # 再開できるようにするため。唐突にクイズ突入は怖い。 puts"enterを押すとクイズに移動します。" gets sleep(0.5) #持ってきたぁ^^ require 'csv' require 'roo' ods = Roo::Spreadsheet.open("quiz2102.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を使うことで、自由にクイズを作ることができます。", "ですが今回は私についてのクイズになっています。", "特別版ということです。といっても実はquiz2102を書き換えればカスタマイズ可能です。", "特別版だからってodsからの設定ではできないことをやるのは個人的に嫌なので、", "「この説明文」と「呼び出すodsファイルの名前」以外は通常版と全く同じものになっています。", "どうぞお楽しみください。" ] 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 # おつかれさまでした!! sleep(1) print"\n" putStory(thankYou) pic = spawn "display -geometry +0+0 thankyou.gif" puts"それではまたどこかで!" gets Process.kill(:INT,pic)