1 |
#include "board.h" |
2 |
|
3 |
BRD *NewBoard(int width, int height, int nfood, int nplayers, char ** plr_names, unsigned int seed) { |
4 |
BRD *B; |
5 |
int i,j,n; |
6 |
|
7 |
srandom(seed); |
8 |
B = (BRD *)malloc(sizeof(BRD)); |
9 |
(B->dim).x=width; |
10 |
(B->dim).y=height; |
11 |
B->nplayers=nplayers; |
12 |
B->live_players=nplayers; |
13 |
B->moves=0; |
14 |
|
15 |
B->board=(int *)malloc(width*height*sizeof(int)); |
16 |
bzero((void *)(B->board),width*height*sizeof(int)); |
17 |
|
18 |
/* create food: dirty */ |
19 |
for (n=0;n<nfood;n++) { |
20 |
do { |
21 |
i=random()%width; |
22 |
j=random()%height; |
23 |
} while (BPos(B,i,j)!=B_EMPTY); |
24 |
BPos(B,i,j)=B_FOOD; |
25 |
} |
26 |
|
27 |
/* initialize players */ |
28 |
B->plr=(PLR_STAT *)malloc(nplayers*sizeof(PLR_STAT)); |
29 |
for (n=0;n<nplayers;n++) { |
30 |
(B->plr)[n].name=(char *)malloc(strlen(plr_names[n])+2); |
31 |
strncpy((B->plr)[n].name,plr_names[n],strlen(plr_names[n])+1); |
32 |
(B->plr)[n].alive=1; |
33 |
(B->plr)[n].length=1; |
34 |
(B->plr)[n].time_of_death=0; |
35 |
(B->plr)[n].moved=0; |
36 |
(B->plr)[n].move_of_death=0; |
37 |
(B->plr)[n].dir=random()%4; /* facing random direction */ |
38 |
|
39 |
/* find starting positioon: dirty */ |
40 |
do { |
41 |
i=(random()%(width-10))+5; /* don't put player near the corner */ |
42 |
j=(random()%(height-10))+5; |
43 |
} while (BPos(B,i,j)!=B_EMPTY); |
44 |
BPos(B,i,j)=BMake(n,B_DIR_NONE); |
45 |
(B->plr)[n].head.x=i; |
46 |
(B->plr)[n].head.y=j; |
47 |
} |
48 |
return B; |
49 |
} |
50 |
|
51 |
|
52 |
int WriteBoard(BRD *B, char *f ) { |
53 |
char *bmp; |
54 |
int i,len; |
55 |
|
56 |
/* todo: sanity test for B */ |
57 |
|
58 |
/* prepare bitmap string */ |
59 |
bmp=(char *)malloc((B->dim).x*(B->dim).y+2); |
60 |
bzero(bmp,(B->dim).x*(B->dim).y+2); |
61 |
|
62 |
|
63 |
/* OLD BITMAP FORMAT -- DELETE */ |
64 |
/* for(i=0;i<(B->dim).x*(B->dim).y;i++) |
65 |
switch ((B->board)[i]) { |
66 |
case B_EMPTY: bmp[i]=53; break; |
67 |
case B_FOOD: bmp[i]=51; break; |
68 |
default: if ((B->plr)[BNum((B->board)[i])].alive) |
69 |
bmp[i]=33+BNum((B->board)[i]); |
70 |
else bmp[i]=52; |
71 |
break; |
72 |
} |
73 |
*/ |
74 |
|
75 |
for (i=0;i<(B->dim).x*(B->dim).y;i++)bmp[i]=(B->board)[i]+33; |
76 |
sprintf(f,"0 %d %d %d %d %s %n", (B->dim).x, (B->dim).y, B->nplayers, B->moves, bmp,&len);f+=len; |
77 |
free(bmp); |
78 |
|
79 |
for (i=0;i<B->nplayers;i++) { |
80 |
sprintf(f,"%s %d %d %d %d %d %d %n", (B->plr)[i].name, (B->plr)[i].alive, (B->plr)[i].length, |
81 |
(B->plr)[i].head.x, (B->plr)[i].head.y, (B->plr)[i].dir, (B->plr)[i].moved, &len);f+=len; |
82 |
} |
83 |
return 0; |
84 |
} |
85 |
|
86 |
|
87 |
/* create a new board from command */ |
88 |
/* TODO: sanity checks!! command must be correct, or expect the worst !!! */ |
89 |
BRD *ReadBoard(char *f) { |
90 |
BRD *B; |
91 |
int width,height,nplayers,moves,alive,length,head_x,head_y,dir,moved; |
92 |
int len,i; |
93 |
char *bmp; |
94 |
static char name[200]; |
95 |
|
96 |
sscanf(f,"0 %d %d %d %d %n",&width,&height,&nplayers,&moves,&len);f+=len; |
97 |
B = (BRD *)malloc(sizeof(BRD)); |
98 |
(B->dim).x=width; |
99 |
(B->dim).y=height; |
100 |
B->nplayers=nplayers; |
101 |
B->moves=moves; |
102 |
|
103 |
B->board=(int *)malloc(width*height*sizeof(int)); |
104 |
bzero((void *)(B->board),width*height*sizeof(int)); |
105 |
bmp=(char *)malloc(width*height+10); |
106 |
sscanf(f,"%s %n",bmp,&len);f+=len; |
107 |
for(i=0;i<width*height;i++)(B->board)[i]=bmp[i]-33; |
108 |
free(bmp); |
109 |
|
110 |
/* initialize players */ |
111 |
B->plr=(PLR_STAT *)malloc(nplayers*sizeof(PLR_STAT)); |
112 |
for (i=0;i<nplayers;i++) { |
113 |
sscanf(f,"%s %d %d %d %d %d %d %n",name,&alive,&length,&head_x,&head_y,&dir,&moved,&len);f+=len; |
114 |
(B->plr)[i].name=(char *)malloc(strlen(name)+2); |
115 |
strcpy((B->plr)[i].name,name); |
116 |
(B->plr)[i].alive=alive; |
117 |
(B->plr)[i].length=length; |
118 |
(B->plr)[i].time_of_death=0; |
119 |
(B->plr)[i].moved=moved; |
120 |
(B->plr)[i].dir=dir; |
121 |
(B->plr)[i].head.x=head_x; |
122 |
(B->plr)[i].head.y=head_y; |
123 |
} |
124 |
|
125 |
/* update live players */ |
126 |
B->live_players=0; |
127 |
for (i=0;i<B->nplayers;i++) |
128 |
if ((B->plr)[i].alive) B->live_players++; |
129 |
|
130 |
return B; |
131 |
} |
132 |
|
133 |
int FreeBoard(BRD *B) { |
134 |
int i; |
135 |
|
136 |
free(B->board); |
137 |
for (i=0;i<B->nplayers;i++) |
138 |
free((B->plr)[i].name); |
139 |
free(B->plr); |
140 |
free(B); |
141 |
return 0; |
142 |
} |
143 |
|
144 |
int CreateMaintenance(BRD *B, char *command) { |
145 |
sprintf(command,"2"); |
146 |
} |
147 |
|
148 |
|
149 |
/* move a single player */ |
150 |
int MakeMove(BRD *B, int plr, int cmd) { |
151 |
POS newpos; |
152 |
int dir,d; |
153 |
POS i,j; |
154 |
|
155 |
/* dead worms do not move */ |
156 |
if ((B->plr)[plr].alive==0) return 0; |
157 |
|
158 |
(B->plr)[plr].moved=1; |
159 |
|
160 |
/* new facing direction */ |
161 |
dir=(B->plr)[plr].dir; |
162 |
if (cmd<2) dir=(dir+3+cmd*2)%4; |
163 |
(B->plr)[plr].dir=dir; |
164 |
|
165 |
/* new head position */ |
166 |
newpos=(B->plr)[plr].head; |
167 |
newpos.x+=PDIR[dir].x; |
168 |
newpos.y+=PDIR[dir].y; |
169 |
|
170 |
/* test death */ |
171 |
if ((newpos.x<0)||(newpos.x>=(B->dim).x)||(newpos.y<0)||(newpos.y>=(B->dim).y)|| |
172 |
( (BPos(B,newpos.x,newpos.y)!=B_FOOD)&&(BPos(B,newpos.x,newpos.y)!=B_EMPTY) )) { |
173 |
(B->plr)[plr].alive=0; |
174 |
(B->plr)[plr].move_of_death=B->moves; |
175 |
B->live_players--; |
176 |
} else { |
177 |
/* player survived, make move */ |
178 |
if (BPos(B,newpos.x,newpos.y)==B_FOOD) { |
179 |
(B->plr)[plr].length++; |
180 |
} else { |
181 |
/* remove tail */ |
182 |
j=i=(B->plr)[plr].head; |
183 |
while (BDir(BPos(B,i.x,i.y))!=B_DIR_NONE) { |
184 |
j=i; |
185 |
d=BDir(BPos(B,i.x,i.y)); |
186 |
i.x+=PDIR[d].x; |
187 |
i.y+=PDIR[d].y; |
188 |
} |
189 |
BPos(B,j.x,j.y)=BMake(plr,B_DIR_NONE); |
190 |
BPos(B,i.x,i.y)=B_EMPTY; |
191 |
} |
192 |
(B->plr)[plr].head=newpos; |
193 |
BPos(B,newpos.x,newpos.y)=(((B->plr)[plr].length>1)?BMake(plr,NDIR[dir]):BMake(plr,B_DIR_NONE)); |
194 |
} |
195 |
} |
196 |
|
197 |
int ApplyCommand(BRD *B, char *command) { |
198 |
int cmd,plr,dir,i; |
199 |
|
200 |
sscanf(command,"%d",&cmd); |
201 |
|
202 |
switch(cmd) { |
203 |
case 1: /* turn */ |
204 |
sscanf(command,"%d %d %d",&cmd,&plr,&dir); |
205 |
MakeMove(B,plr,dir); |
206 |
break; |
207 |
case 2: /* maintanance */ |
208 |
|
209 |
/* end of turn - move all idle players */ |
210 |
for (i=0;i<B->nplayers;i++) { |
211 |
if ((B->plr)[i].moved==0) MakeMove(B,i,2); |
212 |
(B->plr)[i].moved=0; |
213 |
} |
214 |
B->moves++; |
215 |
break; |
216 |
} |
217 |
} |
218 |
|
219 |
|
220 |
|