/****h* GalaxyTools/HallOfFame * * NAME * COPYRIGHT * (c) Maverick Software Development 1996. * This software is public domain and can be freely redistributed * as long as it remains in its original state. * SYNOPSIS * INPUTS * FUNCTION * RESULT * AUTHOR * Frans Slothouber * CREATION DATE * Aug 1996 * MODIFICATION HISTORY * NOTES * BUGS * ********** */ /* $Id: HallOfFame.c,v 1.11 2001/02/25 18:32:55 cvs Exp $ */ #include #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define eq == #define debug FALSE #define LINE_BUFFER_SIZE 255 char line_buffer[LINE_BUFFER_SIZE]; int line_number = 0; /****s* HallOfFame/player [0.5] * * NAME * player -- * FUNCTION * SOURCE */ struct player { struct player *next; char *name; int temp; int numberOfGames; float total_industry; int avg_position; int games_won; char *alias; char *email; char *homepage; char *photo; char *bigphoto; float victory_points; }; typedef struct player player; /********/ /****s* HallOfFame/nation [0.5] * * NAME * nation -- * FUNCTION * SOURCE */ struct nation { struct nation *next; player *player; char *race_name; float eff_industry; }; typedef struct nation nation; /*** nation ***/ /****s* HallOfFame/player [0.5] * * NAME * game -- * FUNCTION * SOURCE */ struct game { struct game *next; char *name; char *gm; int number_of_players; int number; nation *ranking; }; typedef struct game game; /*** game ***/ /* Prototypes */ void Usage(void); player* Read_Players( FILE* galaxybase); game* Read_Games( FILE* galaxybase, player* first_player); int Get_Line(FILE* galaxybase); char* Get_String(char* tagname); player* Find_Player(player* first_player, char* alias); void Create_Hall_Of_Fame( game* first_game, player* first_player); void Create_Score_List( FILE* haf, game* first_game, player* first_player); void Create_Game_List( FILE* haf, game* first_game, player* first_player); void Create_Player_List(FILE* haf, game* first_game, player* first_player); void Slow_Sort_Games(game* first_game); void Print_Players(player* first_player); void Print_Player(player* cur_player); void Print_Games(game* first_game); int noCaseStrcmp(char *s, char *t); /****** HallOfFame/main [0.5] * * * NAME * main -- * SYNOPSIS * main (int argc, char **argv) * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ main(int argc, char **argv) { if (argc > 1) { FILE *galaxybase; if (galaxybase = fopen(argv[1], "r")) { player *first_player; game *first_game; if (first_player = Read_Players(galaxybase)) { rewind(galaxybase); if (first_game = Read_Games(galaxybase, first_player)) { // Print_Games(first_game); // Print_Players(first_player); Create_Hall_Of_Fame(first_game, first_player); } } else { printf("Error: Couldn't read player data, aborting\n"); } } else { printf("Error: can't open %s\n", argv[1]); } } else Usage(); return 0; } /*** main ***/ /****** HallOfFame/Usage [0.5] * * * NAME * Usage -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ void Usage(void) { printf("Usage: HallOfFame \n"); } /*** Usage ***/ /****** HallOfFame/Create_Hall_Of_Fame [0.5] * * * NAME * Create_Hall_Of_Fame -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ void Create_Hall_Of_Fame(game * first_game, player * first_player) { FILE *haf; if (haf = fopen("hall.m4", "w")) { fprintf(haf, "m4_include(`wwwbase.m4')m4_dnl\n" "m4_include(`general.m4')m4_dnl\n" "DocStart\n" "AHeader(`Hall of Fame')\n" "BodyStart\n" "m4_include(`hallnavigator.m4')m4_dnl\n" "ATitle(`Galaxy Hall of Fame')\n"); fprintf(haf, "
    \n"); fprintf(haf, "
  • Based these games\n"); fprintf(haf, "
  • Information about the players\n"); fprintf(haf, "
