home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume21 / kdrill / part01 / game.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-07  |  7.3 KB  |  342 lines

  1. #include <stdio.h>
  2. #include <X11/Xlib.h>
  3. #include <X11/Xatom.h>
  4. #include <X11/Xutil.h>
  5. #include <Intrinsic.h>
  6. #include <StringDefs.h>
  7. #include <Xaw/Command.h>
  8.  
  9. #include "defs.h"
  10. #include "externs.h"
  11.  
  12. int values[4];
  13. int truevalue;
  14. int Kanji2English=GUESSKANJI;
  15. int showEnglish = True;
  16. int doBell = True;
  17.  
  18. extern Display *display;
  19. extern Window mainwindow;
  20.  
  21. int englishwidth=7;
  22. int englishheight=11;
  23.  
  24. /* setstatus:
  25.  *  sets label for main status bar widget.
  26.  *    ( the long one at the bottom)
  27.  */
  28. void setstatus(s)
  29. char *s;
  30. {
  31.     XtVaSetValues(statusline,
  32.               XtNlabel,s,
  33.               NULL);
  34. }
  35.  
  36. /*
  37. *UseThisKanji()
  38. *    Returns Boolean value on whether this is a "valid" kanji for us,
  39. *    based on usefile markings,
  40. *    current grade set,
  41. *    and whether it has english/kana translation
  42. */
  43. Boolean UseThisKanji(kanji)
  44. struct translationstruct *kanji;
  45. {
  46.     /* nonexistant? */
  47.     if(kanji == NULL) return False;
  48.  
  49.     /* "do not read", set by inituse ?*/
  50.     if(kanji == (void *) 1) return False; 
  51.  
  52.     if(showEnglish){
  53.         if(kanji->english == NULL)
  54.             return False;
  55.         if(kanji->english[0] == '\0')
  56.             return False;
  57.     } else {
  58.         /* we're supposed to be showing kana.. are there any? */
  59.         if(kanji->pronunciation == NULL)
  60.             return False;
  61.     }
  62.  
  63.     /* only thing left is to check grade level */
  64.  
  65.     if(gradelevel == 0)
  66.         return True;
  67.     if(kanji->grade_level == 0)
  68.             return False;
  69.  
  70.     if(kanji->grade_level > gradelevel)
  71.         return False;
  72.  
  73.     return True;    
  74. }
  75.  
  76.  
  77. /* CountKanji
  78.  *This routine gets called a hell of a lot:
  79.  *    When we change grade level, and
  80.  *    when we change kana/english display.
  81.  *     (the secnd being because kanjidic does not always have
  82.  *     english and/or kana listings
  83.  */
  84. void CountKanji(){
  85.     int counter;
  86.     numberofkanji=0;
  87.     for(counter=lowest;counter <=highest;counter++){
  88.         if(UseThisKanji(translations[counter])){
  89.             numberofkanji++;
  90.         }
  91.     }
  92. }
  93.  
  94. /* pickkanji:
  95.  *   picks an acceptably random kanji char
  96.  */
  97.  
  98. int pickkanji(){
  99.     int rand_kanji,count;
  100.     
  101.  
  102.     rand_kanji = random()%numberofkanji;
  103.  
  104.     for(count=lowest;count<=highest;count++){
  105.         if(UseThisKanji(translations[count])){
  106.               rand_kanji--;
  107.               if(rand_kanji <0)
  108.               return count;
  109.         }
  110.     }
  111.     fprintf(stderr,"Internal error: picked kanji out of range");
  112.     return 0;
  113.  
  114. }
  115.  
  116. /* printkanji:
  117.  *    updates all the kanji buttons.
  118.  */
  119.  
  120. void printkanji(){
  121.     int i,knum;
  122.     XChar2b onecharstring[2];
  123.  
  124.     onecharstring[1].byte1 = onecharstring[1].byte2 = 0;
  125.  
  126.     if(Kanji2English == GUESSKANJI){
  127.         knum = values[truevalue];
  128.         onecharstring[0].byte1 = (knum & 0xff00)>>8;
  129.         onecharstring[0].byte2 = (knum & 0x00ff);
  130.  
  131.         XtVaSetValues(kanjiWidget[0],XtNlabel,onecharstring,NULL);
  132.         XtVaSetValues(kanjiWidget[1],XtNlabel,"  ",NULL);
  133.         XtVaSetValues(kanjiWidget[2],XtNlabel,"  ",NULL);
  134.         XtVaSetValues(kanjiWidget[3],XtNlabel,"  ",NULL);
  135.         return;
  136.     }
  137.     /* else */
  138.     for(i=0;i<4;i++) {
  139.         knum = values[i];
  140.  
  141.         onecharstring[0].byte1 = (knum & 0xff00)>>8;
  142.         onecharstring[0].byte2 = (knum & 0x00ff);
  143.  
  144.  
  145.         XtVaSetValues(kanjiWidget[i],
  146.                   XtNlabel,onecharstring,
  147.                   XtNsensitive,True,
  148.                   NULL);
  149.  
  150.     }
  151. }
  152.  
  153. /* SetWidgetLabel:
  154.  *    Convenience function to
  155.  *    set label of four lines of english/kana.
  156.  *    Will change fonts, dependant on "showEnglish"
  157.  */
  158. void SetWidgetLabel(widget,Tnum)
  159. Widget widget;
  160. int Tnum;
  161. {
  162.  
  163.     if(showEnglish == True){
  164.         XtVaSetValues(widget,
  165.                  XtNencoding,XawTextEncoding8bit,
  166.                  XtNfont,fixedfont,
  167.                  XtNlabel,translations[Tnum]->english,
  168.                  NULL);
  169.     } else {
  170.         XtVaSetValues(widget,
  171.                  XtNencoding,XawTextEncodingChar2b,
  172.                  XtNfont,smallkfont,
  173.                  NULL);
  174.         XtVaSetValues(widget,
  175.                   XtNlabel,translations[Tnum]->pronunciation,
  176.                   NULL);
  177.     }
  178. }
  179. /* printenglish()
  180.  *  similar to printkanji()
  181.  *  updates all "english" labels...
  182.  *  EXCEPT: sometimes we want then to print kana! :-) so we use
  183.  *  SetWidgetLabel() to do the correct type
  184.  */
  185. void printenglish(){
  186.     int i;
  187.  
  188.     /* we must be guessing which character for one meaning */
  189.     if(Kanji2English == GUESSMEANING){
  190.         SetWidgetLabel(englishWidget[0],values[truevalue]);
  191.         XtVaSetValues(englishWidget[1],XtNlabel,"  ",XtNsensitive,False,NULL);
  192.         XtVaSetValues(englishWidget[2],XtNlabel,"  ",XtNsensitive,False,NULL);
  193.         XtVaSetValues(englishWidget[3],XtNlabel,"  ",XtNsensitive,False,NULL);
  194.         return;
  195.     }
  196.     /* ELSE */
  197.     /* we have all FOUR  active for picking*/
  198.     for(i=0;i<4;i++){
  199.         XtVaSetValues(englishWidget[i],XtNsensitive,True,NULL);
  200.         SetWidgetLabel(englishWidget[i],values[i]);
  201.     }
  202. }
  203.  
  204.  
  205. /* kanjitoenglish
  206.  *    sets up question...
  207.  *    { "what does this symbol? choose one of the four choices"}
  208.  *    
  209.  *    then returns, presumably falling back to XtAppMainLoop()
  210.  *
  211.  *    guesskanji == GUESSKANJI : give kanji, and user guesses the meaning
  212.  *                    int English
  213.  *    guesskanji == GUESSENGLISH : give english, and user guesses which
  214.  *                    kanji fits best. 
  215.  */
  216. void kanjitoenglish(guesskanji)
  217. int guesskanji;
  218. {
  219.     int doloop;
  220.     Kanji2English=guesskanji;
  221.  
  222.     /* determine which value will be correct one.. */
  223.     truevalue = random() %4;
  224.  
  225.     /* hack for random numbers...
  226.      * only picks values that are acceptable by our current
  227.      *  "usefile"
  228.      */
  229.     values[0] = pickkanji();
  230.     values[1] = pickkanji();
  231.     values[2] = pickkanji();
  232.     values[3] = pickkanji();
  233.  
  234.     /* now weed out duplicates.. */
  235.     doloop = 0;
  236.     do{
  237.         if((values[0] == values[1]) || (values[0] == values[2])
  238.             || values[0] == values[3] ){
  239.             values[0] = pickkanji();
  240.             doloop=1;
  241.         } else
  242.         if(values[1] == values[2] || values[1] == values[3]){
  243.             values[1] = pickkanji();
  244.             doloop=1;
  245.         } else 
  246.         if(values[2] == values[3]){
  247.             values[2] = pickkanji();
  248.             doloop=1;
  249.         } else
  250.             doloop = 0;
  251.     }while(doloop);
  252.  
  253.     DescribeCurrent(values[truevalue]);
  254.  
  255.     printkanji();    /* update labels */
  256.     printenglish(); /* likewise      */
  257.     switch(guesskanji){
  258.         case GUESSKANJI:
  259.             XtVaSetValues(kanjimode,XtNsensitive,False,NULL);
  260.             XtVaSetValues(englishmode,XtNsensitive,True,NULL);
  261.             break;
  262.         case GUESSMEANING:
  263.             XtVaSetValues(kanjimode,XtNsensitive,True,NULL);
  264.             XtVaSetValues(englishmode,XtNsensitive,False,NULL);
  265.             break;
  266.     }
  267.     
  268. }
  269.  
  270.  
  271. /* englishcallback:
  272.  *    Handles clicking on "english" widgets.
  273.  *    Only really neccessary if we are guessing the meaning of a
  274.  *    kanji character
  275.  */
  276. void englishcallback(w,data,calldata)
  277. Widget w;
  278. XtPointer data;XtPointer calldata;
  279. {
  280.     if(Kanji2English!= GUESSKANJI)
  281.         return;
  282.     if(data == (XtPointer) truevalue){
  283.         setstatus("Correct!");
  284.         kanjitoenglish(GUESSKANJI);
  285.     } else {
  286.         if(doBell)
  287.             XBell(display,100);
  288.         setstatus("Incorrect.");
  289.     }
  290.  
  291. }
  292.  
  293. /*
  294.  *handles top four kanji buttons at top
  295.  */
  296. void kanjicallback(w,data,calldata)
  297. Widget w;XtPointer data;XtPointer calldata;
  298. {
  299.     if(Kanji2English != GUESSMEANING)
  300.         return;
  301.     if(data == (XtPointer) truevalue){
  302.         setstatus("Correct!");
  303.         kanjitoenglish(GUESSMEANING);
  304.     } else {
  305.         if(doBell)
  306.             XBell(display,100);
  307.         setstatus("Incorrect.");
  308.     }
  309. }
  310.  
  311.  
  312. /* changemode:
  313.  *   change from guessing kanji to guessing english, or vica verse,
  314.  *    by clicking on the appropriate button
  315.  *
  316.  *   Also handles changing from english <->kana display,
  317.  *   calling CountKanji(), because we have to .
  318.  */
  319. void ChangeMode(w,data,calldata)
  320. Widget w;XtPointer data;XtPointer calldata;
  321. {
  322.     int whichbutton = (int) data;
  323. #ifdef DEBUG
  324.     printf("button mode change: %d\n",whichbutton);
  325. #endif
  326.     switch(whichbutton){
  327.         case GUESSMEANING:
  328.         case GUESSKANJI:
  329.             kanjitoenglish(whichbutton);
  330.             break;
  331.         case TOGGLEKANA:
  332. #ifdef DEBUG
  333.             puts("We toggle kana/english now");
  334. #endif
  335.             showEnglish = !showEnglish;
  336.             CountKanji();
  337.             kanjitoenglish(Kanji2English);
  338.             break;
  339.     }
  340. }
  341.  
  342.