#!/bin/env ruby require 'gtk2' Gtk.init rawData = File.new(ARGV[0]).read().split("\n").collect { |line| line.split(";").collect { |pair| pair.split("-") } } $data = [] rawData.each_index { |col| rawData[col].each_index { |row| $data << ( [ col, row ] + rawData[col][row] + [ nil ] ) if rawData[col][row][0] != nil } } #p $data if ARGV.length > 1 and ARGV[1] == "r" $quest = 1 $resp = 0 else $quest = 0 $resp = 1 end $shuffle = 0 $shuffle = ARGV[2].to_i if ARGV.length > 2 $colorQuestion = "#000000" $colorGood = "#0000FF" $colorBad = "#FF0000" $score = $data.collect { [0,0] } $scoreStack = [] $scoreRange = $data.length class AppWindow < Gtk::Window def initialize super('Kana Trainer') @questionTemplate = "$question" @currentQuestion = -1 @question = Gtk::Label.new @question.use_markup = true mainBox = Gtk::VBox.new(false,0) mainBox.pack_start(@question,true,true,10) add(mainBox) @dataWidth = ($data.max { |a,b| a[0] <=> b[0] })[0] @dataHeight = ($data.max { |a,b| a[1] <=> b[1] })[1] @responseTable = Gtk::Table.new(@dataHeight,@dataWidth,true) $data.each_index { |ind| entry = $data[ind] entry[4] = letter = Gtk::Button.new(entry[$resp+2],false) letter.signal_connect("clicked") { clicked(ind) } @responseTable.attach(letter,@dataWidth-entry[0],@dataWidth-entry[0]+1,entry[1],entry[1]+1) # p @dataWidth-entry[0],@dataWidth-entry[0]+1,entry[1],entry[1]+1 # p @responseTable.n_rows } mainBox.pack_start(@responseTable,false,false,10) buttonBox = Gtk::HBox.new(false,0) forwardButton = Gtk::Button.new(Gtk::Stock::GO_FORWARD) forwardButton.signal_connect("clicked") { clicked(-1) } @scoreLabel = Gtk::Label.new("") buttonBox.pack_start(@scoreLabel,true,true) buttonBox.pack_start(forwardButton,false,false,0) mainBox.pack_start(buttonBox,false, false, 0) signal_connect("destroy") { Gtk::main_quit } nextQuestion end def clicked(ind) if @currentQuestion == -1 nextQuestion else if ind == @currentQuestion @question.markup = @questionTemplate.gsub(/\$question/,$data[@currentQuestion][2+$quest]+" = "+$data[@currentQuestion][2+$resp]).gsub(/\$color/,$colorGood) $score[@currentQuestion][1] += 1 $scoreStack.push(1) $scoreStack.shift if $scoreStack.length > $scoreRange @currentQuestion = -1 else @question.markup = @questionTemplate.gsub(/\$question/,$data[@currentQuestion][2+$quest]+" = "+$data[@currentQuestion][2+$resp]).gsub(/\$color/,$colorBad) $score[@currentQuestion][0] += 1 $score[ind][0] += 1 if ind >= 0 $scoreStack.push(0) $scoreStack.shift if $scoreStack.length > $scoreRange @currentQuestion = -1 end scoreSum = 0 $scoreStack.each { |val| scoreSum += val } @scoreLabel.label = "%i"%[(4.0*scoreSum / ($scoreStack.length) + 1.99).floor] end end def shuffle s1 = s2 = rand($data.length) s2 = rand($data.length) while s1 == s2 $data[s1][0..1],$data[s2][0..1] = $data[s2][0..1],$data[s1][0..1] # p $data[s1][0..1],$data[s2][0..1],$data[s2][0..1],$data[s1][0..1] # $data[s1][4].set_focus(false) # $data[s2][4].set_focus(false) @responseTable.remove($data[s1][4]) @responseTable.remove($data[s2][4]) @responseTable.attach($data[s1][4],@dataWidth-$data[s1][0],@dataWidth-$data[s1][0]+1 ,$data[s1][1],$data[s1][1]+1) @responseTable.attach($data[s2][4],@dataWidth-$data[s2][0],@dataWidth-$data[s2][0]+1 ,$data[s2][1],$data[s2][1]+1) end def nextQuestion(shf = $shuffle) # p "A" whole = 0 maxWspSc = $score.max { |a,b| (a[0]+1.0)/(a[1]+1.0) <=> (b[0]+1.0)/(b[1]+1.0) } maxWsp = (maxWspSc[0]+1.0)/(maxWspSc[1]+1.0) begin ind = rand($data.length) wsp = ($score[ind][0]+1.0) / ($score[ind][1]+1.0) los = rand * maxWsp # p wsp,los end while los > wsp p wsp @currentQuestion = ind @question.markup = @questionTemplate.gsub(/\$question/,$data[ind][2+$quest]).gsub(/\$color/,$colorQuestion) # p "B" # p $score shf.times { shuffle } end end x = AppWindow.new x.show_all Gtk.main