[freeciv-ai] Fwd: Re: simple historian agent wants to get into cvs
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
I just want to remind once again thank you.
--- nikodimka <nikodimka@xxxxxxxxx> wrote:
> Date: Tue, 6 Apr 2004 14:24:17 -0700 (PDT)
> From: nikodimka <nikodimka@xxxxxxxxx>
> Subject: [freeciv-ai] Re: simple historian agent wants to get into cvs
> To: Raimar Falke <i-freeciv-lists@xxxxxxxxxxxxx>
> CC: freeciv-ai@xxxxxxxxxxx
>
>
> I have changed the simple historian agent patch
> according to Raimar's comments.
>
> so I present the patch again:
>
> ======================8<======================8<=====================
>
> diff -ruN -Xfreeciv-cvs-Feb-27.sha/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 -ruN -Xfreeciv-cvs-Feb-27.sha/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 Wed Apr 7 00:51:01 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,19 @@
>
> struct my_agent;
>
> +union arguments{
> + int int_arg;
> + struct xy_arg {
> + int x;
> + int y;
> + } xy_arg;
> +};
> +
> 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;
> + union arguments arg;
> };
>
> #define SPECLIST_TAG call
> @@ -87,18 +97,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;
> + union 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:
> + /* nothing */
> + 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 +206,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 +348,7 @@
> /* Add init calls of agents here */
> cma_init();
> cmafec_init();
> + simple_historian_init();
> }
>
> /***********************************************************************
> @@ -445,7 +494,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);
> }
> }
> /*
> @@ -610,6 +659,80 @@
> }
> 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 got removed because of FOW.
> +***********************************************************************/
> +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]) {
> + 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 -ruN -Xfreeciv-cvs-Feb-27.sha/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,
> diff -ruN -Xfreeciv-cvs-Feb-27.sha/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 Wed Apr 7 01:17:06 2004
> @@ -0,0 +1,131 @@
> +/**********************************************************************
> + Freeciv - Copyright (C) 2004 - A. Gorshenev
> + 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.
> +***********************************************************************/
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include "log.h"
> +#include "map.h"
> +#include "support.h"
> +
> +#include "agents.h"
> +
> +#include "sha.h"
> +
> +/**************************************************************************
> +This is the simple historian agent.
> +It just saves the last states of all 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) {
> +
> + int index = map_pos_to_index(x, y);
> + freelog(LOG_DEBUG, "sha got tile: %d ~= (%d, %d)", index, x, y);
> +
> + previous_tiles[index] = *map_get_tile(x, y);
> +}
> +
> +/**************************************************************************
> +...
> +**************************************************************************/
> +static void sha_unit_change(int id) {
> + struct unit *punit = find_unit_by_id(id);
> + struct unit *pold_unit = unit_list_find(&previous_units, id);
> +
> + freelog(LOG_DEBUG, "sha got unit: %d", id);
> +
> + assert(pold_unit);
> + *pold_unit = *punit;
> +}
> +
> +/**************************************************************************
> +...
> +**************************************************************************/
> +static void sha_unit_new(int id) {
> + struct unit *punit= find_unit_by_id(id);
> + struct unit *pold_unit = create_unit_virtual(get_player(punit->owner),
> + NULL, 0, 0);
> +
> + freelog(LOG_DEBUG, "sha got unit: %d", id);
> +
> + *pold_unit = *punit;
> + unit_list_insert(&previous_units, pold_unit);
> +}
> +
> +/**************************************************************************
> +...
> +**************************************************************************/
> +static void sha_unit_remove(int id) {
> + struct unit *pold_unit = unit_list_find(&previous_units, id);;
> +
> + freelog(LOG_DEBUG, "sha got unit: %d", id);
> +
> + assert(pold_unit);
> + unit_list_unlink(&previous_units, pold_unit);
> +}
> +
> +/**************************************************************************
> +...
> +**************************************************************************/
> +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.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);
> +}
> +
> +/**************************************************************************
> +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 -ruN -Xfreeciv-cvs-Feb-27.sha/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 Wed Apr 7 00:57:05 2004
> @@ -0,0 +1,24 @@
> +/**********************************************************************
> + Freeciv - Copyright (C) 2004 - A. Gorshenev
> + 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 -ruN -Xfreeciv-cvs-Feb-27.sha/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 Wed Apr 7 00:45:52 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 is 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 */
>
>
> __________________________________
> Do you Yahoo!?
> Yahoo! Small Business $15K Web Design Giveaway
> http://promotions.yahoo.com/design_giveaway/
>
__________________________________
Do you Yahoo!?
Yahoo! Tax Center - File online by April 15th
http://taxes.yahoo.com/filing.html
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freeciv-ai] Fwd: Re: simple historian agent wants to get into cvs,
nikodimka <=
|
|