home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume6
/
xplumb
/
part01
/
score.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-11
|
6KB
|
253 lines
/*
* Copyright 1990 Digital Equipment Corporation
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of Digital Equipment
* Corporation not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. Digital Equipment Corporation makes no representations
* about the suitability of this software for any purpose. It is
* provided "as is" without express or implied warranty.
*
* DIGITAL EQUIPMENT CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
* ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Terry Weissman
* weissman@wsl.dec.com
*/
#include <string.h>
#include <stdio.h>
#include "pwd.h"
#include <time.h>
#include <malloc.h>
#include "plumbing.h"
extern int geteuid();
extern void qsort(char *, int, int, int (*)(void *, void *));
static int userid;
static char username[100];
ScoreRec::ScoreRec() {
score = 0;
countdown = -1;
}
void ScoreRec::Repaint(Scrn scrn) {
Display *dpy = scrn->GetDpy();
Window window = scrn->GetWindow();
int x0 = scrn->GetScoreX();
int y0 = scrn->GetScoreY();
char buf[500];
if (countdown < 0) {
sprintf(buf, "Score: %d Level: %d Need: %d",
score, level, numtoget);
} else {
sprintf(buf,
"Score: %d Level: %d Need: %d Flow in %d second%s!",
score, level, numtoget, countdown,
countdown == 1 ? "" : "s");
}
XFillRectangle(dpy, window, scrn->GetBackgroundGC(), x0, y0,
scrn->GetWidth(), SCOREHEIGHT);
XDrawString(dpy, window, scrn->GetForegroundGC(),
x0, y0 + SCOREHEIGHT / 2, buf, strlen(buf));
}
void ScoreRec::Repaint() {
int i;
for (i=0 ; i<numscreens ; i++)
Repaint(screen[i]);
}
static void TripCount(void *closure) {
Score score = (Score) closure;
score->SetCountDown(score->GetCountDown() - 1);
}
void ScoreRec::SetCountDown(int c) {
countdown = c;
if (c >= 0) {
TimerAddTimeout(1000, TripCount, (void *) this);
if (c == 0) FlowStart();
}
Repaint();
}
void ScoreRec::AddScore(int d) {
score += d;
if (fastflow && d > 0) score += d;
if (score < 0) score = 0;
Repaint();
}
void ScoreRec::RecordScore() {
FILE *fid = fopen(SCOREFILE, "a");
if (!fid) return;
long t = time(NULL);
char *tstr = ctime(&t);
char *ptr = strchr(tstr, '\n');
if (ptr) *ptr = '\0';
fprintf(fid, "%s;%d;%d;%d;%s\n", tstr, score, level, userid, username);
fclose(fid);
}
char *NameFromUid(int uid) {
static char result[100];
char *ptr;
extern passwd *getpwuid (int); // Should be in pwd.h, but isn't...
struct passwd *password = getpwuid(uid);
if (password && password->pw_gecos) {
strcpy(result, password->pw_gecos);
ptr = strchr(result, ',');
if (ptr) *ptr = 0;
return result;
} else {
sprintf(result, "<User %d>", uid);
return result;
}
}
void ScoreInit() {
extern void srandom(int);
userid = geteuid();
strcpy(username, NameFromUid(userid));
srandom(time(NULL)); // Silly place to init the random number,
// generator, but what the hack...
}
struct ScoreInfo {
int uid;
int score;
int level;
int numgames;
};
static int Comparer(void *a, void *b) {
ScoreInfo *p1 = (ScoreInfo *) a;
ScoreInfo *p2 = (ScoreInfo *) b;
return p2->score - p1->score;
}
void ScoreGetHighScores(char *buf[10], int *numgames) {
static char result[10][200];
char str[500], *ptr;
ScoreInfo *list;
ScoreInfo mine[10];
int nummine = 0;
int num = 0;
int max = 100;
int i, j, low, high, uid, score, level;
Bool found;
list = (ScoreInfo *) malloc(max * sizeof(ScoreInfo));
FILE *fid = fopen(SCOREFILE, "r");
*numgames = 0;
if (!fid) {
buf[0] = NULL;
return;
}
while (fgets(str, 500, fid)) {
ptr = strchr(str, ';');
if (!ptr) continue;
score = atoi(ptr + 1);
ptr = strchr(ptr + 1, ';');
if (!ptr) continue;
level = atoi(ptr + 1);
ptr = strchr(ptr + 1, ';');
if (!ptr) continue;
uid = atoi(ptr + 1);
if (uid == userid) {
(*numgames)++;
if (nummine > 0 && score >= mine[nummine - 1].score) {
for (i=0 ; i<nummine ; i++) {
if (score >= mine[i].score) {
if (nummine < 10) nummine++;
for (j=nummine - 1 ; j>i ; j--) {
mine[j] = mine[j-1];
}
mine[i].score = score;
mine[i].level = level;
break;
}
}
} else if (nummine < 10) {
mine[nummine].score = score;
mine[nummine].level = level;
nummine++;
}
}
low = 0;
high = num;
found = False;
while (low < high) {
i = (low + high) / 2;
if (list[i].uid == uid) {
found = True;
break;
} else if (list[i].uid > uid) high = i;
else low = i + 1;
}
if (found) {
list[i].numgames++;
if (score > list[i].score) {
list[i].score = score;
list[i].level = level;
}
} else {
num++;
if (num >= max) {
max += 100;
list = (ScoreInfo *) realloc((char *) list,
max * sizeof(ScoreInfo));
}
for (i=num-1 ; i>low ; i--) {
list[i] = list[i-1];
}
list[low].uid = uid;
list[low].score = score;
list[low].level = level;
list[low].numgames = 1;
}
}
fclose(fid);
qsort((char *) list, num, sizeof(ScoreInfo), Comparer);
for (i=0 ; i<10 ; i++) {
if (i < nummine) {
sprintf(result[i], "%7d %3d ", mine[i].score, mine[i].level);
} else {
strcpy(result[i], " ");
}
if (i < num) {
sprintf(str, "%7d %3d %5d %s",
list[i].score, list[i].level,
list[i].numgames, NameFromUid(list[i].uid));
strcat(result[i], str);
}
buf[i] = result[i];
}
free((char *) list);
}