?? demo12_7_16b.cpp
字號:
state_prob[curr_elem++] = state4;
for (index = 0; index < prob5; index++)
state_prob[curr_elem++] = state5;
for (index = 0; index < prob6; index++)
state_prob[curr_elem++] = state6;
// now select a state
return(state_prob[rand()%100]);
} // end Select_State_Rand
///////////////////////////////////////////////////////////////////////
void Set_New_State(int new_state, int index, int var1=0, int var2=0)
{
// this function sets the state of the ant to new_state
// reset all state info
ants[index].varsI[ANT_INDEX_AI_STATE] = 0;
ants[index].varsI[ANT_INDEX_AI_SUBSTATE] = 0;
ants[index].counter_1 = 0;
ants[index].counter_2 = 0;
// now set new state info
switch(new_state)
{
case ANT_WANDERING: // moving around randomly
{
// set the ai state of ant
ants[index].varsI[ANT_INDEX_AI_STATE] = ANT_WANDERING;
// set how long to wander
ants[index].counter_1 = RAND_RANGE(150, 300);
// set direction
ants[index].varsI[ANT_INDEX_DIRECTION] = RAND_RANGE(ANT_ANIM_UP, ANT_ANIM_LEFT);
// time in that direction
ants[index].counter_2 = RAND_RANGE(10, 100);
// start animation
Set_Animation_BOB(&ants[index], ants[index].varsI[ANT_INDEX_DIRECTION]);
} break;
case ANT_EATING: // at a mnm eating it
{
// set state to eating
ants[index].varsI[ANT_INDEX_AI_STATE] = ANT_EATING;
// start eating the mnm indexed by var1
ants[index].varsI[ANT_INDEX_MNM_BEING_DEVOURED] = var1;
// counters not used in this state
} break;
case ANT_RESTING: // sleeping :)
{
// set the ai state of ant
ants[index].varsI[ANT_INDEX_AI_STATE] = ANT_RESTING;
// set how long to rest
ants[index].counter_1 = RAND_RANGE(50, 200);
} break;
case ANT_SEARCH_FOOD: // hungry and searching for food
{
// set state to search for food
ants[index].varsI[ANT_INDEX_AI_STATE] = ANT_SEARCH_FOOD;
// start off by scanning for food
ants[index].varsI[ANT_INDEX_AI_SUBSTATE] = ANT_SEARCH_FOOD_S1_SCAN;
// initialize targets tp 0
ants[index].varsI[ANT_INDEX_FOOD_TARGET_X] = 0;
ants[index].varsI[ANT_INDEX_FOOD_TARGET_Y] = 0;
} break;
case ANT_COMMUNICATING: // talking to another ant
{
// set the ai state of ant
ants[index].varsI[ANT_INDEX_AI_STATE] = ANT_COMMUNICATING;
// set how long to communicate
ants[index].counter_1 = RAND_RANGE(60, 90);
// when counter 2 hits 5 then exchange memory
// thus about 5-10% of the memories will be exchanged
ants[index].counter_2 = 0;
} break;
case ANT_DEAD: // this guy is dead, got too hungry
{
// set the ai state of ant
ants[index].varsI[ANT_INDEX_AI_STATE] = ANT_DEAD;
// set direction
ants[index].varsI[ANT_INDEX_DIRECTION] = ANT_ANIM_DEAD;
// start animation
Set_Animation_BOB(&ants[index], ants[index].varsI[ANT_INDEX_DIRECTION]);
} break;
default: break;
} // end switch
} // end Set_New_State
//////////////////////////////////////////////////////////////////////
void Move_Ants(void)
{
// this function moves all the ants and processes the ai
// up, right, down, left
static int ant_movements_x[4] = { 0,2,0,-2};
static int ant_movements_y[4] = {-2,0,2, 0};
static int clear_ilayer = 0; // tracks when to clear the input memory layer
int index;
int select_new_state = -1;
for (index=0; index < NUM_ANTS; index++)
{
// reset new state selector
select_new_state = -1;
// what state is ant in?
switch(ants[index].varsI[ANT_INDEX_AI_STATE])
{
case ANT_WANDERING: // moving around randomly
{
// in this state the ant selects random directions and then
// walks for some period in that direction, if during the ants
// walk, it stumbles across some food, then it will remember
// the rough position of the food in int memory
// burns 1 unit per cycle
// move the ant
ants[index].x+=ant_movements_x[ants[index].varsI[ANT_INDEX_DIRECTION]];
ants[index].y+=ant_movements_y[ants[index].varsI[ANT_INDEX_DIRECTION]];
// test if ant is done with direction and needs a new one
if (--ants[index].counter_2 < 0)
{
// set direction
ants[index].varsI[ANT_INDEX_DIRECTION] = RAND_RANGE(ANT_ANIM_UP, ANT_ANIM_LEFT);
// time in this new direction
ants[index].counter_2 = RAND_RANGE(10, 100);
// start animation
Set_Animation_BOB(&ants[index], ants[index].varsI[ANT_INDEX_DIRECTION]);
} // end if new direction
// burn food
ants[index].varsI[ANT_INDEX_HUNGER_LEVEL]++;
// update memory with presence of food
int ant_cell_x = ants[index].x / 30;
int ant_cell_y = ants[index].y / 30;
// this updates the i,jth memory cell in ant with info about food
ants_mem[index].cell[ant_cell_x][ant_cell_y] =
ANT_MEMORY_RESIDUAL_RATE*ants_mem[index].cell[ant_cell_x][ant_cell_y] +
(1-ANT_MEMORY_RESIDUAL_RATE)*Food_Near_Ant(ant_cell_x, ant_cell_y);
// test if we are done with this state and need a new one?
if (--ants[index].counter_1 < 0)
{
// select either rest or wander, search will pre-empt with logic following
// if hungry, state, probability of state, must sum to 100
select_new_state = Select_State_Rand(ANT_WANDERING, 70,
ANT_EATING, 0,
ANT_RESTING, 30,
ANT_SEARCH_FOOD, 0,
ANT_COMMUNICATING, 0,
ANT_DEAD, 0);
} // end if
// test for pre-empt into communication mode
for (int dialog_ant = 0; dialog_ant < NUM_ANTS; dialog_ant++)
{
// try and talk if this isn't the same ant just talked to and this ant
// is either resting or wandering
if ( ( (dialog_ant!=index) && (ants[index].varsI[ANT_INDEX_LAST_TALKED_WITH] != dialog_ant) ) &&
((ants[dialog_ant].varsI[ANT_INDEX_AI_STATE] == ANT_RESTING) ||
(ants[dialog_ant].varsI[ANT_INDEX_AI_STATE] == ANT_WANDERING)) )
{
// are they close enough to talk?
if ((abs(ants[index].x - ants[dialog_ant].x) < 8) &&
(abs(ants[index].y - ants[dialog_ant].y) < 8) )
{
// set both ants to communicate mode
Set_New_State(ANT_COMMUNICATING,index);
Set_New_State(ANT_COMMUNICATING,dialog_ant);
// set communicate partners for chat
ants[index].varsI[ANT_INDEX_LAST_TALKED_WITH] = dialog_ant;
ants[dialog_ant].varsI[ANT_INDEX_LAST_TALKED_WITH] = index;
break;
} // end if
} // end if
} // end for dialog_ant
// test for pre-empt into search mode if hunger is 75% tolerance
if (ants[index].varsI[ANT_INDEX_HUNGER_LEVEL] > (0.75*ants[index].varsI[ANT_INDEX_HUNGER_TOLERANCE]) )
{
select_new_state = ANT_SEARCH_FOOD;
} // end if
} break;
case ANT_EATING: // at a mnm eating it
{
// in this state the ant is eating and at rest, the ant will
// eat from a single mnm until it puts itself to 50% of its hunger tolerance
// and then stop or if the food runs out it will stop
// ants eat at a rate of 5 energy units per cycle
// burns 1 unit per cycle
// eat the mnm up until its gone or the hunger level drops to 50%
// decrease food supply
food[ants[index].varsI[ANT_INDEX_MNM_BEING_DEVOURED]].energy-=BITE_SIZE;
// transfer to ant and decrease hunger level BITE_SIZE units
ants[index].varsI[ANT_INDEX_HUNGER_LEVEL]-=BITE_SIZE;
// is food supply depleted?
if (food[ants[index].varsI[ANT_INDEX_MNM_BEING_DEVOURED]].energy < 0)
{
food[ants[index].varsI[ANT_INDEX_MNM_BEING_DEVOURED]].energy = 0;
// transfer to search state or rest a sec
select_new_state = Select_State_Rand(ANT_WANDERING, 0,
ANT_EATING, 0,
ANT_RESTING, 30,
ANT_SEARCH_FOOD, 70,
ANT_COMMUNICATING, 0,
ANT_DEAD, 0);
} // end if
// test if done eating?, i.e. hunger < 50% tolerance
else
if (ants[index].varsI[ANT_INDEX_HUNGER_LEVEL] <
(0.50*ants[index].varsI[ANT_INDEX_HUNGER_TOLERANCE]) )
{
// switch to another state
select_new_state = Select_State_Rand(ANT_WANDERING, 50,
ANT_EATING, 0,
ANT_RESTING, 30,
ANT_SEARCH_FOOD, 20,
ANT_COMMUNICATING, 0,
ANT_DEAD, 0);
} // end if
} break;
case ANT_RESTING: // sleeping :)
{
// ant is simply resting and burns 1 unit per cycle
// test if we are done with this state and need a new one?
if (--ants[index].counter_1 < 0)
{
// select either rest or wander, search will pre-empt with logic following
// if hungry, state, probability of state, must sum to 100
select_new_state = Select_State_Rand(ANT_WANDERING, 90,
ANT_EATING, 0,
ANT_RESTING, 10,
ANT_SEARCH_FOOD, 0,
ANT_COMMUNICATING, 0,
ANT_DEAD, 0);
} // end if
// burn food
ants[index].varsI[ANT_INDEX_HUNGER_LEVEL]++;
// test for pre-empt into search mode if hunger is 50% tolerance
if (ants[index].varsI[ANT_INDEX_HUNGER_LEVEL] > (ants[index].varsI[ANT_INDEX_HUNGER_TOLERANCE] >> 1) )
{
select_new_state = ANT_SEARCH_FOOD;
} // end if
} break;
case ANT_SEARCH_FOOD: // hungry and searching for food
{
// in this state the ant is looking for food based on its memory
// if the memory is blank then random walks
// if the ant gets to a location and cant find any food where its
// memory found some then the memory for that food location is degraded by 1
// searching takes 2 units of energy per cycle
#if 0
ants[index].varsI[ANT_INDEX_AI_STATE] = ANT_SEARCH_FOOD;
// start off by scanning for food
ants[index].varsI[ANT_INDEX_AI_SUBSTATE] = ANT_SEARCH_FOOD_S1_SCAN;
// initialize targets tp 0
ants[index].varsI[ANT_INDEX_FOOD_TARGET_X] = 0;
ants[index].varsI[ANT_INDEX_FOOD_TARGET_Y] = 0;
#endif
// test substate
switch(ants[index].varsI[ANT_INDEX_AI_SUBSTATE])
{
case ANT_SEARCH_FOOD_S1_SCAN:
{
// this state is transient and doesn't persist, so
// no energy expended by it
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -