Newer
Older
Final0205 / ume / chinamini.rb
@sakakibara isshin sakakibara isshin on 5 Feb 2022 7 KB ume
#!/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