int read_high_scores_fp(FILE* fp) { char buf[PATH_MAX]; char* token; const char delimiters[] = "\t"; char* name_read; int score_read; int diff_level; DEBUGMSG(debug_highscore, "Entering read_high_scores_fp()\n"); /* get out if file pointer invalid: */ if(!fp) { fprintf(stderr, "In read_high_scores_fp(), file pointer invalid!\n"); return 0; } /* make sure we start at beginning: */ rewind(fp); /* read in a line at a time: */ while (fgets (buf, PATH_MAX, fp)) { /* Ignore comment lines: */ if ((buf[0] == ';') || (buf[0] == '#')) { continue; } /* Split up line with strtok()to get needed values, */ /* then call insert_score() for each line. */ token = strtok(buf, delimiters); if (!token) continue; diff_level = atoi(token); if (diff_level >= NUM_HIGH_SCORE_LEVELS) continue; token = strtok(NULL, delimiters); if (!token) continue; score_read = atoi(token); /* Note that name can contain spaces - \t is only delimiter: */ name_read = strtok(NULL, delimiters); /* Now insert entry: */ insert_score(name_read, diff_level, score_read); } return 1; }
void do_highscores(int score) { read_scores(); ResourceManager& rm = ResourceManager::getInstance(); Input *input = (Input *)rm.getData(RES_INPUT); ALLEGRO_FONT *sm_font = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); ALLEGRO_FONT *big_font = (ALLEGRO_FONT *)rm.getData(RES_LARGEFONT); bool is_high = score >= highScores[NUM_SCORES-1].score; bool entering = is_high; double bail_time = al_get_time() + 8; int letter_num = 0; char name[4] = " "; int character = 0; double next_input = al_get_time(); double spin_start = 0; int spin_dir = 1; for (;;) { /* Catch close button presses */ ALLEGRO_EVENT_QUEUE *events = ((DisplayResource *)rm.getResource(RES_DISPLAY))->getEventQueue(); while (!al_is_event_queue_empty(events)) { ALLEGRO_EVENT event; al_get_next_event(events, &event); #ifdef ALLEGRO_IPHONE if (event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING || event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) { switch_game_out(event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING); } else if (event.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING || event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN) { switch_game_in(); } #else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) exit(0); #endif } input->poll(); if (entering && al_get_time() > next_input) { float lr = input->lr(); if (lr != 0) { if (lr < 0) { character--; if (character < 0) character = 25; spin_dir = 1; } else if (lr > 0) { character++; if (character >= 26) character = 0; spin_dir = -1; } next_input = al_get_time()+0.2; my_play_sample(RES_FIRESMALL); spin_start = al_get_time(); } if (input->b1() && letter_num < 3) { name[letter_num] = 'A' + character; letter_num++; if (letter_num >= 3) { entering = false; bail_time = al_get_time()+8; insert_score(name, score); write_scores(); } next_input = al_get_time()+0.2; my_play_sample(RES_FIRELARGE); } } else if (!entering) { if (al_get_time() > bail_time) { return; } else if (input->b1() && al_get_time() > next_input) { al_rest(0.250); return; } } al_rest(0.010); #ifdef ALLEGRO_IPHONE if (switched_out) { continue; } #endif al_clear_to_color(al_map_rgb(0, 0, 0)); if (entering) { float a = ALLEGRO_PI*3/2; float ainc = ALLEGRO_PI*2 / 26; double elapsed = al_get_time() - spin_start; if (elapsed < 0.1) { a += (elapsed / 0.1) * ainc * spin_dir; } float scrh = BB_H / 2 - 32; float h = al_get_font_line_height(sm_font); for (int i = 0; i < 26; i++) { int c = character + i; if (c >= 26) c -= 26; char s[2]; s[1] = 0; s[0] = 'A' + c; int x = BB_W/2 + (cos(a) * scrh) - al_get_text_width(sm_font, s); int y = BB_H/2 + (sin(a) * scrh) - h/2; al_draw_textf(sm_font, i == 0 ? al_map_rgb(255, 255, 0) : al_map_rgb(200, 200, 200), x, y, 0, "%s", s); a += ainc; } char tmp[4] = { 0, }; for (int i = 0; i < 3 && name[i] != ' '; i++) { tmp[i] = name[i]; } al_draw_textf(big_font, al_map_rgb(0, 255, 0), BB_W/2, BB_H/2-20, ALLEGRO_ALIGN_CENTRE, "%s", tmp); al_draw_text(sm_font, al_map_rgb(200, 200, 200), BB_W/2, BB_H/2-20+5+al_get_font_line_height(big_font), ALLEGRO_ALIGN_CENTRE, "high score!"); } else { int yy = BB_H/2 - al_get_font_line_height(big_font)*NUM_SCORES/2; for (int i = 0; i < NUM_SCORES; i++) { al_draw_textf(big_font, al_map_rgb(255, 255, 255), BB_W/2-10, yy, ALLEGRO_ALIGN_RIGHT, "%s", highScores[i].name); al_draw_textf(big_font, al_map_rgb(255, 255, 0), BB_W/2+10, yy, ALLEGRO_ALIGN_LEFT, "%d", highScores[i].score); yy += al_get_font_line_height(big_font); } } #ifdef ALLEGRO_IPHONE input->draw(); #endif al_flip_display(); } }
int main(int argc, char *argv[], char *envp[]) { FILE *fdata; /* .data file (input)*/ FILE *fmodel; /* .model file (output) */ FILE *fauc; /* .model.1st file (output) */ int atnl; /* at newline (flag) */ char *aucname; /* file name of the AUC file */ double baseline; char c; int divider; /* #of bins to divide in this round */ int failures_seen; /* in this bin */ int i, j, k, l; int maxrounds; /* max(@ROUNDS) */ int numbins; /* misnomer, really "this round" */ char *sca0, *sca, *scc; /* tmp variables */ int t; /* XXX - some kind of counter? */ int this_first, this_last; double this_pauc; double randnum; int *rand_seed = NULL; int total_failures; int num_scores; int init_permute_flag = 1; int unknown_meth = REL_ORDER; Score *p; Score *best; double min_auc; gargc = argc; gargv = argv; genvp = envp; /* * Make sure we grok NaNs * (unknown entries in the input file, given as '?', are * stored as not-a-number values) */ if (!isnan(nan(""))) errx(1, "Implementation does not understand NaNs"); /* * PARSE ARGUMENTS */ if (argc < 3) usage(); if ((fdata = fopen(argv[1], "r")) == NULL) err(1, "cannot open %s for reading", argv[1]); if ((fmodel = fopen(argv[2], "w")) == NULL) err(1, "cannot open %s for writing", argv[2]); if ((aucname = (char *)calloc(strlen(argv[2]) + sizeof (".1st"), 1)) == NULL) err(1, "allocating aucname"); strcpy(aucname, argv[2]); strcat(aucname, ".1st"); if ((fauc = fopen(aucname, "w")) == NULL) err(1, "cannot open %s for writing", aucname); argc -= 3; argv += 3; while (argc > 0) { if (!strcmp(argv[0], "rounds") || !strcmp(argv[0], "--rounds")) { if (argc < 2) usage(); if ((sca0 = sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); while (*sca == ',') /* strip leading commas, if any */ sca++; scc = sca + strlen(sca); if (scc == sca) /* must have at least one digit! */ usage(); while (*--scc == ',') /* strip trailing commas */ *scc = '\0'; if (strchr(sca, ',')) { /* * comma-separated list of rounds, parse */ n_rounds = 0; for (scc = sca; *scc; scc++) if (*scc == ',') n_rounds++; n_rounds++; if ((rounds = (int *)calloc(n_rounds, sizeof (*rounds))) == NULL) err(1, "calloc %d rounds", n_rounds); for (i = 0; i < n_rounds; i++) { rounds[i] = strtol(sca, &scc, 10); if (rounds[i] <= 0) errx(1, "round %d must be positive", i); sca = scc + 1; } } else { n_rounds = strtol(sca, NULL, 10); } if (n_rounds <= 0) usage(); argc -= 2; argv += 2; } else if (!strcmp(argv[0], "topk") || !strcmp(argv[0], "--topk")) { if (argc < 2) usage(); if ((sca0 = sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); scc = sca + strlen(sca); if (scc == sca) /* must have at least one digit! */ usage(); topk = strtol(sca, NULL, 10); if (topk <= 0) usage(); argc -= 2; argv += 2; } else if (!strcmp(argv[0], "miss-limit") || !strcmp(argv[0], "--miss-limit")) { if (argc < 2) usage(); if ((sca0 = sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); scc = sca + strlen(sca); if (scc == sca) /* must have at least one digit! */ usage(); unknown_limit = atof(sca); if (unknown_limit < 0 || unknown_limit > 1) usage(); argc -= 2; argv += 2; } else if (!strcmp(argv[0], "--no-prob-dist")) { prob_dist_flag = 0; argc -= 1; argv += 1; } else if (!strcmp(argv[0], "--no-permute") || !strcmp(argv[0], "no-permute")) { init_permute_flag = 0; argc -= 1; argv += 1; } else if (!strcmp(argv[0], "--sort-unknowns") || !strcmp(argv[0], "sort-unknowns")) { if (argc < 2) usage(); if ((sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); unknown_meth = atoi(sca); if (unknown_meth != RAND_ORDER || unknown_meth != REL_ORDER) { usage(); } argc -= 2; argv += 2; } else if (!strcmp(argv[0], "seed") || !strcmp(argv[0], "--seed")) { if (argc < 2) usage(); if ((sca0 = sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); scc = sca + strlen(sca); if (scc == sca) { //must have one digit usage(); } if ((rand_seed = (int *) malloc(sizeof(int))) == NULL) err(1, "calloc one integer", 1); *rand_seed = atoi(sca); argc -= 2; argv += 2; } else { /* No other options supported */ usage(); } } /* * if we got a single number as the "rounds" argument, we * interpret it as the list 1,2,...,n */ if (rounds == NULL) { if ((rounds = (int *)calloc(n_rounds, sizeof (*rounds))) == NULL) err(1, "calloc %d rounds", n_rounds); for (i = 0; i < n_rounds; i++) rounds[i] = i+1; } /* * Prep @F and @last */ /* * find the max value in rounds[], * needed for allocating space for failures[][] and last[][] */ for (i = 0, maxrounds = 0; i < n_rounds; i++) if (maxrounds < rounds[i]) maxrounds = rounds[i]; if ((failures = (int **)calloc(n_rounds + 3, sizeof (*failures))) == NULL) err(1, "calloc %d failures", n_rounds); if ((last = (int **)calloc(n_rounds + 3, sizeof (*last))) == NULL) err(1, "calloc %d last", n_rounds); for (i = 0; i <= n_rounds; i++) { if ((failures[i] = (int *)calloc(maxrounds + 3, sizeof (**failures))) == NULL) err(1, "calloc failures[%d]", i); if ((last[i] = (int *)calloc(maxrounds + 3, sizeof (**last))) == NULL) err(1, "calloc last[%d]", i); } /* * COUNT NAMES and IDS */ /* * Start reading the first line, counting fields */ //first check to make sure there is data in the file c = fgetc(fdata); if (c == EOF) { fclose(fdata); err(1, "Error: Data file %s is empty\n", gargv[1]); } n_names = 1; /* at least one! */ /* attributes a comma separated. So count the number of commas in the first line to calculate the number of attributes in the data. */ while (!isnewline(c) && c != EOF) { if (c == ',') n_names++; c = fgetc(fdata); } /* * We've read the first line; let's keep counting lines. * There is some cruftiness in the code in order to deal with * text files with lines ending in \r\n and not just \n */ n_ids = 1; /* we've already read one line! */ atnl = 0; while ((c = fgetc(fdata)) != EOF) if (isnewline(c)) { if (!atnl) { n_ids++; atnl++; } } else { atnl = 0; } fclose(fdata); if ((fdata = fopen(gargv[1], "r")) == NULL) err(1, "cannot open %s for reading", gargv[1]); if ((tabula = (double **)calloc(n_ids, sizeof (*tabula))) == NULL) err(1, "allocating tabula"); for (i = 0; i < n_ids; i++) { if ((tabula[i] = (double *)calloc(n_names, sizeof (**tabula))) == NULL) err(1, "allocating %d-th row of table\n", i); for (j = 0; j < n_names - 1; j++) if (fscanf(fdata, "%lg,", &tabula[i][j]) != 1) { tabula[i][j] = nan(""); while (fgetc(fdata) != ',') ; } fscanf(fdata, "%lg", &tabula[i][j]); /* * XXX - a well-formed file * MUST not have the result * value (last column) be a '?' * DOUBLE_CHECK */ } total_failures = 0; for (i = 0; i < n_ids; i++) total_failures += tabula[i][n_names - 1]; printf("data_file = %s\n", gargv[1]); printf("model = %s\n", gargv[2]); printf("nr rounds = %d\tnr splits=", n_rounds); for (i = 0; i < n_rounds; i++) printf(" %d", rounds[i]); printf("\nnr_examples = %d\ttotal_failures = %d", n_ids, total_failures); printf("\tnr_attribs = %d\n", n_names); // seed random no generator if (rand_seed == NULL) { srand((unsigned)time(NULL)); } else { srand(*rand_seed); //don't need rand_seed anymore... free(rand_seed); rand_seed = NULL; } if ((order = (int *)calloc(n_ids, sizeof (*order))) == NULL) err(1, "calloc %d order", n_ids); if ((sublist_order = (int *)calloc(n_ids, sizeof (*sublist_order))) == NULL) err(1, "calloc %d sublist_order", n_ids); if ((scores = (Score *)calloc(MAX_VARS, sizeof (Score))) == NULL) err(1, "calloc %d scores", MAX_VARS); for (i = 0; i < MAX_VARS; i++) { scores[i].auc = 0; if ((scores[i].order = (int *)calloc(n_ids, sizeof (*(scores[i].order)))) == NULL) err(1, "calloc %d scores[%d].order", n_ids, i); } if ((ignore_set = (int *)calloc(n_names-1, sizeof (*ignore_set))) == NULL) err(1, "calloc %d ignore_set", n_names-1); if ((this_order = (int *)calloc(n_ids, sizeof (*this_order))) == NULL) err(1, "calloc %d this_order", n_ids); if ((best_order = (int *)calloc(n_ids, sizeof (*best_order))) == NULL) err(1, "calloc %d best_order", n_ids); /* randomize initial ordering */ if (init_permute_flag) { for (i = 0; i < n_ids; i++) order[i] = -1; for (i = 0; i < n_ids; i++) { randnum = (double)rand()/((unsigned)RAND_MAX+1); // [0,1) j = (int)(randnum*n_ids); while (order[j] != -1) j = (j + 1) % n_ids; order[j] = i; } } else { for (i = 0; i < n_ids; i++) { order[i] = i; } } /* find variables to ignore */ for (i = 0; i < n_names-1; i++) { ignore_set[i] = 0; if (check_var(i,n_ids, unknown_limit) < 0) ignore_set[i] = 1; } /* iteration over rounds */ for (numbins = 1; numbins <= n_rounds; numbins++) { printf("round = %d\tsplits = %d\n", numbins, rounds[numbins - 1]); t = 0; failures_seen = 0; for (divider = 0; divider < rounds[numbins - 1]; divider++) { while ((failures_seen < ((divider + 1) * (double)total_failures / rounds[numbins - 1])) && (t < n_ids)) { failures_seen += tabula[order[t]][n_names-1]; t++; } last[numbins][divider] = t - 1; failures[numbins][divider] = failures_seen; if (divider == (rounds[numbins - 1] - 1)) failures[numbins][divider+1] = total_failures - failures_seen; } this_first = 0; /* find the first element of the sublist */ /* iteration over bins in this round */ for (j = 0; j < rounds[numbins - 1]; j++) { if (j < rounds[numbins - 1] - 1) this_last = last[numbins][j]; else this_last = n_ids - 1; printf("\tbin %d: [%d..%d] %d failures", j, this_first, this_last, failures[numbins][j] - (j ? failures[numbins][j-1] : 0)); printf("\t(%.12f%%)\n", (this_last - this_first + 1) * 100.0 / n_ids); // ordering from previous round for (k = this_first; k <= this_last; k++) sublist_order[k - this_first] = order[k]; baseline = pauc(sublist_order, this_last - this_first + 1); // reset scores for (k = 1; k < MAX_VARS; k++) scores[k].auc = 0; min_score_ptr = NULL; num_scores = 0; /* iteration over variables for this bin */ for (exti = 0; exti < n_names - 1; exti++) { if (ignore_set[exti]) continue; /* variable ascending */ for (k = this_first; k <= this_last; k++) this_order[k - this_first] = sublist_order[k - this_first]; if (sort_examples((void *)this_order, this_last - this_first + 1, sizeof (*this_order), compasc, unknown_meth) < 0) err(1, "sort_examples this_order ascending"); this_pauc = pauc(this_order, this_last - this_first + 1); if (numbins == 1) fprintf(fauc, "VAR=%d AUC=%f DIR=asc\n", exti, this_pauc); if (this_pauc > baseline) insert_score(scores, &num_scores, exti, "a", this_pauc, this_order, this_last - this_first + 1); /* variable descending */ for (k = this_first; k <= this_last; k++) this_order[k - this_first] = sublist_order[k - this_first]; if (sort_examples((void *)this_order, this_last - this_first + 1, sizeof (*this_order), compdesc, unknown_meth) < 0) err(1, "sort_examples this_order descending"); this_pauc = pauc(this_order, this_last - this_first + 1); if (numbins == 1) fprintf(fauc, "VAR=%d AUC=%f DIR=desc\n", exti, this_pauc); if (this_pauc > baseline) insert_score(scores, &num_scores, exti, "d", this_pauc, this_order, this_last - this_first + 1); } /* end variables loop */ if (num_scores > 0) { // sort scores in desc order of auc if (mergesort((void *)scores, num_scores, sizeof (*scores), comp_auc_desc) < 0) err(1, "mergesort scores descending"); if (prob_dist_flag) { // pick top variable probabilistically // XXX: pick topk vars and compute avg sort auc_to_dist(scores, num_scores); best = weighted_rand(scores, num_scores); } else best = scores; // merge results into main array for (k = this_first; k <= this_last; k++) order[k] = (*best).order[k - this_first]; // update model fprintf(fmodel, "%.12f,%1d,%s", (this_last + 1) / (double) n_ids, best->var, best->dir); fflush(fmodel); } else { fprintf(fmodel, "%.12f,nop", (this_last + 1) / (double) n_ids); fflush(fmodel); } if (j < rounds[numbins - 1] - 1) { fprintf(fmodel, ";"); fflush(fmodel); } this_first = this_last + 1; } /* end bins loop */ fprintf(fmodel, "\n"); fflush(fmodel); printf(" Overall training AUC %.6f\n", pauc(order, n_ids)); } /* end rounds loop */ fclose(fmodel); fclose(fauc); exit(0); }