]> git.cworth.org Git - mnemon/commitdiff
Merge branch 'master' into image
authorCarl Worth <cworth@cworth.org>
Sat, 28 Mar 2009 18:00:43 +0000 (11:00 -0700)
committerCarl Worth <cworth@cworth.org>
Sat, 28 Mar 2009 18:00:43 +0000 (11:00 -0700)
1  2 
mnemon.c

diff --combined mnemon.c
index d0a960909d43eb5ea8539fa67f78bb1b1c530812,33f2c260132a6efff082da9989da5ca6be6ef739..74eb2c0a036034f44cba334861845afc863d1e6b
+++ b/mnemon.c
@@@ -55,11 -55,6 +55,11 @@@ typedef enum 
      CATEGORY_ORDER_SEQUENTIAL
  } category_order_t;
  
 +typedef enum {
 +    CHALLENGE_TYPE_TEXT,
 +    CHALLENGE_TYPE_IMAGE
 +} challenge_type_t;
 +
  typedef struct _category {
      char *name;
      int items_size;
@@@ -71,8 -66,6 +71,8 @@@
      /* Support categories where responses are timed (0.0 == disable). */
      double time_limit;
      int bin_zero_head;
 +    /* Support challenges of non-text types (image, audio, etc.) */
 +    challenge_type_t challenge_type;
  } category_t;
  
  typedef struct _mnemon {
@@@ -200,7 -193,6 +200,7 @@@ category_init (category_t *category
      category->order = CATEGORY_ORDER_RANDOM;
      category->time_limit = 0.0;
      category->bin_zero_head = 0;
 +    category->challenge_type = CHALLENGE_TYPE_TEXT;
  }
  
  static void
@@@ -270,17 -262,6 +270,17 @@@ category_print (category_t       *category
      fprintf (file, "time = %f\n\n",
             category->time_limit);
  
 +    fprintf (file, "challenge = ");
 +    switch (category->challenge_type) {
 +    case CHALLENGE_TYPE_TEXT:
 +      fprintf (file, "text");
 +      break;
 +    case CHALLENGE_TYPE_IMAGE:
 +      fprintf (file, "image");
 +      break;
 +    }
 +    fprintf (file, "\n\n");
 +
      for (i = 0; i < category->num_items; i++) {
        item = &category->items[i];
        if (i != 0)
@@@ -597,7 -578,7 +597,7 @@@ mnemon_load_category (mnemon_t             *mnemon
  
        /* An initial digit means we hit an item. Trigger the
         * spaghetti machine. */
-       if (*line >= '0' && *line <= '9')
+       if ((*line >= '0' && *line <= '9') || *line == '-')
            goto PARSE_BIN;
  
        equal = strchr (line, '=');
                         value, path, line_count);
                exit (1);
            }
 +      } else if (strcmp (name, "challenge") == 0) {
 +          if (strcmp (value, "text") == 0) {
 +              category->challenge_type = CHALLENGE_TYPE_TEXT;
 +          } else if (strcmp (value, "image") == 0) {
 +              category->challenge_type = CHALLENGE_TYPE_IMAGE;
 +          } else {
 +              fprintf (stderr, "Unknown value for \"challenge\" option \"%s\" at %s:%d\n",
 +                       value, path, line_count);
 +              exit (1);
 +          }
        } else {
            fprintf (stderr, "Unknown option %s at %s:%d\n",
                     name, path, line_count);
@@@ -894,9 -865,20 +894,20 @@@ mnemon_select_item (mnemon_t      *mnemon
      category_t *category;
  
      bin_index = rand_within_exponential (mnemon->num_bins);
      bin = &mnemon->bins[bin_index];
  
+     /* The most intuitive understanding of the to_introduce counter is
+      * that it's tracking never-before-learned items as they are
+      * pulled from the bin with score 0. But that bin can become
+      * empty. So the refined rule is that we decrement to_introduce
+      * whenever we pull from the lowest-indexed bin with a
+      * non-negative score. */
+     if (mnemon->to_introduce && bin->score >=0 &&
+       (bin_index == 0 || mnemon->bins[bin_index-1].score < 0))
+     {
+       mnemon->to_introduce--;
+     }
      item_index = rand_within (bin->num_items);
  
      item = bin->items[item_index];
@@@ -1131,35 -1113,6 +1142,35 @@@ mnemon_handle_response (mnemon_t      *mnemo
      bin_add_item (bin, item);
  }
  
 +static void
 +mnemon_show_image (mnemon_t *mnemon, const char *filename)
 +{
 +    char *command;
 +
 +    /* XXX: Yes, shelling out to system is total cheese. The planned
 +     * fix here is to bring graphical display in process, (or at least
 +     * have a custom external program that accepts image filenames on
 +     * stdin.
 +     */
 +    xasprintf (&command, "xli -gamma 2.2 %s >/dev/null 2>&1 &",
 +             filename);
 +    system (command);
 +    free (command);
 +}
 +
 +static void
 +mnemon_hide_image (mnemon_t *mnemon)
 +{
 +    char * command;
 +
 +    /* XXX: And this is just embarrassing (obviously wrong in several
 +     * ways). Hopefully I'll amend away any commit that includes this.
 +     */
 +    xasprintf (&command, "killall xli");
 +    system (command);
 +    free (command);
 +}
 +
  static void
  mnemon_do_challenges (mnemon_t *mnemon)
  {
        mnemon_select_item (mnemon, &bin, &item_index, &category);
        item = bin->items[item_index];
  
-       if (bin->score == 0)
-           mnemon->to_introduce--;
        while (1) {
            if (category->time_limit > 0.0) {
                response = readline ("The next one is timed. Press enter when ready:");
                free (response);
            }
 -              
 -          printf ("%s\n", item->challenge);
 +
 +          switch (category->challenge_type) {
 +          case CHALLENGE_TYPE_TEXT:
 +              printf ("%s\n", item->challenge);
 +              break;
 +          case CHALLENGE_TYPE_IMAGE:
 +              {
 +                  char *absolute_filename;
 +
 +                  xasprintf (&absolute_filename, "%s/%s",
 +                             mnemon->dir_name, item->challenge);
 +                  mnemon_show_image (mnemon, absolute_filename);
 +                  free (absolute_filename);
 +              }
 +              break;
 +          }
  
            gettimeofday (&start, NULL);
            response = readline ("> ");
            gettimeofday (&end, NULL);
  
 +          if (category->challenge_type == CHALLENGE_TYPE_IMAGE)
 +              mnemon_hide_image (mnemon);
 +
            /* Terminate on EOF */
            if (response == NULL) {
                printf ("\n");