<1>/* Graphics Not Rendered in HTML */





<2>/* Graphics Not Rendered in HTML */




<3>/* Graphics Not Rendered in HTML */






<4>/* Graphics Not Rendered in HTML */





<5>/* Graphics Not Rendered in HTML */








<6>/* Graphics Not Rendered in HTML */





<7>/* Graphics Not Rendered in HTML */




<8>/* Graphics Not Rendered in HTML */




<9>/* Graphics Not Rendered in HTML */






<10>/* Graphics Not Rendered in HTML */





<11>/* Graphics Not Rendered in HTML */




<12>/* Graphics Not Rendered in HTML */



#define NUM_TILES 200
#define TILE_WIDTH 20
#define TILE_HEIGHT 20

#define NEED_WATER 1

#define WANT_UP         1
#define WANT_DOWN       2
#define WANT_LEFT       3
#define WANT_RIGHT      4
#define WANT_LEFT_UP  5
#define WANT_RIGHT_DOWN 6
/*Since this version of CityBuilder is
  meant to fit on a cd, i made the 
  sprites tiny, but i made it much easier 
  to replace. You can edit the sprites
  or import other sprites and replace
  the pointers below. */
I64 EMPTY=<1>;
I64 WALL_L=<2>;
I64 WALL_R=<3>;
I64 DOUBLE_WALL=<4>;
I64 CASTLE_WALL_L=<7>;
I64 CASTLE_WALL_R=<8>;
I64 CASTLE_WALL_DOUBLE=<6>;
I64 VILLAGE=<5>;
I64 WATER=<9>;
I64 TILE_SELECTED=<10>;
I64 HUMAN_THIRST=<11>;
I64 HUMAN_HAPPY=<12>;
I64 rV;


Bool L_Click=FALSE;
Bool R_Click=FALSE;
U8 NUM_HUMANS=0;
I64 x_start=Fs->pix_width>>1-TILE_WIDTH>>1;
I64 y_start=50;

class Tile{
I64 id;
Bool clicked;
}Matrix[NUM_TILES][NUM_TILES];
//        y           x     

class Human{
Bool exist;
U8 want;
U8 need;
Bool clicked;
Bool moved;
}Humans[NUM_TILES][NUM_TILES];
//        y           x     

U0 Put_Human(I64 y,I64 x)
{
  if(Humans[y][x].exist==0){ 
   if(Matrix[y][x].id==EMPTY){
   Humans[y][x].exist=TRUE;
   Humans[y][x].want=0;
   Humans[y][x].clicked=FALSE;
   Humans[y][x].moved=FALSE;
   Humans[y][x].need=NEED_WATER;
   NUM_HUMANS++;
   }
  }
 }

U0 Gen_Castle(I64 y,I64 x){
if(Matrix[y][x].id==EMPTY&&
   Matrix[y+1][x].id==EMPTY&&
   Matrix[y][x+1].id==EMPTY&&
   Matrix[y+1][x-1].id==EMPTY){
 Matrix[y][x].id=CASTLE_WALL_L;
Sleep(5);
 Matrix[y+1][x].id=CASTLE_WALL_DOUBLE;
Sleep(5);
 Matrix[y+1][x-1].id=CASTLE_WALL_R;
// Matrix[y-1][x-1].id=CASTLE_WALL_DOUBLE;
 }
}

U0 Gen_Water(U8 Spread,I64 x,I64 y)
{
 U8 i,j;
 for(i=0;i<Spread;i++){
  for(j=0;j<Spread;j++){
  rV = RandU64%100;
 if(rV<50){
  if(Matrix[i+y+1][j+x].id==EMPTY&&
     Humans[i+y+1][j+x].exist=FALSE&&
     i>0 && j>0 && i+y+1<NUM_TILES &&
     j+x<NUM_TILES)
     {
 "Water spreads east\n"; 
Sleep(5);
  Matrix[i+y+1][j+x].id=WATER;
  j++;
  Spread--;
   }
}else if(rV<100){
  if(Matrix[i+y-1][j+x].id==EMPTY&&
     Humans[i+y-1][j+x].exist==FALSE&&
     i+y-1>0&&j+x<NUM_TILES){
    Matrix[i+y-1][j+x].id=WATER;
  j--;
  Spread--;
 "Water spreads north\n";
Sleep(5);
  }
 }
 if(rV<75){
  if(Matrix[i+y][j+x-1].id==EMPTY&&
     Humans[i+y][j+x-1].exist==FALSE&&
     j+x-1>0&&i+y<NUM_TILES){
    Matrix[i+y][j+x-1].id=WATER;
  j--;
 "Water spreads south\n";
Sleep(5);
  }
 }else if(rV<125){  
 
  if(Matrix[i+y][j+x+1].id==EMPTY&&
     Humans[i+y][j+x+1].exist==FALSE&&
     j+x+1<NUM_TILES&&i+y<NUM_TILES){
    Matrix[i+y][j+x+1].id=WATER;
  j++;
 "Water spreads south\n";
Sleep(5);
    }
   }
  }
 }
}


U0 Init()
{
 U8 i,j;
 U8 Gen_structs=0;
  for(i=0;i<NUM_TILES;i++){
   for(j=0;j<NUM_TILES;j++){
  Humans[i][j].exist=FALSE;
  Humans[i][j].want=0;
  Humans[i][j].need=0;
   }
  }

 for(i=0;i<NUM_TILES;i++){
  for(j=0;j<NUM_TILES;j++){
  Matrix[i][j].id=EMPTY;
   }
  } 
 
 for(i=0;i<NUM_TILES;i++){
 Matrix[i][NUM_TILES-1].id=WALL_R;
 Matrix[NUM_TILES-1][i].id=WALL_L;
 Matrix[0][0].id=WALL_L;
 if(i!=0)
 Matrix[i][0].id=WALL_R;
 if(i!=0)
 Matrix[0][i].id=WALL_L;
 Matrix[NUM_TILES-1][NUM_TILES-1].id=DOUBLE_WALL;
}
for(i=0;i<NUM_TILES;i++){
 for(j=0;j<NUM_TILES;j++){
  rV = RandU64%100;
  if(rV<7){
 if(Matrix[i][j].id==EMPTY){  
  Print("Struct generated at %d x, %d y\n",j,i);
  Gen_structs++;
  if(rV<4){
  Matrix[i][j].id=VILLAGE;
   Put_Human(i,j-1);
  }else if(rV<5){
  //Gen_Castle(i,j);
  Gen_Water(10,i,j);
  j+=5;
  i+=3;
   }else{
   Gen_Castle(i,j);
    }
   }
  }
 }
}
 Print("%d Structures Generated \n",Gen_structs);
 Print("Num humans=%d\n",NUM_HUMANS);
}

Bool Collision(F64 x, F64 y, U8 radius,
             F64 x2,F64 y2)
{


 F64 distX=x-x2;
 F64 distY=y-y2;
 F64 Dist=Sqrt((distX*distX)+
               (distY*distY));

 return(Dist<=radius);

}


Bool Move_human(U8 y,U8 x,
              U8 newy,U8 newx)
{
 if(Matrix[newy][newx].id==EMPTY&&
    NUM_TILES>newx&&
    NUM_TILES>newy&&
    Humans[newy][newx].exist==FALSE&&
    Humans[y][x].exist==TRUE){
 Humans[newy][newx].want=Humans[y][x].want;
 Humans[newy][newx].need=Humans[y][x].need;
 Humans[newy][newx].clicked=Humans[y][x].clicked;
 Humans[newy][newx].exist=TRUE;
 Humans[newy][newx].moved=TRUE;
 Humans[y][x].exist=FALSE;
 Humans[y][x].want=0;
 Humans[y][x].need=0;
 Humans[y][x].clicked=FALSE;
 Humans[y][x].moved=FALSE;
//Print("moved %d, %d to %d, %d\n",x,y,newx,newy);
 return 1; //Human moved
 }else{
//Print("Cannot move %d, %d to %d, %d\n",x,y,newx,newy); 
 return 0; //Human not moved
 }
} 


