#!/usr/bin/env ruby # -*- coding: utf-8 -*- #trrでなかなか成長しないのでいっそのこと、、っていうか。うーん? #まあとにかく。自作ならやる気出るだろう。という、実に謎い思考回路。 #ところがどっこい、結局trrを参考にしているという矛盾。^^;むう。。 #このプログラムはタイピングです。 #自分にとって楽しく、または便利なタイピングが作りたいと思い、こうなりました。 #これを作ろうと思ったのは、タイピングを速くなりたいけど、何が課題かわからない人に #役に立つものを作りたかったからです。 #作ろうとした機能、考えた機能は、 #*打つのにかかった時間、各キーでのミス回数、最高得点中何点で何%取れているのかの結果表示 #*CSVからランダムに出題、選択式のお題 #*楽しく打てる内容(早口言葉、メソッド名など) #*アルファベットやローマ字をランダムに羅列して出題したり(予測したら負けモード)、 # ミスした文をやり直す(パーフェクト出すまで帰れませんモード)「正確さトレーニング」機能 #*とにかく文章を打ちまくる「素早さトレーニング」機能(ミスしても次に行く) #*自分の打った文がお題になる「自習」機能 #です。100行までということでかなり不完全な仕上がりですが require 'curses' include Curses require 'csv' sentence = CSV.read("happyou/typing-texts.csv" , :headers => true)#タイピング本文 sentence_utu= CSV.read("happyou/typing-texts-utu.csv",:headers => true) menu_sentakusi ={1=>"play",2=>"option",3=>"practice"} play_sentakusi =sentence.headers type_list =[] #打つ内容を呼び出すための文字列を格納する kaisu = 0 # 問題数を指定 miss_now = nil # 各文字でミスったか否か miss_all = [] # 全部で何回、どの字でミスったか class Window @@numbers = CSV.read("happyou/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 while true a = getch if a == "q" return "q" elsif @@numbers[a] return @@numbers[a].join.to_i end 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,10,10) win.addstr("タイピングです。\nメニュー\n番号を入れてください\n") win.putSentakusi(menu_sentakusi.values) choice = win.getAns win.setpos(0,0) case menu_sentakusi[choice] when "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" 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{|type|sentaku = type.sub(/\(.*?\)/,"").to_s;sentence_utu[sentaku]}.flatten.compact odai_length = odai_display_list.length # 問題数を拾っている win.clear win.addstr(sprintf("何問やりますか(最大%d問)\n",odai_length)) 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.getAns 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.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 ch_count += 1 ;miss_now = false ; win.refresh else miss_all << odai[:utu][ch_count] ; miss_now = true end end win.clear ; odai_length -= 1 odai_display_list.delete_at(number)#2回出題を防ぐ odai_utu_list.delete_at(number)##for最終行## end finish_time = Time.now.to_i keikajikan = finish_time - start_time miss = miss_all.tally win.addstr_sousyoku([A_BOLD],"結果\n") win.addstr(sprintf("かかった時間: %d秒(1問あたり: %d秒),ミス: %d回\nミスの詳細\n",keikajikan,keikajikan/kaisu,miss_all.length)) win.putSentakusi(miss.values,miss.keys) refresh else win.addstr("未実装か存在しない選択肢です。\n") win.refresh end ensure close_screen end