\n"); Create_Score_List(haf, first_game, first_player); fprintf(haf, "BodyEnd\nDocEnd\n"); fclose(haf); } else { printf("Error: can't open hall.html\n"); } if (haf = fopen("players.m4", "w")) { fprintf(haf, "m4_include(`wwwbase.m4')m4_dnl\n" "m4_include(`general.m4')m4_dnl\n" "DocStart\n" "AHeader(`Hall of Fame: List of Players')\n" "BodyStart\n" "m4_include(`hallnavigator.m4')m4_dnl\n" "ATitle(`List of Players')\n"); fprintf(haf, "ASection(`The names behind your " "friends and enemies')\n"); Create_Player_List(haf, first_game, first_player); fprintf(haf, "BodyEnd\nDocEnd\n"); fclose(haf); } else { printf("Error: can't open players.html\n"); } Slow_Sort_Games(first_game); if (haf = fopen("games.m4", "w")) { fprintf(haf, "m4_include(`wwwbase.m4')m4_dnl\n" "m4_include(`general.m4')m4_dnl\n" "DocStart\n" "AHeader(`Hall of Fame: Game List')\n" "BodyStart\n" "m4_include(`hallnavigator.m4')m4_dnl\n" "ATitle(`Game List')\n"); fprintf(haf, "

The Hall of Fame is based on the following games.

\n"); Create_Game_List(haf, first_game, first_player); fprintf(haf, "BodyEnd\nDocEnd\n"); fclose(haf); } else { printf("Error: can't open hall.html\n"); } } /*** Create_Hall_Of_Fame ***/ void Create_Score_List(FILE * haf, game * first_game, player * first_player) { player *cur_player; int nr_of_players; int nr; fprintf(haf, "

Sorted according to the number of victory points.

\n" "\n" "" "" "" "\n"); for (cur_player = first_player, nr_of_players = 0; cur_player; cur_player = cur_player->next) { cur_player->temp = TRUE; if (cur_player->victory_points > 0.0) nr_of_players++; } for (nr = 1; nr <= nr_of_players; nr++) { player *top_player; float max_points; for (cur_player = first_player, top_player = NULL, max_points = 0.0; cur_player; cur_player = cur_player->next) { if ((cur_player->victory_points != 0.0) && cur_player->temp) { if (cur_player->victory_points >= max_points) { top_player = cur_player; max_points = cur_player->victory_points; } } } if (top_player) { fprintf(haf, "", nr); fprintf(haf, "\n", top_player->alias, top_player->name); fprintf(haf, "\n", top_player->victory_points); fprintf(haf, "\n", top_player->numberOfGames); fprintf(haf, "\n", top_player->total_industry); fprintf(haf, "\n", top_player->total_industry / top_player->numberOfGames); fprintf(haf, "\n", (float)top_player->avg_position / (float)top_player->numberOfGames); fprintf(haf, "\n", (float)top_player->games_won / (float)top_player->numberOfGames); fprintf(haf, ""); top_player->temp = FALSE; } } fprintf(haf, "
#NameVictory Points# GamesIeff totalIeff / GameAvg PositionWin Rate
%d%s%7.2f%d%.f%.f%.2f%.2f
\n"); fprintf(haf, "

Sorted according to the number of games won.

\n"); fprintf(haf, "\n"); fprintf(haf, "" "\n"); for (cur_player = first_player, nr_of_players = 0; cur_player; cur_player = cur_player->next) { cur_player->temp = TRUE; if (cur_player->numberOfGames > 0) nr_of_players++; } for (nr = 1; nr <= nr_of_players; nr++) { player *top_player; float max_games; for (cur_player = first_player, top_player = NULL, max_games = 0; cur_player; cur_player = cur_player->next) { if ((cur_player->numberOfGames != 0) && cur_player->temp) { if (cur_player->numberOfGames >= max_games) { top_player = cur_player; max_games = cur_player->numberOfGames; } } } if (top_player) { fprintf(haf, "\n", nr); fprintf(haf, "\n", top_player->alias, top_player->name); fprintf(haf, "\n", top_player->victory_points); fprintf(haf, "\n", top_player->numberOfGames); top_player->temp = FALSE; } } fprintf(haf, "
#namevictory pointsGames Won
%d%s%7.2f%d
\n"); } /****f* HallOfFame/Slow_Sort_Games * NAME * Slow_Sort_Games * SYNOPSIS * void Slow_Sort_Games(game *first_game) * FUNCTION * Assigns each game a number. This number corresponds * to the position the game would have had in a list * where the game are sorted alphabetical according to name. * NOTES * It is a very slow way of sorting. But since this programs * runs a couple of times per year we do not care. ****** */ void Slow_Sort_Games(game *first_game) { game *aGame; int n; for (aGame = first_game; aGame; aGame = aGame->next) { aGame->number = 0; } for (n = 1, aGame = first_game; aGame; aGame = aGame->next, n++) { game *smallestGame, *aGame2; smallestGame = NULL; for (aGame2 = first_game; aGame2; aGame2 = aGame2->next) { if ((smallestGame == NULL) && (aGame2->number == 0)) { smallestGame = aGame2; } if (smallestGame && (aGame2->number == 0) && (noCaseStrcmp(smallestGame->name, aGame2->name)) > 0) { smallestGame = aGame2; } } assert(smallestGame); smallestGame->number = n; } } /****f* HallOfFame/noCaseStrcmp * NAME * noCaseStrcmp -- * FUNCTION * Compare two strings, but do not pay attention to the * case of the characters. ***** */ int noCaseStrcmp(char *s, char *t) { for (; tolower(*s) == tolower(*t); s++, t++) if (*s == '\0') return 0; return (int) (tolower(*s) - tolower(*t)); } /****f* HallOfFame/Create_Game_List * NAME * Create_Game_List -- create list of all games. ***** */ void Create_Game_List(FILE * haf, game *first_game, player *first_player) { game *aGame; int column; int nr; fprintf(haf, "" "\n"); for (column = 0, nr = 1, aGame = first_game; aGame; aGame = aGame->next, nr++) { game *aGame2; for (aGame2 = first_game; aGame2; aGame2 = aGame2->next) { if (aGame2->number == nr) { if (column == 0) { fprintf(haf, ""); } fprintf(haf, "\n", aGame2->name, aGame2->name); column++; if (column >= 7) { fprintf(haf, ""); column = 0; } } } } for(;column < 7;) { if (column == 0) { fprintf(haf, ""); } column++; fprintf(haf, "\n"); } fprintf(haf, ""); fprintf(haf, "
All Games
%s
\n\n"); for (column = 0, nr = 1, aGame = first_game; aGame; aGame = aGame->next, nr++) { game *aGame2; for (aGame2 = first_game; aGame2; aGame2 = aGame2->next) { if (aGame2->number == nr) { nation *cur_pl; fprintf(haf, "" "\n", aGame2->name, aGame2->name); fprintf(haf, "\n", aGame2->gm); fprintf(haf, "\n", aGame2->number_of_players); fprintf(haf, "\n"); fprintf(haf, "" "\n"); for (cur_pl = aGame2->ranking; cur_pl; cur_pl = cur_pl->next) { fprintf(haf, "", cur_pl->race_name); fprintf(haf, "", (cur_pl->player)->name); fprintf(haf, "\n ", cur_pl->eff_industry); } fprintf(haf, "
%s
GM%s
Players%d
Final Score
RacePlayerEffective Industry
%s%s%7.2f
\n"); } } } } void Create_Player_List(FILE * haf, game * first_game, player * first_player) { player *aPlayer; for (aPlayer = first_player; aPlayer; aPlayer = aPlayer->next) { game *aGame; int nr; fprintf(haf, "\n", aPlayer->homepage, aPlayer->name); } else { fprintf(haf, "%s\n",aPlayer->name); } fprintf(haf, "\n"); fprintf(haf, "\n"); for(aGame = first_game; aGame; aGame = aGame->next) { nation *aNation; for (aNation = aGame->ranking, nr = 1; aNation; aNation = aNation->next, nr++) { if (strcmp(aNation->player->alias, aPlayer->alias) == 0) { fprintf(haf, "", aGame->name); fprintf(haf, "", aNation->race_name); fprintf(haf, "", nr); } } } fprintf(haf, "
", aPlayer->alias, aPlayer->name); if (strcmp("none", aPlayer->homepage)) { fprintf(haf, "%s
GameNationPosition
%s%s%d
\n"); } } /****** HallOfFame/Read_Players [0.5] * * * NAME * Read_Players -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ player * Read_Players(FILE * galaxybase) { player *first_player; int fail; int charsFound; if (debug) printf("Read_Players\n"); charsFound = Get_Line(galaxybase); for (fail = FALSE, first_player = NULL; charsFound && !fail; ) { if (strncmp(line_buffer, "PLAYER", 6) == 0) { player *aPlayer; if (aPlayer = malloc(sizeof(player))) { aPlayer->alias = Get_String("PLAYER"); if (!Get_Line(galaxybase)) { fail = TRUE; break; }; aPlayer->name = Get_String("NAME"); if (!Get_Line(galaxybase)) { fail = TRUE; break; }; aPlayer->email = Get_String("EMAIL"); if (!Get_Line(galaxybase)) { fail = TRUE; break; }; aPlayer->homepage = Get_String("HOMEPAGE"); if (!Get_Line(galaxybase)) { fail = TRUE; break; }; // aPlayer->photo = Get_String("PHOTO"); // if (!Get_Line(galaxybase)) { // fail = TRUE; // break; // }; // aPlayer->bigphoto = Get_String("BPHOTO"); aPlayer->victory_points = 0.0; aPlayer->numberOfGames = 0; aPlayer->total_industry = 0.0; aPlayer->games_won = 0; } else { printf("Error: Out of memory\n"); fail = TRUE; } aPlayer->next = first_player; first_player = aPlayer; } charsFound = Get_Line(galaxybase); } return (fail) ? NULL : first_player; } /*** Read_Players ***/ /****** HallOfFame/Read_Games [0.5] * * * NAME * Read_Games -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ game * Read_Games(FILE * galaxybase, player * first_player) { game *first_game; int fail; int charsFound; if (debug) printf("Read_Games\n"); charsFound = Get_Line(galaxybase); for (fail = FALSE, first_game = NULL; charsFound && !fail; ) { if (strncmp(line_buffer, "GAME", 4) == 0) { game *aGame; char *gm; if (aGame = malloc(sizeof(game))) { aGame->name = Get_String("GAME"); if (!Get_Line(galaxybase)) { fail = TRUE; break; }; gm = Get_String("GAME_MASTER"); aGame->gm = (Find_Player(first_player, gm))->name; if (!Get_Line(galaxybase)) { fail = TRUE; break; }; if ((strncmp(line_buffer, "NUMBER", 6) eq 0) && (sscanf(line_buffer, "%*s%d", &(aGame->number_of_players)) eq 1)) { nation *cur_pl, *head_pl; int position; aGame->ranking = NULL; head_pl = NULL; charsFound = Get_Line(galaxybase); for (position = 1; charsFound && !isspace(*line_buffer); position++) { if (cur_pl = malloc(sizeof(nation))) { char *cur_char; char alias[30]; int race_name_length; for (cur_char = line_buffer, race_name_length = 0; !isspace(*cur_char) && *cur_char; cur_char++) race_name_length++; if (cur_pl->race_name = calloc(race_name_length + 2, sizeof(char))) { int nrRead; float points; strncpy(cur_pl->race_name, line_buffer, race_name_length); (cur_pl->race_name)[race_name_length + 1] = '\0'; nrRead = sscanf(line_buffer, "%*s%s%f%f", alias, &(cur_pl->eff_industry), &points); if (nrRead < 2) { printf("Error in line (%d): can't read alias or eff industry\n"); fail = TRUE; break; } else { if (position <= aGame->number_of_players / 2) { player *target_player; target_player = Find_Player(first_player, alias); if (nrRead == 2) { target_player->victory_points += ((float) aGame->number_of_players) / ((float) position); } else { target_player->victory_points += points; } target_player->numberOfGames++; target_player->total_industry += cur_pl->eff_industry; target_player->avg_position += position; if (position == 1) target_player->games_won++; cur_pl->player = target_player; if (head_pl) { head_pl->next = cur_pl; cur_pl->next = NULL; head_pl = cur_pl; } else { aGame->ranking = cur_pl; head_pl = cur_pl; cur_pl->next = NULL; } } } } else { printf("Error: out of memory\n"); fail = TRUE; break; } } else { printf("Error: out of memory\n"); fail = TRUE; break; } charsFound = Get_Line(galaxybase); } } else { printf("Error in line (%d): can't determine the number of player" "\n in game %s\n", line_number, aGame->name); fail = TRUE; } aGame->next = first_game; first_game = aGame; } } charsFound = Get_Line(galaxybase); } return (fail) ? NULL : first_game; } /*** Read_Games ***/ /****** HallOfFame/Get_Line [0.5] * * * NAME * Get_Line -- * SYNOPSIS * FUNCTION * Operates on two globals * o line_buffer * o line_number * INPUTS * RESULT * NOTE * SOURCE */ int Get_Line(FILE * galaxybase) { char *s; if (debug) printf("Get_Line\n"); line_number++; for (s = fgets(line_buffer, LINE_BUFFER_SIZE - 2, galaxybase); (s != NULL) && (line_buffer[0] == '#'); s = fgets(line_buffer, LINE_BUFFER_SIZE - 2, galaxybase)) ; return (s != NULL); } /*** Get_Line ***/ /****** HallOfFame/Get_String [0.5] * * * NAME * Get_String -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ char * Get_String(char *tagname) { char *data_string; int fail = FALSE; if (debug) printf("Get_String\n"); if (strncmp(line_buffer, tagname, strlen(tagname))) { printf("Error in line (%d): Expected the tag %s\n", line_number, tagname); fail = TRUE; } else { char *cur_char; int data_length; cur_char = line_buffer + strlen(tagname) + 1; for (; isspace(*cur_char) && *cur_char; cur_char++); data_length = strlen(cur_char); if (data_length) { char *c; for (c = cur_char; *c; c++) if (*c eq '\n') *c = '\0'; if (data_string = calloc(data_length + 2, sizeof(char))) { strcpy(data_string, cur_char); } else { printf("Error: Out of Memory\n"); fail = TRUE; } } else { printf("Error in line (%d): No data following the tag %s\n", line_number, tagname); fail = TRUE; } } return (fail) ? NULL : data_string; } /*** Get_String ***/ /****** HallOfFame/Find_Player [0.5] * * * NAME * Find_Player -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ player * Find_Player(player * first_player, char *alias) { player *aPlayer; player *target_player; if (debug) printf("Find_Player\n"); for (aPlayer = first_player, target_player = NULL; aPlayer; aPlayer = aPlayer->next) { if (strcmp(aPlayer->alias, alias) eq 0) { target_player = aPlayer; } } if (target_player) return target_player; else { printf("Error: can't find the player with alias %s\n", alias); printf("Aborting Program\n"); printf("This error resulted from processing line\n(%d) %s", line_number, line_buffer); exit(100); } } /*** Find_Player ***/ /****** HallOfFame/Print_Players [0.5] * * * NAME * Print_Players -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ void Print_Players(player * first_player) { player *aPlayer; if (debug) printf("Print_Players\n"); for (aPlayer = first_player; aPlayer; aPlayer = aPlayer->next) { Print_Player(aPlayer); } } /*** Print_Players ***/ /****** HallOfFame/Print_Player [0.5] * * * NAME * Print_Player -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ void Print_Player(player * aPlayer) { printf("Alias:\t%s\n", aPlayer->alias); printf("Name:\t%s\n", aPlayer->name); printf("Email:\t%s\n", aPlayer->email); printf("VPs:\t%7.2f\n", aPlayer->victory_points); } /*** Print_Player ***/ /****** HallOfFame/Print_Games [0.5] * * * NAME * Print_Games -- * SYNOPSIS * FUNCTION * INPUTS * RESULT * NOTE * SOURCE */ void Print_Games(game * first_game) { game *aGame; for (aGame = first_game; aGame; aGame = aGame->next) { printf("Name:\t%s\n", aGame->name); printf("Game Master:\t%s\n", aGame->gm); printf("Number of Players:\t%d\n", aGame->number_of_players); } } /*** Print_Games ***/