author | waspe <waspe> | 2003-03-30 11:30:54 (UTC) |
---|---|---|
committer | waspe <waspe> | 2003-03-30 11:30:54 (UTC) |
commit | 3065a1c13bec5d0b101bec48ff666d45a02ce8a6 (patch) (unidiff) | |
tree | f8fe8d3eba81ef4e371c12f530be9cd4debc895b /noncore/games/backgammon/moveengine.cpp | |
parent | 87ba3646367397e149979a8477a33239cb341e99 (diff) | |
download | opie-3065a1c13bec5d0b101bec48ff666d45a02ce8a6.zip opie-3065a1c13bec5d0b101bec48ff666d45a02ce8a6.tar.gz opie-3065a1c13bec5d0b101bec48ff666d45a02ce8a6.tar.bz2 |
*** empty log message ***
Diffstat (limited to 'noncore/games/backgammon/moveengine.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/games/backgammon/moveengine.cpp | 558 |
1 files changed, 558 insertions, 0 deletions
diff --git a/noncore/games/backgammon/moveengine.cpp b/noncore/games/backgammon/moveengine.cpp new file mode 100644 index 0000000..009c449 --- a/dev/null +++ b/noncore/games/backgammon/moveengine.cpp | |||
@@ -0,0 +1,558 @@ | |||
1 | #include "moveengine.h" | ||
2 | |||
3 | #include <qmessagebox.h> | ||
4 | |||
5 | #include <qtimer.h> | ||
6 | |||
7 | MoveEngine::MoveEngine() | ||
8 | : QObject() | ||
9 | { | ||
10 | int offset=7; | ||
11 | int a=0; //counter variable | ||
12 | int xfill[]={210,185,170,155,140,125,110,85,70,55,40,25,10,10,25,40,55,70,85,110,125,140,155,170,185,210}; | ||
13 | for(a=0;a<26;a++) | ||
14 | { | ||
15 | x_coord[a]=xfill[a]; | ||
16 | } | ||
17 | |||
18 | int yfill[]={10,25,40,55,70,10+offset,25+offset,40+offset,55+offset,25,40,55, 25+offset,40+offset,40}; | ||
19 | int zfill[]={1,1,1,1,1,2,2,2,2,3,3,3,4,4,5}; | ||
20 | for(a=0;a<15;a++) | ||
21 | { | ||
22 | yup_coord[a]=yfill[a]; | ||
23 | ylow_coord[a]=185-(yfill[a]); | ||
24 | z_coord[a]=zfill[a]; | ||
25 | } | ||
26 | for(a=0;a<5;a++) | ||
27 | { | ||
28 | if(a<3) | ||
29 | { | ||
30 | x_fin1[a]=65+a*15; | ||
31 | x_fin2[a]=155-a*15; | ||
32 | } | ||
33 | y_fin[a]=225-a*5; | ||
34 | } | ||
35 | z_fin=1; | ||
36 | |||
37 | reset(); | ||
38 | } | ||
39 | |||
40 | MoveEngine::~MoveEngine() | ||
41 | {} | ||
42 | |||
43 | void MoveEngine::position(Pieces& pieces,bool non_qte) | ||
44 | { | ||
45 | int player1_counter=0; | ||
46 | int player2_counter=0; | ||
47 | |||
48 | //non qte styles are smaller !! | ||
49 | int offset=(non_qte) ? 5 : 0; | ||
50 | |||
51 | for(int a=0;a<28;a++) | ||
52 | { | ||
53 | for(int b=0;b<abs(population[a].total);b++) | ||
54 | { | ||
55 | if(population[a].total>0) //player 1 pieces | ||
56 | { | ||
57 | pieces.player1[player1_counter].x=x_coord[a]-offset; | ||
58 | if(a>=0 && a<13) | ||
59 | { | ||
60 | pieces.player1[player1_counter].y=yup_coord[b]-offset; | ||
61 | pieces.player1[player1_counter].z=z_coord[b]; | ||
62 | pieces.player1[player1_counter].side=false; | ||
63 | player1_counter++; | ||
64 | } | ||
65 | else if(a>12 && a<26) | ||
66 | { | ||
67 | pieces.player1[player1_counter].y=ylow_coord[b]-offset; | ||
68 | pieces.player1[player1_counter].z=z_coord[b]; | ||
69 | pieces.player1[player1_counter].side=false; | ||
70 | player1_counter++; | ||
71 | } | ||
72 | else if(a==26) | ||
73 | { | ||
74 | if(b<5) | ||
75 | { | ||
76 | pieces.player1[player1_counter].x=x_fin1[0]-offset; | ||
77 | pieces.player1[player1_counter].y=y_fin[b]-offset; | ||
78 | pieces.player1[player1_counter].z=z_fin; | ||
79 | } | ||
80 | else if(b>=5 && b<10) | ||
81 | { | ||
82 | pieces.player1[player1_counter].x=x_fin1[1]-offset; | ||
83 | pieces.player1[player1_counter].y=y_fin[b-5]-offset; | ||
84 | pieces.player1[player1_counter].z=z_fin; | ||
85 | } | ||
86 | else | ||
87 | { | ||
88 | pieces.player1[player1_counter].x=x_fin1[2]-offset; | ||
89 | pieces.player1[player1_counter].y=y_fin[b-10]-offset; | ||
90 | pieces.player1[player1_counter].z=z_fin; | ||
91 | } | ||
92 | pieces.player1[player1_counter].side=true; | ||
93 | player1_counter++; | ||
94 | |||
95 | } | ||
96 | } | ||
97 | |||
98 | else if(population[a].total<0) //player 2 pieces | ||
99 | { | ||
100 | pieces.player2[player2_counter].x=x_coord[a]-offset; | ||
101 | if(a>=0 && a<13) | ||
102 | { | ||
103 | pieces.player2[player2_counter].y=yup_coord[b]-offset; | ||
104 | pieces.player2[player2_counter].z=z_coord[b]; | ||
105 | pieces.player2[player2_counter].side=false; | ||
106 | player2_counter++; | ||
107 | } | ||
108 | else if(a>12 && a<26) | ||
109 | { | ||
110 | pieces.player2[player2_counter].y=ylow_coord[b]-offset; | ||
111 | pieces.player2[player2_counter].z=z_coord[b]; | ||
112 | pieces.player2[player2_counter].side=false; | ||
113 | player2_counter++; | ||
114 | } | ||
115 | else if(a==27) | ||
116 | { | ||
117 | if(b<5) | ||
118 | { | ||
119 | pieces.player2[player2_counter].x=x_fin2[0]-offset; | ||
120 | pieces.player2[player2_counter].y=y_fin[b]-offset; | ||
121 | pieces.player2[player2_counter].z=z_fin; | ||
122 | } | ||
123 | else if(b>=5 && b<10) | ||
124 | { | ||
125 | pieces.player2[player2_counter].x=x_fin2[1]-offset; | ||
126 | pieces.player2[player2_counter].y=y_fin[b-5]-offset; | ||
127 | pieces.player2[player2_counter].z=z_fin; | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | pieces.player2[player2_counter].x=x_fin2[2]-offset; | ||
132 | pieces.player2[player2_counter].y=y_fin[b-10]-offset; | ||
133 | pieces.player2[player2_counter].z=z_fin; | ||
134 | } | ||
135 | pieces.player2[player2_counter].side=true; | ||
136 | player2_counter++; | ||
137 | |||
138 | } | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | void MoveEngine::diceroll(const int& newplayer,const int& face1,const int& face2,const int& face3,const int& face4,bool computer) | ||
145 | { | ||
146 | checkstate(); | ||
147 | player=newplayer; | ||
148 | otherplayer=(player==1) ? 2 : 1; | ||
149 | dice[0]=face1; | ||
150 | dice[1]=face2; | ||
151 | dice[2]=face3; | ||
152 | dice[3]=face4; | ||
153 | marker_current=-1; | ||
154 | if(getPossibleMoves()==0) | ||
155 | { | ||
156 | emit nomove(); | ||
157 | return; // player will be changed | ||
158 | } | ||
159 | if(!computer) | ||
160 | return; //human intervention required | ||
161 | |||
162 | QTimer::singleShot(2000,this,SLOT(automove())); | ||
163 | } | ||
164 | |||
165 | |||
166 | void MoveEngine::automove() | ||
167 | { | ||
168 | //the maximimum possibility | ||
169 | int maxpos=0; | ||
170 | //the position in the moves array | ||
171 | int from=-1; | ||
172 | int to=-1; | ||
173 | //dice1 or dice 2 ?? | ||
174 | int index_dice=0; | ||
175 | for(int counter=0;counter<26;counter++) | ||
176 | { | ||
177 | int a=(player==1) ? counter : 25-counter; | ||
178 | for(int b=0;b<4;b++) | ||
179 | { | ||
180 | if(moves[a].weight[b]>maxpos) | ||
181 | { | ||
182 | maxpos=moves[a].weight[b]; | ||
183 | from=a; | ||
184 | to=moves[a].to[b]; | ||
185 | index_dice=b+1; | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | move(from,to,index_dice); | ||
190 | } | ||
191 | |||
192 | |||
193 | void MoveEngine::boardpressed(const int& x,const int& y,Marker& marker,bool non_qte) | ||
194 | { | ||
195 | //get the position of the mouse click | ||
196 | bool upper=true; | ||
197 | bool found=false; | ||
198 | |||
199 | int offset=(non_qte) ? 5 : 0; | ||
200 | |||
201 | if(y<=85) // board slots 0 to 12 | ||
202 | marker.y_current=0; | ||
203 | else if(y>=105) //board slots 13 to 25 | ||
204 | { | ||
205 | marker.y_current=195-2*offset; | ||
206 | upper=false; | ||
207 | } | ||
208 | |||
209 | int index=13; // the clicked board slot | ||
210 | |||
211 | while(index<25 && !found) | ||
212 | { | ||
213 | if(x>=x_coord[index] && x<x_coord[index+1]) | ||
214 | { | ||
215 | marker.x_current=x_coord[index]; | ||
216 | found=true; | ||
217 | ; | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | index++; | ||
222 | } | ||
223 | } | ||
224 | if(!found) | ||
225 | { | ||
226 | marker.x_current=x_coord[25]; | ||
227 | index=25; | ||
228 | } | ||
229 | if(upper) | ||
230 | { | ||
231 | index=25-index; | ||
232 | } | ||
233 | |||
234 | int a=0; | ||
235 | int usedice=-1; | ||
236 | int dice_value=7; | ||
237 | for(a=0;a<4;a++) | ||
238 | { | ||
239 | if(index==marker_next[a] && marker_next[a]!=-1 && dice_value>dice[a]) | ||
240 | { | ||
241 | usedice=a; | ||
242 | dice_value=dice[0]; | ||
243 | } | ||
244 | } | ||
245 | if(usedice!=-1) | ||
246 | { | ||
247 | move(marker_current,marker_next[usedice],usedice+1); | ||
248 | nomarker(marker); | ||
249 | return; | ||
250 | |||
251 | } | ||
252 | |||
253 | |||
254 | if(dice[0]==7 && dice[1]==7 && dice[2]==7 && dice[3]==7) //no dice rolled | ||
255 | { | ||
256 | nomarker(marker); | ||
257 | return; | ||
258 | } | ||
259 | else if(fieldColor(index)==player) | ||
260 | { | ||
261 | marker.visible_current=true; | ||
262 | marker_current=index; | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | nomarker(marker); | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | for(a=0;a<4;a++) | ||
271 | { | ||
272 | if(moves[index].weight[a]>0) | ||
273 | { | ||
274 | int nextfield=moves[index].to[a]; | ||
275 | marker.x_next[a]=x_coord[nextfield]; | ||
276 | marker_next[a]=nextfield; | ||
277 | if(nextfield<13) //upper half | ||
278 | marker.y_next[a]=0; | ||
279 | else //lower half | ||
280 | marker.y_next[a]=195-2*offset; | ||
281 | marker.visible_next[a]=true; | ||
282 | } | ||
283 | else | ||
284 | { | ||
285 | marker.x_next[a]=0; | ||
286 | marker.y_next[a]=0; | ||
287 | marker_next[a]=-1; | ||
288 | marker.visible_next[a]=false; | ||
289 | } | ||
290 | } | ||
291 | return; | ||
292 | } | ||
293 | |||
294 | void MoveEngine::reset() | ||
295 | { | ||
296 | int a=0; | ||
297 | for(a=0;a<28;a++) | ||
298 | { | ||
299 | population[a].total=0; | ||
300 | } | ||
301 | |||
302 | int p1_index[]={1,1,12,12,12,12,12,17,17,17,19,19,19,19,19}; | ||
303 | int p2_index[]={24,24,13,13,13,13,13,8,8,8,6,6,6,6,6}; | ||
304 | //int p1_index[]={19,20,21,22,22,23,23,18,18,23,24,24,24,24,24}; | ||
305 | //int p2_index[]={6,5,4,3,3,2,2,2,2,2,1,7,7,1,1}; | ||
306 | for(a=0;a<15;a++) | ||
307 | { | ||
308 | population[p1_index[a]].total++; | ||
309 | population[p2_index[a]].total--; | ||
310 | } | ||
311 | |||
312 | player=0; | ||
313 | dice[0]=7; | ||
314 | dice[1]=7; | ||
315 | dice[2]=7; | ||
316 | dice[3]=7; | ||
317 | |||
318 | marker_current=-1; | ||
319 | marker_next[0]=-1; | ||
320 | marker_next[1]=-1; | ||
321 | marker_next[2]=-1; | ||
322 | marker_next[3]=-1; | ||
323 | //allclear[0]==false; | ||
324 | allclear[1]=false; | ||
325 | allclear[2]=false; | ||
326 | last_piece[1]=0; | ||
327 | last_piece[2]=25; | ||
328 | } | ||
329 | |||
330 | void MoveEngine::loadGame(const LoadSave& load) | ||
331 | { | ||
332 | for(int a=0;a<28;a++) | ||
333 | { | ||
334 | population[a].total=load.pop[a].total; | ||
335 | } | ||
336 | checkstate(); | ||
337 | } | ||
338 | |||
339 | LoadSave MoveEngine::saveGame() | ||
340 | { | ||
341 | LoadSave save; | ||
342 | for(int a=0;a<28;a++) | ||
343 | { | ||
344 | save.pop[a].total=population[a].total; | ||
345 | } | ||
346 | return save; | ||
347 | } | ||
348 | |||
349 | AISettings MoveEngine::getAISettings() | ||
350 | { | ||
351 | return ai; | ||
352 | } | ||
353 | |||
354 | void MoveEngine::setAISettings(const AISettings& new_ai) | ||
355 | { | ||
356 | ai=new_ai; | ||
357 | } | ||
358 | |||
359 | void MoveEngine::setRules(Rules rules) | ||
360 | { | ||
361 | move_with_pieces_out=rules.move_with_pieces_out; | ||
362 | nice_dice=rules.generous_dice; | ||
363 | } | ||
364 | |||
365 | |||
366 | int MoveEngine::getPossibleMoves() | ||
367 | { | ||
368 | int homezone[]={0,25,0}; | ||
369 | int lastToHomeZone=abs(last_piece[player]-homezone[player]); | ||
370 | for(int field=0;field<26;field++) | ||
371 | { | ||
372 | |||
373 | for(int b=0;b<4;b++) | ||
374 | { | ||
375 | int dice_tmp=dice[b]; | ||
376 | if(dice[b]!=7 && dice[b]> lastToHomeZone) | ||
377 | dice_tmp=lastToHomeZone; | ||
378 | |||
379 | int nextfield=(player==1) ? field+dice_tmp : field-dice_tmp; | ||
380 | |||
381 | if(nice_dice) | ||
382 | { | ||
383 | if(player==1 && nextfield>homezone[1]) | ||
384 | nextfield=homezone[1]; | ||
385 | else if(player==2 && nextfield<homezone[2]) | ||
386 | nextfield=homezone[2]; | ||
387 | } | ||
388 | |||
389 | moves[field].weight[b]=0; | ||
390 | moves[field].to[b]=nextfield; | ||
391 | |||
392 | int out_of_board[]={-1,0,25}; | ||
393 | if(!move_with_pieces_out && field!=out_of_board[player] && pieces_out[player]) | ||
394 | { | ||
395 | continue; | ||
396 | } | ||
397 | |||
398 | |||
399 | |||
400 | if(dice[b]!=7 && fieldColor(field)==player ) //player can only move his own pieces | ||
401 | { | ||
402 | if((player==1 && nextfield > homezone[1]) || (player==2 && nextfield < homezone[2])) | ||
403 | { | ||
404 | moves[field].weight[b]=0; //movement would be far out of board | ||
405 | } | ||
406 | else if(nextfield==homezone[player] && !allclear[player]) | ||
407 | { | ||
408 | moves[field].weight[b]=0; //can not rescue pieces until all are in the endzone | ||
409 | } | ||
410 | else if(nextfield==homezone[player] && allclear[player]) | ||
411 | { | ||
412 | moves[field].weight[b]=ai.rescue; //rescue your pieces : nuff said ;-) | ||
413 | } | ||
414 | else if(fieldColor(nextfield)==otherplayer) | ||
415 | { | ||
416 | if(abs(population[nextfield].total)>1) //can not move to this field | ||
417 | moves[field].weight[b]=0; | ||
418 | else if(abs(population[nextfield].total)==1) //eliminate opponent : very nice | ||
419 | moves[field].weight[b]=ai.eliminate; | ||
420 | } | ||
421 | else if(fieldColor(nextfield)==player) //nextfield already occupied by player | ||
422 | { | ||
423 | if(abs(population[field].total)==2) //expose own piece : not diserable | ||
424 | moves[field].weight[b]=ai.expose; | ||
425 | else if(abs(population[nextfield].total)>1) //own pices already there : safe | ||
426 | moves[field].weight[b]=ai.safe; | ||
427 | else if(abs(population[nextfield].total)==1) //protect own piece : most importatnt | ||
428 | moves[field].weight[b]=ai.protect; | ||
429 | } | ||
430 | else if(population[nextfield].total==0) //nextfield empty | ||
431 | { | ||
432 | if(abs(population[field].total)==2) //expose own piece : not diserable | ||
433 | moves[field].weight[b]=ai.expose; | ||
434 | else | ||
435 | moves[field].weight[b]=ai.empty; | ||
436 | } | ||
437 | else | ||
438 | moves[field].weight[b]=0; //default. | ||
439 | } | ||
440 | |||
441 | |||
442 | |||
443 | else | ||
444 | moves[field].weight[b]=0; //dice already used or field not used by player | ||
445 | } | ||
446 | |||
447 | |||
448 | |||
449 | } | ||
450 | |||
451 | int total=0; | ||
452 | for(int field=0;field<26;field++) | ||
453 | { | ||
454 | total+=moves[field].weight[0]+moves[field].weight[1]+moves[field].weight[2]+moves[field].weight[3]; | ||
455 | } | ||
456 | return total; | ||
457 | } | ||
458 | |||
459 | void MoveEngine::move(const int& from, int to, const int& dice) | ||
460 | { | ||
461 | //qDebug("%d moves from %d to %d (%d) with dice %d",player,from,to,to-from,dice); | ||
462 | |||
463 | if(player==1 && to==25) | ||
464 | to=26; | ||
465 | if(player==2 && to==0) | ||
466 | to=27; | ||
467 | |||
468 | //if space is occupied by enemy move pieces to startzone | ||
469 | if(fieldColor(to)==otherplayer) | ||
470 | { | ||
471 | population[to].total=0; | ||
472 | if(otherplayer==1) | ||
473 | population[0].total++; | ||
474 | else | ||
475 | population[25].total--; | ||
476 | } | ||
477 | |||
478 | if(player==1) | ||
479 | { | ||
480 | population[from].total--; | ||
481 | population[to].total++; | ||
482 | } | ||
483 | else //player=2 | ||
484 | { | ||
485 | population[from].total++; | ||
486 | population[to].total--; | ||
487 | } | ||
488 | |||
489 | if(dice==1) | ||
490 | emit done_dice1(); | ||
491 | else if(dice==2) | ||
492 | emit done_dice2(); | ||
493 | else if(dice==3) | ||
494 | emit done_dice3(); | ||
495 | else | ||
496 | emit done_dice4(); | ||
497 | |||
498 | if(abs(population[26].total)==15) | ||
499 | emit player_finished(1); | ||
500 | if(abs(population[27].total)==15) | ||
501 | emit player_finished(2); | ||
502 | } | ||
503 | |||
504 | void MoveEngine::checkstate() | ||
505 | { | ||
506 | //check if pieces are out | ||
507 | pieces_out[1]=(population[0].total>0) ? true : false; | ||
508 | pieces_out[2]=(population[25].total<0) ? true : false; | ||
509 | |||
510 | //check if all pieces are in the endzones | ||
511 | allclear[1]=true; | ||
512 | allclear[2]=true; | ||
513 | |||
514 | last_piece[1]=25; | ||
515 | bool found_last_piece1=false; | ||
516 | last_piece[2]=0; | ||
517 | |||
518 | for(int a=0;a<26;a++) | ||
519 | { | ||
520 | if(a<19 && population[a].total>0) | ||
521 | allclear[1]=false; | ||
522 | if(a>6 && population[a].total<0) | ||
523 | allclear[2]=false; | ||
524 | |||
525 | if(population[a].total>0 && !found_last_piece1) | ||
526 | { | ||
527 | last_piece[1]=a; | ||
528 | found_last_piece1=true; | ||
529 | } | ||
530 | if(population[a].total<0) | ||
531 | last_piece[2]=a; | ||
532 | } | ||
533 | } | ||
534 | |||
535 | void MoveEngine::nomarker(Marker& marker) | ||
536 | { | ||
537 | marker.visible_current=false; | ||
538 | marker_current=-1; | ||
539 | for(int a=0;a<4;a++) | ||
540 | { | ||
541 | marker.x_next[a]=0; | ||
542 | marker.y_next[a]=0; | ||
543 | marker_next[a]=-1; | ||
544 | marker.visible_next[a]=false; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | int MoveEngine::fieldColor(const int& index) const | ||
549 | { | ||
550 | if(population[index].total>0) | ||
551 | return 1; | ||
552 | else if(population[index].total<0) | ||
553 | return 2; | ||
554 | else | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | |||