;; XEmacs version of virtuoso keyboard practicer
;; by Zajcev Evgeny 2001
(eval-when-compile (require 'cl))
(setq ex '((
"kkjk kjkkj jkjjk kkjkj jjkjk jkjkk kjkjj jkjkj kkjkj jjkjk"
"dffdf fdffd dfddf ffdfd ddfdf dfdff fdfdd dfdfd ffdfd ddfdf"
"dkfdj jdfkf kjdkf fkjdk fkdkj fkfdj kjdkf dfkfj kfkdj fjkjd"
"djk kjd dfk kfdf jdfk jkjdj"
"l;;l; ;l;;l l;ll; ;;l;l ll;l; l;l;; ;l;ll l;l;l ;;l;l ll;l;"
"lfk ;fk djlf kflf ;fkj kj;f dj;;f ;f;lf ;lfkf dljdf ;f;lfkf"
"assas sassa asaas ssasa aasas asass sasaa asasa ssasa aasas"
"all add; as ask; sad; fas lad dak; dad fad fall; lass gall;"
"alas dald gall; dad flak; lass sad; fass; all fall lad; ask")
("ghhgh hghhg ghggh hhghg gghgh ghghh hghgg ghghg hhghg gghgh"
"gad has aha; had flag gas; sag ash; gag fag dash glag half;"
"gaff; hall hald saga hash; sash gall flag; has dash half"
"rttrt trttr rtrrt ttrtr rrtrt rtrtt trtrr rtrtr ttrtr rrtrt"
"art tad gar at sat rag tag; far jar tar rah hat rat rag tat"
"daft dart jack task; hard tart start grad data talk; shaft rash"
"hart; haft karat halt salt dark; raft draft shark; fart grass"
"graft fast raja shart gard shard tasty lard; fault"
"yuuyu uyuuy yuyyu uuyuy yyuyu yuyuu uyuyy yuyuy uuyuy yyuyu"
"day fly dug lay jay sky lug fur fry try hut; say lady yard"
"lush gay dust shut fray surd lurk usual surf flay just lust"
"vbbvb bvbbv vbvvb bbvbv vvbvb vbvbb bvbvv vbvbv bbvbv vvbvb"
"bad vag bug bar vug vas vat bav bay bat bag bah vast bur"
"baby vagary burst vary burn valuta buy vast vault vulgar by"
"nmmnm mnmmn nmnnm mmnmn nnmnm nmnmm mnmnn nmnmn mmnmn nnmnm"
"ham gun jam ran gum man hen mat nab arm sun may nut tun mil"
"hang damm harm darn farm hung lamb rang sand tang tank many"
"must bank gang busy hand thank bury junk human marry funny"
"numb bush ray black flask bald stuff bask sharp navy hurry")
("iooio oiooi ioiio ooioi iioio ioioo oioii ioioi ooioi iioio"
"hid ill oil for hit out rid dog hot old too sit oat fin aim"
"weewe eweew wewwe eewew wwewe wewee eweww wewew eewew wwewe"
"red tea way leg tie let see owe wet set lie few how sir who"
",..,. .,.., ,.,,. ..,., ,,.,. ,.,.. .,.,, ,.,., ..,., ,,.,."
"why, yes. low, two, was, den. led. ebb, ten, you. new, met."
"xccxc cxccx xcxxc ccxcx xxcxc xcxcc cxcxx xcxcx ccxcx xxcxc"
"act, six icy cub fix cab car. wax cry arc axe, cap cat cod"
"also take, wake late ease, joke sort food obey under beyond"
"exercise hair rare. gold xenon warry; worm shirt luxury soul"
"after death known; early first jewel large offer raise order"
"hotel later ready. agree dirty earth, floor weight water soil"
"night knife; house lunch empty yield; world story where habit")
("zqqzq qzqqz zqzzq qqzqz zzqzq zqzqq qzqzz zqzqz qqzqz zzqzq"
"zoo quit zip quite zoom quick zest zing quake zeal zany"
"p[[p[ [p[[p p[pp[ [[p[p pp[p[ p[p[[ [p[pp p[p[p [[p[p pp[p["
"put opaque [pup puzzle [proposal [prompt plan [pomp lamp"
"']]'/ ]'/]' ']'/] /]']' '/]'] ']'/] ]']/' /]']' ]/']' '']/]"
"plus/minus; acropolis' [appall] miles/hour [cm/sec] per' pair"
"zombie square; poetic /marquee/ question prize [quiz] proper"
"poster. price queen [plate] zippy, reply zero km/h quality;"
"zigzag' porosity, quantity peace/poker camp zodiac damp plan"
"zone quarter. prosperity zirconium' /pound/ power; [press]"
"zipper [zoological] quack, piece proud; pearl. penetrate/")
("mean mean mean mean mean mean mean mean mean mean mean mean"
"jeans jeans jeans jeans jeans jeans jeans jeans jeans jeans"
"echo echo echo echo echo echo echo echo echo echo echo echo"
"thin thin thin thin thin thin thin thin thin thin thin thin"
"disk disk disk disk disk disk disk disk disk disk disk disk"
"dish dish dish dish dish dish dish dish dish dish dish dish"
"dale dale dale dale dale dale dale dale dale dale dale dale"
"oils oils oils oils oils oils oils oils oils oils oils oils"
"path path path path path path path path path path path path"
"last last last last last last last last last last last last"
"land land land land land land land land land land land land"
"pets pets pets pets pets pets pets pets pets pets pets pets"
"mean jeans echo thin disk dish dale oils path last land pets"
"mean jeans echo thin disk dish dale oils path last land pets"
"mean jeans echo thin disk dish dale oils path last land pets"
"mean jeans echo thin disk dish dale oils path last land pets"
"mean jeans echo thin disk dish dale oils path last land pets")
("pound pound pound pound pound pound pound pound pound pound"
"pits pits pits pits pits pits pits pits pits pits pits pits"
"ryas ryas ryas ryas ryas ryas ryas ryas ryas ryas ryas ryas"
"ebbed ebbed ebbed ebbed ebbed ebbed ebbed ebbed ebbed ebbed"
"risk risk risk risk risk risk risk risk risk risk risk risk"
"reeks reeks reeks reeks reeks reeks reeks reeks reeks reeks"
"leak leak leak leak leak leak leak leak leak leak leak leak"
"lens lens lens lens lens lens lens lens lens lens lens lens"
"flux flux flux flux flux flux flux flux flux flux flux flux"
"lave lave lave lave lave lave lave lave lave lave lave lave"
"leis leis leis leis leis leis leis leis leis leis leis leis"
"leaf leaf leaf leaf leaf leaf leaf leaf leaf leaf leaf leaf"
"pound pits ryas ebbed risk reeks leak lens flux leave leis leaf"
"pound pits ryas ebbed risk reeks leak lens flux leave leis leaf"
"pound pits ryas ebbed risk reeks leak lens flux leave leis leaf"
"pound pits ryas ebbed risk reeks leak lens flux leave leis leaf"
"pound pits ryas ebbed risk reeks leak lens flux leave leis leaf")
("lief lief lief lief lief lief lief lief lief lief lief lief"
"lazy lazy lazy lazy lazy lazy lazy lazy lazy lazy lazy lazy"
"keno keno keno keno keno keno keno keno keno keno keno keno"
"quack quack quack quack quack quack quack quack quack quack"
"knife knife knife knife knife knife knife knife knife knife"
"jack jack jack jack jack jack jack jack jack jack jack jack"
"chap chap chap chap chap chap chap chap chap chap chap chap"
"sock sock sock sock sock sock sock sock sock sock sock sock"
"keys keys keys keys keys keys keys keys keys keys keys keys"
"obey obey obey obey obey obey obey obey obey obey obey obey"
"men's men's men's men's men's men's men's men's men's men's"
"caps caps caps caps caps caps caps caps caps caps caps caps"
"lief lazy keno quack knife jack chap sock keys obey men's caps"
"lief lazy keno quack knife jack chap sock keys obey men's caps"
"lief lazy keno quack knife jack chap sock keys obey men's caps"
"lief lazy keno quack knife jack chap sock keys obey men's caps"
"lief lazy keno quack knife jack chap sock keys obey men's caps")
("vale vale vale vale vale vale vale vale vale vale vale vale"
"back back back back back back back back back back back back"
"bans bans bans bans bans bans bans bans bans bans bans bans"
"bags bags bags bags bags bags bags bags bags bags bags bags"
"tins tins tins tins tins tins tins tins tins tins tins tins"
"gift gift gift gift gift gift gift gift gift gift gift gift"
"grit grit grit grit grit grit grit grit grit grit grit grit"
"herb herb herb herb herb herb herb herb herb herb herb herb"
"hand hand hand hand hand hand hand hand hand hand hand hand"
"vile fine vent vale back bans bags tins gift grit herb hand"
"vile fine vent vale back bans bags tins gift grit herb hand"
"vile fine vent vale back bans bags tins gift grit herb hand"
"vile fine vent vale back bans bags tins gift grit herb hand"
"vile fine vent vale back bans bags tins gift grit herb hand")
("78878 87887 78778 88787 77878 78788 87877 78787 88787 77878"
"mean7 jeans8 echo7 thin8 disk7 dish8 dale7 oils8 path7 last8"
"56656 65665 56556 66565 55656 56566 65655 56565 66565 55656"
"land5 pets6 pound8 pits7 ryas5 ebbed6 risk5 reeks7 leak8 lens6"
"90090 09009 90990 00909 99090 90900 09099 90909 00909 99090"
"flux9 lave0 leis7 leaf0 lief6 lazy9 keno5 quack9 knife8 jack0"
"34434 43443 34334 44343 33434 34344 43433 34343 44343 33434"
"chap3 sock4 keys3 obey0 men's7 caps4 vile3 fine4 vent6 vale4"
"-==-= =-==- -=--= ==-=- --=-= -=-== =-=-- -=-=- ==-=- --=-="
"back= bans- bags3 tins- gift4 grit= herb5 hand= pink7 chin="
"12212 21221 12112 22121 11212 12122 21211 12121 22121 11212"
"cash2 come1 earn= evil2 form- join3 vote1 deck6 fern2 zeal1"
"only6 pain3 sale3 rank0===king7 5bait5 3 5deny5 3 4find42-10"
"`\\\\`\\ \\`\\\\` `\\``\\ \\\\`\\` ``\\`\\ `\\`\\\\ \\`\\`` `\\`\\` \\\\`\\` ``\\`\\"
"7-5=12\\ 8-3=11 9-3=12 6-4=10 3-2=5 9-7=16 8-6=14\\ 9-8=17 6-2=8"
"49-1=10\\ 4-7=11 6-9=15 2-8=10 3-4=7\\ 8-5=13 9-3=12 4-6=10 5-4=9")
("GHDJY GYDUC Z:CCH HGXCD V:JPR JGKXG JDJEG YLG<N JENGT CJGCY"
"GTY<D FGYDH KYNUN RDA:G F,DUJ LPDUY RLCPF GCGGD YAFCJ YGEXR"
"RPVDC D,\"DV BVXCN TWYPY DNBTG AGLYV RFKBD HYPVL YRPJC G<H:X"
"MAGIC RIVER MONEY NOISE PAPER WOMAN EVENT ANGRY COVER METAL"
"COMPANY HORSES HAPPY SPECIAL VENTURE CHANGE RETURN KNIGHT")
("! @! @ !@! @ ! @!! ! @! @@ !@@ @ ! !@ @ !!@ !@ ! @! @ @! !@@"
"@song ! song @! song @ song !@ song ! song @@! song @ song !!"
"# $# #$$ $# $#$ # $ $ ##$ # $# $ #$# # $#$ #$ $ # $$# $ #$$"
"rain $ rain #$ rain ##$ rain # rain $# rain $ rain $# rain $"
"%^ ^ %%^ % ^% ^ %^% ^^ % ^%^ ^ %^ % ^%% ^% ^ %^^ % ^^% % ^%^"
"pale %@ pale @ pale @%@ pale % pale %@ pale @% pale @ pale %"
"& *& * &*& * *&& & *& ** &** & * &* * &&* &* & *& * *& &* **"
"calf & calf *& calf * calf &*& calf & calf **& calf * calf &"
"() ) ( ))( ( )( ()( ) () ))( ( ) ))( )( ) (() )( ( )() () (("
"mask ( mask )( mask) mask ( mask )() mask ) mask () mask )("
"+ _ _+_ _+ _ __+ +_+ _ ++ _+ + _ ++_ _ + +_+ _ +_ + _+ + _+_"
"mine _ mine +_ mine _+_ mine + mine _+ mine + mine _ mine _+"
"coal (@ coal *# coal ) coal $^ coal #_ coal )% coal & coal ^"
"face $ face #( face $% face * face ^_ face @ face ) face %&@"
"deal *$ deal )# deal ( deal &@ deal %^ deal &_ deal $ deal @"
"view & view @# view (_) view $ view * view % view ^_ view &$"
"maid ^ maid &# maid * maid (% maid )$ maid #_ maid & maid %#"
"task * task $( task )@^ task % task *_ task # task ) task &$"
"part % part #^ part &( part ) part $ part &_ part ^#* part ^"
"*!^+@# (!$+@@ )!$+@# &!%+!_ $!#+^ )!*+@& (!&+@% )!(+@* &!#+("
")!@+@_ %!*+@@ &!)+@^ #!(+@_ $!%+* (!^+@$ )!$+@# %!&+@_ ^!%+)")
("ouoie uaueo iyaei yoeia eyaie uaoyi oyaey iyoeo iouya eaiyu"
"ieyoi auyei oeaui eyaey oyuae eyoei uyieo aeoyi yioae oiyeu"
"aeoua ieyoa uaeoe iaeoa ueaya aeyoi uaeoy eioae uaeya ioeia"
"oeiau yoeie ieaua ieyei auaeo yoieu aeyoi auioy eaiae uoaie"
"oyeao ieauy ioeya aueai oaeya iueie yoeau eioei aeyei iyuoa")
("gowof hrocj ayxle rfkqk dugpw cjxln dma]e xjnup skxnz rmokl"
"aixle rlnlb dmywg tvprh lumtk ajrmw heomc zlnuk pfpex ndlyv"
"nsptn bwitk zopsw vkstg mdibw auvle quvkn smrkx nithd krihx"
"odmyl dlekh xutnv cmdiw lwubr hcken amrug ltnxp kwoby cysna"
"kruxm aodnw ylq]s kpayc xuspg nzkej iehxf krmxl hsitb dmysk")
("ing ing ing ing ing ing ing ing ing ing ing ing ing"
"tion tion tion tion tion tion tion tion tion tion tion"
"ment ment ment ment ment ment ment ment ment ment ment"
"ure ure ure ure ure ure ure ure ure ure ure ure ure ure"
"sion sion sion sion sion sion sion sion sion sion sion"
"ous ous ous ous ous ous ous ous ous ous ous ous ous ous"
"our our our our our our our our our our our our our our"
"er or er or er or er or er or er or er or er or er or"
"tch tch tch tch tch tch tch tch tch tch tch tch tch tch"
"ck ch ck ch ck ch ck ch ck ch ck ch ck ch ck ch ck ch ck"
"ea ea ea ea ea ea ea ea ea ea ea ea ea ea ea ea ea ea ea"
"er er er er er er er er er er er er er er er er er er er"
"the ht the ht the ht the ht the ht the ht the ht the ht the"
"ght ght ght ght ght ght ght ght ght ght ght ght ght ght ght"
"es ly es ly es ly es ly es ly es ly es ly es ly es ly es ly")
("1. A bad workman quarrels with his tools."
"2. Better a glorious death than a shameful life."
"3. Calamity is man's true touchstone."
"4. Eat at pleasure, drink with measure."
"5. He who pleased everybody died before he was born."
"6. Jack of all trades and master of none."
"7. Keep a thing seven years and you will find a use for it."
"8. Make hay while the sun shine."
"9. Between two stools one falls to the ground."
"10. Roll my log and I will roll yours."
"11. Scornful dogs will eat dirty puddings."
"12. We never know the value of water till the well is dry."
"13. Old birds are not to be caught with chaff."
"14. Zeal without knowledge is a runaway horse."
"15. Better die standing than live kneeling.")
("1. The young journalist was sent to get a personal interview"
"with a rich old merchant. His newspaper wanted a story"
"on how he made himself rich. \"Well, it is a long story\","
"said the old man, \"and while I'm telling it, we'll save"
"the candle\". And he blew it out at once. \"Never mind about"
"the story\", said journalist. \"I understand\"."
"2. What a good companion and true friends the dog is!"
"He will guard your life if something happens to you."
"He will work for you if you train him. He will hunt for you."
"He will swim rivers to get to you. He will play with you."
"The dog is very clever. He is the only animal who always"
"knows his master, and the friends of his family."
"He knows his master by the tone of his voice and even by"
"his looks. All the dogs were wild once. They belonged"
"to the same family as the wolf and the fox. But people"
"tamed them, and now dogs are very useful to man."
"There are many kinds of dogs.")
))
;; ((string skills) (exercise skills))
;; ((simbols/minute disrhithm_chars/all_chars errors/all-chars))
(setq virt-skills '(((0 .4 .04) (100 .4 .02)) 
                    ((0 .3 .02) (150 .3 .01))
                    ((0 .2 .005) (200 .2 .005))))
(setq virt-skill 0) ;; default skill
;; ---- scores ---- position -----------
(setq virt-width (window-width))
(setq virt-height (window-height))
(setq virt-ex-y (floor virt-height 2));; "Y position where words begin")
(setq virt-score-x (/ virt-width 3)) ;; "X position to show scores")
(setq virt-score-y (- virt-height 3));; "Y pos to show scores")
(setq virt-l-score-x (* (/ virt-width 3) 2));; "X pos to show local scores")
(setq virt-l-score-y (- virt-height 3));; "Y pos to show local scores")
(setq virt-speed-y (- virt-height 3));; "Y position where to show cur speed")
(setq virt-speed-x 3)                ;; "X position where to show cur speed")
(setq virt-cx 0)                     ;; "X cursor position")
(setq virt-cy 0)                     ;; "X cursor position")
(setq virt-l-cc 0)                   ;; "local chars counter 
                                     ;; 1 to prevent devision bye zero
;; ---- scores ---- local -- and -- global -------
(defun virt-null-scores ()
  (setq virt-l-dr 0)      ;; local rhythm
  (setq virt-l-errors 0);; "local errors")
  (setq virt-dr 0) ;;       "global disrhythm")
  (setq virt-dr-timestamp 0) ;; average of keystrokes in (high-16-bits low-16bits milisecs)
  (setq virt-errors 0);;   "global errors")
  (setq virt-speed 0 );;   "current type speed")
  (setq virt-cc 0)
)
;; ----- vezde odinakovye -------------
(defun virt-draw-scores ()
  (let ((strings (vector (format "l_disrhythm: %f %%" (/ (* virt-l-dr 100.0) virt-l-cc))
                         (format "l_errors:   %f %%" (/ (* virt-l-errors 100.0) virt-l-cc)))))
    (loop for y from 0 to 1 do
          (let ((string (aref strings y)))
                (virt-pr-cell   virt-l-score-x (+ virt-l-score-y y) string))))
  (let ((strings (vector (format "disrhythm: %f %%" (/ (* virt-dr 100.0) virt-cc)) 
                         (format "errors:   %f %%" (/ (* virt-errors 100.0) virt-cc)))))
    (loop for y from 0 to 1 do
          (let ((string (aref strings y)))
                  (virt-pr-cell virt-score-x (+ virt-score-y y) string))))
  (let ((string (format "speed: %05d" virt-speed)))
          (virt-pr-cell  virt-speed-x virt-speed-y string))
  (virt-topos virt-cx virt-cy)
)
(defun virt-pr-cell (x y str)
   (virt-topos x y)
   (delete-char (length str))
   (insert str)
)

