#include #include "defs.h" #undef BUFSIZ #define BUFSIZ 8192 #define MAXNAMELEN 15 update_highscore_table() { int i, j; long when; extern char *ctime(); extern long time(); char hostname[20]; char buf[BUFSIZ]; /* re-read high-score table in case someone else on the network is * playing at the same time */ read_high_scores(); score_position = -1; /* Next line finds score greater than current one */ for (i = LOW_SCORES; ((i < HIGH_TABLE_SIZE) && (score >= high_scores[i].score)); i++); i--; if (i >= LOW_SCORES && i < HIGH_TABLE_SIZE) { for (j = LOW_SCORES; j < i; j++) { high_scores[j] = high_scores[j + 1]; high_aux_scores[j] = high_aux_scores[j + 1]; } score_position = i; strcpy(high_scores[i].name, name); high_scores[i].score = score; high_scores[i].rows = rows; high_scores[i].level = rows / 10; catch_aux(&high_aux_scores[i]); if (gethostname(hostname, BUFSIZ) == -1) strcpy(high_scores[i].hostname, "unknown-host"); else strcpy(high_scores[i].hostname, hostname); time(&when); strcpy(buf, ctime(&when)); /* ctime() adds a newline * char */ strip_eoln(buf);/* so remove it */ strcpy(high_scores[i].date, buf); write_high_scores(); } if (i < LOW_SCORES) { /* maybe got a low score, not a high score */ for (i = 0; ((i < LOW_SCORES) && (score >= high_scores[i].score) && high_scores[i].score > 0); i++) {;} if (i < LOW_SCORES) { /* new low score */ for (j = LOW_SCORES-1; j > i; j--){ high_scores[j] = high_scores[j - 1]; high_aux_scores[j] = high_aux_scores[j - 1]; } score_position = i; strcpy(high_scores[i].name, name); high_scores[i].score = score; high_scores[i].rows = rows; high_scores[i].level = rows / 10; catch_aux(&high_aux_scores[i]); if (gethostname(hostname, BUFSIZ) == -1) strcpy(high_scores[i].hostname, "unknown-host"); else strcpy(high_scores[i].hostname, hostname); time(&when); strcpy(buf, ctime(&when)); /* ctime() adds a newline * char */ strip_eoln(buf); /* so remove it */ strcpy(high_scores[i].date, buf); write_high_scores(); } } } read_high_scores() { FILE *fp; int i; char *c, buf[BUFSIZ]; for (i = 0; i < HIGH_TABLE_SIZE; i++) { strcpy(high_scores[i].name, " "); high_scores[i].score = 0; high_scores[i].rows = 0; high_scores[i].level = 0; strcpy(high_scores[i].hostname, " "); strcpy(high_scores[i].date, " "); } if ((fp = fopen(HIGH_SCORE_TABLE, "r")) == NULL) { fprintf(stderr, "tetris: No High score file\n"); return; } for (i = 0; i < HIGH_TABLE_SIZE; i++) { fgets(buf, BUFSIZ, fp); if (feof(fp)) break; strip_eoln(buf); strcpy(high_scores[i].name, buf); decode_aux(high_scores[i].name, &high_aux_scores[i]); high_scores[i].name[MAXNAMELEN] = '\0'; /* truncate name */ fgets(buf, BUFSIZ, fp); strip_eoln(buf); high_scores[i].score = atoi(buf); fgets(buf, BUFSIZ, fp); strip_eoln(buf); high_scores[i].rows = atoi(buf); fgets(buf, BUFSIZ, fp); strip_eoln(buf); high_scores[i].level = atoi(buf); fgets(buf, BUFSIZ, fp); strip_eoln(buf); strcpy(high_scores[i].hostname, buf); fgets(buf, BUFSIZ, fp); strip_eoln(buf); strcpy(high_scores[i].date, buf); } if (i < HIGH_TABLE_SIZE) { /* some blank entries to skip over */ struct score_table tab; struct aux_score_table auxtab; int j; bzero(&tab, sizeof(tab)); bzero(&auxtab, sizeof(auxtab)); for (j = 0; j < i; j++) { high_scores[HIGH_TABLE_SIZE - j - 1] = high_scores[i - j - 1]; high_aux_scores[HIGH_TABLE_SIZE - j - 1] = high_aux_scores[i - j - 1]; } for (j = 0; j < HIGH_TABLE_SIZE - i; j++) { high_scores[j] = tab; high_aux_scores[j] = auxtab; } } fclose(fp); } strip_eoln(s) char *s; { char *s1; while (*s != '\0') { if (*s == '\n') { /* End of line char */ s1 = s; do { *s1 = *(s1 + 1); /* Copy rest of string */ s1++; } while (*s1 != '\0'); } else s++; } } write_high_scores() { FILE *fp; int i; if ((fp = fopen(HIGH_SCORE_TABLE, "w")) == NULL) { fprintf(stderr, "tetris: Couldn't open high score file %s\n", HIGH_SCORE_TABLE); return; } for (i = 0; i < HIGH_TABLE_SIZE; i++) { encode_aux(high_scores[i].name, &high_aux_scores[i]); fprintf(fp, "%s\n%d\n%d\n%d\n%s\n%s\n", high_scores[i].name, high_scores[i].score, high_scores[i].rows, high_scores[i].level, high_scores[i].hostname, high_scores[i].date); } fclose(fp); } void print_high_scores() { int i; char buf[BUFSIZ]; /* re-read high-score table in case someone else on the network is * playing at the same time */ read_high_scores(); for (i = 0; i < HIGH_TABLE_SIZE; i++) { bzero(buf, sizeof(buf)); /* In the "%-.15" below, the 15 should be equal to MAXNAMELEN. */ sprintf(buf, "%3d) %-.15s %6d %5d %3d %-10s %-24s ", HIGH_TABLE_SIZE - i, high_scores[i].name, high_scores[i].score, high_scores[i].rows, high_scores[i].level, high_scores[i].hostname, high_scores[i].date); print_aux(buf+strlen(buf), &high_aux_scores[i]); xv_set(high_score_item[HIGH_TABLE_SIZE - i - 1], PANEL_LABEL_BOLD, FALSE, PANEL_LABEL_STRING, buf, 0); } if (score_position != -1) xv_set(high_score_item[HIGH_TABLE_SIZE - score_position - 1], PANEL_LABEL_BOLD, TRUE, 0); xv_set(score_frame, WIN_SHOW, TRUE, 0); } char * about_string() { return "This is a self-playing tetris, hacked by Mark Weiser from the version of tetris that was written by Phill Everson and Martyn Shortley , Based on the version posted to comp.sources.games by Adam Marguilies \n\nLet us know if you like it.\n31st March 1989"; } /* * Find the auxiliary information inside a user name. Done this way for * backward compatibility. The aux information follows the first * slash in a name. */ decode_aux(name, aux_table) char *name; struct aux_score_table *aux_table; { int version; char *ptr; if ((ptr = strchr(name, '/')) == NULL) { /* There are not auxiliary symbols here. */ bzero(aux_table, sizeof(*aux_table)); } else { sscanf(ptr+1, "%d", &version); if (version != MYVERSION) { /* wrong version, don't try to do anything */ bzero(aux_table, sizeof(*aux_table)); } else { /* a version I know, take it apart */ sscanf(ptr+1, "%d %d %d %d %d %d %d %d %d %d %d %d %d", &aux_table->version, &aux_table->seed, &aux_table->RowElimWeight, &aux_table->MaxFlatWeight, &aux_table->VariationWeight, &aux_table->HolesWeight, &aux_table->GameOverWeight, &aux_table->FissureWeight, &aux_table->ExposeHoleWeight, &aux_table->RowElimProgressWeight, &aux_table->MaxHeightWeight, &aux_table->Seconds, &aux_table->LookAheadWeight ); } } } /* * Encode the auxiliary information inside a user name. Done this way for * backward compatibility. The aux information follows the first * slash in a name. */ encode_aux(name, aux_table) char *name; struct aux_score_table *aux_table; { char *ptr; ptr = name + strlen(name); sprintf(ptr, " / %d ", aux_table->version); ptr += strlen(ptr); print_aux(ptr, aux_table); } print_aux(buf, aux_table) char *buf; struct aux_score_table *aux_table; { sprintf(buf, "%11d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d", aux_table->seed, aux_table->RowElimWeight, aux_table->MaxFlatWeight, aux_table->VariationWeight, aux_table->HolesWeight, aux_table->GameOverWeight, aux_table->FissureWeight, aux_table->ExposeHoleWeight, aux_table->RowElimProgressWeight, aux_table->MaxHeightWeight, aux_table->Seconds, aux_table->LookAheadWeight ); }