void account_boot(void) { PGresult *res; account_cache = g_hash_table_new(g_direct_hash, g_direct_equal); res = sql_query("select MAX(idnum) from accounts"); account_top_id = atol(PQgetvalue(res, 0, 0)); if (player_count()) slog("... %zd character%s in db", player_count(), (player_count() == 1) ? "" : "s"); else slog("WARNING: No characters loaded"); }
void mlrate(double mean, FILE *fdiag) { double maxchange; /* The max change of one turn. */ size_t pcount, gcount, rcount; /* Player, game, and removed counters. */ size_t wcount, lcount; /* Win/loss counters. */ double wsum, lsum; /* Weighted sums. */ size_t globturns = 0; /* Counts the turns of the outer loop. */ size_t hcount[10]; /* Handicap game counters. */ player_t p; /* A player. */ piter_t piter; /* An iterator over players. */ char *pflags; assert(0.0 < mean && mean < RANK_MAXIMUM); pflags = (char *)malloc(player_count()); if (pflags == NULL) errex("malloc(%lu) failed", player_count()); memset(pflags, 0, player_count()); /* Assign a start rating for every player. */ player_start(&piter); while ((p = player_next(&piter)) != NO_PLAYER) if (!player_get_rated(p) && !player_get_ignore(p)) { player_set_rank(p, mean); player_set_rated(p, 1); } /* Remove players with no wins or no losses against other rated ** players; then again and again, until no more can be removed. ** While we're at it, count some statistics as well. */ do { pcount = gcount = rcount = 0; hcount[0] = hcount[1] = hcount[2] = hcount[3] = hcount[4] = hcount[5] = hcount[6] = hcount[7] = hcount[8] = hcount[9] = 0; player_start(&piter); while ((p = player_next(&piter)) != NO_PLAYER) if (player_get_rated(p) && !player_get_ignore(p)) { game_t g; giter_t giter; unsigned oppcount = 0; wcount = lcount = 0; wsum = lsum = 0.0; player_games_start(p, &giter); while ((g = player_games_next(&giter)) != NO_GAME) if (game_weight(g) > 0.0) { double a = game_advantage(g); if (a >= 10.0) hcount[0] += 1; else if (a >= 1.0) hcount[(unsigned)floor(a)] += 1; if (p == game_winner(g) && player_get_rated(game_loser(g))) { wcount += 1; wsum += game_weight(g); if (!pflags[game_loser(g)]) { pflags[game_loser(g)] = 1; oppcount += 1; } } else if (p == game_loser(g) && player_get_rated(game_winner(g))) { lcount += 1; lsum += game_weight(g); if (!pflags[game_winner(g)]) { pflags[game_winner(g)] = 1; oppcount += 1; } } else game_set_weight(g, 0.0); } else game_set_weight(g, 0.0); if (wsum < 0.25 || lsum < 0.25 || oppcount < 3) { player_set_rated(p, 0); rcount += 1; } else { pcount += 1; gcount += wcount + lcount; } player_set_ratedgames(p, wcount, lcount); player_set_wratedgames(p, wsum, lsum); /* Clear flags. */ player_games_start(p, &giter); while ((g = player_games_next(&giter)) != NO_GAME) pflags[game_loser(g)] = pflags[game_winner(g)] = 0; } } while (rcount > 0); player_gc_games(); if (fdiag) { int i; fprintf(fdiag, "\nRemaining:\n%6lu players\n%6lu games\n\n", (unsigned long)pcount, (unsigned long)gcount/2); for (i = 1 ; i <= 9 ; i++) fprintf(fdiag, "Advantage %2d: %5lu games\n", i, (unsigned long)hcount[i]); fprintf(fdiag, "Advantage >=10: %5lu games\n\n", (unsigned long)hcount[0]); } if (pcount == 0 || gcount == 0) errex("No player or no games"); /* ** The outer loop. */ do { /* while (maxchange > CHANGE_LIMIT && globturns < GLOBAL_TURNS_MAX); */ int maxp = 0; pcount = 0; maxchange = 0.0; globturns += 1; /* ** Loop over all players. */ player_start(&piter); while ((p = player_next(&piter)) != NO_PLAYER) { /* ** We use bisection to find the root of the derivative (the maximum). */ irank_t r, oldrank; irank_t ileft = RANK_MINIMUM, iright = RANK_MAXIMUM; if (!player_get_rated(p) || player_get_ignore(p)) continue; /* ** Inner (bisection) loop. */ pcount += 1; r = oldrank = player_get_rank(p); do { /* while (iright - ileft > CLOSE_ENOUGH); */ game_t g; double sum = 0.0; giter_t giter; player_games_start(p, &giter); while ((g = player_games_next(&giter)) != NO_GAME) { player_t opp; double diff; if (p == game_winner(g)) { opp = game_loser(g); if (player_get_rated(opp)) { diff = RANK_DIFF(r, player_get_rank(opp)) + game_advantage(g); sum += dP(diff, 1) * game_weight(g); } } else { opp = game_winner(g); if (player_get_rated(opp)) { diff = RANK_DIFF(r, player_get_rank(opp)) - game_advantage(g); sum += dP(diff, 0) * game_weight(g); } } } if (sum > 0.0) iright = r; /* Root's somewhere to the left. */ else ileft = r; /* Root's somewhere to the right. */ r = (iright + ileft)/2; } while (iright - ileft > CLOSE_ENOUGH); if (r > oldrank) { if (r - oldrank > maxchange) { maxchange = r - oldrank; maxp = p; } } else { if (oldrank - r > maxchange) { maxchange = oldrank - r; maxp = p; } } player_set_rank(p, r); } /* while ((p = player_next())) */ #ifdef MAXP fprintf(stderr, "\n--- Maxp: %s rank=%g ww=%g wl=%g w=%u l=%u rg=%u\n", player_get_name(maxp), player_get_rank(maxp), player_get_wwins(maxp), player_get_wlosses(maxp), player_get_wins(maxp), player_get_losses(maxp), player_get_ratedgames(maxp)); #endif if (globturns > 100) circular_check(maxp); if (fdiag) { fprintf(fdiag, " %3lu: %6.3f", (unsigned long)globturns, maxchange); if (globturns % 5) fflush(fdiag); else fputc('\n', fdiag); } } while (maxchange > CHANGE_LIMIT && globturns < GLOBAL_TURNS_MAX); if (fdiag) { if (globturns % 5) fputc('\n', fdiag); fputc('\n', fdiag); } if (globturns == GLOBAL_TURNS_MAX) errex("Aborted after maximum %u turns\n", GLOBAL_TURNS_MAX); if (pflags != NULL) free(pflags); }
void send_mssp_data( DESCRIPTOR_DATA *d ) { if ( !d ) { bug( "%s: NULL d", __FUNCTION__ ); return; } write_to_descriptor( d, "\r\nMSSP-REPLY-START\r\n", 0 ); mssp_reply( d, "HOSTNAME", "%s", mssp_info->hostname ); mssp_reply( d, "PORT", "%d", port ); mssp_reply( d, "UPTIME", "%d", ( int ) mud_start_time ); mssp_reply( d, "PLAYERS", "%d", player_count( ) ); mssp_reply( d, "CODEBASE", "%s", codebase ); mssp_reply( d, "CONTACT", "%s", mssp_info->contact ); mssp_reply( d, "CREATED", "%d", mssp_info->created ); mssp_reply( d, "ICON", "%s", mssp_info->icon ); mssp_reply( d, "LANGUAGE", "%s", mssp_info->language ); mssp_reply( d, "LOCATION", "%s", mssp_info->location ); mssp_reply( d, "MINIMUM AGE", "%d", mssp_info->minAge ); mssp_reply( d, "NAME", "%s", sysdata.mud_name ); mssp_reply( d, "WEBSITE", "%s", mssp_info->website ); mssp_reply( d, "FAMILY", "%s", mssp_info->family ); mssp_reply( d, "GENRE", "%s", mssp_info->genre ); mssp_reply( d, "GAMEPLAY", "%s", mssp_info->gamePlay ); mssp_reply( d, "GAMESYSTEM", "%s", mssp_info->gameSystem ); mssp_reply( d, "INTERMUD", "%s", mssp_info->intermud ); mssp_reply( d, "STATUS", "%s", mssp_info->status ); mssp_reply( d, "SUBGENRE", "%s", mssp_info->subgenre ); mssp_reply( d, "AREAS", "%d", top_area ); mssp_reply( d, "HELPFILES", "%d", top_help ); mssp_reply( d, "MOBILES", "%d", top_mob_index ); mssp_reply( d, "OBJECTS", "%d", top_obj_index ); mssp_reply( d, "ROOMS", "%d", top_room ); mssp_reply( d, "RESETS", "%d", top_reset ); // mssp_reply( d, "MUDPROGS", "%d", top_prog ); mssp_reply( d, "CLASSES", "%d", MAX_CLASS ); mssp_reply( d, "LEVELS", "%d", MAX_LEVEL ); mssp_reply( d, "RACES", "%d", MAX_RACE ); // mssp_reply( d, "SKILLS", "%d", num_skills ); mssp_reply( d, "WORLDS", "%d", mssp_info->worlds ); mssp_reply( d, "ANSI", "%d", mssp_info->ansi ); mssp_reply( d, "MCCP", "%d", mssp_info->mccp ); mssp_reply( d, "MCP", "%d", mssp_info->mcp ); mssp_reply( d, "MSP", "%d", mssp_info->msp ); mssp_reply( d, "SSL", "%d", mssp_info->ssl ); mssp_reply( d, "MXP", "%d", mssp_info->mxp ); mssp_reply( d, "PUEBLO", "%d", mssp_info->pueblo ); mssp_reply( d, "VT100", "%d", mssp_info->vt100 ); mssp_reply( d, "XTERM 256 COLORS", "%d", mssp_info->xterm256 ); mssp_reply( d, "PAY TO PLAY", "%d", mssp_info->pay2play ); mssp_reply( d, "PAY FOR PERKS", "%d", mssp_info->pay4perks ); mssp_reply( d, "HIRING BUILDERS", "%d", mssp_info->hiringBuilders ); mssp_reply( d, "HIRING CODERS", "%d", mssp_info->hiringCoders ); mssp_reply( d, "ADULT MATERIAL", "%d", mssp_info->adultMaterial ); mssp_reply( d, "MULTICLASSING", "%d", mssp_info->multiclassing ); mssp_reply( d, "NEWBIE FRIENDLY", "%d", mssp_info->newbieFriendly ); mssp_reply( d, "PLAYER CITIES", "%d", mssp_info->playerCities ); mssp_reply( d, "PLAYER CLANSS", "%d", mssp_info->playerClans ); mssp_reply( d, "PLAYER CRAFTING", "%d", mssp_info->playerCrafting ); mssp_reply( d, "PLAYER GUILDS", "%d", mssp_info->playerGuilds ); mssp_reply( d, "EQUIPMENT SYSTEM", "%s", mssp_info->equipmentSystem ); mssp_reply( d, "MULTIPLAYING", "%s", mssp_info->multiplaying ); mssp_reply( d, "PLAYERKILLING", "%s", mssp_info->playerKilling ); mssp_reply( d, "QUEST SYSTEM", "%s", mssp_info->questSystem ); mssp_reply( d, "ROLEPLAYING", "%s", mssp_info->roleplaying ); mssp_reply( d, "TRAINING SYSTEM", "%s", mssp_info->trainingSystem ); mssp_reply( d, "WORLD ORIGINALITY", "%s", mssp_info->worldOriginality ); write_to_descriptor( d, "MSSP-REPLY-END\r\n", 0 ); }