xref: /original-bsd/games/robots/score.c (revision 43bfbc1c)
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
8 static char sccsid[] = "@(#)score.c	5.1 (Berkeley) 05/30/85";
9 #endif not lint
10 
11 # include	"robots.h"
12 # include	<pwd.h>
13 
14 typedef struct {
15 	int	s_uid;
16 	int	s_score;
17 	char	s_name[MAXNAME];
18 } SCORE;
19 
20 typedef struct passwd	PASSWD;
21 
22 char	*Scorefile = SCOREFILE;
23 
24 int	Max_per_uid = MAX_PER_UID;
25 
26 static SCORE	Top[MAXSCORES];
27 
28 /*
29  * score:
30  *	Post the player's score, if reasonable, and then print out the
31  *	top list.
32  */
33 score()
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 
110 set_name(scp)
111 register 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  */
124 cmp_sc(s1, s2)
125 register 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  */
134 show_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 }
156