Skip to content

Instantly share code, notes, and snippets.

@bugQ
Created August 13, 2008 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bugQ/5254 to your computer and use it in GitHub Desktop.
Save bugQ/5254 to your computer and use it in GitHub Desktop.
a little tyiping tutor for curses
%w(curses matrix).each { |lib| require lib }
class Range
def any
first + rand(last + (exclude_end? ? 0 : 1))
end
end
module Indexable
def any(len = nil)
i = (0...size).any
len ? self[i, len] : self[i]
end
end
[String, Array].each { |c| c.module_eval { include Indexable } }
class TypingTutor
COURSES = {
:qwerty => %w(fj dk sl a; gh ty ru ei wo qp z/ x. c, vm bn
FJDKSLA:GHTYRUEIWOQPBNVMC<X>Z? 67 58 49 30
2- 1= ^& %* $( #) @_ !+ ]['\\` }{"|~),
:dvorak => %w(uh et on as id yf pg .c ,r 'l ;z qv jw km xb
UHETONASIDYFPG>C<R"L:ZQVJWKMXB 67 58 49 30
2[ 1] ^& %* $( #) @{ !} =/-\\` +?_|~),
:ag5 => %w(tn ei so ap vx jz fu d, w. qb yh lg km cr
TNEISOAPVXJZFUD;W:QBYHLGKMCR 12 34 56 78 90
=/ -* +@ #$ ~%"\' ^_!? &| <> `\\ []{}()),
}
def initialize window = Curses.init_screen
@window = window
end
attr_accessor :line_pos
def line= line
@window.setpos(1, 0)
@window << line
line
end
def run course, line_length = 28
Curses.noecho
clean_lines = 0
COURSES[course].inject do |chars, lesson|
self.line = (1..line_length).inject('') do |m, i|
m << if (2...line_length) === i && m[-1] != ?\s && rand < 0.25
?\s
else
(rand < 0.3 ? lesson : chars).tr(m[-1,1] || '', '').any
end
end
@window.setpos(1, 0)
error = false
(1..line_length).each do |i|
unless @window.getch == @window.inch
Curses.beep
error = true
redo
end
@window.setpos(1, i)
end
Curses.beep until @window.getch == 32
clean_lines = error ? 0 : clean_lines + 1
clean_lines < 3 ? redo : clean_lines = 0
chars << lesson
end
end
end
TypingTutor.new(Curses.init_screen).run(:qwerty) if __FILE__ == $0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment