#!/usr/bin/env ruby # -*- coding: utf-8 -*- #ちなみに.rbです(ダジャレ?) #お察しの通りかと思いますが。 #ちなみに100行越した方(つまり本当の現状)はこんなんです。っていうやつです。 #よかったら見てってほしいです require 'curses' include Curses require 'csv' about = CSV.read("typing-about.csv",:headers => true) sentence = CSV.read("typing-texts.csv" , :headers => true)#タイピング本文 sentence_utu= CSV.read("typing-texts-utu.csv",:headers => true) menu_sentakusi ={1=>"play",2=>"option",3=>"practice", 4=>"about",5=>"exit"} play_sentakusi =sentence.headers type_list =[] #打つ内容を呼び出すための文字列を格納する odai_utta =[] #打ったお題を入れる配列 kaisu = 0 # 問題数を指定 miss_now = nil # 各文字でミスったか否か miss_all = [] # 全部で何回、どの字でミスったか class Window @@numbers = CSV.read("futaketa-alpha.csv",:headers => true) def putSentakusi(nani,zip = @@numbers.headers) for na,s in nani.zip(zip) self.addstr(sprintf("%s => %s\n",s,na)) end self.refresh end def getAns() self.addstr("入力:") self.refresh begin a = getch return "q" if a == "q" return @@numbers[a].join.to_i #アルファベットを対応表@@numbersを利用し2桁の整数にする rescue retry end end def addstr_sousyoku(nani,str) nani.each{|n|self.attron(n)} self.addstr(str) nani.each{|n|self.attroff(n)} end end init_screen noecho cbreak begin win = Window.new(32,60,7,10) while true win.addstr("タイピングです。\nメニュー\n番号を入れてください\n") win.putSentakusi(menu_sentakusi.values) choice = win.getAns win.setpos(0,0) if menu_sentakusi[choice] == "play" win.addstr("ジャンルを決めてください(複数選択可能、qで入力終了\n") win.addstr("もう一度選ぶと選択解除)\n")#refreshはquestionに cursor_position =[win.cury,win.curx] while true win.setpos(*cursor_position) ##* s e t "p o" s *##setopsって書くとそのエラーすっごく見つけづらい win.putSentakusi(play_sentakusi) choice = win.getAns break if choice == "q" && type_list != [] redo if choice.class == String play_choice = play_sentakusi[choice-1] already_chosen = (type_list.include?(play_choice)) if play_choice #- 選択、解除のトグル部分 -# type_list << play_choice #打つ内容に紐付いた文字を格納 type_list.delete(play_choice)if already_chosen end win.addstr(sprintf("\n選択済み:%s\n",type_list.join(",")) ) win.refresh end odai_display_list = type_list.collect{|type|sentence[type]}.flatten.compact odai_utu_list = type_list.collect do|type| sentaku = type.sub(/\(.*\)/,"").to_s # カッコを外す sentence_utu[sentaku] end.flatten.compact odai_length = odai_display_list.length # 問題数を拾っている win.clear win.addstr(sprintf("何問やりますか(最大%d問)\n",[odai_length,20].min))#数字変換のCSVが20までのため until kaisu != "q" && kaisu >= 1 && kaisu <= odai_length kaisu = win.getAns win.setpos(1,0) end win.addstr(kaisu.to_s) win.addstr("\nなにか打つと開始!!\n") win.getch win.clear refresh #-=* タイピング本体 *=-# number = 0 #お題の番号 #文字の様子 -> 入力前太字。入力後普通、ミス下線 start_time = Time.now.to_i kaisu.times do number = rand(0..(odai_length-1) ) #この回のループで出すお題の番号 odai = {display: odai_display_list[number],utu: odai_utu_list[number]}#この回のループで出すお題のハッシュ ch_count = 0 #今カーソルのある文字の番号 win.setpos(0,0) win.addstr_sousyoku([A_BOLD],odai[:display]+"\n") cursor_position =[win.cury,win.curx] win.addstr_sousyoku([A_DIM,A_BOLD],odai[:utu]) #-- 入力と反映 --# while odai[:utu].length > ch_count win.setpos(cursor_position[0],(cursor_position[1])+ch_count) win.refresh input = getch if input == odai[:utu][ch_count] win.addch(odai[:utu][ch_count])unless miss_now win.addstr_sousyoku([A_UNDERLINE],odai[:utu][ch_count])if miss_now win.setpos(win.cury+1,win.curx) win.deleteln ch_count += 1 ; miss_now = false win.refresh else miss_all << odai[:utu][ch_count] win.setpos(win.cury+1,win.curx) print("\e[2m") win.addstr(input) win.setpos(win.cury,win.curx+1) win.clrtoeol win.refresh print("\e[m") miss_now = true end end win.clear odai_length -= 1 odai_display_list.delete_at(number)#2回出題を防ぐ odai_utta << odai_utu_list.delete_at(number)##for最終行## end #-=* 結果表示の準備 *=-# finish_time = Time.now.to_i keikajikan = finish_time - start_time miss_result = miss_all.tally miss = {syousai:{chars: miss_result.keys, kaisu: miss_result.values}, kaisu: miss_all.length} utu = {perfect: odai_utta.join.length, seitou: (odai_utta.join.length) - miss[:kaisu], kaisu: (odai_utta.join.length) + miss[:kaisu]} seidaritu = (utu[:perfect].to_f/utu[:kaisu].to_f)*100 point = [(60*(utu[:perfect]-miss[:kaisu])/keikajikan).to_i,0].max #trr参考です。 win.resize((lines)+5,60) win.clear win.setpos(1,10) #-- 結果表示 --# win.addstr_sousyoku([A_BOLD],"結果\n") win.addstr("かかった時間: #{keikajikan}秒(1問あたり: #{keikajikan/kaisu}秒,1打あたり: #{(keikajikan/(utu[:kaisu].to_f)).truncate(3)}秒),\nミス: #{miss[:kaisu]}回,正打率: #{seidaritu.truncate(2)}%(パーフェクト#{utu[:perfect]}字、打数#{utu[:kaisu]}打)\n得点: #{point}点\n") miss_kaisu_with_unit = (miss[:syousai][:kaisu].join("回,").to_s)+"回"#String win.addstr("ミスの詳細: ") win.addstr_sousyoku([A_BOLD,A_UNDERLINE],"PERFECT!!\n")if miss[:kaisu] == 0 unless miss[:kaisu] == 0 win.addstr("\n") win.putSentakusi(miss_kaisu_with_unit.split(","), miss[:syousai][:chars]) end win.refresh elsif menu_sentakusi[choice] == "about" win.clear for i in about["about"] addstr(sprintf("%s\n",i)) end refresh elsif menu_sentakusi[choice] == "exit" break else#`if menu_sentakusi[choice]'のelse win.addstr("未実装か存在しない選択肢です。\n") win.refresh end getch clear win.clear refresh win.refresh end win.clear clear win.refresh refresh ensure close_screen end