diff options
Diffstat (limited to 'FICS/ratings.c.orig')
-rw-r--r-- | FICS/ratings.c.orig | 1432 |
1 files changed, 0 insertions, 1432 deletions
diff --git a/FICS/ratings.c.orig b/FICS/ratings.c.orig deleted file mode 100644 index 37e26f9..0000000 --- a/FICS/ratings.c.orig +++ /dev/null @@ -1,1432 +0,0 @@ -/* - ratings.c - - fics - An internet chess server. - Copyright (C) 1993 Richard V. Nash - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ - -/* Revision history: - name email yy/mm/dd Change - Richard Nash 93/10/22 Created - vek leeds@math.gatech.edu 95/04/05 Glicko system, with sterr -*/ - -#include "stdinclude.h" - -#include "common.h" -#include "playerdb.h" -#include "ratings.h" -#include "gamedb.h" -#include "command.h" -#include "comproc.h" -#include "lists.h" -#include "ficsmain.h" -#include "config.h" -#include "utils.h" - -/* grimm */ -#if defined(SGI) -#else -/* int system(char *arg); */ -/* int rewind(FILE *stream); */ -#endif - - -PUBLIC double Ratings_B_Average; -PUBLIC double Ratings_B_StdDev; - -PUBLIC double Ratings_S_Average; -PUBLIC double Ratings_S_StdDev; - -PUBLIC double Ratings_W_Average; -PUBLIC double Ratings_W_StdDev; - -PRIVATE double Rb_M = 0.0, Rb_S = 0.0, Rb_total = 0.0; -PRIVATE int Rb_count = 0; - -PRIVATE double Rs_M = 0.0, Rs_S = 0.0, Rs_total = 0.0; -PRIVATE int Rs_count = 0; - -PRIVATE double Rw_M = 0.0, Rw_S = 0.0, Rw_total = 0.0; -PRIVATE int Rw_count = 0; - -/* -PUBLIC rateStruct bestS[MAX_BEST]; -PUBLIC int numS = 0; -PUBLIC rateStruct bestB[MAX_BEST]; -PUBLIC int numB = 0; -PUBLIC rateStruct bestW[MAX_BEST]; -PUBLIC int numW = 0; -*/ - -#define MAXHIST 30 -#define LOWESTHIST 800 -PUBLIC int sHist[MAXHIST]; -PUBLIC int bHist[MAXHIST]; -PUBLIC int wHist[MAXHIST]; - -char sdir[] = DEFAULT_STATS; - -PUBLIC int is_active(int Games) -{ - return (Games >= PROVISIONAL); -} - - -PUBLIC void rating_add(int rating, int type) -{ - int which; - - which = (rating - LOWESTHIST) / 100; - if (which < 0) - which = 0; - if (which >= MAXHIST) - which = MAXHIST - 1; - if (type == TYPE_BLITZ) { - bHist[which] += 1; - Rb_count++; - Rb_total += rating; - if (Rb_count == 1) { - Rb_M = rating; - } else { - Rb_S = Rb_S + (rating - Rb_M) * (rating - Rb_M); - Rb_M = Rb_M + (rating - Rb_M) / (Rb_count); - } - Ratings_B_StdDev = sqrt(Rb_S / Rb_count); - Ratings_B_Average = Rb_total / (double) Rb_count; - } else if (type == TYPE_WILD) { /* TYPE_WILD */ - wHist[which] += 1; - Rw_count++; - Rw_total += rating; - if (Rw_count == 1) { - Rw_M = rating; - } else { - Rw_S = Rw_S + (rating - Rw_M) * (rating - Rw_M); - Rw_M = Rw_M + (rating - Rw_M) / (Rw_count); - } - Ratings_W_StdDev = sqrt(Rw_S / Rw_count); - Ratings_W_Average = Rw_total / (double) Rw_count; - } else { /* TYPE_STAND */ - sHist[which] += 1; - Rs_count++; - Rs_total += rating; - if (Rs_count == 1) { - Rs_M = rating; - } else { - Rs_S = Rs_S + (rating - Rs_M) * (rating - Rs_M); - Rs_M = Rs_M + (rating - Rs_M) / (Rs_count); - } - Ratings_S_StdDev = sqrt(Rs_S / Rs_count); - Ratings_S_Average = Rs_total / (double) Rs_count; - } -} - -PUBLIC void rating_remove(int rating, int type) -{ - int which; - - which = (rating - LOWESTHIST) / 100; - if (which < 0) - which = 0; - if (which >= MAXHIST) - which = MAXHIST - 1; - if (type == TYPE_BLITZ) { - bHist[which] = bHist[which] - 1; - if (bHist[which] < 0) - bHist[which] = 0; - if (Rb_count == 0) - return; - Rb_count--; - Rb_total -= rating; - if (Rb_count == 0) { - Rb_M = 0; - Rb_S = 0; - } else { - Rb_M = Rb_M - (rating - Rb_M) / (Rb_count); - Rb_S = Rb_S - (rating - Rb_M) * (rating - Rb_M); - /* added this 3.11.95 foxbat */ if (Rb_S < 0) - Rb_S = 0; - } - if (Rb_count) { - Ratings_B_StdDev = sqrt(Rb_S / Rb_count); - Ratings_B_Average = Rb_total / (double) Rb_count; - } else { - Ratings_B_StdDev = 0; - Ratings_B_Average = 0; - } - } else if (type == TYPE_WILD) { /* TYPE_WILD */ - wHist[which] = wHist[which] - 1; - if (wHist[which] < 0) - wHist[which] = 0; - if (Rw_count == 0) - return; - Rw_count--; - Rw_total -= rating; - if (Rw_count == 0) { - Rw_M = 0; - Rw_S = 0; - } else { - Rw_M = Rw_M - (rating - Rw_M) / (Rw_count); - Rw_S = Rw_S - (rating - Rw_M) * (rating - Rw_M); - /* added this 3.10.95 foxbat */ if (Rw_S < 0) - Rw_S = 0; - } - if (Rw_count) { - Ratings_W_StdDev = sqrt(Rw_S / Rw_count); - Ratings_W_Average = Rw_total / (double) Rw_count; - } else { - Ratings_W_StdDev = 0; - Ratings_W_Average = 0; - } - } else { /* TYPE_STAND */ - sHist[which] = sHist[which] - 1; - if (sHist[which] < 0) - sHist[which] = 0; - if (Rs_count == 0) - return; - Rs_count--; - Rs_total -= rating; - if (Rs_count == 0) { - Rs_M = 0; - Rs_S = 0; - } else { - Rs_M = Rs_M - (rating - Rs_M) / (Rs_count); - Rs_S = Rs_S - (rating - Rs_M) * (rating - Rs_M); - /* added this 3.10.95 foxbat */ if (Rs_S < 0) - Rs_S = 0; - } - if (Rs_count) { - Ratings_S_StdDev = sqrt(Rs_S / Rs_count); - Ratings_S_Average = Rs_total / (double) Rs_count; - } else { - Ratings_S_StdDev = 0; - Ratings_S_Average = 0; - } - } -} - -PRIVATE void load_ratings(void) -{ - FILE *fp; - char fname[MAX_FILENAME_SIZE]; - int i; - - sprintf(fname, "%s/newratings_data", stats_dir); - fp = fopen(fname, "r"); - if (!fp) { - fprintf(stderr, "FICS: Can't read ratings data!\n"); - return; - } - fscanf(fp, "%lf %lf %lf %d", &Rb_M, &Rb_S, &Rb_total, &Rb_count); - fscanf(fp, "%lf %lf %lf %d", &Rs_M, &Rs_S, &Rs_total, &Rs_count); - fscanf(fp, "%lf %lf %lf %d", &Rw_M, &Rw_S, &Rw_total, &Rw_count); -/* loon testing - fscanf(fp, "%d", &numB); - for (i = 0; i < numB; i++) { - fscanf(fp, "%s %d", bestB[i].name, &(bestB[i].rating)); - } - fscanf(fp, "%d", &numS); - for (i = 0; i < numS; i++) { - fscanf(fp, "%s %d", bestS[i].name, &bestS[i].rating); - } - fscanf(fp, "%d", &numW); - for (i = 0; i < numW; i++) { - fscanf(fp, "%s %d", bestW[i].name, &bestW[i].rating); - } -*/ - for (i = 0; i < MAXHIST; i++) { - fscanf(fp, "%d %d %d", &sHist[i], &bHist[i], &wHist[i]); - } - fclose(fp); - if (Rs_count) { - Ratings_S_StdDev = sqrt(Rs_S / Rs_count); - Ratings_S_Average = Rs_total / (double) Rs_count; - } else { - Ratings_S_StdDev = 0; - Ratings_S_Average = 0; - } - if (Rb_count) { - Ratings_B_StdDev = sqrt(Rb_S / Rb_count); - Ratings_B_Average = Rb_total / (double) Rb_count; - } else { - Ratings_B_StdDev = 0; - Ratings_B_Average = 0; - } - if (Rw_count) { - Ratings_W_StdDev = sqrt(Rw_S / Rw_count); - Ratings_W_Average = Rw_total / (double) Rw_count; - } else { - Ratings_W_StdDev = 0; - Ratings_W_Average = 0; - } -} - -PUBLIC void save_ratings(void) -{ - FILE *fp; - char fname[MAX_FILENAME_SIZE]; - int i; - - sprintf(fname, "%s/newratings_data", stats_dir); - fp = fopen(fname, "w"); - if (!fp) { - fprintf(stderr, "FICS: Can't write ratings data!\n"); - return; - } - fprintf(fp, "%10f %10f %10f %d\n", Rb_M, Rb_S, Rb_total, Rb_count); - fprintf(fp, "%10f %10f %10f %d\n", Rs_M, Rs_S, Rs_total, Rs_count); - fprintf(fp, "%10f %10f %10f %d\n", Rw_M, Rw_S, Rw_total, Rw_count); -/* loon testing - fprintf(fp, "%d\n", numB); - for (i = 0; i < numB; i++) { - fprintf(fp, "%s %d\n", bestB[i].name, bestB[i].rating); - } - fprintf(fp, "%d\n", numS); - for (i = 0; i < numS; i++) { - fprintf(fp, "%s %d\n", bestS[i].name, bestS[i].rating); - } - fprintf(fp, "%d\n", numW); - for (i = 0; i < numW; i++) { - fprintf(fp, "%s %d\n", bestW[i].name, bestW[i].rating); - } -*/ - for (i = 0; i < MAXHIST; i++) { - fprintf(fp, "%d %d %d\n", sHist[i], bHist[i], wHist[i]); - } - fclose(fp); -} - -/* -PRIVATE void BestRemove(int p) -{ - int i; - - for (i = 0; i < numB; i++) { - if (!strcmp(bestB[i].name, parray[p].name)) - break; - } - if (i < numB) { - for (; i < numB - 1; i++) { - strcpy(bestB[i].name, bestB[i + 1].name); - bestB[i].rating = bestB[i + 1].rating; - } - numB--; - } - for (i = 0; i < numS; i++) { - if (!strcmp(bestS[i].name, parray[p].name)) - break; - } - if (i < numS) { - for (; i < numS - 1; i++) { - strcpy(bestS[i].name, bestS[i + 1].name); - bestS[i].rating = bestS[i + 1].rating; - } - numS--; - } - for (i = 0; i < numW; i++) { - if (!strcmp(bestW[i].name, parray[p].name)) - break; - } - if (i < numW) { - for (; i < numW - 1; i++) { - strcpy(bestW[i].name, bestW[i + 1].name); - bestW[i].rating = bestW[i + 1].rating; - } - numW--; - } -} - -PRIVATE void BestAdd(int p) -{ - int where, j; - - if ((parray[p].b_stats.rating > 0) && (parray[p].b_stats.num > 19)) { - for (where = 0; where < numB; where++) { - if (parray[p].b_stats.rating > bestB[where].rating) - break; - } - if (where < MAX_BEST) { - for (j = numB; j > where; j--) { - if (j == MAX_BEST) - continue; - strcpy(bestB[j].name, bestB[j - 1].name); - bestB[j].rating = bestB[j - 1].rating; - } - strcpy(bestB[where].name, parray[p].name); - bestB[where].rating = parray[p].b_stats.rating; - if (numB < MAX_BEST) - numB++; - } - } - if ((parray[p].s_stats.rating > 0) && (parray[p].s_stats.num > 19)) { - for (where = 0; where < numS; where++) { - if (parray[p].s_stats.rating > bestS[where].rating) - break; - } - if (where < MAX_BEST) { - for (j = numS; j > where; j--) { - if (j == MAX_BEST) - continue; - strcpy(bestS[j].name, bestS[j - 1].name); - bestS[j].rating = bestS[j - 1].rating; - } - strcpy(bestS[where].name, parray[p].name); - bestS[where].rating = parray[p].s_stats.rating; - if (numS < MAX_BEST) - numS++; - } - } - if ((parray[p].w_stats.rating > 0) && (parray[p].w_stats.num > 19)) { - for (where = 0; where < numW; where++) { - if (parray[p].w_stats.rating > bestW[where].rating) - break; - } - if (where < MAX_BEST) { - for (j = numW; j > where; j--) { - if (j == MAX_BEST) - continue; - strcpy(bestW[j].name, bestW[j - 1].name); - bestW[j].rating = bestW[j - 1].rating; - } - strcpy(bestW[where].name, parray[p].name); - bestW[where].rating = parray[p].w_stats.rating; - if (numW < MAX_BEST) - numW++; - } - } -} - -PUBLIC void BestUpdate(int p) -{ - BestRemove(p); - BestAdd(p); -} - -*/ - -PUBLIC void zero_stats(void) -{ - int i; - for (i = 0; i < MAXHIST; i++) { - sHist[i] = 0; - bHist[i] = 0; - wHist[i] = 0; - } - Rb_M = 0.0, Rb_S = 0.0, Rb_total = 0.0; - Rb_count = 0; - - Rs_M = 0.0, Rs_S = 0.0, Rs_total = 0.0; - Rs_count = 0; - - Rw_M = 0.0, Rw_S = 0.0, Rw_total = 0.0; - Rw_count = 0; - -/* - numS = 0; - numB = 0; - numW = 0; -*/ -} - -PUBLIC void rating_init(void) -{ - zero_stats(); - load_ratings(); -} - -/* This recalculates the rating info from the player data, it can take - a long time! */ -PUBLIC void rating_recalc(void) -{ - char dname[MAX_FILENAME_SIZE]; - int p1; - int c; - int t = time(0); - DIR *dirp; -#if USE_DIRENT - struct dirent *dp; -#else - struct direct *dp; -#endif - - fprintf(stderr, "FICS: Recalculating ratings at %s\n", strltime(&t)); - zero_stats(); - for (c = 'a'; c <= 'z'; c++) { - /* Never done as ratings server */ - sprintf(dname, "%s/%c", player_dir, c); - dirp = opendir(dname); - if (!dirp) - continue; - for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { - if (dp->d_name[0] != '.') { - p1 = player_new(); - if (player_read(p1, dp->d_name)) { - player_remove(p1); - fprintf(stderr, "FICS: Problem reading player %s.\n", dp->d_name); - continue; - } - if (parray[p1].b_stats.rating > 0) { - rating_add(parray[p1].b_stats.rating, TYPE_BLITZ); - } - if (parray[p1].s_stats.rating > 0) { - rating_add(parray[p1].s_stats.rating, TYPE_STAND); - } - if (parray[p1].w_stats.rating > 0) { - rating_add(parray[p1].w_stats.rating, TYPE_WILD); - } - player_remove(p1); - } - } - closedir(dirp); - } - if (Rs_count) { - Ratings_S_StdDev = sqrt(Rs_S / Rs_count); - Ratings_S_Average = Rs_total / (double) Rs_count; - } else { - Ratings_S_StdDev = 0; - Ratings_S_Average = 0; - } - if (Rb_count) { - Ratings_B_StdDev = sqrt(Rb_S / Rb_count); - Ratings_B_Average = Rb_total / (double) Rb_count; - } else { - Ratings_B_StdDev = 0; - Ratings_B_Average = 0; - } - if (Rw_count) { - Ratings_W_StdDev = sqrt(Rw_S / Rw_count); - Ratings_W_Average = Rw_total / (double) Rw_count; - } else { - Ratings_W_StdDev = 0; - Ratings_W_Average = 0; - } - save_ratings(); - t = time(0); - fprintf(stderr, "FICS: Finished at %s\n", strltime(&t)); -} - -/* Constants for Glicko system */ -#define Gd 3.25 -#define Gr0 1720 -#define Gs0 350 -#define Gq 0.00575646273249 -#define Gp 0.000010072398601964 - -/* End of Glicko system variables */ - -PRIVATE double Gf(double ss) -{ - return (1.0 / sqrt(1.0 + Gp * ss * ss)); -} - -/* Confusing but economical: calculate error and attenuation function together */ -PRIVATE double GE(int r, int rr, double ss, double *fss) -{ - *fss = Gf(ss); - return (1.0 / (1.0 + pow(10.0, (rr - r) * (*fss) / 400.0))); -} - -PUBLIC double current_sterr(double s, int t) -{ - if (t < 0) - t = 0; /* this shouldn't happen */ - return (sqrt(s * s + Gd * Gd * log(1.0 + t / 60.0))); -} - -/* Calculates new rating and standard error. By vek. The person */ -/* who invented the ratings system is Mark E. Glickman, Ph.D. */ -/* His e-mail address is glickman@hustat.harvard.edu as of April '95. */ -/* Postscript copy of the note I coded this from should be available */ -/* for ftp from ics.onenet.net, if not elsewhere. */ - -PUBLIC void rating_sterr_delta(int p1, int p2, int type, int gtime, int result, - int *deltarating, double *newsterr) -{ - statistics *p1_stats; - statistics *p2_stats; - - double s1, s2; - int t1, r1, t2, r2; /* Initial sterrs and ratings */ - double E, fs2, denominator, GK, w; /* Parts of fancy formulas */ - double delta, sigma; /* Results to return */ - - if (type == TYPE_BLITZ) { - p1_stats = &parray[p1].b_stats; - p2_stats = &parray[p2].b_stats; - } else if (type == TYPE_WILD) { - p1_stats = &parray[p1].w_stats; - p2_stats = &parray[p2].w_stats; - } else { - p1_stats = &parray[p1].s_stats; - p2_stats = &parray[p2].s_stats; - } - - /* Calculate effective pre-game sterrs. ltime==0 implies never had sterr. */ - - if (p1_stats->ltime == 0) - s1 = Gs0; - else { - t1 = gtime - p1_stats->ltime; - s1 = current_sterr(p1_stats->sterr, t1); - if (s1 > Gs0) - s1 = Gs0; - } - - if (p2_stats->ltime == 0) - s2 = Gs0; - else { - t2 = gtime - p2_stats->ltime; - s2 = current_sterr(p2_stats->sterr, t2); - if (s2 > Gs0) - s2 = Gs0; - } - - /* pre-game ratings */ - if (p1_stats->rating == 0 && p1_stats->num == 0) - r1 = Gr0; - else - r1 = p1_stats->rating; - - if (p2_stats->rating == 0 && p2_stats->num == 0) - r2 = Gr0; - else - r2 = p2_stats->rating; - - /* now crunch */ - - if (result == RESULT_WIN) { - w = 1.0; - } else if (result == RESULT_DRAW) { - w = 0.5; - } else { - w = 0.0; - } - - E = GE(r1, r2, s2, &fs2); /* side effect: calculate fs2 */ - - denominator = 1.0 / (s1 * s1) + Gq * Gq * fs2 * fs2 * E * (1.0 - E); - GK = Gq * fs2 / denominator; - - delta = GK * (w - E); - if (p1_stats->rating == 0 && p1_stats->num == 0) - *deltarating = (int) (Gr0 + delta + 0.5); - else - *deltarating = (int) delta + 0.5; /* Returned values: deltarating, - newsterr */ - - sigma = 1.0 / sqrt(denominator); - *newsterr = (double) sigma; - -} - -/* vek: Next is for when we want just the delta, and not the sigma. */ - -PUBLIC int rating_delta(int p1, int p2, int type, int result, int gtime) -{ - int delta; - double sigma; - - rating_sterr_delta(p1, p2, type, gtime, result, &delta, &sigma); - return (delta); - -} - -PUBLIC int rating_update(int g) -{ - int wDelta, bDelta; - double wSigma, bSigma; /* vek */ - - int wRes, bRes; - statistics *w_stats; - statistics *b_stats; - - int gtime; - - int inprogress = (g == parray[garray[g].black].game); - /* if this is adjudication of stored game, be quiet about ratings change */ - - if (garray[g].type == TYPE_BLITZ) { - w_stats = &parray[garray[g].white].b_stats; - b_stats = &parray[garray[g].black].b_stats; - } else if (garray[g].type == TYPE_STAND) { - w_stats = &parray[garray[g].white].s_stats; - b_stats = &parray[garray[g].black].s_stats; - } else if (garray[g].type == TYPE_WILD) { - w_stats = &parray[garray[g].white].w_stats; - b_stats = &parray[garray[g].black].w_stats; - } else { - fprintf(stderr, "FICS: Can't update untimed ratings!\n"); - return -1; - } - - switch (garray[g].result) { - case END_CHECKMATE: - case END_RESIGN: - case END_FLAG: - case END_ADJWIN: - if (garray[g].winner == WHITE) { - wRes = RESULT_WIN; - bRes = RESULT_LOSS; - } else { - bRes = RESULT_WIN; - wRes = RESULT_LOSS; - } - break; - case END_AGREEDDRAW: - case END_REPETITION: - case END_50MOVERULE: - case END_STALEMATE: - case END_NOMATERIAL: - case END_BOTHFLAG: - case END_ADJDRAW: - case END_FLAGNOMATERIAL: - wRes = bRes = RESULT_DRAW; - break; - default: - fprintf(stderr, "FICS: Update undecided game %d?\n", garray[g].result); - return -1; - } - gtime = untenths(garray[g].timeOfStart); - rating_sterr_delta(garray[g].white, garray[g].black, - garray[g].type, gtime, wRes, - &wDelta, &wSigma); - - rating_sterr_delta(garray[g].black, garray[g].white, - garray[g].type, gtime, bRes, - &bDelta, &bSigma); - - /* vek: Update time of last rated game played, for future ratings calcs. */ - /* Kept independently for blitz and standard. */ - w_stats->ltime = gtime; - b_stats->ltime = gtime; - /* end vek add 4/5/95 */ - - if (wRes == RESULT_WIN) { - w_stats->win++; - } else if (wRes == RESULT_LOSS) { - w_stats->los++; - } else { - w_stats->dra++; - } - w_stats->num++; - if (bRes == RESULT_WIN) { - b_stats->win++; - } else if (bRes == RESULT_LOSS) { - b_stats->los++; - } else { - b_stats->dra++; - } - b_stats->num++; - rating_remove(w_stats->rating, garray[g].type); - rating_remove(b_stats->rating, garray[g].type); - - if (inprogress) { - pprintf(garray[g].white, "%s rating adjustment: %d ", - ((garray[g].type == TYPE_BLITZ) ? "Blitz" : ((garray[g].type == TYPE_WILD) ? "Wild" : "Standard")), w_stats->rating); - pprintf(garray[g].black, "%s rating adjustment: %d ", - ((garray[g].type == TYPE_BLITZ) ? "Blitz" : ((garray[g].type == TYPE_WILD) ? "Wild" : "Standard")), b_stats->rating); - } - if (wDelta < -1000) { - pprintf(garray[g].white, "not changed due to bug (way too small)! sorry!\n"); - fprintf(stderr, "FICS: Got too small ratings bug for %s (w) vs. %s\n", - parray[garray[g].white].login, parray[garray[g].black].login); - } else if (wDelta > 3000) { - pprintf(garray[g].white, "not changed due to bug (way too big)! sorry!\n"); - fprintf(stderr, "FICS: Got too big ratings bug for %s (w) vs. %s\n", - parray[garray[g].white].login, parray[garray[g].black].login); - } else { - w_stats->rating += wDelta; - w_stats->sterr = wSigma; - } - - if (bDelta < -1000) { - pprintf(garray[g].black, "not changed due to bug (way too small)! sorry! "); - fprintf(stderr, "FICS: Got too small ratings bug for %s (b) vs. %s\n", - parray[garray[g].black].login, parray[garray[g].white].login); - } else if (bDelta > 3000) { - pprintf(garray[g].black, "not changed due to bug (way too big)! sorry! "); - fprintf(stderr, "FICS: Got too big ratings bug for %s (b) vs. %s\n", - parray[garray[g].black].login, parray[garray[g].white].login); - } else { - b_stats->rating += bDelta; - b_stats->sterr = bSigma; - } /* error messages down to vek */ - - rating_add(w_stats->rating, garray[g].type); - rating_add(b_stats->rating, garray[g].type); - - if ((w_stats->rating > w_stats->best) && (is_active(w_stats->num))) { - w_stats->best = w_stats->rating; - w_stats->whenbest = time(NULL); - } - if ((b_stats->rating > b_stats->best) && (is_active(b_stats->num))) { - b_stats->best = b_stats->rating; - b_stats->whenbest = time(NULL); - } -/* Ratings are now saved to disk after each game */ - player_save(garray[g].white); - player_save(garray[g].black); - -/* foxbat 3.11.95 */ - if (garray[g].type == TYPE_BLITZ) { - Rb_count++; - Rb_total += (w_stats->rating + b_stats->rating) / 2.0; - } else if (garray[g].type == TYPE_STAND) { - Rs_count++; - Rs_total += (w_stats->rating + b_stats->rating) / 2.0; - } else if (garray[g].type == TYPE_WILD) { - Rw_count++; - Rw_total += (w_stats->rating + b_stats->rating) / 2.0; - } -/* end add */ -/* loon testing - BestUpdate(garray[g].white); - BestUpdate(garray[g].black); -*/ - if (inprogress) { - pprintf(garray[g].white, "--> %d\n", w_stats->rating); - pprintf(garray[g].black, "--> %d\n", b_stats->rating); - } - save_ratings(); - UpdateRank(garray[g].type, parray[garray[g].white].name, - w_stats, parray[garray[g].white].name); - UpdateRank(garray[g].type, parray[garray[g].black].name, - b_stats, parray[garray[g].black].name); - return 0; -} - -PUBLIC int com_assess(int p, param_list param) -{ - int p1 = p, p2, nowtime; - int p1_connected = 1, p2_connected = 1; - int win1, draw1, loss1; - double newsterr1; - int win2, draw2, loss2; - double newsterr2; - - nowtime = time(0); - -/* Hawk: Now assess can be used with players not */ -/* logged on -- I wonder if anyone doesn't */ -/* get just a bit confused here :) */ - - if (param[0].type == TYPE_NULL) { - if (parray[p].game <0) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } else if (garray[parray[p].game].status == GAME_EXAMINE) { - if (!strcmp(garray[parray[p].game].black_name, parray[p].name)) { - pcommand(p, "assess %s\n", garray[parray[p].game].white_name); - } else { - pcommand(p, "assess %s %s\n", - garray[parray[p].game].white_name, - garray[parray[p].game].black_name); - } - return COM_OK; - } else { - p2 = parray[p].opponent; - } - } else { - if (!FindPlayer(p, ¶m[0], &p2, &p2_connected)) { - pprintf(p, "No user named \"%s\" was found.\n", param[0].val.word); - return COM_OK; - } - if (param[1].type != TYPE_NULL) { - p1 = p2; - p1_connected = p2_connected; - if (!FindPlayer(p, ¶m[1], &p2, &p2_connected)) { - pprintf(p, "No user named \"%s\" was found.\n", param[1].val.word); - if (!p1_connected) - player_remove(p1); - return COM_OK; - } - } - } - if (p1 == p2) { - pprintf(p, "You can't assess the same players.\n"); - if (!p1_connected) - player_remove(p1); - if (!p2_connected) - player_remove(p2); - return COM_OK; - } - rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_WIN, &win1, &newsterr1); - rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_DRAW, &draw1, &newsterr1); - rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_LOSS, &loss1, &newsterr1); - rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_WIN, &win2, &newsterr2); - rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_DRAW, &draw2, &newsterr2); - rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_LOSS, &loss2, &newsterr2); - - pprintf(p, "\nBlitz\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n", - parray[p1].name, ratstrii(parray[p1].b_stats.rating, parray[p1].registered), parray[p1].b_stats.sterr, - parray[p2].name, ratstrii(parray[p2].b_stats.rating, parray[p2].registered), parray[p2].b_stats.sterr); - pprintf(p, "Win : %4d %4d\n", win1, loss2); - pprintf(p, "Draw: %4d %4d\n", draw1, draw2); - pprintf(p, "Loss: %4d %4d\n", loss1, win2); - pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2); - - rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_WIN, &win1, &newsterr1); - rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_DRAW, &draw1, &newsterr1); - rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_LOSS, &loss1, &newsterr1); - rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_WIN, &win2, &newsterr2); - rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_DRAW, &draw2, &newsterr2); - rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_LOSS, &loss2, &newsterr2); - - pprintf(p, "\nStandard\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n", - parray[p1].name, ratstrii(parray[p1].s_stats.rating, parray[p1].registered), parray[p1].s_stats.sterr, - parray[p2].name, ratstrii(parray[p2].s_stats.rating, parray[p2].registered), parray[p2].s_stats.sterr); - pprintf(p, "Win : %4d %4d\n", win1, loss2); - pprintf(p, "Draw: %4d %4d\n", draw1, draw2); - pprintf(p, "Loss: %4d %4d\n", loss1, win2); - pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2); - - rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_WIN, &win1, &newsterr1); - rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_DRAW, &draw1, &newsterr1); - rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_LOSS, &loss1, &newsterr1); - rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_WIN, &win2, &newsterr2); - rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_DRAW, &draw2, &newsterr2); - rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_LOSS, &loss2, &newsterr2); - - pprintf(p, "\nWild\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n", - parray[p1].name, ratstrii(parray[p1].w_stats.rating, parray[p1].registered), parray[p1].w_stats.sterr, - parray[p2].name, ratstrii(parray[p2].w_stats.rating, parray[p2].registered), parray[p2].w_stats.sterr); - pprintf(p, "Win : %4d %4d\n", win1, loss2); - pprintf(p, "Draw: %4d %4d\n", draw1, draw2); - pprintf(p, "Loss: %4d %4d\n", loss1, win2); - pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2); - - if (!p1_connected) - player_remove(p1); - if (!p2_connected) - player_remove(p2); - return COM_OK; -} - - -PUBLIC int com_best(int p, param_list param) -{ - return Best(p, param, 1); -} - -PUBLIC int com_hbest(int p, param_list param) -{ - return Best(p, param, 0); -} - -#if 0 -PUBLIC int com_best(int p, param_list param) -{ - int i; - - pprintf(p, "Standard Blitz Wild\n"); - for (i = 0; i < MAX_BEST; i++) { - if ((i >= numS) && (i >= numB)) - break; - if (i < numS) { - pprintf(p, "%4d %-17s ", bestS[i].rating, bestS[i].name); - } else { - pprintf(p, " "); - } - if (i < numB) { - pprintf(p, "%4d %-17s ", bestB[i].rating, bestB[i].name); - } else { - pprintf(p, " "); - } - if (i < numW) { - pprintf(p, "%4d %-17s\n", bestW[i].rating, bestW[i].name); - } else { - pprintf(p, "\n"); - } - } - return COM_OK; -} -#endif - -PUBLIC int com_statistics(int p, param_list param) -{ - pprintf(p, " Standard Blitz Wild\n"); - pprintf(p, "average: %7.2f %7.2f %7.2f\n", Ratings_S_Average, Ratings_B_Average, Ratings_W_Average); - pprintf(p, "std dev: %7.2f %7.2f %7.2f\n", Ratings_S_StdDev, Ratings_B_StdDev, Ratings_W_StdDev); - pprintf(p, "number : %7d %7d %7d\n", Rs_count, Rb_count, Rw_count); - return COM_OK; -} - -PUBLIC int com_fixrank(int p, param_list param) -{ - int p1, connected; - - if (!FindPlayer(p, ¶m[0], &p1, &connected)) - return COM_OK; - UpdateRank(TYPE_BLITZ, parray[p1].name, &parray[p1].b_stats, - parray[p1].name); - UpdateRank(TYPE_STAND, parray[p1].name, &parray[p1].s_stats, - parray[p1].name); - UpdateRank(TYPE_WILD, parray[p1].name, &parray[p1].w_stats, - parray[p1].name); - if (!connected) - player_remove(p1); - return COM_OK; -} - -PUBLIC int com_rank(int p, param_list param) -{ - return DisplayRank(p, param, 1); -} - -PUBLIC int com_hrank(int p, param_list param) -{ - return DisplayRank(p, param, 0); -} - -PUBLIC int DisplayRank(int p, param_list param, int showComputers) -{ - int start, end, target, connected; - int show = SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD; - - if (param[0].type == TYPE_NULL) { - DisplayTargetRank(p, parray[p].name, show, showComputers); - return COM_OK; - } else if (isdigit(param[0].val.word[0])) { - end = -1; - sscanf(param[0].val.word, "%d-%d", &start, &end); - if (end > 0 && (param[1].type != TYPE_NULL)) - show = ShowFromString(param[1].val.word); - DisplayRankedPlayers(p, start, end, show, showComputers); - return COM_OK; - } else { - target = player_search(p, param[0].val.word); - if (target == 0) { - pprintf(p, "Target %s not found.\n", param[0].val.word); - return COM_OK; - } - connected = (target > 0); - if (!connected) - target = -target - 1; - else - target--; - - if (param[1].type != TYPE_NULL) - show = ShowFromString(param[1].val.word); - DisplayTargetRank(p, parray[target].name, show, showComputers); - if (!connected) - player_remove(target); - return COM_OK; - } -} - -/* CompareStats returns 1 if s1 comes first, -1 if s2 comes first, and 0 - if neither takes precedence. */ -PRIVATE int CompareStats(char *name1, statistics *s1, - char *name2, statistics *s2) -{ - int i, l1; - - if (s1 == NULL) - if (s2 == NULL) - return 0; - else - return -1; - else if (s2 == NULL) - return 1; - - if (s1->rating > s2->rating) - return 1; - if (s1->rating < s2->rating) - return -1; - l1 = strlen(name1); - for (i = 0; i < l1; i++) { - if (name2[i] == '\0') - return -1; - if (tolower(name1[i]) < tolower(name2[i])) - return 1; - if (tolower(name1[i]) > tolower(name2[i])) - return -1; - } - if (name2[i] != '\0') - return 1; -/* if (s1->sterr < s2->sterr) return 1; - if (s1->sterr > s2->sterr) return -1; - if (s1->num > s2->num) return 1; - if (s1->num < s2->num) return -1; -*/ - fprintf(stderr, "Duplicate entries found: %s.\n", name1); - return 0; -} - -PRIVATE int GetRankFileName(char *out, int type) -{ - switch (type) { - case TYPE_BLITZ:sprintf(out, "%s/rank.blitz", sdir); - return type; - case TYPE_STAND: - sprintf(out, "%s/rank.std", sdir); - return type; - case TYPE_WILD: - sprintf(out, "%s/rank.wild", sdir); - return type; - default: - return -1; - } -} - -PUBLIC void UpdateRank(int type, char *addName, - statistics *sNew, char *delName) -{ - char RankFile[MAX_FILENAME_SIZE]; - char TmpRankFile[MAX_FILENAME_SIZE]; - char line[MAX_RANK_LINE]; - char login[MAX_LOGIN_NAME]; - char command[MAX_STRING_LENGTH]; - int comp; - statistics sCur; - FILE *fp; - FILE *fptemp; - - if (GetRankFileName(RankFile, type) < 0) - return; - fp = fopen(RankFile, "r"); - if (fp == NULL) { - fprintf(stderr, "Can't open rank file to update.\n"); - return; - } - sprintf(TmpRankFile, "%s/tmpRank", sdir); - fptemp = fopen(TmpRankFile, "w"); - - while (fgets(line, MAX_RANK_LINE - 1, fp)) { - sscanf(line, "%s %d %d %d", login, &sCur.rating, - &sCur.num, &comp); - if (delName != NULL && !strcasecmp(delName, login)) { /* Kill name. */ - delName = NULL; - continue; - } - if (addName != NULL && CompareStats(addName, sNew, login, &sCur) > 0) { - int computer = in_list("computer", addName); - fprintf(fptemp, "%s %d %d %d\n", addName, sNew->rating, - sNew->num, computer); - addName = NULL; - } - fprintf(fptemp, "%s %d %d %d\n", login, sCur.rating, sCur.num, comp); - } - fclose(fptemp); - fclose(fp); - - sprintf(command, "mv %s %s", TmpRankFile, RankFile); - system(command); -} - -PRIVATE void DisplayRankHead(int p, int show) -{ - char Line[MAX_STRING_LENGTH]; - - Line[0] = '\0'; - if (CheckFlag(show, SHOW_BLITZ)) - strcat(Line, " Blitz "); - if (CheckFlag(show, SHOW_STANDARD)) - strcat(Line, " Standard "); - if (CheckFlag(show, SHOW_WILD)) - strcat(Line, " Wild"); - pprintf(p, "%s\n\n", Line); -} - -PRIVATE int CountRankLine(int countComp, char *loginName, - int num, int is_computer) -{ - if (loginName == NULL || loginName[0] == '\0') - return 0; - return (countComp || !is_computer) && (is_active(num)); -} - -PRIVATE int GetRank(FILE * fp, char *target, int countComp) -{ - int count = 0; - int nGames, is_computer; - int playerFound = 0; - char line[MAX_RANK_LINE]; - char login[MAX_LOGIN_NAME]; - - while (fgets(line, MAX_RANK_LINE - 1, fp) && !playerFound) { - sscanf(line, "%s %*d %d %d", login, &nGames, &is_computer); - if ((playerFound = !strcasecmp(login, target)) - || CountRankLine(countComp, login, nGames, is_computer)) - count++; - } - return (playerFound ? count : -1); -} - -PRIVATE void PositionFilePtr(FILE * fp, int count, int *last, - int *nTied, int showComp) -{ - int i, rating, nGames, is_computer; - char login[MAX_LOGIN_NAME]; - char line[MAX_RANK_LINE]; - - if (fp == NULL) - return; - rewind(fp); - for (i = 1; i < count; i++) { - do { - fgets(line, MAX_RANK_LINE - 1, fp); - if (feof(fp)) - break; - sscanf(line, "%s %d %d %d", login, &rating, &nGames, &is_computer); - } while (!CountRankLine(showComp, login, nGames, is_computer)); - if (rating != *last) { - *nTied = 1; - *last = rating; - } else - (*nTied)++; - } -} - -PRIVATE int ShowRankEntry(int p, FILE * fp, int count, int comp, - char *target, int *lastRating, int *nTied) -{ - char newLine[MAX_RANK_LINE]; - char login[MAX_LOGIN_NAME]; - int rating, findable, nGames, is_comp; - - findable = (count > 0) && !feof(fp); - if (findable) { - do { - fgets(newLine, MAX_RANK_LINE - 1, fp); - if (feof(fp)) - findable = 0; - else if (newLine[0] != '\0') - sscanf(newLine, "%s %d %d %d", - login, &rating, &nGames, &is_comp); - else - login[0] = '\0'; - } while (!CountRankLine(comp, login, nGames, is_comp) && findable - && strcasecmp(login, target)); - } - if (findable) { - if (!strcasecmp(login, target) - && !CountRankLine(comp, login, nGames, is_comp)) { - pprintf_highlight(p, "---- %-12.12s %4s", login, ratstr(rating)); - pprintf(p, " "); - return 0; - } else if (*lastRating == rating && *nTied < 1) { - pprintf(p, " "); - if (!strcasecmp(login, target)) - pprintf_highlight(p, "%-12.12s %4s", login, ratstr(rating)); - else - pprintf(p, "%-12.12s %4s", login, ratstr(rating)); - pprintf(p, " "); - return 1; - } else { - if (*nTied >= 1) { - if (*lastRating == rating) - count -= *nTied; - *nTied = -1; - } - if (!strcasecmp(login, target)) - pprintf_highlight(p, "%4d. %-12.12s %4s", - count, login, ratstr(rating)); - else - pprintf(p, "%4d. %-12.12s %4s", - count, login, ratstr(rating)); - pprintf(p, " "); - *lastRating = rating; - return 1; - } - } else { - pprintf(p, "%25s", ""); - return 1; - } -} - -PRIVATE int CountAbove(int num, int blitz, int std, int wild, int which) -{ - int max = blitz; - - if (max < std) - max = std; - if (max < wild) - max = wild; - return (max <= (num + 1) / 2 ? max - 1 : (num + 1) / 2); -} - -PRIVATE int ShowRankLines(int p, FILE * fb, FILE * fs, FILE * fw, int bCount, - int sCount, int wCount, int n, int showComp, int show, char *target) -{ - int lastBlitz = 9999, nTiedBlitz = 0; - int lastStd = 9999, nTiedStd = 0; - int lastWild = 9999, nTiedWild = 0; - int i; - - if (n <= 0) - return 0; - if (CheckFlag(show, SHOW_BLITZ)) { - PositionFilePtr(fb, bCount, &lastBlitz, &nTiedBlitz, showComp); - if (feof(fb)) - ClearFlag(show, SHOW_BLITZ); - } - if (CheckFlag(show, SHOW_STANDARD)) { - PositionFilePtr(fs, sCount, &lastStd, &nTiedStd, showComp); - if (feof(fs)) - ClearFlag(show, SHOW_STANDARD); - } - if (CheckFlag(show, SHOW_WILD)) { - PositionFilePtr(fw, wCount, &lastWild, &nTiedWild, showComp); - if (feof(fw)) - ClearFlag(show, SHOW_WILD); - } - if (!CheckFlag(show, SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD)) - return 0; - DisplayRankHead(p, show); - - for (i = 0; i < n && show; i++) { - if (CheckFlag(show, SHOW_BLITZ)) - bCount += ShowRankEntry(p, fb, bCount, showComp, target, - &lastBlitz, &nTiedBlitz); - if (CheckFlag(show, SHOW_STANDARD)) - sCount += ShowRankEntry(p, fs, sCount, showComp, target, - &lastStd, &nTiedStd); - if (CheckFlag(show, SHOW_WILD)) - wCount += ShowRankEntry(p, fw, wCount, showComp, target, - &lastWild, &nTiedWild); - pprintf(p, "\n"); - } - return 1; -} - -PUBLIC int DisplayTargetRank(int p, char *target, int show, int showComp) -{ - int numToShow = 20; - int blitzRank = -1, blitzCount; - int stdRank = -1, stdCount; - int wildRank = -1, wildCount; - int numAbove; - char Path[MAX_FILENAME_SIZE]; - FILE *fb = NULL, *fs = NULL, *fw = NULL; - - if (CheckFlag(show, SHOW_BLITZ)) { - GetRankFileName(Path, TYPE_BLITZ); - fb = (FILE *) fopen(Path, "r"); - if (fb != NULL) - blitzRank = GetRank(fb, target, showComp); - if (blitzRank < 0) - ClearFlag(show, SHOW_BLITZ); - } - if (CheckFlag(show, SHOW_STANDARD)) { - GetRankFileName(Path, TYPE_STAND); - fs = (FILE *) fopen(Path, "r"); - if (fs != NULL) - stdRank = GetRank(fs, target, showComp); - if (stdRank < 0) - ClearFlag(show, SHOW_STANDARD); - } - if (CheckFlag(show, SHOW_WILD)) { - GetRankFileName(Path, TYPE_WILD); - if (CheckFlag(show, SHOW_WILD)) - fw = (FILE *) fopen(Path, "r"); - if (fw != NULL) - wildRank = GetRank(fw, target, showComp); - if (wildRank < 0) - ClearFlag(show, SHOW_WILD); - } - if (!CheckFlag(show, SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD)) { - pprintf(p, "No ratings to show.\n"); - return (0); - } - numAbove = CountAbove(numToShow, blitzRank, stdRank, wildRank, show); - blitzCount = blitzRank - numAbove; - stdCount = stdRank - numAbove; - wildCount = wildRank - numAbove; - - ShowRankLines(p, fb, fs, fw, blitzCount, stdCount, wildCount, - numToShow, showComp, show, target); - if (fb != NULL) - fclose(fb); - if (fs != NULL) - fclose(fs); - if (fw != NULL) - fclose(fw); - return (1); -} - -PUBLIC int DisplayRankedPlayers(int p, int start, int end, - int show, int showComp) -{ - int num = end - start + 1; - FILE *fb = NULL, *fs = NULL, *fw = NULL; - char Path[MAX_FILENAME_SIZE]; - - if (start <= 0) - start = 1; - if (num <= 0) - return 0; - if (num > 100) - num = 100; - if (CheckFlag(show, SHOW_BLITZ)) { - GetRankFileName(Path, TYPE_BLITZ); - fb = (FILE *) fopen(Path, "r"); - if (fb == NULL) - ClearFlag(show, SHOW_BLITZ); - } - if (CheckFlag(show, SHOW_STANDARD)) { - GetRankFileName(Path, TYPE_STAND); - fs = (FILE *) fopen(Path, "r"); - if (fs == NULL) - ClearFlag(show, SHOW_STANDARD); - } - if (CheckFlag(show, SHOW_WILD)) { - GetRankFileName(Path, TYPE_WILD); - fw = (FILE *) fopen(Path, "r"); - if (fw == NULL) - ClearFlag(show, SHOW_WILD); - } - ShowRankLines(p, fb, fs, fw, start, start, start, - num, showComp, show, ""); - if (fb) - fclose(fb); - if (fs) - fclose(fs); - if (fw) - fclose(fw); - return 1; -} - -PUBLIC int ShowFromString(char *s) -{ - int i, len = strlen(s); - int show = 0; - - if (s == NULL || s[0] == '\0') - return SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD; - for (i = 0; i < len; i++) { - switch (s[i]) { - case 'b': - SetFlag(show, SHOW_BLITZ); - break; - case 's': - SetFlag(show, SHOW_STANDARD); - break; - case 'w': - SetFlag(show, SHOW_WILD); - break; - } - } - return (show); -} - -PUBLIC int Best(int p, param_list param, int ShowComp) -{ - int show = SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD; - - if (param[0].type != TYPE_NULL) - show = ShowFromString(param[0].val.word); - - DisplayRankedPlayers(p, 1, 20, show, ShowComp); - return COM_OK; -} |