Date: Friday January 26, 2001 @ 17:58
Author: ahn
Update of /home/netrek/cvsroot/Vanilla/robots
In directory swashbuckler.fortress.real-time.com:/var/tmp/cvs-serv2637
Modified Files:
inl.c inlcomm.c inldefs.h
Log Message:
Added momentum scoring support. Changed continuous scoring parameters.
See README.scores and ChangeLog for details.
****************************************
Index: Vanilla/robots/inl.c
diff -u Vanilla/robots/inl.c:1.35 Vanilla/robots/inl.c:1.36
--- Vanilla/robots/inl.c:1.35 Tue Nov 14 22:12:47 2000
+++ Vanilla/robots/inl.c Fri Jan 26 17:58:01 2001
@@ -1,7 +1,7 @@
-/* $Id: inl.c,v 1.35 2000/11/15 04:12:47 ahn Exp $ */
+/* $Id: inl.c,v 1.36 2001/01/26 23:58:01 ahn Exp $ */
#ifndef lint
-static char vcid[] = "$Id: inl.c,v 1.35 2000/11/15 04:12:47 ahn Exp $";
+static char vcid[] = "$Id: inl.c,v 1.36 2001/01/26 23:58:01 ahn Exp $";
#endif /* lint */
/*
@@ -114,6 +114,7 @@
0, /* tmout_ticks */
0, /* time */
0, /* overtime */
+ 0, /* extratime */
0, /* score_mode */
0.0 /* weighted_divisor */
};
@@ -600,24 +601,30 @@
int p, t;
double weight = (double) inl_stat.game_ticks / (double) inl_stat.time;
+ static const double weight_max = 2.7408445; /* 0.5 + 0.5 * exp(1.5); */
+
+ /* sanity check! */
if (weight < 0.0)
weight = 0.0;
else if (weight > 1.0)
weight = 1.0;
/* weight = linear range between 0.0 and 1.0 during regulation.
- * map this to 0.75 <-> 1.5 range
+ * map this to exponential curve using formula:
+ * weight = 0.5 + 0.5 * exp(1.5 * time)
+ * weight range is 1.0 to 2.7408445
* -da */
- weight = 0.75 + (0.75 * weight);
+ weight = 0.5 + 0.5 * exp(1.5 * weight);
/* sanity check */
- if (weight < 0.75)
- weight = 0.75;
- else if (weight > 1.5)
- weight = 1.5;
+ if (weight < 1.0)
+ weight = 1.0;
+ else if (weight > weight_max)
+ weight = weight_max;
- inl_stat.weighted_divisor += (weight * 4.0);
+ /* weight multiply factor should be max points you can get per planet */
+ inl_stat.weighted_divisor += (weight * 2.0);
for (p=0; p<MAXPLANETS; p++) {
@@ -626,12 +633,15 @@
if (sides[inl_teams[t].side_index].flag == planets[p].pl_owner) {
/* planet is owned by this team, so it has > 0 armies. each planet
- is worth 1-4 points for each army on the planet, capped at 4. */
+ is worth 1-2 points for each pair of armies on the planet,
+ capped at 2. I.e. 1-2 armies = 1 pt, >=3 armies = 2 pts. */
int points = planets[p].pl_armies;
- if (points > 4)
- points = 4;
+ if (points > 2)
+ points = 2;
+ else
+ points = 1;
/* absolute continuous score is just the cumulative point total */
inl_teams[t].abs_score += points;
@@ -651,9 +661,9 @@
}
- /* announce updated scores every 5 minutes */
+ /* announce updated scores every 5 minutes if not in normal mode */
- if ((inl_stat.game_ticks % (5 * PERMIN)) == 0)
+ if (inl_stat.score_mode && ((inl_stat.game_ticks % (5 * PERMIN)) == 0))
announce_scores(0, MALL, NULL);
}
@@ -733,30 +743,44 @@
#endif
/* Determine if there is a winner at the end of regulation.
- returns 0 if game is tied
- returns 1 if there is a winner by planet count
- returns 2 if there is a winner by continuous score > 2.0
- returns 3 if there is a winner by continuous score < 2.0 & planet 11-8-1
+ returns -1 if momentum score goes to EXTRA TIME
+ returns 0 if game is tied
+ returns 1 if winner by planet count
+ returns 2 if winner by continuous score > 2.0
+ returns 3 if winner by continuous score < 2.0 & planet 11-8-1
+ returns 4 if winner by momentum scoring
-da
*/
int check_winner() {
double divisor = inl_stat.weighted_divisor;
double delta;
+ /* -1 = HOME is winning
+ * 0 = tied
+ * 1 = AWAY is winning */
+ int winning_cont = 0;
+ int winning_norm = 0;
+
countplanets();
- /* NORMAL scoring mode; OR, continuous scoring and in OT.
+ if (inl_teams[HOME].planets > inl_teams[AWAY].planets + 2)
+ winning_norm = -1;
+ else if (inl_teams[AWAY].planets > inl_teams[HOME].planets + 2)
+ winning_norm = 1;
+ else
+ winning_norm = 0;
+
+ /* NORMAL scoring mode; OR, continuous/momentum scoring and in OT.
Use absolute planet count. */
+
if ((inl_stat.score_mode == 0) || (inl_stat.flags & S_OVERTIME)) {
- if (inl_teams[HOME].planets > inl_teams[AWAY].planets + 2)
- return 1;
- else if (inl_teams[AWAY].planets > inl_teams[HOME].planets + 2)
+ if (winning_norm)
return 1;
else
return 0;
}
- /* CONTINUOUS scoring mode */
+ /* CONTINUOUS or MOMENTUM scoring mode */
/* sanity check */
if (inl_stat.weighted_divisor < 1.0)
@@ -765,25 +789,51 @@
if (inl_stat.game_ticks < 100)
return 0;
- delta = inl_teams[0].weighted_score / divisor -
- inl_teams[1].weighted_score / divisor;
+ delta = inl_teams[HOME].weighted_score / divisor -
+ inl_teams[AWAY].weighted_score / divisor;
- /* multiply by -1 instead of fabs() */
- if (delta < 0.0)
- delta *= -1.0;
-
- /* if continuous score delta is >= 2.0, we have winner */
+ /* 2.0 is the differential */
if (delta >= 2.0)
- return 2;
+ winning_cont = -1;
+ else if (delta <= -2.0)
+ winning_cont = 1;
+ else
+ winning_cont = 0;
+
+ /* CONTINUOUS scoring mode:
+ delta > 2.0: win
+ delta < 2.0 but planet > 11-8-1: win
+ otherwise, tie.
+ */
+
+ if (inl_stat.score_mode == 1) {
+
+ if (winning_cont)
+ return 2;
+ else if (winning_norm)
+ return 3;
+ else
+ return 0;
+
+ }
- /* if continuous score delta is < 2.0, but a team has > 11-8-1,
- we have a winner */
- else if ((inl_teams[HOME].planets > inl_teams[AWAY].planets + 2) ||
- (inl_teams[AWAY].planets > inl_teams[HOME].planets + 2))
- return 3;
+ /* MOMENTUM scoring mode */
+ else if (inl_stat.score_mode == 2) {
- /* otherwise, game is a tie */
- return 0;
+ /* game tied, go to OT */
+ if (!winning_cont && !winning_norm)
+ return 0;
+
+ /* if either team is winning by at least one method, return winner */
+ if (winning_cont + winning_norm)
+ return 4;
+
+ /* otherwise, EXTRA TIME */
+ else
+ return -1;
+
+ }
+
}
int
@@ -792,44 +842,102 @@
int game_over = 0;
int win_cond;
- if ((win_cond = check_winner()) != 0)
+ /* check_winner always returns > 0 if winner exists */
+ if ((win_cond = check_winner()) > 0)
{
pmessage(0, MALL, inl_from, "---------- Game Over ----------");
- pmessage(0, MALL, inl_from, "Planet count: %i - %i - %i",
- inl_teams[HOME].planets, inl_teams[AWAY].planets,
- (20 - inl_teams[HOME].planets - inl_teams[AWAY].planets));
/* need to write this to the inl_log because the pmessages don't
get flushed out to the log before the close */
fprintf(inl_log, "---------- Game Over ---------\n");
- fprintf(inl_log, "SCORE: Planet count: %i - %i - %i\n",
- inl_teams[HOME].planets, inl_teams[AWAY].planets,
- (20 - inl_teams[HOME].planets - inl_teams[AWAY].planets));
announce_scores(0, MALL, inl_log);
switch(win_cond) {
case 1:
- pmessage(0, MALL, inl_from, "Victory by: planet count (normal scoring)");
- fprintf(inl_log, "SCORE: Victory by planet count (normal scoring)\n");
+ pmessage(0, MALL, inl_from, "Victory by planet count");
+ fprintf(inl_log, "SCORE: Victory by planet count\n");
break;
case 2:
- pmessage(0, MALL, inl_from, "Victory by: continuous score >= 2.0");
- fprintf(inl_log, "SCORE: Victory by: continuous score >= 2.0\n");
+ pmessage(0, MALL, inl_from, "Victory by continuous score >= 2.0");
+ fprintf(inl_log, "SCORE: Victory by continuous score >= 2.0\n");
break;
case 3:
- pmessage(0, MALL, inl_from, "Victory by: planet count (continuous score < 2.0)");
- fprintf(inl_log, "SCORE: Victory by: planet count (continuous score < 2.0)\n");
+ pmessage(0, MALL, inl_from, "Victory by planet count (continuous score < 2.0)");
+ fprintf(inl_log, "SCORE: Victory by planet count (continuous score < 2.0)\n");
+ break;
+ case 4:
+ pmessage(0, MALL, inl_from, "Victory by momentum score");
+ fprintf(inl_log, "SCORE: Victory by momentum score\n");
break;
default:
- pmessage(0, MALL, inl_from, "Victory by: UNKNOWN");
- fprintf(inl_log, "SCORE: Victory by: UNKNOWN\n");
+ pmessage(0, MALL, inl_from, "Victory by UNKNOWN");
+ fprintf(inl_log, "SCORE: Victory by UNKNOWN\n");
break;
}
game_over = 1;
}
+
+ /* still in regulation, but momentum scoring dictates EXTRA TIME */
+ else if ((inl_stat.flags & S_TOURNEY) && (win_cond == -1))
+ {
+
+ static const int extratime = 5 * PERMIN;
+ static const int extra_max = 5 * PERMIN * 3;
+
+ /* only allow 3 cycles of extra time */
+ if (inl_stat.extratime < extra_max) {
+
+ pmessage(0, MALL, inl_from, "---------- Extra Time (Momentum) ----------");
+ pmessage(0, MALL, inl_from, "%i of %i total minutes added to regulation.",
+ extratime / PERMIN, extra_max);
+
+ fprintf(inl_log, "---------- Extra Time (Momentum) ----------\n");
+ fprintf(inl_log, "%i of %i total minutes added to regulation\n",
+ extratime / PERMIN, extra_max);
+
+ /* first extra time cycle results in obliteration */
+ if (inl_stat.extratime == 0)
+ obliterate(0,KPROVIDENCE);
+
+ inl_stat.extratime += extratime;
+
+ inl_game.idx = 0;
+ inl_game.end += extratime;
+ inl_game.message = "%i %s left in EXTRA time (momentum)";
+
+ announce_scores(0, MALL, inl_log);
+
+ }
+
+ /* after extra time is over, declare continuous score the winner */
+ else {
+ pmessage(0, MALL, inl_from, "---------- Game Over (Momentum) ----------");
+
+ fprintf(inl_log, "---------- Game Over (Momentum) ----------\n");
+
+ announce_scores(0, MALL, inl_log);
+
+ if (inl_teams[0].weighted_score > inl_teams[1].weighted_score) {
+ pmessage(0, MALL, inl_from, "Tie breaker: %s wins by continuous score",
+ sides[inl_teams[0].side_index].name);
+ fprintf(inl_log, "Tie breaker: %s wins by continuous score\n",
+ sides[inl_teams[0].side_index].name);
+ }
+ else {
+ pmessage(0, MALL, inl_from, "Tie breaker: %s wins by continuous score",
+ sides[inl_teams[1].side_index].name);
+ fprintf(inl_log, "Tie breaker: %s wins by continuous score\n",
+ sides[inl_teams[1].side_index].name);
+ }
+
+ game_over = 1;
+ }
+
+ }
+
else if (inl_stat.flags & S_TOURNEY)
{
inl_stat.flags &= ~(S_TOURNEY | S_COUNTDOWN);
@@ -843,10 +951,6 @@
/* inl_game.counts[0] = inl_stat.overtime / (PERMIN*2); */
inl_game.message = "%i %s left in overtime";
- fprintf(inl_log, "SCORE: Planet count: %i - %i - %i\n",
- inl_teams[HOME].planets, inl_teams[AWAY].planets,
- (20 - inl_teams[HOME].planets - inl_teams[AWAY].planets));
-
announce_scores(0, MALL, inl_log);
}
else if (inl_game.end <= inl_stat.game_ticks)
@@ -855,9 +959,6 @@
"------ Game ran out of time without a winner ------");
fprintf(inl_log, "---------- Game Over (TIED) ---------\n");
- fprintf(inl_log, "SCORE: Planet count: %i - %i - %i\n",
- inl_teams[HOME].planets, inl_teams[AWAY].planets,
- (20 - inl_teams[HOME].planets - inl_teams[AWAY].planets));
announce_scores(0, MALL, inl_log);
game_over = 1;
@@ -1320,8 +1421,17 @@
pmessage (0, MALL, inl_from, "%s is the starting time of t-mode play.",
tmp);
- if (inl_stat.score_mode)
- pmessage(0, MALL, inl_from, "Continuous scoring enabled.");
+ switch(inl_stat.score_mode) {
+ case 0:
+ pmessage(0, MALL, inl_from, "Planet scoring enabled.");
+ break;
+ case 1:
+ pmessage(0, MALL, inl_from, "Continuous scoring enabled.");
+ break;
+ case 2:
+ pmessage(0, MALL, inl_from, "Momentum scoring enabled.");
+ break;
+ }
doResources(0);
Index: Vanilla/robots/inlcomm.c
diff -u Vanilla/robots/inlcomm.c:1.19 Vanilla/robots/inlcomm.c:1.20
--- Vanilla/robots/inlcomm.c:1.19 Sat Nov 4 17:49:40 2000
+++ Vanilla/robots/inlcomm.c Fri Jan 26 17:58:01 2001
@@ -259,6 +259,20 @@
return 0;
}
+ if (inl_teams[HOME].score_mode != inl_teams[AWAY].score_mode)
+ {
+ pmessage(0, MALL, inl_from,
+ "Scoring mode has not be approved by both sides!");
+ for (c = 0; c < INLTEAM; c++)
+ {
+ pmessage(0, MALL, inl_from,
+ "%s (%s) has set score mode to %d",
+ inl_teams[c].t_name, inl_teams[c].name,
+ inl_teams[c].score_mode);
+ }
+ return 0;
+ }
+
for (c=0; c < INLTEAM; c++)
inl_teams[c].flags &= ~T_START;
@@ -314,6 +328,9 @@
time = inl_stat.time;
if (inl_stat.flags & S_OVERTIME)
time += inl_stat.overtime;
+
+ time += inl_stat.extratime;
+
#ifdef nodef
pmessage(who, MINDIV, addr_mess(who, MINDIV),
"Minutes remaining: %i Planet tally: %i - %i - %i",
@@ -324,9 +341,13 @@
{
int seconds = ( (time - inl_stat.game_ticks) / PERSEC ) % 60;
int minutes = ( (time - inl_stat.game_ticks) / PERMIN );
-
- pmessage(who, MINDIV, addr_mess(who, MINDIV),
- "Time remaining: %d:%02.2d", minutes, seconds);
+
+ if (inl_stat.overtime)
+ pmessage(who, MINDIV, addr_mess(who, MINDIV),
+ "Extra Time remaining: %d:%02.2d", minutes, seconds);
+ else
+ pmessage(who, MINDIV, addr_mess(who, MINDIV),
+ "Time remaining: %d:%02.2d", minutes, seconds);
}
#endif
@@ -1033,9 +1054,11 @@
void announce_scores(int who, int flag, FILE *fp) {
int win_cond;
- char *side;
-
- float divisor = (float) (inl_stat.game_ticks * 4);
+ char *h_name, *a_name;
+ char *p_ahead, *c_ahead, *m_ahead;
+ char *s_mode;
+ float h_cont, a_cont;
+ int h_planets, a_planets, n_planets;
if (inl_stat.game_ticks < 1)
return;
@@ -1043,81 +1066,94 @@
if (inl_stat.weighted_divisor < 1.0)
return;
- if (inl_stat.score_mode == 0)
- pmessage(who, flag, addr_mess(who, flag), "Scoring mode: planet count");
- else
- pmessage(who, flag, addr_mess(who, flag), "Scoring mode: continuous score");
+ /* this is critical! */
+ win_cond = check_winner();
- pmessage(who, flag, addr_mess(who, flag),
- "Continuous score: %s vs %s %.2f - %.2f (weighted)",
- sides[inl_teams[0].side_index].name,
- sides[inl_teams[1].side_index].name,
- (float) inl_teams[0].weighted_score / inl_stat.weighted_divisor,
- (float) inl_teams[1].weighted_score / inl_stat.weighted_divisor);
-
- if (fp)
- fprintf(fp, "SCORE: Continuous score: %s vs %s %.2f - %.2f (weighted)\n",
- sides[inl_teams[0].side_index].name,
- sides[inl_teams[1].side_index].name,
- (float) inl_teams[0].weighted_score / inl_stat.weighted_divisor,
- (float) inl_teams[1].weighted_score / inl_stat.weighted_divisor);
-
-
- /***** no need for these debug statements -da
- if (divisor < 1.0f)
- divisor = 1.0f;
+ h_name = sides[inl_teams[HOME].side_index].name;
+ a_name = sides[inl_teams[AWAY].side_index].name;
- pmessage(who, flag, addr_mess(who, flag),
- "Debug: %s vs %s %.2f - %.2f (continuous)",
- sides[inl_teams[0].side_index].name,
- sides[inl_teams[1].side_index].name,
- (float) inl_teams[0].abs_score / divisor,
- (float) inl_teams[1].abs_score / divisor);
+ h_cont = (float) inl_teams[HOME].weighted_score / inl_stat.weighted_divisor;
+ a_cont = (float) inl_teams[AWAY].weighted_score / inl_stat.weighted_divisor;
- divisor = (float) ((inl_stat.game_ticks / PERMIN) * 4);
+ h_planets = inl_teams[HOME].planets;
+ a_planets = inl_teams[AWAY].planets;
+ n_planets = 20 - h_planets - a_planets;
+
+ if (h_planets > a_planets + 2)
+ p_ahead = h_name;
+ else if (a_planets > h_planets + 2)
+ p_ahead = a_name;
+ else
+ p_ahead = "tied";
- if (divisor <= 1.0f)
- divisor = 1.0f;
+ if (h_cont > a_cont + 2.0)
+ c_ahead = h_name;
+ else if (a_cont > h_cont + 2.0)
+ c_ahead = a_name;
+ else
+ c_ahead = "tied";
+ if ((h_planets > a_planets + 2) || (h_cont > a_cont + 2.0))
+ m_ahead = h_name;
+ else if ((a_planets > h_planets + 2) || (a_cont > h_cont + 2.0))
+ m_ahead = a_name;
+ else
+ m_ahead = "tied";
+
pmessage(who, flag, addr_mess(who, flag),
- "Debug: %s vs %s %.2f - %.2f (semi-continuous)",
- sides[inl_teams[0].side_index].name,
- sides[inl_teams[1].side_index].name,
- (float) inl_teams[0].semi_score / divisor,
- (float) inl_teams[1].semi_score / divisor);
+ "Planet count: %s - %s: %i - %i - %i [%s]",
+ h_name, a_name, h_planets, a_planets, n_planets, p_ahead);
- ******/
+ pmessage(who, flag, addr_mess(who, flag),
+ "Continuous score: %s - %s: %.2f - %.2f [%s]",
+ h_name, a_name, h_cont, a_cont, c_ahead);
- win_cond = check_winner();
+ if (fp) {
+ fprintf(fp, "SCORE: Planet count: %s - %s: %i - %i - %i [%s]\n",
+ h_name, a_name, h_planets, a_planets, n_planets, p_ahead);
- side = (inl_teams[0].weighted_score > inl_teams[1].weighted_score)?
- sides[inl_teams[0].side_index].name:
- sides[inl_teams[1].side_index].name;
+ fprintf(fp, "SCORE: Continuous score: %s - %s: %.2f - %.2f [%s]\n",
+ h_name, a_name, h_cont, a_cont, c_ahead);
+ }
- switch(win_cond) {
+ switch(inl_stat.score_mode) {
case 0:
- if (inl_stat.score_mode) {
- pmessage(who, flag, addr_mess(who, flag), "Game TIED.");
+ s_mode = "planet count";
+ break;
+ case 1:
+ s_mode = "continuous score";
+ break;
+ case 2:
+ s_mode = "momentum score";
+ break;
+ default:
+ s_mode = "UNKNOWN (report this bug)";
+ break;
+ }
- if (fp) fprintf(fp, "SCORE: Game TIED.\n");
- }
+ switch(win_cond) {
+ case -1:
+ case 0:
+ pmessage(who, flag, addr_mess(who, flag), "Game TIED by %s", s_mode);
+ if (fp) fprintf(fp, "SCORE: Game TIED by %s\n", s_mode);
break;
case 1:
- pmessage(who, flag, addr_mess(who, flag),
- "%s winning by planet count", side);
- /* ignore NORMAL scoring mode */
+ pmessage(who, flag, addr_mess(who, flag), "%s winning by %s", p_ahead, s_mode);
+ if (fp) fprintf(fp, "SCORE: %s winning by %s\n", p_ahead, s_mode);
break;
case 2:
- pmessage(who, flag, addr_mess(who, flag),
- "%s winning by score >= 2.0", side);
- if (fp)
- fprintf(fp, "SCORE: %s winning by score >= 2.0\n", side);
+ pmessage(who, flag, addr_mess(who, flag), "%s winning by %s", c_ahead, s_mode);
+ if (fp) fprintf(fp, "SCORE: %s winning by %s\n", c_ahead, s_mode);
break;
case 3:
- pmessage(who, flag, addr_mess(who, flag),
- "%s winning by score < 2.0 but planet > 11-8-1", side);
- if (fp)
- fprintf(fp, "SCORE: %s winning by score < 2.0 but planet > 11-8-1\n", side);
+ pmessage(who, flag, addr_mess(who, flag), "%s winning by %s [tie break]",
+ p_ahead, s_mode);
+ if (fp) fprintf(fp, "SCORE: %s winning by %s [tie break]\n", p_ahead, s_mode);
+ break;
+ case 4:
+ pmessage(who, flag, addr_mess(who, flag), "%s winning by %s",
+ m_ahead, s_mode);
+ if (fp) fprintf(fp, "SCORE: %s winning by %s\n", m_ahead, s_mode);
break;
}
@@ -1134,6 +1170,7 @@
int who, team;
char *mode;
+ int sc_mode = -1;
who = mess->m_from;
@@ -1145,12 +1182,29 @@
team = check_player(who, 1);
- if (inl_teams[team].score_mode)
- inl_teams[team].score_mode = 0;
- else
- inl_teams[team].score_mode = 1;
+ comm = strchr(comm, ' ');
+
+ if (comm && (sscanf(comm, "%d", &sc_mode) != 1))
+ sc_mode = -1;
- mode = (inl_teams[team].score_mode? "CONTINUOUS": "NORMAL");
+ switch(sc_mode) {
+ case 0:
+ inl_teams[team].score_mode = 0;
+ mode = "NORMAL";
+ break;
+ case 1:
+ inl_teams[team].score_mode = 1;
+ mode = "CONTINUOUS";
+ break;
+ case 2:
+ inl_teams[team].score_mode = 2;
+ mode = "MOMENTUM";
+ break;
+ default:
+ pmessage(who, MINDIV, addr_mess(who, MINDIV),
+ "Usage: SCOREMODE [012]; 0=planets, 1=continuous; 2=momentum");
+ return 0;
+ }
pmessage(0, MALL, inl_from, "%s requests %s scoring mode.",
players[who].p_mapchars, mode);
Index: Vanilla/robots/inldefs.h
diff -u Vanilla/robots/inldefs.h:1.4 Vanilla/robots/inldefs.h:1.5
--- Vanilla/robots/inldefs.h:1.4 Wed Jun 7 15:41:17 2000
+++ Vanilla/robots/inldefs.h Fri Jan 26 17:58:01 2001
@@ -106,6 +106,7 @@
int game_ticks; /* ticks in official game */
int tmout_ticks;
int time, overtime;
+ int extratime;
int score_mode;
double weighted_divisor;
} Inl_stats;