else if (mnemon->bins[i].count > count)
break;
- mnemon_bins_grow (mnemon);
+ if (mnemon->num_bins == mnemon->bins_size)
+ mnemon_bins_grow (mnemon);
bin = &mnemon->bins[i];
/* Make room to insert new bin at its sorted location. */
- memmove (bin + 1, bin, (mnemon->num_bins - i) * sizeof (bin_t));
+ if (i < mnemon->num_bins)
+ memmove (bin + 1, bin, (mnemon->num_bins - i) * sizeof (bin_t));
mnemon->num_bins++;
bin_init (bin, count);
{
int i = bin - mnemon->bins;
+ bin_fini (bin);
+
memmove (bin, bin + 1, (mnemon->num_bins - i) * sizeof (bin_t));
mnemon->num_bins--;
}
err = rename (lock_filename, filename);
if (err < 0) {
- fprintf (stderr, "Error: Failes to rename %s to %s: %s\n",
+ fprintf (stderr, "Error: Failed to rename %s to %s: %s\n",
lock_filename, filename, strerror (errno));
continue;
}
}
static void
-mnemon_do_challenges (mnemon_t *mnemon)
+mnemon_do_challenges (mnemon_t *mnemon,
+ int to_introduce)
{
bin_t *bin;
int item_index;
item_t *item;
char *response;
bool_t correct;
+ int unlearned;
+ int i;
- while (1) {
+ /* Count the number of items with negative counts. */
+ unlearned = 0;
+ for (i = 0; i < mnemon->num_bins; i++) {
+ bin = &mnemon->bins[i];
+ if (bin->count >= 0)
+ break;
+ unlearned += bin->num_items;
+ }
+
+ to_introduce -= unlearned;
+ if (to_introduce < 0)
+ to_introduce = 0;
+
+ if (unlearned) {
+ printf ("You've got %d items to learn already. ", unlearned);
+ if (to_introduce)
+ printf ("I'll introduce %d more as we go.", to_introduce);
+ printf ("\n");
+ } else {
+ printf ("Introducing %d new items.\n", to_introduce);
+ }
+ printf ("\n");
+
+ do {
mnemon_select_item (mnemon, &bin, &item_index);
+
+ if (bin->count == 0)
+ to_introduce--;
+
item = bin->items[item_index];
printf ("%s\n", item->challenge);
correct = (strcmp (response, item->response) == 0);
bin_remove_item (bin, item_index);
- if (bin->num_items == 0)
+
+ /* If the bin is now empty, we must remove it. Also if we just
+ * picked the last word we'll ever pick from the bin with
+ * count 0, then we can remove that as well. */
+ if (bin->num_items == 0 ||
+ (bin->count == 0 && to_introduce == 0))
+ {
mnemon_remove_bin (mnemon, bin);
+ }
if (correct) {
- printf ("Correct!\n\n");
item->count++;
+ /* We reserve an item count of 0 for an item that has
+ * never been asked. */
+ if (item->count == 0) {
+ item->count = 1;
+ unlearned--;
+ printf ("You got it!");
+ } else if (item->count < 0) {
+ printf ("Yes---just give me %d more.",
+ - item->count);
+ } else if (item->count == 1) {
+ printf ("On your first try, no less!");
+ } else {
+ printf ("Masterful (%dx).", item->count);
+ }
} else {
- printf (" %s is the correct answer.\n\n",
+ printf (" %s is the correct answer.",
item->response);
+ if (item->count >= 0)
+ unlearned++;
item->count--;
- if (item->count > 0)
+ /* Penalize an incorrect response by forcing the count
+ * negative. */
+ if (item->count >= 0) {
item->count = -1;
+ printf ( " Oops, you knew that, right?\n ");
+ }
}
+ printf (" (");
+ if (to_introduce)
+ printf ("%d to come.", to_introduce);
+ if (to_introduce && unlearned)
+ printf (" ");
+ if (unlearned)
+ printf ("%d still unlearned.", unlearned);
+ if (to_introduce == 0 && unlearned == 0)
+ printf ("Great job!");
+ printf (")\n\n");
+
bin = mnemon_get_bin (mnemon, item->count);
bin_add_item (bin, item);
- }
+ } while (unlearned || to_introduce);
}
int
{
mnemon_t mnemon;
- srand (1);
+ srand (time (NULL));
mnemon_init (&mnemon);
mnemon_load (&mnemon);
- mnemon_do_challenges (&mnemon);
+ mnemon_do_challenges (&mnemon, 10);
mnemon_save (&mnemon);