#include "os.h"
#include "wiz_list.h"
/* comm1.c */
extern void add_message(char *fmt, ...);
/* simulate.c */
extern void fatal(char *fmt, ...);
/* main.c */
extern void *xalloc(int size);
extern char *string_copy(char *str);
/*
* Maintain the wizards high score list about most popular castle.
*/
static struct wiz_list *all_wiz;
static struct wiz_list *insert (struct wiz_list *w, struct wiz_list *wl);
static void rebuild_list (void);
static struct wiz_list *find_wiz (char *name);
static void add_score(char *name, int score);
/*
* Sort the wiz list in ascending order.
*/
static struct wiz_list *insert (struct wiz_list *w, struct wiz_list *wl)
{
if (wl == 0) {
w->next = 0;
return w;
}
if (w->score > wl->score) {
wl->next = insert (w, wl->next);
return wl;
}
w->next = wl;
return w;
}
static void rebuild_list (void)
{
struct wiz_list *wl, *w, *new_list = 0;
for (w = all_wiz; w; w = wl) {
wl = w->next;
new_list = insert (w, new_list);
}
all_wiz = new_list;
}
/*
* Find the data, if it exists.
*/
static struct wiz_list *find_wiz (char *name)
{
int length;
struct wiz_list *wl;
length = strlen (name);
for (wl = all_wiz; wl; wl = wl->next)
if (wl->length == length && strcmp (wl->name, name) == 0)
return wl;
return 0;
}
/*
* Check that a name exists. Add it, if it doesn't.
*/
struct wiz_list *add_name (char *str)
{
struct wiz_list *wl;
wl = find_wiz (str);
if (wl)
return wl;
wl = (struct wiz_list *) xalloc (sizeof (struct wiz_list));
str = string_copy (str);
wl->name = str;
wl->length = strlen (str);
wl->score = 0;
wl->cost = 0;
wl->heart_beats = 0;
wl->total_worth = 0;
wl->next = all_wiz;
all_wiz = wl;
return wl;
}
/*
* Add score to an existing name.
*/
static void add_score (char *name, int score)
{
struct wiz_list *wl;
wl = find_wiz (name);
if (!wl)
fatal ("Add_score: could not find wizard %s\n", name);
wl->score += score;
}
/*
* This one is called at every complete walkaround of reset.
*/
void wiz_decay (void)
{
struct wiz_list *wl;
for (wl = all_wiz; wl; wl = wl->next) {
wl->score = wl->score * 99 / 100;
wl->total_worth = wl->total_worth * 99 / 100;
wl->cost = wl->cost * 9 / 10;
wl->heart_beats = wl->heart_beats * 9 / 10;
}
}
/*
* Load the wizlist file.
*/
void load_wiz_file (void)
{
char buff[1000]; /* I hate not knowing how much I need. */
FILE *f;
f = fopen ("WIZLIST", "r");
if (f == NULL)
return;
while (fgets (buff, sizeof buff, f)) {
char *p;
p = strchr (buff, ' ');
if (p == 0) {
fprintf (stderr, "Bad WIZLIST file.\n");
break;
}
*p = '\0';
p++;
if (*p == '\0') {
fprintf (stderr, "Bad WIZLIST file.\n");
break;
}
(void) add_name (buff);
add_score (buff, atoi (p));
}
fclose (f);
}
/*
* Save the wizlist file.
*/
void save_wiz_file (void)
{
struct wiz_list *wl;
FILE *f;
f = fopen ("WIZLIST", "w");
if (f == NULL) {
fprintf (stderr, "Could not open WIZLIST for write\n");
return;
}
for (wl = all_wiz; wl; wl = wl->next)
fprintf (f, "%s %d %d\n", wl->name, wl->score, wl->total_worth);
fclose (f);
}
/* Print out the wizlist file */
void wizlist (void)
{
struct wiz_list *wl;
int total = 0, num = 0;
rebuild_list ();
for (wl = all_wiz; wl; wl = wl->next) {
total += wl->score;
num++;
}
add_message ("\nWizard top score list\n\n");
for (wl = all_wiz; wl; wl = wl->next) {
if (wl->score)
add_message ("%-15s %5d %2d%% (%d)\t[%3dk,%5d] %d\n", wl->name,
wl->score, wl->score * 100 / total, num,
wl->cost / 1000, wl->heart_beats, wl->total_worth);
num--;
}
add_message ("\nTotal %7d\n\n", total);
}