Newer
Older
Ruby / sample / sample_ui2.rb
#!/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)