[Freeciv-Dev] Re: (PR#14274) new ranking server code
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=14274 >
here's the final version of the patch to be committed.
-mike
Index: server/score.c
===================================================================
--- server/score.c (revision 11364)
+++ server/score.c (working copy)
@@ -407,3 +407,97 @@
fclose(fp);
}
+
+/**************************************************************************
+ At the end of a game, figure the winners and losers of the game and
+ output to a suitable place.
+
+ The definition of winners and losers: a winner is one who is alive at the
+ end of the game and has not surrendered, or in the case of a team game,
+ is alive or a teammate is alive and has not surrendered. A loser is
+ surrendered or dead. Exception: the winner of the spacerace and his
+ teammates will win of course.
+
+ Barbarians do not count as winners or losers.
+**************************************************************************/
+void rank_users(void)
+{
+ FILE *fp;
+ int i;
+ enum victory_state { VS_NONE, VS_LOSER, VS_WINNER };
+ enum victory_state plr_state[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
+ struct player *spacerace_winner = NULL;
+
+ fp = fopen("ranking.log","w");
+
+ /* oh well, we can fail silently */
+ if (!fp) {
+ return;
+ }
+
+ /* initialize plr_state */
+ for (i = 0; i < MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS; i++) {
+ plr_state[i] = VS_NONE;
+ }
+
+ /* do we have a spacerace winner? */
+ players_iterate(pplayer) {
+ if (pplayer->spaceship.state == SSHIP_ARRIVED) {
+ spacerace_winner = pplayer;
+ break;
+ }
+ } players_iterate_end;
+
+ /* make this easy: if we have a spacerace winner, then treat all others
+ * who are still alive as surrendered */
+ if (spacerace_winner) {
+ players_iterate(pplayer) {
+ if (pplayer != spacerace_winner) {
+ pplayer->surrendered = TRUE;
+ }
+ } players_iterate_end;
+ }
+
+ /* first pass: locate those alive who haven't surrendered, set them to win;
+ * barbarians won't count, and everybody else is a loser for now. */
+ players_iterate(pplayer) {
+ if (is_barbarian(pplayer)) {
+ plr_state[pplayer->player_no] = VS_NONE;
+ } else if (pplayer->is_alive && !pplayer->surrendered) {
+ plr_state[pplayer->player_no] = VS_WINNER;
+ } else {
+ plr_state[pplayer->player_no] = VS_LOSER;
+ }
+ } players_iterate_end;
+
+ /* second pass: find the teammates of those winners, they win too. */
+ players_iterate(pplayer) {
+ if (plr_state[pplayer->player_no] == VS_WINNER) {
+ players_iterate(aplayer) {
+ if (aplayer->team == pplayer->team) {
+ plr_state[aplayer->player_no] = VS_WINNER;
+ }
+ } players_iterate_end;
+ }
+ } players_iterate_end;
+
+ /* write out ranking information to file */
+ fprintf(fp, "turns: %d\n", game.info.turn);
+ fprintf(fp, "winners: ");
+ players_iterate(pplayer) {
+ if (plr_state[pplayer->player_no] == VS_WINNER) {
+ fprintf(fp, "%s (%s,%s), ", pplayer->ranked_username, pplayer->name,
+ pplayer->username);
+ }
+ } players_iterate_end;
+ fprintf(fp, "\nlosers: ");
+ players_iterate(pplayer) {
+ if (plr_state[pplayer->player_no] == VS_LOSER) {
+ fprintf(fp, "%s (%s,%s), ", pplayer->ranked_username, pplayer->name,
+ pplayer->username);
+ }
+ } players_iterate_end;
+ fprintf(fp, "\n");
+
+ fclose(fp);
+}
Index: server/srv_main.c
===================================================================
--- server/srv_main.c (revision 11364)
+++ server/srv_main.c (working copy)
@@ -552,6 +552,16 @@
} players_iterate_end;
}
+ /* find out if users attached to players have been attached to those players
+ * for long enough. The first user to do so becomes "associated" to that
+ * player for ranking purposes. */
+ players_iterate(pplayer) {
+ if (strcmp(pplayer->ranked_username, ANON_USER_NAME) == 0
+ && pplayer->user_turns++ > TURNS_NEEDED_TO_RANK) {
+ sz_strlcpy(pplayer->ranked_username, pplayer->username);
+ }
+ } players_iterate_end;
+
/* See if the value of fog of war has changed */
if (is_new_turn && game.info.fogofwar != game.fogofwar_old) {
if (game.info.fogofwar) {
@@ -1676,7 +1686,9 @@
(void) send_server_info_to_metaserver(META_REFRESH);
if (server_state != GAME_OVER_STATE && check_for_game_over()) {
- server_state=GAME_OVER_STATE;
+ server_state = GAME_OVER_STATE;
+ /* this goes here, because we don't rank users after an /endgame */
+ rank_users();
}
}
Index: server/score.h
===================================================================
--- server/score.h (revision 11364)
+++ server/score.h (working copy)
@@ -21,4 +21,6 @@
void save_ppm(void);
+void rank_users(void);
+
#endif /* FC__SCORE_H */
Index: server/connecthand.c
===================================================================
--- server/connecthand.c (revision 11364)
+++ server/connecthand.c (working copy)
@@ -437,6 +437,7 @@
if (!pconn->observer) {
sz_strlcpy(pplayer->username, pconn->username);
+ pplayer->user_turns = 0; /* reset for a new user */
pplayer->is_connected = TRUE;
}
Index: server/stdinhand.c
===================================================================
--- server/stdinhand.c (revision 11364)
+++ server/stdinhand.c (working copy)
@@ -63,6 +63,7 @@
#include "ruleset.h"
#include "sanitycheck.h"
#include "savegame.h"
+#include "score.h"
#include "sernet.h"
#include "settings.h"
#include "srv_main.h"
@@ -3635,7 +3636,6 @@
caller->player->name);
caller->player->surrendered = TRUE;
if (check_for_game_over()) {
- server_state = GAME_OVER_STATE;
force_end_of_sniff = TRUE;
}
return TRUE;
Index: common/player.c
===================================================================
--- common/player.c (revision 11364)
+++ common/player.c (working copy)
@@ -176,6 +176,8 @@
sz_strlcpy(plr->name, ANON_PLAYER_NAME);
sz_strlcpy(plr->username, ANON_USER_NAME);
+ sz_strlcpy(plr->ranked_username, ANON_USER_NAME);
+ plr->user_turns = 0;
plr->is_male = TRUE;
plr->government = NULL;
plr->target_government = NULL;
Index: common/player.h
===================================================================
--- common/player.h (revision 11364)
+++ common/player.h (working copy)
@@ -157,6 +157,8 @@
int player_no;
char name[MAX_LEN_NAME];
char username[MAX_LEN_NAME];
+ char ranked_username[MAX_LEN_NAME]; /* the user who will be ranked */
+ int user_turns; /* number of turns this user has played */
bool is_male;
struct government *government; /* may be NULL in pregame */
struct government *target_government; /* may be NULL */
Index: common/game.h
===================================================================
--- common/game.h (revision 11364)
+++ common/game.h (working copy)
@@ -50,6 +50,10 @@
#define CONTAMINATION_POLLUTION 1
#define CONTAMINATION_FALLOUT 2
+/* The number of turns that the first user needs to be attached to a
+ * player for that user to be ranked as that player */
+#define TURNS_NEEDED_TO_RANK 10
+
struct civ_game {
struct packet_game_info info;
struct government *government_when_anarchy;
|
|