Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2004:
[Freeciv-Dev] (PR#8493) Selective draw
Home

[Freeciv-Dev] (PR#8493) Selective draw

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#8493) Selective draw
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Mon, 12 Apr 2004 10:31:03 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=8493 >

Due to popular demand:

> help endgame
Command: endgame  -  End the game.  If players are listed, these win the
game.
Synopsis: endgame <player1 player2 player3 ...>
Level: ctrl
Description:
  This command ends the game immediately and credits the given players, if
  any, with winning it.

Patch attached. It is quite simple: Scores are set to the highest score
available for all winning players. All other scores are left alone (so you
still get a ranking among the losers).

  - Per

Index: server/gamelog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamelog.c,v
retrieving revision 1.31
diff -u -r1.31 gamelog.c
--- server/gamelog.c    5 Mar 2004 18:57:19 -0000       1.31
+++ server/gamelog.c    12 Apr 2004 17:27:26 -0000
@@ -24,10 +24,11 @@
 #include "log.h"
 #include "map.h"
 #include "mem.h"
+#include "score.h"
+#include "srv_main.h"
 #include "support.h"
 
 #include "gamelog.h"
-#include "score.h"
 
 int gamelog_level;             /* also accessed from stdinhand.c */
 static char *gamelog_filename;
@@ -138,7 +139,8 @@
   and status info.
 **************************************************************************/
 void gamelog_save(void) {
-  int i, count = 0;
+  int i, count = 0, highest = -1;
+  struct player *highest_plr = NULL;
   char buffer[4096];
   struct player_score_entry *size =
     fc_malloc(sizeof(struct player_score_entry) * game.nplayers);
@@ -151,45 +153,28 @@
       rank[count].idx = pplayer->player_no;
       size[count].value = total_player_citizens(pplayer);
       size[count].idx = pplayer->player_no;
+      if (rank[count].value > highest) {
+        highest = rank[count].value;
+        highest_plr = pplayer;
+      }
       count++;
     }
   } players_iterate_end;
 
-  /* average game scores for teams */
-  team_iterate(pteam) {
-    int team_members = 0;
-    int count = 0;
-    int team_score = 0;
-    int team_size = 0;
-
-    /* sum team score */
-    players_iterate(pplayer) {
-      if (pplayer->team == pteam->id) {
-        team_members++;
-        team_score += rank[count].value;
-        team_size += size[count].value;
+  /* Draws and team victories */
+  count = 0;
+  players_iterate(pplayer) {
+    if (!is_barbarian(pplayer)) {
+      if ((BV_ISSET_ANY(srvarg.draw)
+           && BV_ISSET(srvarg.draw, pplayer->player_no))
+          || (pplayer->team != TEAM_NONE
+              && pplayer->team == highest_plr->team)) {
+        /* We win a shared victory, so equal the score. */
+        rank[count].value = highest;
       }
       count++;
-    } players_iterate_end;
-
-    if (team_members == 0) {
-      continue;
     }
-
-    /* average them */
-    team_score = team_score / team_members;
-    team_size = team_size / team_members;
-
-    /* set scores to average */
-    count = 0;
-    players_iterate(pplayer) {
-      if (pplayer->team == pteam->id) {
-        rank[count].value = team_score;
-        size[count].value = team_size;
-      }
-      count++;
-    } players_iterate_end;
-  } team_iterate_end;
+  } players_iterate_end;
 
   qsort(size, count, sizeof(struct player_score_entry), secompare1);
   buffer[0] = 0;
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.158
diff -u -r1.158 srv_main.c
--- server/srv_main.c   10 Apr 2004 03:47:50 -0000      1.158
+++ server/srv_main.c   12 Apr 2004 17:27:27 -0000
@@ -171,6 +171,7 @@
   srvarg.script_filename = NULL;
 
   srvarg.quitidle = 0;
+  BV_CLR_ALL(srvarg.draw);
 
   srvarg.extra_metaserver_info[0] = '\0';
 
@@ -1726,4 +1727,5 @@
   diplhand_free();
   game_free();
   stdinhand_free();
+  BV_CLR_ALL(srvarg.draw);
 }
Index: server/srv_main.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.h,v
retrieving revision 1.18
diff -u -r1.18 srv_main.h
--- server/srv_main.h   10 Apr 2004 03:47:50 -0000      1.18
+++ server/srv_main.h   12 Apr 2004 17:27:27 -0000
@@ -19,6 +19,8 @@
 struct connection;
 struct unit;
 
+BV_DEFINE(bv_draw, MAX_NUM_PLAYERS);
+
 struct server_arguments {
   /* metaserver information */
   bool metaserver_no_send;
@@ -40,6 +42,8 @@
   char extra_metaserver_info[256];
   /* quit if there no players after a given time interval */
   int quitidle;
+  /* what kind of end game we should use */
+  bv_draw draw;
 };
 
 void srv_init(void);
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.313
diff -u -r1.313 stdinhand.c
--- server/stdinhand.c  10 Apr 2004 03:47:50 -0000      1.313
+++ server/stdinhand.c  12 Apr 2004 17:27:31 -0000
@@ -84,7 +84,7 @@
 static bool take_command(struct connection *caller, char *name, bool check);
 static bool detach_command(struct connection *caller, char *name, bool check);
 static bool start_command(struct connection *caller, char *name, bool check);
-static bool end_command(struct connection *caller, char *name, bool check);
+static bool end_command(struct connection *caller, char *str, bool check);
 
 struct voting {
   char command[MAX_LEN_CONSOLE_LINE]; /* [0] == \0 if none in action */
@@ -1385,9 +1385,11 @@
       "concert with the option \"timeout\". Defaults are 0 0 0 1")
   },
   {"endgame",  ALLOW_CTRL,
-   "endgame",
-   N_("End the game."),
-   N_("This command ends the game immediately.")
+   /* TRANS: translate text between <> only */
+   N_("endgame <player1 player2 player3 ...>"),
+   N_("End the game.  If players are listed, these win the game."),
+   N_("This command ends the game immediately and credits the given players, "
+      "if any, with winning it.")
   },
   {"remove",   ALLOW_CTRL,
    /* TRANS: translate text between <> only */
@@ -4449,19 +4451,56 @@
 }
 
 /**************************************************************************
-...
+  End the game and accord victory to the listed players, if any.
 **************************************************************************/
-static bool end_command(struct connection *caller, char *name, bool check)
+static bool end_command(struct connection *caller, char *str, bool check)
 {
   if (server_state == RUN_GAME_STATE) {
+    char *arg[MAX_NUM_PLAYERS];
+    int ntokens = 0, i;
+    enum m_pre_result plr_result;
+    bool result = TRUE;
+    char buf[MAX_LEN_CONSOLE_LINE];
+
+    if (str != NULL || strlen(str) > 0) {
+      sz_strlcpy(buf, str);
+      ntokens = get_tokens(buf, arg, MAX_NUM_PLAYERS, TOKEN_DELIMITERS);
+    }
+    /* Ensure players exist */
+    for (i = 0; i < ntokens; i++) {
+      struct player *pplayer = find_player_by_name_prefix(arg[i], &plr_result);
+
+      if (!pplayer) {
+        cmd_reply_no_such_player(CMD_TEAM, caller, arg[i], plr_result);
+        result = FALSE;
+        goto cleanup;
+      } else if (pplayer->is_alive == FALSE) {
+        cmd_reply(CMD_END_GAME, caller, C_FAIL, _("But %s is dead!"),
+                  pplayer->name);
+        result = FALSE;
+        goto cleanup;
+      }
+    }
     if (check) {
-      return TRUE;
+      goto cleanup;
+    }
+    if (ntokens > 0) {
+      /* Mark players for victory. */
+      for (i = 0; i < ntokens; i++) {
+        BV_SET(srvarg.draw, 
+               find_player_by_name_prefix(arg[i], &plr_result)->player_no);
+      }
     }
     server_state = GAME_OVER_STATE;
     force_end_of_sniff = TRUE;
     cmd_reply(CMD_END_GAME, caller, C_OK,
               _("Ending the game. The server will restart once all clients "
               "have disconnected."));
+
+    cleanup:
+    for (i = 0; i < ntokens; i++) {
+      free(arg[i]);
+    }
     return TRUE;
   } else {
     cmd_reply(CMD_END_GAME, caller, C_FAIL, 

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#8493) Selective draw, Per I. Mathisen <=