[freeciv-ai] simple historian agent wants to get into cvs
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Hello,
I have fixed the Simple Historian Agent initial implementation
acording to Raimar's comments and would like to present the patch.
What should I do to get it into the CVS?
nikodimka
Here it goes.
======================================================================
diff -bwruN -X./freeciv-cvs-Feb-27/diff_ignore
./freeciv-cvs-Feb-27/client/agents/Makefile.am
./freeciv-cvs-Feb-27.sha/client/agents/Makefile.am
--- ./freeciv-cvs-Feb-27/client/agents/Makefile.am Sat Dec 21 07:19:05 2002
+++ ./freeciv-cvs-Feb-27.sha/client/agents/Makefile.am Tue Mar 30 01:50:30 2004
@@ -10,4 +10,6 @@
cma_core.c \
cma_core.h \
cma_fec.c \
- cma_fec.h
+ cma_fec.h \
+ sha.c \
+ sha.h
diff -bwruN -X./freeciv-cvs-Feb-27/diff_ignore
./freeciv-cvs-Feb-27/client/agents/sha.c
./freeciv-cvs-Feb-27.sha/client/agents/sha.c
--- ./freeciv-cvs-Feb-27/client/agents/sha.c Wed Dec 31 17:00:00 1969
+++ ./freeciv-cvs-Feb-27.sha/client/agents/sha.c Tue Mar 30 01:50:09 2004
@@ -0,0 +1,142 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2001 - A. Gorshenev (aka nikodimka)
+ 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, 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.
+***********************************************************************/
+
+#include "agents.h"
+#include "log.h"
+#include "map.h"
+#include "sha.h"
+#include "support.h"
+
+/**************************************************************************
+This is the simple historian agent.
+It just saves the last states of all cities, tiles and units.
+The trick is just to call this agent the last of all
+so it still keeps old values whereas all other agents
+allready got the new ones.
+**************************************************************************/
+
+static struct agent simple_historian_agent;
+
+static struct tile *previous_tiles = NULL;
+static struct unit_list previous_units;
+
+static void sha_tile_update(int x, int y);
+
+static void sha_unit_new(int id);
+static void sha_unit_change(int id);
+static void sha_unit_remove(int id);
+
+
+/**************************************************************************
+...
+**************************************************************************/
+void simple_historian_init(void) {
+
+ previous_tiles = fc_malloc(MAX_MAP_INDEX*sizeof(*previous_tiles));
+ memset(previous_tiles, 0, MAX_MAP_INDEX*sizeof(*previous_tiles));
+
+ unit_list_init(&previous_units);
+
+ memset(&simple_historian_agent, 0, sizeof(simple_historian_agent));
+ sz_strlcpy(simple_historian_agent.name, "Simple Historian");
+
+ simple_historian_agent.level = LAST_AGENT_LEVEL;
+
+ simple_historian_agent.unit_callbacks[CB_REMOVE] = sha_unit_remove;
+ simple_historian_agent.unit_callbacks[CB_CHANGE] = sha_unit_change;
+ simple_historian_agent.unit_callbacks[CB_NEW] = sha_unit_new;
+ /*
+ simple_historian_agent.city_callbacks[CB_REMOVE] = sha_city_remove;
+ simple_historian_agent.city_callbacks[CB_CHANGE] = sha_city_change;
+ simple_historian_agent.city_callbacks[CB_NEW] = sha_city_new;
+ */
+ simple_historian_agent.tile_callbacks[CB_REMOVE] = sha_tile_update;
+ simple_historian_agent.tile_callbacks[CB_CHANGE] = sha_tile_update;
+ simple_historian_agent.tile_callbacks[CB_NEW] = sha_tile_update;
+ register_agent(&simple_historian_agent);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void sha_tile_update(int x, int y) {
+
+ int index = map_pos_to_index(x, y);
+ freelog(LOG_DEBUG, "sha got tile: %d ~= (%d, %d)\n", index, x, y);
+
+ previous_tiles[index] = *map_get_tile(x, y);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void sha_unit_change(int id) {
+ struct unit * punit, *pold_unit;
+
+ freelog(LOG_DEBUG, "sha got unit: %d\n", id);
+
+ punit = find_unit_by_id(id);
+ pold_unit = unit_list_find(&previous_units, id);
+
+ assert(pold_unit);
+ *pold_unit = *punit;
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void sha_unit_new(int id) {
+ struct unit * punit, *pold_unit;
+
+ freelog(LOG_DEBUG, "sha got unit: %d\n", id);
+
+ punit = find_unit_by_id(id);
+ pold_unit = create_unit_virtual(get_player(punit->owner),
+ NULL,
+ 0,
+ 0);
+ *pold_unit = *punit;
+ unit_list_insert(&previous_units, pold_unit);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void sha_unit_remove(int id) {
+ struct unit *pold_unit;
+
+ freelog(LOG_DEBUG, "sha got unit: %d\n", id);
+
+ pold_unit = unit_list_find(&previous_units, id);
+ assert(pold_unit);
+ unit_list_unlink(&previous_units, pold_unit);
+}
+
+/**************************************************************************
+Public interface
+**************************************************************************/
+
+/**************************************************************************
+...
+**************************************************************************/
+struct tile* sha_tile_recall(int x, int y) {
+ int index = map_pos_to_index(x, y);
+ return &previous_tiles[index];
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+struct unit* sha_unit_recall(int id) {
+ return unit_list_find(&previous_units, id);
+}
diff -bwruN -X./freeciv-cvs-Feb-27/diff_ignore
./freeciv-cvs-Feb-27/client/agents/sha.h
./freeciv-cvs-Feb-27.sha/client/agents/sha.h
--- ./freeciv-cvs-Feb-27/client/agents/sha.h Wed Dec 31 17:00:00 1969
+++ ./freeciv-cvs-Feb-27.sha/client/agents/sha.h Tue Mar 30 01:50:09 2004
@@ -0,0 +1,24 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2001 - A. Gorshenev (aka nikodimka)
+ 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, 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.
+***********************************************************************/
+
+#ifndef FC__CLIENT_AGENTS_SIMPLE_HISTORIAN_H
+#define FC__CLIENT_AGENTS_SIMPLE_HISTORIAN_H
+
+void simple_historian_init(void);
+
+struct tile* sha_tile_recall(int x, int y);
+struct unit* sha_unit_recall(int id);
+
+#endif /* header guard */
+
+
diff -bwruN -X./freeciv-cvs-Feb-27/diff_ignore
./freeciv-cvs-Feb-27/client/packhand.c
./freeciv-cvs-Feb-27.sha/client/packhand.c
--- ./freeciv-cvs-Feb-27/client/packhand.c Sun Feb 22 23:01:50 2004
+++ ./freeciv-cvs-Feb-27.sha/client/packhand.c Tue Mar 30 01:50:09 2004
@@ -1902,6 +1902,7 @@
struct tile *ptile = map_get_tile(packet->x, packet->y);
enum known_type old_known = ptile->known;
bool tile_changed = FALSE;
+ bool known_changed = FALSE;
if (ptile->terrain != packet->type) { /*terrain*/
tile_changed = TRUE;
@@ -1924,6 +1925,9 @@
tile_changed = TRUE;
}
}
+ if (ptile->known != packet->known) {
+ known_changed = TRUE;
+ }
ptile->known = packet->known;
if (packet->spec_sprite[0] != '\0') {
@@ -1965,6 +1969,19 @@
if (ptile->continent > map.num_continents) {
map.num_continents = ptile->continent;
allot_island_improvs();
+ }
+
+ if (known_changed || tile_changed) {
+ /* here I assume that tile can *change* only if it was known
+ and still is known. Otherwise it new or removed
+ and that it can not go into UNKNOWN after it has been known */
+ if (known_changed && (ptile->known == TILE_KNOWN)) {
+ agents_tile_new(packet->x, packet->y);
+ } else if (known_changed && (ptile->known == TILE_KNOWN_FOGGED)) {
+ agents_tile_remove(packet->x, packet->y);
+ } else {
+ agents_tile_changed(packet->x, packet->y);
+ }
}
/* refresh tiles */
diff -bwruN -X./freeciv-cvs-Feb-27/diff_ignore
./freeciv-cvs-Feb-27/client/agents/agents.c
./freeciv-cvs-Feb-27.sha/client/agents/agents.c
--- ./freeciv-cvs-Feb-27/client/agents/agents.c Mon Nov 10 22:59:57 2003
+++ ./freeciv-cvs-Feb-27.sha/client/agents/agents.c Tue Mar 30 01:51:25 2004
@@ -16,6 +16,7 @@
#endif
#include <assert.h>
+#include <stdarg.h>
#include <string.h>
#include "capability.h"
@@ -29,6 +30,7 @@
#include "cma_core.h"
#include "cma_fec.h"
#include "mapctrl_g.h"
+#include "sha.h"
#include "agents.h"
@@ -41,11 +43,20 @@
struct my_agent;
+typedef union {
+ int null_arg;
+ int int_arg;
+ struct xy_arg {
+ int x;
+ int y;
+ } xy_arg;
+} arguments;
+
struct call {
struct my_agent *agent;
- enum oct { OCT_NEW_TURN, OCT_UNIT, OCT_CITY } type;
+ enum oct { OCT_NEW_TURN, OCT_UNIT, OCT_CITY, OCT_TILE } type;
enum callback_type cb_type;
- int arg;
+ arguments arg;
};
#define SPECLIST_TAG call
@@ -87,18 +98,53 @@
***********************************************************************/
static void enqueue_call(struct my_agent *agent,
enum oct type,
- enum callback_type cb_type, int arg)
+ enum callback_type cb_type, ...)
{
+ va_list ap;
struct call *pcall2;
+ arguments arg;
+
+ va_start(ap, cb_type);
if (client_is_observer()) {
return;
}
+ switch (type) {
+ case OCT_UNIT:
+ case OCT_CITY:
+ arg.int_arg = va_arg(ap, int);
+ break;
+ case OCT_TILE:
+ arg.xy_arg.x = va_arg(ap, int);
+ arg.xy_arg.y = va_arg(ap, int);
+ break;
+ case OCT_NEW_TURN:
+ arg.null_arg = 0;
+ break;
+ default:
+ assert(0);
+ }
+ va_end(ap);
+
call_list_iterate(agents.calls, pcall) {
if (pcall->type == type && pcall->cb_type == cb_type
- && pcall->arg == arg && pcall->agent == agent) {
- return;
+ && pcall->agent == agent) {
+ switch (type) {
+ case OCT_UNIT:
+ case OCT_CITY:
+ if (arg.int_arg == pcall->arg.int_arg) return;
+ break;
+ case OCT_TILE:
+ if (arg.xy_arg.x == pcall->arg.xy_arg.x &&
+ arg.xy_arg.y == pcall->arg.xy_arg.y) return;
+ break;
+ case OCT_NEW_TURN:
+ /* no checks needed for no-arg calls*/
+ break;
+ default:
+ assert(0);
+ }
}
} call_list_iterate_end;
@@ -161,9 +207,12 @@
if (call->type == OCT_NEW_TURN) {
call->agent->agent.turn_start_notify();
} else if (call->type == OCT_UNIT) {
- call->agent->agent.unit_callbacks[call->cb_type] (call->arg);
+ call->agent->agent.unit_callbacks[call->cb_type] (call->arg.int_arg);
} else if (call->type == OCT_CITY) {
- call->agent->agent.city_callbacks[call->cb_type] (call->arg);
+ call->agent->agent.city_callbacks[call->cb_type] (call->arg.int_arg);
+ } else if (call->type == OCT_TILE) {
+ call->agent->agent.tile_callbacks[call->cb_type]
+ (call->arg.xy_arg.x, call->arg.xy_arg.y);
} else {
assert(0);
}
@@ -300,6 +349,7 @@
/* Add init calls of agents here */
cma_init();
cmafec_init();
+ simple_historian_init();
}
/***********************************************************************
@@ -445,7 +495,7 @@
continue;
}
if (agent->agent.turn_start_notify) {
- enqueue_call(agent, OCT_NEW_TURN, CB_LAST, 0);
+ enqueue_call(agent, OCT_NEW_TURN, CB_LAST);
}
}
/*
@@ -465,7 +515,6 @@
void agents_unit_changed(struct unit *punit)
{
int i;
-
freelog(LOG_DEBUG,
"A: agents_unit_changed(unit=%d) type=%s pos=(%d,%d) owner=%s",
punit->id, unit_types[punit->type].name, punit->x, punit->y,
@@ -610,6 +659,81 @@
}
if (agent->agent.city_callbacks[CB_REMOVE]) {
enqueue_call(agent, OCT_CITY, CB_REMOVE, pcity->id);
+ }
+ }
+
+ call_handle_methods();
+}
+
+/***********************************************************************
+ Called from client/packhand.c. See agents_unit_changed for a generic
+ documentation.
+ Tiles not removed, tiles lost in fog of war.
+***********************************************************************/
+void agents_tile_remove(int x, int y)
+{
+ int i;
+
+ freelog(LOG_DEBUG,
+ "A: agents_tile_remove(tile=(%d, %d))", x, y);
+
+ for (i = 0; i < agents.entries_used; i++) {
+ struct my_agent *agent = &agents.entries[i];
+
+ if (is_outstanding_request(agent)) {
+ continue;
+ }
+ if (agent->agent.tile_callbacks[CB_REMOVE]) {
+ /* encoding tile coordinates into single integer */
+ enqueue_call(agent, OCT_TILE, CB_REMOVE, x, y);
+ }
+ }
+
+ call_handle_methods();
+}
+
+/***********************************************************************
+ Called from client/packhand.c. See agents_unit_changed for a generic
+ documentation.
+***********************************************************************/
+void agents_tile_changed(int x, int y)
+{
+ int i;
+ freelog(LOG_DEBUG,
+ "A: agents_tile_changed(tile=(%d, %d))", x, y);
+
+ for (i = 0; i < agents.entries_used; i++) {
+ struct my_agent *agent = &agents.entries[i];
+
+ if (is_outstanding_request(agent)) {
+ continue;
+ }
+ if (agent->agent.tile_callbacks[CB_CHANGE]) {
+ enqueue_call(agent, OCT_TILE, CB_CHANGE, x, y);
+ }
+ }
+
+ call_handle_methods();
+}
+
+/***********************************************************************
+ Called from client/packhand.c. See agents_unit_changed for a generic
+ documentation.
+***********************************************************************/
+void agents_tile_new(int x, int y)
+{
+ int i;
+ freelog(LOG_DEBUG,
+ "A: agents_tile_new(tile=(%d, %d))", x, y);
+
+ for (i = 0; i < agents.entries_used; i++) {
+ struct my_agent *agent = &agents.entries[i];
+
+ if (is_outstanding_request(agent)) {
+ continue;
+ }
+ if (agent->agent.tile_callbacks[CB_NEW]) {
+ enqueue_call(agent, OCT_TILE, CB_NEW, x, y);
}
}
diff -bwruN -X./freeciv-cvs-Feb-27/diff_ignore
./freeciv-cvs-Feb-27/client/agents/agents.h
./freeciv-cvs-Feb-27.sha/client/agents/agents.h
--- ./freeciv-cvs-Feb-27/client/agents/agents.h Thu Nov 7 09:04:52 2002
+++ ./freeciv-cvs-Feb-27.sha/client/agents/agents.h Tue Mar 30 01:50:09 2004
@@ -22,6 +22,9 @@
* every agent is only called once at any time.
*/
+/* Don't use the very last level unless you know what you're doing */
+#define LAST_AGENT_LEVEL 99
+
#define MAX_AGENT_NAME_LEN 10
struct city;
@@ -38,6 +41,7 @@
void (*turn_start_notify) (void);
void (*city_callbacks[CB_LAST]) (int);
void (*unit_callbacks[CB_LAST]) (int);
+ void (*tile_callbacks[CB_LAST]) (int, int);
};
void agents_init(void);
@@ -64,6 +68,10 @@
void agents_city_changed(struct city *pcity);
void agents_city_new(struct city *pcity);
void agents_city_remove(struct city *pcity);
+
+void agents_tile_changed(int, int);
+void agents_tile_new(int, int);
+void agents_tile_remove(int, int);
/* called from agents */
void cause_a_city_changed_for_agent(const char *name_of_calling_agent,
__________________________________
Do you Yahoo!?
Yahoo! Finance Tax Center - File online. File on time.
http://taxes.yahoo.com/filing.html
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freeciv-ai] simple historian agent wants to get into cvs,
nikodimka <=
|
|