home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume6 / xplumb / part01 / score.C < prev    next >
C/C++ Source or Header  |  1990-04-11  |  6KB  |  253 lines

  1. /*
  2.  * Copyright 1990 Digital Equipment Corporation
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and its
  5.  * documentation for any purpose and without fee is hereby granted,
  6.  * provided that the above copyright notice appear in all copies and that
  7.  * both that copyright notice and this permission notice appear in
  8.  * supporting documentation, and that the name of Digital Equipment
  9.  * Corporation not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  Digital Equipment Corporation makes no representations
  12.  * about the suitability of this software for any purpose.  It is
  13.  * provided "as is" without express or implied warranty.
  14.  *
  15.  * DIGITAL EQUIPMENT CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16.  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
  18.  * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20.  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  21.  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Terry Weissman
  24.  *          weissman@wsl.dec.com
  25.  */
  26.  
  27. #include <string.h>
  28. #include <stdio.h>
  29. #include "pwd.h"
  30. #include <time.h>
  31. #include <malloc.h>
  32. #include "plumbing.h"
  33.  
  34. extern int geteuid();
  35.  
  36. extern void qsort(char *, int, int, int (*)(void *, void *));
  37.  
  38. static int userid;
  39. static char username[100];
  40.  
  41.  
  42. ScoreRec::ScoreRec() {
  43.     score = 0;
  44.     countdown = -1;
  45. }
  46.  
  47. void ScoreRec::Repaint(Scrn scrn) {
  48.     Display *dpy = scrn->GetDpy();
  49.     Window window = scrn->GetWindow();
  50.     int x0 = scrn->GetScoreX();
  51.     int y0 = scrn->GetScoreY();
  52.     char buf[500];
  53.     if (countdown < 0) {
  54.     sprintf(buf, "Score: %d    Level: %d    Need: %d",
  55.         score, level, numtoget);
  56.     } else {
  57.     sprintf(buf,
  58.         "Score: %d    Level: %d    Need: %d     Flow in %d second%s!",
  59.         score, level, numtoget, countdown,
  60.         countdown == 1 ? "" : "s");
  61.     }
  62.     XFillRectangle(dpy, window, scrn->GetBackgroundGC(), x0, y0,
  63.            scrn->GetWidth(), SCOREHEIGHT);
  64.     XDrawString(dpy, window, scrn->GetForegroundGC(),
  65.         x0, y0 + SCOREHEIGHT / 2, buf, strlen(buf));
  66. }
  67.  
  68. void ScoreRec::Repaint() {
  69.     int i;
  70.     for (i=0 ; i<numscreens ; i++)
  71.     Repaint(screen[i]);
  72. }
  73.  
  74.  
  75.  
  76. static void TripCount(void *closure) {
  77.     Score score = (Score) closure;
  78.     score->SetCountDown(score->GetCountDown() - 1);
  79. }
  80.  
  81. void ScoreRec::SetCountDown(int c) {
  82.     countdown = c;
  83.     if (c >= 0) {
  84.     TimerAddTimeout(1000, TripCount, (void *) this);
  85.     if (c == 0) FlowStart();
  86.     }
  87.     Repaint();
  88. }
  89.  
  90.  
  91. void ScoreRec::AddScore(int d) {
  92.     score += d;
  93.     if (fastflow && d > 0) score += d;
  94.     if (score < 0) score = 0;
  95.     Repaint();
  96. }
  97.  
  98.  
  99. void ScoreRec::RecordScore() {
  100.     FILE *fid = fopen(SCOREFILE, "a");
  101.     if (!fid) return;
  102.     long t = time(NULL);
  103.     char *tstr = ctime(&t);
  104.     char *ptr = strchr(tstr, '\n');
  105.     if (ptr) *ptr = '\0';
  106.     fprintf(fid, "%s;%d;%d;%d;%s\n", tstr, score, level, userid, username);
  107.     fclose(fid);
  108. }
  109.  
  110.  
  111.  
  112. char *NameFromUid(int uid) {
  113.     static char result[100];
  114.     char *ptr;
  115.     extern passwd *getpwuid (int); // Should be in pwd.h, but isn't...
  116.     struct passwd *password = getpwuid(uid);
  117.     if (password && password->pw_gecos) {
  118.     strcpy(result, password->pw_gecos);
  119.     ptr = strchr(result, ',');
  120.     if (ptr) *ptr = 0;
  121.     return result;
  122.     } else {
  123.     sprintf(result, "<User %d>", uid);
  124.     return result;
  125.     }
  126. }
  127.     
  128.  
  129.  
  130. void ScoreInit() {
  131.     extern void srandom(int);
  132.     userid = geteuid();
  133.     strcpy(username, NameFromUid(userid));
  134.     
  135.     srandom(time(NULL));    // Silly place to init the random number,
  136.                 // generator, but what the hack...
  137. }
  138.  
  139.  
  140. struct ScoreInfo {
  141.     int uid;
  142.     int score;
  143.     int level;
  144.     int numgames;
  145. };
  146.  
  147.  
  148. static int Comparer(void *a, void *b) {
  149.     ScoreInfo *p1 = (ScoreInfo *) a;
  150.     ScoreInfo *p2 = (ScoreInfo *) b;
  151.     return p2->score - p1->score;
  152. }
  153.  
  154.  
  155. void ScoreGetHighScores(char *buf[10], int *numgames) {
  156.     static char result[10][200];
  157.     char str[500], *ptr;
  158.     ScoreInfo *list;
  159.     ScoreInfo mine[10];
  160.     int nummine = 0;
  161.     int num = 0;
  162.     int max = 100;
  163.     int i, j, low, high, uid, score, level;
  164.     Bool found;
  165.     list = (ScoreInfo *) malloc(max * sizeof(ScoreInfo));
  166.     FILE *fid = fopen(SCOREFILE, "r");
  167.     *numgames = 0;
  168.     if (!fid) {
  169.     buf[0] = NULL;
  170.     return;
  171.     }
  172.     while (fgets(str, 500, fid)) {
  173.     ptr = strchr(str, ';');
  174.     if (!ptr) continue;
  175.     score = atoi(ptr + 1);
  176.     ptr = strchr(ptr + 1, ';');
  177.     if (!ptr) continue;
  178.     level = atoi(ptr + 1);
  179.     ptr = strchr(ptr + 1, ';');
  180.     if (!ptr) continue;
  181.     uid = atoi(ptr + 1);
  182.     if (uid == userid) {
  183.         (*numgames)++;
  184.         if (nummine > 0 && score >= mine[nummine - 1].score) {
  185.         for (i=0 ; i<nummine ; i++) {
  186.             if (score >= mine[i].score) {
  187.             if (nummine < 10) nummine++;
  188.             for (j=nummine - 1 ; j>i ; j--) {
  189.                 mine[j] = mine[j-1];
  190.             }
  191.             mine[i].score = score;
  192.             mine[i].level = level;
  193.             break;
  194.             }
  195.         }
  196.         } else if (nummine < 10) {
  197.         mine[nummine].score = score;
  198.         mine[nummine].level = level;
  199.         nummine++;
  200.         }
  201.     }
  202.     low = 0;
  203.     high = num;
  204.     found = False;
  205.     while (low < high) {
  206.         i = (low + high) / 2;
  207.         if (list[i].uid == uid) {
  208.         found = True;
  209.         break;
  210.         } else if (list[i].uid > uid) high = i;
  211.         else low = i + 1;
  212.     }
  213.     if (found) {
  214.         list[i].numgames++;
  215.         if (score > list[i].score) {
  216.         list[i].score = score;
  217.         list[i].level = level;
  218.         }
  219.     } else {
  220.         num++;
  221.         if (num >= max) {
  222.         max += 100;
  223.         list = (ScoreInfo *) realloc((char *) list,
  224.                          max * sizeof(ScoreInfo));
  225.         }
  226.         for (i=num-1 ; i>low ; i--) {
  227.         list[i] = list[i-1];
  228.         }
  229.         list[low].uid = uid;
  230.         list[low].score = score;
  231.         list[low].level = level;
  232.         list[low].numgames = 1;
  233.     }
  234.     }
  235.     fclose(fid);
  236.     qsort((char *) list, num, sizeof(ScoreInfo), Comparer);
  237.     for (i=0 ; i<10 ; i++) {
  238.     if (i < nummine) {
  239.         sprintf(result[i], "%7d %3d    ", mine[i].score, mine[i].level);
  240.     } else {
  241.         strcpy(result[i], "               ");
  242.     }
  243.     if (i < num) {
  244.         sprintf(str, "%7d %3d %5d           %s",
  245.             list[i].score, list[i].level,
  246.             list[i].numgames, NameFromUid(list[i].uid));
  247.         strcat(result[i], str);
  248.     }
  249.     buf[i] = result[i];
  250.     }
  251.     free((char *) list);
  252. }
  253.