Home | History | Annotate | Line # | Download | only in robots
score.c revision 1.3
      1 /*	$NetBSD: score.c,v 1.3 1995/04/22 10:09:12 cgd Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1980, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the University of
     18  *	California, Berkeley and its contributors.
     19  * 4. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #ifndef lint
     37 #if 0
     38 static char sccsid[] = "@(#)score.c	8.1 (Berkeley) 5/31/93";
     39 #else
     40 static char rcsid[] = "$NetBSD: score.c,v 1.3 1995/04/22 10:09:12 cgd Exp $";
     41 #endif
     42 #endif /* not lint */
     43 
     44 # include	"robots.h"
     45 # include	<sys/types.h>
     46 # include	<pwd.h>
     47 # include	"pathnames.h"
     48 
     49 typedef struct {
     50 	int	s_uid;
     51 	int	s_score;
     52 	char	s_name[MAXNAME];
     53 } SCORE;
     54 
     55 typedef struct passwd	PASSWD;
     56 
     57 char	*Scorefile = _PATH_SCORE;
     58 
     59 int	Max_per_uid = MAX_PER_UID;
     60 
     61 static SCORE	Top[MAXSCORES];
     62 
     63 /*
     64  * score:
     65  *	Post the player's score, if reasonable, and then print out the
     66  *	top list.
     67  */
     68 score()
     69 {
     70 	register int	inf;
     71 	register SCORE	*scp;
     72 	register int	uid;
     73 	register bool	done_show = FALSE;
     74 	static int	numscores, max_uid;
     75 
     76 	Newscore = FALSE;
     77 	if ((inf = open(Scorefile, 2)) < 0) {
     78 		perror(Scorefile);
     79 		return;
     80 	}
     81 
     82 	if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid)
     83 		read(inf, Top, sizeof Top);
     84 	else {
     85 		for (scp = Top; scp < &Top[MAXSCORES]; scp++)
     86 			scp->s_score = -1;
     87 		max_uid = Max_per_uid;
     88 	}
     89 
     90 	uid = getuid();
     91 	if (Top[MAXSCORES-1].s_score <= Score) {
     92 		numscores = 0;
     93 		for (scp = Top; scp < &Top[MAXSCORES]; scp++)
     94 			if (scp->s_score < 0 ||
     95 			    (scp->s_uid == uid && ++numscores == max_uid)) {
     96 				if (scp->s_score > Score)
     97 					break;
     98 				scp->s_score = Score;
     99 				scp->s_uid = uid;
    100 				set_name(scp);
    101 				Newscore = TRUE;
    102 				break;
    103 			}
    104 		if (scp == &Top[MAXSCORES]) {
    105 			Top[MAXSCORES-1].s_score = Score;
    106 			Top[MAXSCORES-1].s_uid = uid;
    107 			set_name(&Top[MAXSCORES-1]);
    108 			Newscore = TRUE;
    109 		}
    110 		if (Newscore)
    111 			qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
    112 	}
    113 
    114 	if (!Newscore) {
    115 		Full_clear = FALSE;
    116 		close(inf);
    117 		return;
    118 	}
    119 	else
    120 		Full_clear = TRUE;
    121 
    122 	for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
    123 		if (scp->s_score < 0)
    124 			break;
    125 		move((scp - Top) + 1, 15);
    126 		if (!done_show && scp->s_uid == uid && scp->s_score == Score)
    127 			standout();
    128 		printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name);
    129 		if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
    130 			standend();
    131 			done_show = TRUE;
    132 		}
    133 	}
    134 	Num_scores = scp - Top;
    135 	refresh();
    136 
    137 	if (Newscore) {
    138 		lseek(inf, 0L, 0);
    139 		write(inf, &max_uid, sizeof max_uid);
    140 		write(inf, Top, sizeof Top);
    141 	}
    142 	close(inf);
    143 }
    144 
    145 set_name(scp)
    146 register SCORE	*scp;
    147 {
    148 	register PASSWD	*pp;
    149 
    150 	if ((pp = getpwuid(scp->s_uid)) == NULL)
    151 		pp->pw_name = "???";
    152 	strncpy(scp->s_name, pp->pw_name, MAXNAME);
    153 }
    154 
    155 /*
    156  * cmp_sc:
    157  *	Compare two scores.
    158  */
    159 cmp_sc(s1, s2)
    160 register SCORE	*s1, *s2;
    161 {
    162 	return s2->s_score - s1->s_score;
    163 }
    164 
    165 /*
    166  * show_score:
    167  *	Show the score list for the '-s' option.
    168  */
    169 show_score()
    170 {
    171 	register SCORE	*scp;
    172 	register int	inf;
    173 	static int	max_score;
    174 
    175 	if ((inf = open(Scorefile, 0)) < 0) {
    176 		perror(Scorefile);
    177 		return;
    178 	}
    179 
    180 	for (scp = Top; scp < &Top[MAXSCORES]; scp++)
    181 		scp->s_score = -1;
    182 
    183 	read(inf, &max_score, sizeof max_score);
    184 	read(inf, Top, sizeof Top);
    185 	close(inf);
    186 	inf = 1;
    187 	for (scp = Top; scp < &Top[MAXSCORES]; scp++)
    188 		if (scp->s_score >= 0)
    189 			printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name);
    190 }
    191