U0 Human_ai(U8 i,U8 j)
{ 
  if(Humans[i][j].exist==TRUE&&j>1&&i>1){

if(Humans[i][j].want==WANT_DOWN){
 Move_human(i,j,i,j-1);
 Move_human(i,j,i-1,j);
 j++;
 } else if(Humans[i][j].want==WANT_UP){
 Move_human(i,j,i+1,j);
 Move_human(i,j,i,j+1);     
 j++;
 } else if(Humans[i][j].want==WANT_RIGHT){
 Move_human(i,j,i,j-1);     
 } else if(Humans[i][j].want==WANT_LEFT){
 Move_human(i,j,i,j+1);     
 } else if(Humans[i][j].want==WANT_LEFT_UP){
 Move_human(i,j,i,j+1);     
 Move_human(i,j,i-1,j);
 } else if(Humans[i][j].want==WANT_RIGHT_DOWN){
 Move_human(i,j,i,j+1);     
 Move_human(i,j,i-1,j);

  }
 }
}

U0 Advanced_human_ai()
{
 U8 i,j;
 for(i=0;i<NUM_TILES;i++){
  for(j=0;j<NUM_TILES;j++){
   if(Humans[i][j].exist==TRUE){
  // Ignore this jungle of is else statements lol
  // This my first time making an "Ai"
  /* Check if next to any water */
      if(Matrix[i+1][j+1].id==WATER){
      //Print("Human ar %d, %d doesn't need water anymore.\n",j,i);
      Humans[i][j].want=0;    
      Humans[i][j].need=0;
      j++;
      }else if(Matrix[i-1][j-1].id==WATER){
      //Print("Human ar %d, %d doesn't need water anymore.\n",j,i);
      Humans[i][j].want=0;    
      Humans[i][j].need=0;
      j++;
      }else if(Matrix[i][j-1].id==WATER){
      //Print("Human ar %d, %d doesn't need water anymore.\n",j,i);
      Humans[i][j].want=0;    
      Humans[i][j].need=0;
      j++;
      }else if(Matrix[i][j+1].id==WATER){
      //Print("Human ar %d, %d doesn't need water anymore.\n",j,i);
      Humans[i][j].want=0;    
      Humans[i][j].need=0;
      j++;
      }else if(Matrix[i-1][j].id==WATER){
      //Print("Human ar %d, %d doesn't need water anymore.\n",j,i);
      Humans[i][j].want=0;    
      Humans[i][j].need=0;
      j++;
      }else if(Matrix[i+1][j].id==WATER){
      //Print("Human ar %d, %d doesn't need water anymore.\n",j,i);
      Humans[i][j].want=0;    
      Humans[i][j].need=0;
      j++;
           
/********************************************/ 
   }else if(Matrix[i+2][j+2].id==WATER&&
            Matrix[i+1][j+1].id==EMPTY){
       Humans[i][j].want=WANT_UP;
   }else if(Matrix[i+3][j+3].id==WATER&&
            Matrix[i+1][j+1].id==EMPTY){
       Humans[i][j].want=WANT_UP;
   }else if(Matrix[i+4][j+4].id==WATER&&
            Matrix[i+1][j+1].id==EMPTY){
       Humans[i][j].want=WANT_UP;
   }else if(Matrix[i+5][j+5].id==WATER&&
            Matrix[i+1][j+1].id==EMPTY){
       Humans[i][j].want=WANT_UP;
  /*******************************************/
   }else if(Matrix[i-2][j-2].id==WATER&&
            Matrix[i-1][j-1].id==EMPTY){
    Humans[i][j].want=WANT_DOWN;
   }else if(Matrix[i-3][j-3].id==WATER&&
            Matrix[i-1][j-1].id==EMPTY){
    Humans[i][j].want=WANT_DOWN;
   }else if(Matrix[i-4][j-4].id==WATER&&
            Matrix[i-1][j-1].id==EMPTY){
    Humans[i][j].want=WANT_DOWN;
   }else if(Matrix[i-5][j-5].id==WATER&&
            Matrix[i-1][j-1].id==EMPTY){
    Humans[i][j].want=WANT_DOWN;
 /******************************************/ 
   }else if(Matrix[i][j-2].id==WATER&&
            Matrix[i][j-1].id==EMPTY){
    Humans[i][j].want=WANT_RIGHT;
   }else if(Matrix[i][j-3].id==WATER&&
            Matrix[i][j-1].id==EMPTY){
    Humans[i][j].want=WANT_RIGHT;
   }else if(Matrix[i][j-4].id==WATER&&
            Matrix[i][j-1].id==EMPTY){
    Humans[i][j].want=WANT_RIGHT;
   }else if(Matrix[i][j-5].id==WATER&&
            Matrix[i][j-1].id==EMPTY){
    Humans[i][j].want=WANT_RIGHT; 
 /******************************************/ 
   }else if(Matrix[i][j+2].id==WATER&&
            Matrix[i][j+1].id==EMPTY){
    Humans[i][j].want=WANT_LEFT;
   }else if(Matrix[i][j+3].id==WATER&&
            Matrix[i][j+1].id==EMPTY){
    Humans[i][j].want=WANT_LEFT;
   }else if(Matrix[i][j+4].id==WATER&&
            Matrix[i][j+1].id==EMPTY){
    Humans[i][j].want=WANT_LEFT;
   }else if(Matrix[i][j+5].id==WATER&&
            Matrix[i][j+1].id==EMPTY){
    Humans[i][j].want=WANT_LEFT;
 /*******************************************/
   }else if(Matrix[i-2][j+2].id==WATER&&
            Matrix[i-1][j+1].id==EMPTY){
    Humans[i][j].want=WANT_LEFT_UP;
   }else if(Matrix[i-3][j+3].id==WATER&&
            Matrix[i-1][j+1].id==EMPTY){
    Humans[i][j].want=WANT_LEFT_UP;
   }else if(Matrix[i-4][j+4].id==WATER&&
            Matrix[i-1][j+1].id==EMPTY){
    Humans[i][j].want=WANT_LEFT_UP;
   }else if(Matrix[i-5][j+5].id==WATER&&
            Matrix[i-1][j+1].id==EMPTY){
    Humans[i][j].want=WANT_LEFT_UP;
/********************************************/ 
   }else if(Matrix[i+2][j-2].id==WATER&&
            Matrix[i+1][j-1].id==EMPTY){
    Humans[i][j].want=WANT_RIGHT_DOWN;
   }else if(Matrix[i+3][j-3].id==WATER&&
            Matrix[i-1][j+1].id==EMPTY){
    Humans[i][j].want=WANT_RIGHT_DOWN;
   }else if(Matrix[i+4][j-4].id==WATER&&
            Matrix[i+1][j-1].id==EMPTY){
    Humans[i][j].want=WANT_RIGHT_DOWN;
   }else if(Matrix[i+5][j-5].id==WATER&&
            Matrix[i+1][j-1].id==EMPTY){
    Humans[i][j].want=WANT_RIGHT_DOWN;

   }else{ 
 if(rV=RandU64%100<25){ 
 if(rV=RandU64%100<25){
    Humans[i][j].want=WANT_RIGHT_DOWN; 
   }else{
    Humans[i][j].want=WANT_UP;
   }
  Human_ai(i,j); 
 }else{
  if(rV<25){
    Humans[i][j].want=WANT_LEFT_UP;
   }else{
   Humans[i][j].want=WANT_DOWN;
     }
    }
   }
 if(!Humans[i][j].moved)
 Human_ai(i,j);
   }
  }
 } 
for(i=0;i<NUM_TILES;i++){
 for(j=0;j<NUM_TILES;j++){
  Humans[i][j].moved=FALSE;
  }
 }
}
U0 DrawIt(CTask *task, CDC *dc){

DCFill;
I64 mouse_x=ms.pos.x-task->pix_left;
I64 mouse_y=ms.pos.y-task->pix_top;


I64 x_screen;
I64 y_screen;
U8 i,j;
for(i=0;i<NUM_TILES;i++){
  for(j=0;j<NUM_TILES;j++){  
   x_screen=x_start+(j-i)*TILE_WIDTH/2;
   y_screen=y_start+(j+i)*TILE_HEIGHT/2;
   if(Matrix[i][j].id!=0)
  if(!Collision(x_screen+TILE_HEIGHT/4,y_screen+TILE_WIDTH/4,
                10,mouse_x,mouse_y))
  {
   Sprite3(dc,x_screen,y_screen,0,Matrix[i][j].id);
  }else{
    Sprite3(dc,x_screen,y_screen,0,TILE_SELECTED);   
    if(L_Click){
    if(Matrix[i][j].id!=VILLAGE&&
       Matrix[i][j].id!=WATER){
     if(Matrix[i][j].id!=WALL_R&&
        Matrix[i][j].id!=WALL_L){
     Matrix[i][j].id=WALL_L;
      }else if(Matrix[i][j].id==WALL_R){
     Matrix[i][j].id=DOUBLE_WALL;
      }else if(Matrix[i][j].id==WALL_L){
     Matrix[i][j].id=EMPTY;
      }
    L_Click=FALSE;
      }
     }
    if(R_Click){
    if(Matrix[i][j].id!=VILLAGE&&
       Matrix[i][j].id!=WATER)
   if(Matrix[i][j].id!=WALL_L&&
      Matrix[i][j].id!=WALL_R){
    Matrix[i][j].id=WALL_R;
     }else if(Matrix[i][j].id==WALL_L){
    Matrix[i][j].id=DOUBLE_WALL;
     }else if(Matrix[i][j].id==WALL_R){
      Matrix[i][j].id=EMPTY;
     }
    R_Click=FALSE;
    }   
   }
  }
 }
 for(i=0;i<NUM_TILES;i++){
  for(j=0;j<NUM_TILES;j++){  
   x_screen=x_start+(j-i)*TILE_WIDTH/2;
   y_screen=y_start+(j+i)*TILE_HEIGHT/2;
    if(Humans[i][j].exist==TRUE)
     if(Humans[i][j].need==NEED_WATER){ 
  Sprite3(dc,x_screen,y_screen,0,HUMAN_THIRST);
      }else{
  Sprite3(dc,x_screen,y_screen,0,HUMAN_HAPPY); 
   }
  }
 }
L_Click=FALSE;
R_Click=FALSE;
}


