le jeu des motos dans tron - retour accueil
git clone git://bebou.netlib.re/tron
Log | Files | Refs | README |
tron.c (6975B)
1 #define TB_IMPL 2 #include "termbox2.h" 3 #include <time.h> 4 5 #define TAIL 100 6 #define MAX_CAR_NUMBER 3 7 #define NB_DEFAULT_PLAYERS 2 8 9 enum direction { UP, RIGHT, DOWN, LEFT }; 10 enum status { DEAD, ALIVE }; 11 12 typedef struct { 13 int x; 14 int y; 15 } coord; 16 17 struct bike { 18 coord position; 19 coord* path; 20 int direction; 21 int color; 22 int status; 23 }; 24 25 struct arena { 26 int width; 27 int height; 28 }; 29 30 struct bikes { 31 struct bike* list; 32 int count; 33 }; 34 35 /*Helper functions*/ 36 37 int rd(int min, int max) { return (rand()%(max-min+1))+min; } 38 int remain(int a, int b) { return ((a%b)+b)%b; } 39 40 /*Display functions*/ 41 42 void display_title_screen(int height, int width) { 43 tb_printf(width/2-35/2-5,height/2-5/2,0,0,"\ 44 ████████ ██████ ██████ ███ ██\n\ 45 ██ ██ ██ ██ ██ ████ ██\n\ 46 ██ ██████ ██ ██ ██ ██ ██\n\ 47 ██ ██ ██ ██ ██ ██ ██ ██\n\ 48 ██ ██ ██ ██████ ██ ████"); 49 50 tb_printf(width/2-35/2-5,height/2-5/2+5+2,0,0,"\ 51 Espace pour continuer ou mettre en pause\n\ 52 Echap pour quitter\n\ 53 \n\ 54 + pour ajouter un vélo\n\ 55 - pour retirer un vélo\n\ 56 \n\ 57 Vélo 1 ←→\n\ 58 Vélo 2 qd\n\ 59 Vélo 3 jl\n"); 60 } 61 62 63 void display(struct bikes bikes, int ticks, struct arena arena, int timeout) { 64 for (int i=0;i<bikes.count;i++) { 65 if(bikes.list[i].status==DEAD) continue; 66 tb_printf(bikes.list[i].position.x,bikes.list[i].position.y,bikes.list[i].color,0,"●"); 67 for (int j=0;j<TAIL;j++) 68 if(bikes.list[i].path[j].x!=0 && bikes.list[i].path[j].y!=0) 69 tb_printf(bikes.list[i].path[j].x,bikes.list[i].path[j].y,bikes.list[i].color,0,"▒"); 70 tb_printf(arena.width+1,i*5,bikes.list[i].color,0,"vélo %d\nx: %d\ny: %d\ndir %d\n",i+1,bikes.list[i].position.x,bikes.list[i].position.y,bikes.list[i].direction); 71 } 72 tb_printf(arena.width+1,arena.height-2,0,0,"t %d\ns %d",ticks,timeout); 73 tb_print(0,0,0,0,"╭"); 74 tb_print(0,arena.height,0,0,"╰"); 75 tb_print(arena.width,0,0,0,"╮"); 76 tb_print(arena.width,arena.height,0,0,"╯"); 77 for (int i=1;i<arena.width;i++) { 78 tb_print(i,0,0,0,"─"); 79 tb_print(i,arena.height,0,0,"─"); 80 } 81 for (int i=1;i<arena.height;i++) { 82 tb_print(0,i,0,0,"│"); 83 tb_print(arena.width,i,0,0,"│"); 84 } 85 } 86 87 /*Logic functions*/ 88 89 void update(struct bike *bike, coord *incs) { 90 for(int i=TAIL-1;i>0;i--) bike->path[i]=bike->path[i-1]; 91 bike->path[0]=bike->position; 92 bike->position.x=bike->position.x+incs[bike->direction].x; 93 bike->position.y=bike->position.y+incs[bike->direction].y; 94 } 95 96 void createbike(int color, struct bikes *bikes, struct arena a) { 97 struct bike c; 98 c.status=ALIVE; 99 c.path=malloc(sizeof(coord)*TAIL); 100 for (int i=0;i<TAIL;i++) { 101 coord p; p.x=0; p.y=0; 102 c.path[i]=p; 103 } 104 c.color=color; 105 c.position.x=rd(10,a.width-10); c.position.y=rd(10,a.height-10); 106 if(c.position.x<a.width/2) c.direction=RIGHT; else c.direction=LEFT; 107 bikes->list[bikes->count]=c; 108 bikes->count++; 109 } 110 111 void kill_bikes(struct bikes *bikes, struct arena arena) { 112 for (int i=0;i<bikes->count;i++) { 113 if(bikes->list[i].status==DEAD) continue; 114 if(bikes->list[i].position.x<=0 || bikes->list[i].position.x>=arena.width || bikes->list[i].position.y<=0 || bikes->list[i].position.y>=arena.height) 115 bikes->list[i].status=DEAD; 116 for (int j=0;j<TAIL;j++) 117 for (int k=0;k<bikes->count;k++) 118 if (bikes->list[i].position.x==bikes->list[k].path[j].x && bikes->list[i].position.y==bikes->list[k].path[j].y && bikes->list[k].status==ALIVE) 119 bikes->list[i].status=DEAD; 120 } 121 } 122 123 int main(int argc, char **argv) { 124 125 /* On init des trucs */ 126 127 int ticknb=0; 128 129 coord up; up.x=0; up.y=-1; 130 coord right; right.x=1; right.y=0; 131 coord down; down.x=0; down.y=1; 132 coord left; left.x=-1; left.y=0; 133 coord incs[4] = { up, right, down, left }; 134 135 srand(time(NULL)); 136 137 tb_init(); 138 tb_hide_cursor(); 139 tb_set_input_mode(TB_INPUT_ESC | TB_INPUT_MOUSE); 140 struct tb_event ev; 141 142 int height=tb_height(); int width=tb_width(); 143 struct arena arena; 144 arena.width=width-10; arena.height=height-1; 145 146 struct bikes bikes; bikes.count=0; 147 bikes.list=malloc(MAX_CAR_NUMBER*sizeof(struct bike)); 148 for(int i=0;i<NB_DEFAULT_PLAYERS;i++) 149 createbike(bikes.count%8+6, &bikes, arena); 150 151 int timeout=80; 152 int input=0; 153 154 /*TITRE*/ 155 156 /*Comme ça on sait dans quelle direction vont les vélos*/ 157 for(int i=0;i<bikes.count;i++) 158 if(bikes.list[i].status==ALIVE) 159 update(&bikes.list[i],incs); 160 161 while(ev.ch!=32) { 162 tb_clear(); 163 display_title_screen(arena.height, arena.width); 164 display(bikes,ticknb,arena,timeout); 165 tb_present(); 166 tb_poll_event(&ev); 167 switch(ev.ch) { 168 case 43: /*+*/ 169 if (bikes.count<MAX_CAR_NUMBER) { 170 createbike(bikes.count%8+6,&bikes,arena); 171 update(&bikes.list[bikes.count-1],incs); 172 } else 173 for (int i=0;i<bikes.count;i++) 174 if(bikes.list[i].status==DEAD) { 175 bikes.list[i].status=ALIVE; 176 break; 177 } 178 break; 179 case 45: /*-*/ 180 for (int i=bikes.count-1;i>=0;i--) 181 if(bikes.list[i].status==ALIVE) { 182 bikes.list[i].status=DEAD; 183 break; 184 } 185 } 186 if (ev.type==TB_EVENT_RESIZE) { 187 arena.width=ev.w-10; 188 arena.height=ev.h-1; 189 } 190 if(ev.key==27) { 191 for (int i=0;i<bikes.count;i++) free(bikes.list[i].path); 192 free (bikes.list); 193 tb_shutdown(); 194 return 0; 195 } 196 } 197 198 /*On joue*/ 199 200 while(1) { 201 for(int i=0;i<bikes.count;i++) 202 update(&bikes.list[i],incs); 203 kill_bikes(&bikes,arena); 204 tb_clear(); 205 display(bikes,ticknb,arena,timeout); 206 tb_present(); 207 tb_peek_event(&ev, timeout); 208 if(ev.ch!=0) input=ev.ch; 209 else if (ev.key!=0) input=ev.key; 210 /* On accélère tous les 10 ticks */ 211 if(ticknb%10==0 && timeout>30) timeout--; 212 switch(input) { 213 case 32: /*space*/ 214 display_title_screen(height,width); 215 display(bikes,ticknb,arena,timeout); 216 tb_present(); 217 do { 218 tb_poll_event(&ev); 219 if (ev.key==27) { 220 for (int i=0;i<bikes.count;i++) free(bikes.list[i].path); 221 free (bikes.list); 222 tb_shutdown(); 223 return 0; 224 } 225 } while(ev.ch!=32); 226 break; 227 case 100: /*d*/ 228 bikes.list[1].direction=remain(bikes.list[1].direction+1,4); 229 break; 230 case 113: /*q*/ 231 bikes.list[1].direction=remain(bikes.list[1].direction-1,4); 232 break; 233 case 108: /*l*/ 234 bikes.list[2].direction=remain(bikes.list[2].direction+1,4); 235 break; 236 case 106: /*j*/ 237 bikes.list[2].direction=remain(bikes.list[2].direction-1,4); 238 break; 239 case 27: /*echap*/ 240 for (int i=0;i<bikes.count;i++) free(bikes.list[i].path); 241 free (bikes.list); 242 tb_shutdown(); 243 return 0; 244 case 65514: /*right*/ 245 bikes.list[0].direction=remain(bikes.list[0].direction+1,4); 246 break; 247 case 65515: /*left*/ 248 bikes.list[0].direction=remain(bikes.list[0].direction-1,4); 249 break; 250 default: 251 break; 252 } 253 input=0; 254 tb_printf(0,3,0,0,"ticknb : %d",ticknb++); 255 } 256 return 0; 257 }