|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 4859 (0x12fb)
Types: TextFile
Names: »scores.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/Sun/Sdi/scores.c«
/********************************** scores.c **********************/
#include <pwd.h>
#include <stdio.h>
#include "sdi.h"
/*
* Copyright 1987 by Mark Weiser.
* Permission to reproduce and use in any manner whatsoever on Suns is granted
* so long as this copyright and other identifying marks of authorship
* in the code and the game remain intact and visible. Use of this code
* in other products is reserved to me--I'm working on Mac and IBM versions.
*/
/*
* This code is responsible
* reading, updating, and displaying the score file.
*/
#ifndef SCOREFILE
#define SCOREFILE "/usr/games/lib/sdi_scores"
#endif
struct scores *get_scores();
/* Already updated is used to prevent rewriting the score file more than
* once per game.
*/
static int already_updated = 0;
/*
* This routine is called whenever there is absolutely positively a new
* game beginning, and so if it ever gets anywhere it is ok to update
* the score file.
*/
new_score()
{
already_updated = 0;
}
/*
* Read in the old scores and insert the current game score into the file
* if it is within the top ten. No scores are recorded in gamemaster mode.
*/
update_scores()
{
extern int gamemaster;
struct scores *scp, *new_pos = NULL;
int i;
int score = atol((char *)panel_get_value(score_item));
int level = atol((char *)panel_get_value(level_item));
int skill = (int)panel_get_value(skill_item);
if (already_updated || gamemaster)
return;
if ((scp = get_scores()) == NULL)
return;
while (scp->score > score) {
scp += 1;
}
if (scp->score >= 0) {
struct scores *new_sc = sc_end;
while (--new_sc > scp) {
strcpy(new_sc->name, (new_sc-1)->name);
new_sc->score = (new_sc-1)->score;
new_sc->level = (new_sc-1)->level;
new_sc->skill = (new_sc-1)->skill;
}
strcpy(scp->name, USER_NAME);
scp->score = score;
scp->level = level;
scp->skill = skill;
}
if (! put_scores(sc)) {
printf("Could not write to score file '%s'.\n",scorefile);
}
already_updated = 1;
}
/*
* Get the name of the current user.
*/
char *
get_name()
{
char *s;
struct passwd *p;
if (s = (char *)getlogin())
return s;
p = (struct passwd *)getpwuid(getuid());
return p->pw_name;
}
/*
* Read the score file. The format is obvious. Exactly 11 scores are always
* returned. The 11th is a sentinal with score '-1'. If the score file did
* not have 10, then the extras are for user '(nobody)', score 0.
* A user name may not contain a "'". The result of get_scores is an array
* of score structures, statically allocated.
*/
struct scores *
get_scores()
{
struct scores *scp;
char *tmpfile, *getenv();
FILE *f;
if (scorefile) {
tmpfile = scorefile;
} else if ((tmpfile = getenv("SDI_SCORES")) == NULL) {
tmpfile = scorefile;
} else {
tmpfile = "/usr/games/lib/sdi_scores";
}
/* Try hard to open some kind of score file */
if (((f = fopen(tmpfile, "r+")) == NULL)) {
tmpfile = SCOREFILE;
if (((f = fopen(tmpfile, "r+")) == NULL)) {
tmpfile = "/usr/games/lib/sdi_scores";
if ((f = fopen("/usr/games/lib/sdi_scores", "r+")) == NULL)
return NULL;
}
}
scorefile = tmpfile;
/* read entries */
scp = sc;
while (scp < sc_end &&
(fscanf(f, " '%[^']' %d %d %d", scp->name, &scp->score, &scp->level, &scp->skill) == 4) &&
scp->score > 0) {
scp += 1;
}
while (scp < sc_end) {
strcpy(scp->name, "(nobody)");
scp->score = 0;
scp->level = 0;
scp->skill = 0;
scp += 1;
}
scp->score = -1;
fclose(f);
return sc;
}
/*
* Write a list of scores to the score file. Never called directly, except
* by update_scores.
*/
put_scores(scp)
struct scores *scp;
{
FILE *f;
if ((f = fopen(scorefile, "w")) == NULL)
return 0;
/* write entries */
while (scp->score > 0) {
fprintf(f, "'%s' %d %d %d\n", scp->name, scp->score, scp->level, scp->skill);
scp += 1;
}
fclose(f);
return 1;
}
/*
* This routine formats the score file for display when the 'scores'
* button is pressed.
*/
static char string_for_build_scores[1024];
char *
build_scores()
{
char *sp = string_for_build_scores;
struct scores *scp;
char *type_of_skill;
scp = (struct scores *)get_scores();
if (scp == NULL) {
strcpy(sp, "Could not find a score file.");
} else {
strcpy(sp, "No scores yet: play some games.");
while (scp->score > 0) {
switch(scp->skill) {
case 0:
type_of_skill = " novice";
break;
case 1:
type_of_skill = "n occasional user";
break;
case 2:
type_of_skill = "n expert";
break;
}
sprintf(sp,
"%s, playing as a%s, melted with score %d at level %d.\n",
scp->name, type_of_skill, scp->score, scp->level);
scp += 1;
sp += strlen(sp);
}
}
return string_for_build_scores;
}
/*
* Free the result of a call to build_scores.
*/
free_scores(a)
char **a;
{
/* Oh, how I long for garbage collection. */
while (*++a)
free(*a);
}