(defun virt-topos (col row)
   (goto-line row)
   (beginning-of-line)
   (forward-char col)
)
(defun virt-center (len)
   (/ (- virt-width len) 2)
)
(defun virt-on-error ()
  (setq virt-l-errors (+ virt-l-errors 1))
  (setq virt-errors (+ virt-errors 1))
  (virt-draw-scores)
)
;; draw one line
(defun virt-draw-str (x)
   (setq virt-cy (- (/ virt-height 2) 3))
   (setq virt-cx (virt-center (length x)))
   (virt-topos virt-cx virt-cy)
   (insert (format "%s\n" x))
   (virt-draw-scores)
)

;; num is taken from virt-do-ex
(defun virt-key-down ()
  (let ((keyd (next-event nil (format "exercise %d" num))))
   (while (not (key-press-event-p keyd)) (setq keyd (next-event nil (format "exercise %d" num))))
     (let ((kd (event-key keyd)))
     (cond ((and (eq kd ?s) (equal (event-modifiers keyd) '(control))) (call-interactively 'virt-set-skill) (virt-key-down))
	 ((equal kd 'space) (string-to-char " "))
         ((and (eq kd ?n) (equal (event-modifiers keyd) '(control))) (throw 'end-ex nil))
         ((and (eq kd ?p) (equal (event-modifiers keyd) '(control))) (throw 'end-ex t))
	 ((and (eq kd ?g) (equal (event-modifiers keyd) '(control))) (throw 'end-virt t))
         (t  kd)
   ))
  )
)
;; get time in form secs.millisecs
(defun virt-time (time)
  (setq rtime (+ (nth 1 time) (/ (nth 2 time) 1000000.0)))
)

;; helpfull func '(1 2 3) '(2 3 5) -> (-1 -1 -2)
(defun virt-list-min (list1 list2)
  (let ((list nil))
    (loop for i from (- (min (length list1) (length list2)) 1) downto 0 do
     (setq list (cons (- (nth i list1) (nth i list2)) list)))
     list)
)
;; (in elem list) t if elem in list
(defun in (elem list)
  (cond ((null list) nil)
        ((eq elem (car list)) t)
        (t (in elem (cdr list)))
  )
)
;; do exercise number ``num''
(defun virt-do-ex (num skill)
  (catch 'end-ex
  (virt-null-scores)
  (loop for i in (nth num ex) do
    (setq virt-cc (+ virt-cc (length i)))
  )
  (let ((lind 0)
        (ind 0))
   (while (< lind (length (nth num ex)))
     (setq virt-l-cc 1)
     (setq begin-time (virt-time (current-time)))
     (setq virt-l-errors 0)
     (setq virt-l-dr 0)
     (erase-buffer)
     (let ((i 0))
        (while (< i virt-width)
          (setq i (+ i 1))
          (insert-char ?\ (1- virt-width))
          (insert ?\n)
        )
     )
     (insert-char ?= (1- virt-width))
     (setq x (nth lind (nth num ex)))
     (virt-draw-str x)
     (setq virt-l-cc (length x))
     (while (< ind virt-l-cc) 
       (while (not (eq (virt-key-down) (aref x ind)))
          ;; error occured
          (virt-on-error)
          (beep)
          (setq virt-time (current-time))
       )
       ;; char is typed correctly
       ;; calculate disrhythm
       (cond ((eq 0 ind) (setq virt-time (current-time)))
             ((eq 1 ind) (setq virt-dr-timestamp (virt-list-min (current-time) virt-time)))
             ((> ind 1)
                (let ((raz (virt-list-min (current-time) virt-time)) (virt-cur-time (current-time)))
	        (if (> (/ (abs (- (virt-time raz) (virt-time virt-dr-timestamp))) (virt-time virt-dr-timestamp)) (nth 1 (nth 0 (nth skill virt-skills))))
                  (let ()
                    (setq virt-dr (+ virt-dr 1))
	            (setq virt-l-dr (+ virt-l-dr 1))
                  )
                nil)
                (let ((temp-dr-time virt-dr-timestamp))
                (loop for i from 2 downto 0 do
                 (let ((virt-dr-timestamp nil))
                  (setq virt-dr-timestamp (cons (/ (+ (nth i temp-dr-time) (nth i raz)) 2) virt-dr-timestamp)))))
                (setq virt-time (current-time))
                ))
       )
       (setq ind (+ ind 1))
       (delete-char 1)
       (insert " ")
       (setq virt-cx (+ virt-cx 1))
       (virt-draw-scores)
     )
     ;; count speed
     (let ((virt-speed-time (- (virt-time (current-time)) begin-time)))
          (if (eq 0 lind)
             (setq virt-speed (round (/ (* (length x) 60) virt-speed-time)))
             (setq virt-speed (/ (+ virt-speed (round (/ (* (length x) 60) virt-speed-time))) 2))
          )
     )
     ;; end count
     ;; check results
     (if (or (> (/ virt-l-errors (+ (length x) 0.0)) (nth 2 (nth 0 (nth skill virt-skills)))) (> (/ virt-l-dr (+ (length x) 0.0)) (nth 1 (nth 0 (nth skill virt-skills))))) 
        nil
        (setq lind (+ lind 1))
     )
     (setq ind 0)
     (insert "\n")
   )
  )nil)
)

(defun virt-set-skill (key)
   (interactive "kset skill 0 or 1 or 2:\n")
   (if (not (in (event-key (aref key 0)) '(?0 ?1 ?2))) (call-interactively 'virt-set-skill) (setq virt-skill (- (char-to-int (event-key (aref key 0))) 48)) t)
)
(defun virt-mode ()
   (call-interactively 'virt-set-skill)
   (interactive)
   (setq major-mode 'virt-mode)
   (setq mode-name "Virt")
   (catch 'end-virt
   (let ((i 0))
     (while (< i (length ex))
       (if (virt-do-ex i virt-skill) (if (> i 0) (setq i (- i 1)) (setq i (- (length ex) 1)))
       ;; check results
       (if (or (< (/ virt-errors  virt-cc) (nth 2 (nth 1 (nth virt-skill virt-skills)))) (< (/ virt-dr virt-cc) (nth 1 (nth 1 (nth virt-skill virt-skills)))) (> virt-speed (nth 0 (nth 1 (nth virt-skill virt-skills)))) (eq virt-speed 0)) (setq i (+ i 1))))
     )
   ))
   (erase-buffer)
   (if (yes-or-no-p "again? ") (virt-mode) (kill-buffer nil))
)
(defun virt ()
   (interactive)
   (switch-to-buffer "*virt*")
   (virt-mode)
)
Hosted by uCoz