U0 Main(){
 I64 ch, sc, arg1, arg2, msg_code;
 U8 wait=0;
 Bool pause=FALSE;
WinMax;
//  WinHorz(TEXT_COLS/2-20,TEXT_COLS/2+20);
//  WinVert(TEXT_ROWS/2-20,TEXT_ROWS/2+20);
DocClear;
Fs->win_inhibit|=WIF_SELF_MS_L|WIF_SELF_MS_R;
Fs->draw_it=&DrawIt;
Init;

while(TRUE){
    
if (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN | 1<<MSG_KEY_UP
                                   |1<<MSG_MS_L_UP|1<<MSG_MS_R_UP|1<<MSG_MS_R_D_UP
                                   |1<<MSG_MS_L_D_UP)) {
sc=arg2; ch=arg1;

 if(msg_code==MSG_KEY_DOWN){
   switch(sc.u8[0]){
   case SC_CURSOR_DOWN:
   case Char2ScanCode('s'):   
   y_start-=20;
   break;
   case SC_CURSOR_UP:
   case Char2ScanCode('w'):
   y_start+=20;
   break;
   case Char2ScanCode('d'):
   case SC_CURSOR_LEFT:
   x_start+=20;
   break;
   case SC_CURSOR_RIGHT:
   case Char2ScanCode('a'):
   x_start-=20;
   break;
   }
   switch(ch)
   {
    case CH_SPACE:
    {
    if(pause!=TRUE)
    pause=TRUE;
    else
    pause=FALSE;
    }
    break;
    case CH_ESC:
    case CH_SHIFT_ESC:
    "esc";
    goto nv_done;
    break;
    }
  }
 if(msg_code==MSG_MS_R_D_UP)
 {
 "double mouse R up";
 }
 if(msg_code==MSG_MS_L_D_UP)
 {
 "double mouse L up"; 
 Init;
 }
 if(msg_code==MSG_MS_L_UP)
 L_Click=TRUE;
 if(msg_code==MSG_MS_R_UP)
 R_Click=TRUE;
 }
if(!pause)
if(wait>=5){
Advanced_human_ai;
wait=0;
}else{
wait++;
}
Sleep(50);
}
DCFill;
nv_done:
DCFill;
}
Main;