?? demo12_7_16b.cpp
字號:
// now test if target reached
if (abs(ants[index].x - ants[index].varsI[ANT_INDEX_FOOD_TARGET_X]) < 4 &&
abs(ants[index].y - ants[index].varsI[ANT_INDEX_FOOD_TARGET_Y]) < 4)
{
// food reached, now find the biggest piece of food and
// vector to it, if none exist then go back to scan
// is there any food left?
if (ants[index].varsI[ANT_INDEX_FOOD_TARGET_ID] > 0)
{
// thank god!
Set_New_State(ANT_EATING, index, ants[index].varsI[ANT_INDEX_FOOD_TARGET_ID],0);
} // end if
else
{
// go back to scan
ants[index].varsI[ANT_INDEX_AI_SUBSTATE] = ANT_SEARCH_FOOD_S1_SCAN;
} // end if
} // end if
} break;
case ANT_SEARCH_FOOD_S5: break;
case ANT_SEARCH_FOOD_S6: break;
case ANT_SEARCH_FOOD_S7: break;
default: break;
} // end switch
} break;
case ANT_COMMUNICATING: // talking to another ant
{
// the ants sit and talk for a little bit, each ant picks
// 16 memory cells from the matrix of 16x16 and then averages
// the info, that is, they exchange information
// this takes 1 unit of energy
// time to exchange memory?
if (++ants[index].counter_2 >= 3)
{
// reset counter
ants[index].counter_2 = 0;
// select cell to exchange and exchange memory imprints
int memx = rand()%16;
int memy = rand()%16;
// sum with partners experience
ants_mem[index].cell[memx][memy] +=
0.5*ants_mem[ants[index].varsI[ANT_INDEX_LAST_TALKED_WITH]].cell[memx][memy];
// illuminate green to show communication
ants_mem[index].ilayer[memx][memy] = 250;
} // end if
// test if we are done with this state and need a new one?
if (--ants[index].counter_1 < 0 ||
ants[ants[index].varsI[ANT_INDEX_LAST_TALKED_WITH]].varsI[ANT_INDEX_AI_STATE]!=ANT_COMMUNICATING)
{
// 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_DEAD: // this guy is dead, got too hungry
{
// the any just sits there and is worm food, no enery expended
} break;
default: break;
} // end switch
// was there a forced state transition?
if (ants[index].varsI[ANT_INDEX_AI_STATE]!=ANT_DEAD &&
(ants[index].varsI[ANT_INDEX_HUNGER_LEVEL] >= ants[index].varsI[ANT_INDEX_HUNGER_TOLERANCE]))
{
// dead ant
select_new_state = ANT_DEAD;
} // end if
///////////////////////////////////////////////////////////////////////////
// add a little forgetfulness, select a memory at random and weaken it
int memx = rand()%16;
int memy = rand()%16;
ants_mem[index].ilayer[memx][memy] = 249; // illuminate red to show degradation
if (ants_mem[index].cell[memx][memy] > 5)
{
ants_mem[index].cell[memx][memy]-=rand()%5;
} // end if
//////////////////////////////////////////////////////////////////////////
// set new state if needed
if (select_new_state >= 0)
{
// set the state
Set_New_State(select_new_state, index);
} // end if
////////////////////////////////////////////////////
// clear the memory matrix
if (clear_ilayer >= 5)
memset(ants_mem[index].ilayer,0, 1024);
// this point is where the "physics" system need to operate
// have any of the state changes or motions caused a physical problem
// in the universe, we could do it in each state, but this is simpler
// test for out of bounds
if (ants[index].x > 472)
{
// bounce back a bit
ants[index].x-=4;
// turn to new heading
switch(rand()%3)
{
case 0: ants[index].varsI[ANT_INDEX_DIRECTION] = ANT_ANIM_LEFT; break;
case 1: ants[index].varsI[ANT_INDEX_DIRECTION] = ANT_ANIM_UP; break;
case 2: ants[index].varsI[ANT_INDEX_DIRECTION] = ANT_ANIM_DOWN; break;
default: break;
} // end switch
// add a little time to counters
ants[index].counter_2 += RAND_RANGE(30, 60);
ants[index].counter_1 += RAND_RANGE(15, 30);
// start animation
Set_Animation_BOB(&ants[index], ants[index].varsI[ANT_INDEX_DIRECTION]);
} // end if
else
if (ants[index].x <= 16)
{
// bounce back a bit
ants[index].x+=4;
// turn to new heading
switch(rand()%3)
{
case 0: ants[index].varsI[ANT_INDEX_DIRECTION] = ANT_ANIM_RIGHT; break;
case 1: ants[index].varsI[ANT_INDEX_DIRECTION] = ANT_ANIM_UP; break;
case 2: ants[index].varsI[ANT_INDEX_DIRECTION] = ANT_ANIM_DOWN; break;
default: break;
} // end switch
// add a little time to counter
ants[index].counter_2 += RAND_RANGE(30, 60);
ants[index].counter_1 += RAND_RANGE(15, 30);
// start animation
Set_Animation_BOB(&ants[index], ants[index].varsI[ANT_INDEX_DIRECTION]);
} // end if
if (ants[index].y < 0)
ants[index].y = screen_height;
else
if (ants[index].y > screen_height)
ants[index].y = 0;
///////////////////////////////////////////////////////////////////////////////////
} // end for index
// update global memory clear counter
if (++clear_ilayer > 5)
clear_ilayer= 0;
} // end Move_Ants
///////////////////////////////////////////////////////////////////
void Draw_Food(void)
{
// draw the food
int index;
for (index=0; index<NUM_MNMS; index++)
{
if (food[index].energy > 0)
{
// set position of mnm
Set_Pos_BOB(&mnm, food[index].x-4, food[index].y-4);
Draw_BOB16(&mnm, lpddsback);
} // end if
} // end for index
} // end Draw_Food
///////////////////////////////////////////////////////////////////
void Draw_Info(void)
{
// this function draws the state information for 8 ants
static char *state_to_text[6] = {"Wander", "Eating", "Resting", "Srchfood", "Talking", "Dead"};
static int intensity_to_index[16] = {0,65,94,151,166,175,203,208,221,227,233,236,239,242,245,245};
#define DELTA_LINE 14
for (int index=0; index < NUM_ANTS; index++)
{
int px = 480;
int py = 8+index * 60;
// only show infor for first 8 ants
if (index < 8 )
{
// print name of ant and state
sprintf(buffer,"Ant%d=%s,%d", index, state_to_text[ants[index].varsI[ANT_INDEX_AI_STATE]], ants[index].varsI[ANT_INDEX_AI_SUBSTATE]);
Draw_Text_GDI(buffer,px, py, RGB(0,255,0),lpddsback);
// print counters
sprintf(buffer, "C1:%d,C2:%d", ants[index].counter_1, ants[index].counter_2);
Draw_Text_GDI(buffer,px, py+DELTA_LINE, RGB(0,255,0),lpddsback);
// print hunger level and tolerance
sprintf(buffer,"Hungr:%d,Tol:%d", ants[index].varsI[ANT_INDEX_HUNGER_LEVEL],
ants[index].varsI[ANT_INDEX_HUNGER_TOLERANCE]);
Draw_Text_GDI(buffer,px, py+2*DELTA_LINE, RGB(0,255,0),lpddsback);
// draw memory, the brighter the green dot, the stronger the memory
Draw_Rectangle(px+124, py, px+124+18, py+18, 0, lpddsback);
// dont draw memory if ant dead
if (ants[index].varsI[ANT_INDEX_AI_STATE]!=ANT_DEAD)
{
DDraw_Lock_Back_Surface();
for (int x = 0; x<16; x++)
for (int y=0; y<16; y++)
{
// get memory and convert into pixel value to disply
// dark means low recall, bright white means strong memory of food
float mem_strength = ants_mem[index].cell[x][y];
// each mnm is worth on average 500, so if a cell has a 2500 then we know there is
// a lot of food, use this as the highest strength
if (mem_strength > 2500)
mem_strength = 2500;
// normalize and scale to color range
int color_intensity = (int)((mem_strength/2500)*15);
Draw_Pixel16(px+124+x+1,py+y+1, RGB16Bit((color_intensity*16),0,0), back_buffer, back_lpitch);
int active_pixel = ants_mem[index].ilayer[x][y];
if (active_pixel)
// scan input layer to see where degradation and communication have taken place
Draw_Pixel16(px+124+x+1,py+y+1, RGB16Bit(0,active_pixel,0), back_buffer, back_lpitch);
} // end for
DDraw_Unlock_Back_Surface();
} // end if
else
// draw flat line :)
{
DDraw_Lock_Back_Surface();
HLine16(px+124,px+124+18, py+9, RGB16Bit(255,0,0), back_buffer, back_lpitch);
DDraw_Unlock_Back_Surface();
} // end else
} // end if < 8
} // end for index
} // end Draw_Info
////////////////////////////////////////////////////////////////////
int Game_Main(void *parms)
{
// this is the workhorse of your game it will be called
// continuously in real-time this is like main() in C
// all the calls for you game go here!
int index; // looping var
// start the timing clock
Start_Clock();
// clear the drawing surface
DDraw_Fill_Surface(lpddsback, 0);
// lock back buffer and copy background into it
DDraw_Lock_Back_Surface();
// draw background
Draw_Bitmap16(&background_bmp, back_buffer, back_lpitch,0);
// unlock back surface
DDraw_Unlock_Back_Surface();
// read keyboard
DInput_Read_Keyboard();
// move ants and perform ai
Move_Ants();
// draw the food
Draw_Food();
// draw ants and animate image
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -