AI start.

This commit is contained in:
johns 2001-04-24 22:55:05 +00:00
parent 186ea58173
commit 2adff994b7
7 changed files with 328 additions and 89 deletions

View file

@ -23,6 +23,6 @@ MODULE = ai
HDRS = ai_local.h
OBJS = ai.$(OE) new_ai.$(OE) ccl_ai.$(OE)
OBJS = ai.$(OE) new_ai.$(OE) ccl_ai.$(OE) ai_resource.$(OE)
include $(TOPDIR)/Common.mk

View file

@ -43,6 +43,8 @@ global int AiCostFactor = 100; /// Adjust the AI costs
global AiType* AiTypes; /// List of all AI types.
global AiHelper AiHelpers; /// AI helper variables
global PlayerAi* AiPlayer; /// Current AI player
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
@ -54,6 +56,20 @@ global AiHelper AiHelpers; /// AI helper variables
*/
global void AiInit(Player* player)
{
PlayerAi* pai;
DebugLevel0Fn("%d - %s\n" _C_ player->Player _C_ player->Name);
pai=calloc(1,sizeof(PlayerAi));
if( !pai ) {
fprintf(stderr,"Out of memory.\n");
exit(0);
}
pai->Player=player;
pai->AiType=AiTypes;
pai->Script=AiTypes->Script;
player->Ai=pai;
}
/*----------------------------------------------------------------------------
@ -68,7 +84,7 @@ global void AiInit(Player* player)
*/
global void AiHelpMe(Unit* unit)
{
DebugLevel0Fn("%d %d",unit->X,unit->Y);
DebugLevel0Fn("%d %d" _C_ unit->X _C_ unit->Y);
}
/**
@ -127,7 +143,25 @@ global void AiEachFrame(Player* player)
*/
global void AiEachSecond(Player* player)
{
// FIXME: Not needed, will be removed.
SCM value;
PlayerAi* pai;
DebugLevel0Fn("%d:\n" _C_ player->Player);
AiPlayer=pai=player->Ai;
//
// Advance script
//
if( !gh_null_p(pai->Script) ) {
if( pai->ScriptDebug ) { // display executed command
gh_display(gh_car(pai->Script));
gh_newline();
}
value=leval(gh_car(pai->Script),NIL);
if( !gh_eq_p(value,SCM_BOOL_T) ) {
pai->Script=gh_cdr(pai->Script);
}
}
}
//@}

View file

@ -26,13 +26,17 @@
-- Includes
----------------------------------------------------------------------------*/
#include "ccl.h"
#include "player.h"
#include "unittype.h"
#include "upgrade.h"
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
#if 0
/**
** Ai Script commands.
*/
@ -53,28 +57,6 @@ typedef struct _ai_script_ {
unsigned char Cnt; /// counter
} AiScript;
/**
** Ai Type typedef.
*/
typedef struct _ai_type_ AiType;
/**
** Ai Type structure.
*/
struct _ai_type_ {
AiType* Next; /// Next ai type.
char* Name; /// Name of this ai.
char* Race; /// for this race.
char* Class; /// class of this ai.
// nice flags
unsigned char AllExplored : 1; /// Ai sees unexplored area.
unsigned char AllVisibile : 1; /// Ai sees invisibile area.
AiScript* Script; /// Main script
};
/**
** AI goal typedef.
*/
@ -101,41 +83,97 @@ struct _ai_goal_ {
int Priority; /// Priority of this goal.
};
// goals stuff
AiGoal* GoalHead; /// Goals start of double linked list
AiGoal* GoalNil1; /// Goals dummy end of dl-list
AiGoal* GoalTail; /// Goals end of double linked list
AiGoal* WaitHead; /// Wait start of double linked list
AiGoal* WaitNil1; /// Wait dummy end of dl-list
AiGoal* WaitTail; /// Wait end of double linked list
// scripting stuff
AiScript* Ip; /// AI script instruction pointer
AiScript** Sp; /// Ai script stack pointer
AiScript** Stack; /// Ai script stack
#endif // --------------------------------------------------------------------
/**
** Ai Type typedef.
*/
typedef struct _ai_type_ AiType;
/**
** Ai Type structure.
*/
struct _ai_type_ {
AiType* Next; /// Next ai type.
char* Name; /// Name of this ai.
char* Race; /// for this race.
char* Class; /// class of this ai.
// nice flags
//unsigned char AllExplored : 1; /// Ai sees unexplored area.
//unsigned char AllVisibile : 1; /// Ai sees invisibile area.
SCM Script; /// Main script
};
/**
** AI unit-type table with counter in front.
*/
typedef struct _ai_unittype_table_ {
int Count; /// elements in table
UnitType* Table[1]; /// the table
} AiUnitTypeTable;
/**
** AI force typedef.
*/
typedef struct _ai_force_ AiForce;
/**
** Define an AI force.
**
** A force is a group of units belonging together.
*/
struct _ai_force_ {
AiUnitTypeTable UnitTypeTable; /// Count and types of unit-type
};
/**
** AI variables.
*/
typedef struct _player_ai_ {
Player* Player; /// engine player structure.
Player* Player; /// Engine player structure
AiType* AiType; /// AI type of this player AI.
AiType* AiType; /// AI type of this player AI
// goals stuff.
AiGoal* GoalHead; /// goals start of double linked list
AiGoal* GoalNil1; /// goals dummy end of dl-list
AiGoal* GoalTail; /// goals end of double linked list
// controller
SCM Script; /// Script executed
int ScriptDebug; /// Flag script debuging on/off
AiGoal* WaitHead; /// wait start of double linked list
AiGoal* WaitNil1; /// wait dummy end of dl-list
AiGoal* WaitTail; /// wait end of double linked list
// resource manager
// scripting stuff.
AiScript* Ip; /// AI script instruction pointer.
AiScript** Sp; /// Ai script stack pointer.
AiScript** Stack; /// Ai script stack.
/// unit-types to build/train requested and priority list
AiUnitTypeTable* UnitTypeRequests;
struct {
int Want; /// requested number
int Made; /// builded number
UnitType* Type; /// unit-type
}* UnitTypeBuilded; /// What the resource manager does
UnitType* Priority[256]; /// Building order
} PlayerAi;
/**
** AI Unittable with counter in front.
*/
typedef struct _ai_unittable_ {
unsigned Count; /// elements in table
UnitType* Table[0]; /// the table (GNU feature used)
} AiUnitTable;
/**
** AI Helper.
**
** Contains informations needed for the AI. If the AI needs an unit or
** building or upgrade or spell, it could lookup in this tables to find
** where it could be trained, builded or researched.
*/
typedef struct _ai_helper_ {
/**
@ -143,34 +181,36 @@ typedef struct _ai_helper_ {
** units/buildings which could train this unit.
*/
int TrainCount;
AiUnitTable* Train;
AiUnitTypeTable** Train;
/**
** The index is the unit that should be build, giving a table of all
** units/buildings which could build this unit.
*/
int BuildCount;
AiUnitTable* Build;
AiUnitTypeTable** Build;
/**
** The index is the upgrade that should be made, giving a table of all
** units/buildings which could do the upgrade.
*/
int UpgradeCount;
AiUnitTable* Upgrade;
AiUnitTypeTable** Upgrade;
/**
** The index is the research that should be made, giving a table of all
** units/buildings which could research this upgrade.
*/
int ResearchCount;
AiUnitTable* Research;
AiUnitTypeTable** Research;
} AiHelper;
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
extern AiType* AiTypes; /// List of all AI types.
extern AiType* AiTypes; /// List of all AI types
extern AiHelper AiHelpers; /// AI helper variables
extern PlayerAi* AiPlayer; /// Current AI player
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/

43
src/ai/ai_resource.cpp Normal file
View file

@ -0,0 +1,43 @@
// ___________ _________ _____ __
// \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_
// | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\
// | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | |
// \___ / |__| \___ >\___ >\______ /|__| (____ /__| |__|
// \/ \/ \/ \/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name ai_resource.c - AI resource manager. */
//
// (c) Copyright 2000,2001 by Lutz Sammer
//
// $Id$
#ifdef NEW_AI // {
//@{
/*----------------------------------------------------------------------------
-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "freecraft.h"
#include "unit.h"
#include "ai_local.h"
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
//@}
#endif // } NEW_AI

View file

@ -40,49 +40,83 @@
/**
** Setup AI helper table.
**
** Expand the table if needed.
**
** @param count Pointer to number of elements in table.
** @param table Pointer to table with elements.
** @param n Index to insert new into table
*/
local void AiHelperSetupTable(int* count,AiUnitTable** table,UnitType* type)
local void AiHelperSetupTable(int* count,AiUnitTypeTable*** table,int n)
{
if( type->Type>=*count ) {
int i;
++n;
if( n>(i=*count) ) {
if( *table ) {
*table=realloc(*table,(1+type->Type)*sizeof(UnitType*));
memset(*table+*count,0,((1+type->Type)-*count)*sizeof(UnitType*));
*table=realloc(*table,n*sizeof(AiUnitTypeTable*));
memset((*table)+i,0,(n-i)*sizeof(AiUnitTypeTable*));
} else {
*table=malloc((1+type->Type)*sizeof(UnitType*));
memset(*table,0,(1+type->Type)*sizeof(UnitType*));
*table=malloc(n*sizeof(AiUnitTypeTable*));
memset(*table,0,n*sizeof(AiUnitTypeTable*));
}
*count=type->Type+1;
*count=n;
}
}
/**
** Insert new element.
** Insert new unit-type element.
**
** @param table Pointer to table with elements.
** @param base Base type to insert into table.
*/
local void AiHelperInsert(AiUnitTable** table,UnitType* base)
local void AiHelperInsert(AiUnitTypeTable** tablep,UnitType* base)
{
int i;
int n;
AiUnitTypeTable* table;
if( !*table ) {
*table=malloc(sizeof(AiUnitTable*)+sizeof(UnitType*));
(*table)->Count=1;
(*table)->Table[0]=base;
//
// New unit-type
//
if( !(table=*tablep) ) {
table=*tablep=malloc(sizeof(AiUnitTypeTable));
table->Count=1;
table->Table[0]=base;
return;
}
n=(*table)->Count;
//
// Look if already known.
//
n=table->Count;
for( i=0; i<n; ++i ) {
if( (*table)->Table[i]==base ) {
if( table->Table[i]==base ) {
return;
}
}
n++;
*table=realloc(*table,sizeof(AiUnitTable*)+sizeof(UnitType*)*n);
(*table)->Count=n;
(*table)->Table[n-1]=base;
//
// Append new base unit-type to units.
//
table=*tablep=realloc(table,sizeof(AiUnitTypeTable)+sizeof(UnitType*)*n);
table->Count=n+1;
table->Table[n]=base;
}
#ifdef DEBUG
/**
** Print AI helper table.
*/
local void PrintAiHelperTable(void)
{
}
#endif
/**
** Define helper for Ai.
**
** @param list List of all helpers.
*/
local SCM CclDefineAiHelper(SCM list)
{
@ -92,7 +126,9 @@ local SCM CclDefineAiHelper(SCM list)
char* str;
UnitType* base;
UnitType* type;
Upgrade* upgrade;
IfDebug( type=NULL; upgrade=NULL; ); // keep the compiler happy
while( !gh_null_p(list) ) {
sub_list=gh_car(list);
list=gh_cdr(list);
@ -111,9 +147,10 @@ local SCM CclDefineAiHelper(SCM list)
} else if( gh_eq_p(value,gh_symbol2scm("research")) ) {
what=3;
} else {
fprintf(stderr,"unknown tag");
fprintf(stderr,"unknown tag\n");
continue;
}
//
// Get the base unit type, which could handle the action.
//
@ -122,7 +159,7 @@ local SCM CclDefineAiHelper(SCM list)
str=gh_scm2newstr(value,NULL);
base=UnitTypeByIdent(str);
if( !base ) {
fprintf(stderr,"unknown unittype %s",str);
fprintf(stderr,"unknown unittype %s\n",str);
free(str);
continue;
}
@ -136,39 +173,56 @@ local SCM CclDefineAiHelper(SCM list)
value=gh_car(sub_list);
sub_list=gh_cdr(sub_list);
str=gh_scm2newstr(value,NULL);
type=UnitTypeByIdent(str);
if( !type ) {
fprintf(stderr,"unknown unittype %s",str);
free(str);
continue;
if( what==3 ) {
upgrade=UpgradeByIdent(str);
if( !upgrade ) {
fprintf(stderr,"unknown upgrade %s\n",str);
free(str);
continue;
}
DebugLevel0Fn("> %s\n",upgrade->Ident);
} else {
type=UnitTypeByIdent(str);
if( !type ) {
fprintf(stderr,"unknown unittype %s\n",str);
free(str);
continue;
}
DebugLevel0Fn("> %s\n",type->Name);
}
DebugLevel0Fn("> %s\n",type->Name);
free(str);
switch( what ) {
case 0: // build
AiHelperSetupTable(
&AiHelpers.BuildCount,&AiHelpers.Build,type);
&AiHelpers.BuildCount,&AiHelpers.Build,type->Type);
AiHelperInsert(
&AiHelpers.Build+type->Type,base);
AiHelpers.Build+type->Type,base);
break;
case 1: // train
AiHelperSetupTable(
&AiHelpers.TrainCount,&AiHelpers.Train,type);
&AiHelpers.TrainCount,&AiHelpers.Train,type->Type);
AiHelperInsert(
&AiHelpers.Train+type->Type,base);
AiHelpers.Train+type->Type,base);
break;
case 2: // upgrade
AiHelperSetupTable(
&AiHelpers.UpgradeCount,&AiHelpers.Upgrade,type);
&AiHelpers.UpgradeCount,&AiHelpers.Upgrade,
type->Type);
AiHelperInsert(
&AiHelpers.Upgrade+type->Type,base);
AiHelpers.Upgrade+type->Type,base);
break;
case 3: // research
AiHelperSetupTable(
&AiHelpers.ResearchCount,&AiHelpers.Research,
upgrade-Upgrades);
AiHelperInsert(
AiHelpers.Research+(upgrade-Upgrades),base);
break;
}
}
}
return list;
}
@ -177,7 +231,6 @@ local SCM CclDefineAiHelper(SCM list)
*/
local SCM CclDefineAi(SCM list)
{
SCM sub_list;
SCM value;
char* str;
AiType* aitype;
@ -213,6 +266,15 @@ local SCM CclDefineAi(SCM list)
DebugLevel0Fn("%s\n",str);
aitype->Class=str;
//
// AI Script
//
value=gh_car(list);
list=gh_cdr(list);
aitype->Script=value;
//gc_protect(&aitype->Script);
#if 0
//
// AI Script
//
@ -232,14 +294,66 @@ local SCM CclDefineAi(SCM list)
} else if( gh_eq_p(value,gh_symbol2scm("force")) ) {
} else {
str=gh_scm2newstr(value,NULL);
fprintf(stderr,"unknown tag %s",str);
fprintf(stderr,"unknown tag %s\n",str);
free(str);
continue;
}
}
#endif
return list;
}
/*----------------------------------------------------------------------------
-- Ai script functions
----------------------------------------------------------------------------*/
/**
** Set debuging flag of AI script.
*/
local SCM CclAiDebug(SCM flag)
{
if( gh_eq_p(flag,SCM_BOOL_T) ) {
AiPlayer->ScriptDebug=1;
} else {
AiPlayer->ScriptDebug=0;
}
return SCM_BOOL_F;
}
/**
** Need an unit.
*/
local SCM CclAiNeed(SCM unit)
{
printf("Need: ");
gh_display(unit);
gh_newline();
return SCM_BOOL_F;
}
/**
** Set the number of units.
*/
local SCM CclAiSet(SCM unit,SCM count)
{
printf("Set: ");
gh_display(unit);
gh_display(unit);
gh_newline();
return SCM_BOOL_F;
}
/**
** Wait for an unit.
*/
local SCM CclAiWait(SCM unit)
{
printf("Wait: ");
gh_display(unit);
gh_newline();
return SCM_BOOL_F;
}
#else
/**
@ -270,6 +384,14 @@ global void AiCclRegister(void)
gh_new_procedureN("define-ai-helper",CclDefineAiHelper);
gh_new_procedureN("define-ai",CclDefineAi);
#if defined(NEW_AI)
gh_new_procedure1_0("ai:debug",CclAiDebug);
gh_new_procedure1_0("ai:need",CclAiNeed);
gh_new_procedure2_0("ai:set",CclAiSet);
gh_new_procedure1_0("ai:wait",CclAiWait);
#endif
}
#endif // } USE_CCL

View file

@ -247,7 +247,7 @@ global Unit* MakeUnit(UnitType* type,Player* player)
//
unit->Type=type;
unit->SeenFrame=-1;
unit->SeenFrame=0xFF;
if( !type->Building ) {
unit->Direction=(MyRand()>>8)&0xFF;// random heading
player->NumFoodUnits++; // food needed

View file

@ -963,7 +963,7 @@ local void DrawBuilding(Unit* unit)
frame = unit->SeenFrame = unit->Frame;
} else {
frame = unit->SeenFrame;
DebugCheck( frame==-1 || frame==255 );
DebugCheck( frame==-1 || frame==0xFF );
}
type=unit->Type;