date and time created 85/05/30 18:36:31 by mckusick
[unix-history] / usr / src / games / robots / score.c
CommitLineData
3783acaf
KM
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8static char sccsid[] = "@(#)score.c 5.1 (Berkeley) %G%";
9#endif not lint
10
11# include "robots.h"
12# include <pwd.h>
13
14typedef struct {
15 int s_uid;
16 int s_score;
17 char s_name[MAXNAME];
18} SCORE;
19
20typedef struct passwd PASSWD;
21
22char *Scorefile = SCOREFILE;
23
24int Max_per_uid = MAX_PER_UID;
25
26static SCORE Top[MAXSCORES];
27
28/*
29 * score:
30 * Post the player's score, if reasonable, and then print out the
31 * top list.
32 */
33score()
34{
35 register int inf;
36 register SCORE *scp;
37 register int uid;
38 register bool done_show = FALSE;
39 static int numscores, max_uid;
40
41 Newscore = FALSE;
42 if ((inf = open(Scorefile, 2)) < 0) {
43 perror(Scorefile);
44 return;
45 }
46
47 if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid)
48 read(inf, Top, sizeof Top);
49 else {
50 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
51 scp->s_score = -1;
52 max_uid = Max_per_uid;
53 }
54
55 uid = getuid();
56 if (Top[MAXSCORES-1].s_score <= Score) {
57 numscores = 0;
58 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
59 if (scp->s_score < 0 ||
60 (scp->s_uid == uid && ++numscores == max_uid)) {
61 if (scp->s_score > Score)
62 break;
63 scp->s_score = Score;
64 scp->s_uid = uid;
65 set_name(scp);
66 Newscore = TRUE;
67 break;
68 }
69 if (scp == &Top[MAXSCORES]) {
70 Top[MAXSCORES-1].s_score = Score;
71 Top[MAXSCORES-1].s_uid = uid;
72 set_name(&Top[MAXSCORES-1]);
73 Newscore = TRUE;
74 }
75 if (Newscore)
76 qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
77 }
78
79 if (!Newscore) {
80 Full_clear = FALSE;
81 close(inf);
82 return;
83 }
84 else
85 Full_clear = TRUE;
86
87 for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
88 if (scp->s_score < 0)
89 break;
90 move((scp - Top) + 1, 15);
91 if (!done_show && scp->s_uid == uid && scp->s_score == Score)
92 standout();
93 printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name);
94 if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
95 standend();
96 done_show = TRUE;
97 }
98 }
99 Num_scores = scp - Top;
100 refresh();
101
102 if (Newscore) {
103 lseek(inf, 0L, 0);
104 write(inf, &max_uid, sizeof max_uid);
105 write(inf, Top, sizeof Top);
106 }
107 close(inf);
108}
109
110set_name(scp)
111register SCORE *scp;
112{
113 register PASSWD *pp;
114
115 if ((pp = getpwuid(scp->s_uid)) == NULL)
116 pp->pw_name = "???";
117 strncpy(scp->s_name, pp->pw_name, MAXNAME);
118}
119
120/*
121 * cmp_sc:
122 * Compare two scores.
123 */
124cmp_sc(s1, s2)
125register SCORE *s1, *s2;
126{
127 return s2->s_score - s1->s_score;
128}
129
130/*
131 * show_score:
132 * Show the score list for the '-s' option.
133 */
134show_score()
135{
136 register SCORE *scp;
137 register int inf;
138 static int max_score;
139
140 if ((inf = open(Scorefile, 0)) < 0) {
141 perror(Scorefile);
142 return;
143 }
144
145 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
146 scp->s_score = -1;
147
148 read(inf, &max_score, sizeof max_score);
149 read(inf, Top, sizeof Top);
150 close(inf);
151 inf = 1;
152 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
153 if (scp->s_score >= 0)
154 printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name);
155}