Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

moveengine.cpp

Go to the documentation of this file.
00001 #include "moveengine.h"
00002 
00003 #include <qtimer.h>
00004 #include <stdlib.h>
00005 
00006 MoveEngine::MoveEngine()
00007         : QObject()
00008 {
00009     int offset=7;
00010     int a=0; //counter variable
00011     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};
00012     for(a=0;a<26;a++)
00013     {
00014         x_coord[a]=xfill[a];
00015     }
00016 
00017     int yfill[]={10,25,40,55,70,10+offset,25+offset,40+offset,55+offset,25,40,55, 25+offset,40+offset,40};
00018     int zfill[]={1,1,1,1,1,2,2,2,2,3,3,3,4,4,5};
00019     for(a=0;a<15;a++)
00020     {
00021         yup_coord[a]=yfill[a];
00022         ylow_coord[a]=185-(yfill[a]);
00023         z_coord[a]=zfill[a];
00024     }
00025     for(a=0;a<5;a++)
00026     {
00027         if(a<3)
00028         {
00029             x_fin1[a]=65+a*15;
00030             x_fin2[a]=155-a*15;
00031         }
00032         y_fin[a]=225-a*5;
00033     }
00034     z_fin=1;
00035 
00036     reset();
00037 }
00038 
00039 MoveEngine::~MoveEngine()
00040 {}
00041 
00042 void MoveEngine::position(Pieces& pieces,bool non_qte)
00043 {
00044     int player1_counter=0;
00045     int player2_counter=0;
00046 
00047     //non qte styles are smaller !!
00048     int offset=(non_qte) ? 5 : 0;
00049 
00050     for(int a=0;a<28;a++)
00051     {
00052         for(int b=0;b<abs(population[a].total);b++)
00053         {
00054             if(population[a].total>0) //player 1 pieces
00055             {
00056                 pieces.player1[player1_counter].x=x_coord[a]-offset;
00057                 if(a>=0 && a<13)
00058                 {
00059                     pieces.player1[player1_counter].y=yup_coord[b]-offset;
00060                     pieces.player1[player1_counter].z=z_coord[b];
00061                     pieces.player1[player1_counter].side=false;
00062                     player1_counter++;
00063                 }
00064                 else if(a>12 && a<26)
00065                 {
00066                     pieces.player1[player1_counter].y=ylow_coord[b]-offset;
00067                     pieces.player1[player1_counter].z=z_coord[b];
00068                     pieces.player1[player1_counter].side=false;
00069                     player1_counter++;
00070                 }
00071                 else if(a==26)
00072                 {
00073                     if(b<5)
00074                     {
00075                         pieces.player1[player1_counter].x=x_fin1[0]-offset;
00076                         pieces.player1[player1_counter].y=y_fin[b]-offset;
00077                         pieces.player1[player1_counter].z=z_fin;
00078                     }
00079                     else if(b>=5 && b<10)
00080                     {
00081                         pieces.player1[player1_counter].x=x_fin1[1]-offset;
00082                         pieces.player1[player1_counter].y=y_fin[b-5]-offset;
00083                         pieces.player1[player1_counter].z=z_fin;
00084                     }
00085                     else
00086                     {
00087                         pieces.player1[player1_counter].x=x_fin1[2]-offset;
00088                         pieces.player1[player1_counter].y=y_fin[b-10]-offset;
00089                         pieces.player1[player1_counter].z=z_fin;
00090                     }
00091                     pieces.player1[player1_counter].side=true;
00092                     player1_counter++;
00093 
00094                 }
00095             }
00096 
00097             else if(population[a].total<0) //player 2 pieces
00098             {
00099                 pieces.player2[player2_counter].x=x_coord[a]-offset;
00100                 if(a>=0 && a<13)
00101                 {
00102                     pieces.player2[player2_counter].y=yup_coord[b]-offset;
00103                     pieces.player2[player2_counter].z=z_coord[b];
00104                     pieces.player2[player2_counter].side=false;
00105                     player2_counter++;
00106                 }
00107                 else if(a>12 && a<26)
00108                 {
00109                     pieces.player2[player2_counter].y=ylow_coord[b]-offset;
00110                     pieces.player2[player2_counter].z=z_coord[b];
00111                     pieces.player2[player2_counter].side=false;
00112                     player2_counter++;
00113                 }
00114                 else if(a==27)
00115                 {
00116                     if(b<5)
00117                     {
00118                         pieces.player2[player2_counter].x=x_fin2[0]-offset;
00119                         pieces.player2[player2_counter].y=y_fin[b]-offset;
00120                         pieces.player2[player2_counter].z=z_fin;
00121                     }
00122                     else if(b>=5 && b<10)
00123                     {
00124                         pieces.player2[player2_counter].x=x_fin2[1]-offset;
00125                         pieces.player2[player2_counter].y=y_fin[b-5]-offset;
00126                         pieces.player2[player2_counter].z=z_fin;
00127                     }
00128                     else
00129                     {
00130                         pieces.player2[player2_counter].x=x_fin2[2]-offset;
00131                         pieces.player2[player2_counter].y=y_fin[b-10]-offset;
00132                         pieces.player2[player2_counter].z=z_fin;
00133                     }
00134                     pieces.player2[player2_counter].side=true;
00135                     player2_counter++;
00136 
00137                 }
00138             }
00139         }
00140     }
00141 }
00142 
00143 void MoveEngine::diceroll(const int& newplayer,const int& face1,const int& face2,const int& face3,const int& face4,bool computer)
00144 {
00145     checkstate();
00146     player=newplayer;
00147     otherplayer=(player==1) ? 2 : 1;
00148     dice[0]=face1;
00149     dice[1]=face2;
00150     dice[2]=face3;
00151     dice[3]=face4;
00152     marker_current=-1;
00153     if(getPossibleMoves()==0)
00154     {
00155         emit nomove();
00156         return; // player will be changed
00157     }
00158     if(!computer)
00159         return; //human intervention required
00160 
00161     QTimer::singleShot(2000,this,SLOT(automove()));
00162 }
00163 
00164 
00165 void MoveEngine::automove()
00166 {
00167     //the maximimum possibility
00168     int maxpos=0;
00169     //the position in the moves array
00170     int from=-1;
00171     int to=-1;
00172     //dice1 or dice 2 ??
00173     int index_dice=0;
00174     for(int counter=0;counter<26;counter++)
00175     {
00176         int a=(player==1) ? counter : 25-counter;
00177         for(int b=0;b<4;b++)
00178         {
00179             if(moves[a].weight[b]>maxpos)
00180             {
00181                 maxpos=moves[a].weight[b];
00182                 from=a;
00183                 to=moves[a].to[b];
00184                 index_dice=b+1;
00185             }
00186         }
00187     }
00188     move(from,to,index_dice);
00189 }
00190 
00191 
00192 void MoveEngine::boardpressed(const int& x,const int& y,Marker& marker,bool non_qte)
00193 {
00194     //get the position of the mouse click
00195     bool upper=true;
00196     bool found=false;
00197 
00198     int offset=(non_qte) ? 5 : 0;
00199 
00200     if(y<=85) // board slots 0 to 12
00201         marker.y_current=0;
00202     else if(y>=105) //board slots 13 to 25
00203     {
00204         marker.y_current=195-2*offset;
00205         upper=false;
00206     }
00207 
00208     int index=13; // the clicked board slot
00209 
00210     while(index<25 && !found)
00211     {
00212         if(x>=x_coord[index] && x<x_coord[index+1])
00213         {
00214             marker.x_current=x_coord[index];
00215             found=true;
00216             ;
00217         }
00218         else
00219         {
00220             index++;
00221         }
00222     }
00223     if(!found)
00224     {
00225         marker.x_current=x_coord[25];
00226         index=25;
00227     }
00228     if(upper)
00229     {
00230         index=25-index;
00231     }
00232 
00233     int a=0;
00234     int usedice=-1;
00235     int dice_value=7;
00236     for(a=0;a<4;a++)
00237     {
00238         if(index==marker_next[a] && marker_next[a]!=-1 && dice_value>dice[a])
00239         {
00240           usedice=a;
00241           dice_value=dice[0];
00242          }        
00243     }  
00244     if(usedice!=-1)
00245     {
00246         move(marker_current,marker_next[usedice],usedice+1);
00247         nomarker(marker);
00248         return;
00249 
00250     }
00251 
00252 
00253     if(dice[0]==7 && dice[1]==7 && dice[2]==7 && dice[3]==7) //no dice rolled
00254     {
00255         nomarker(marker);
00256         return;
00257     }
00258     else if(fieldColor(index)==player)
00259     {
00260         marker.visible_current=true;
00261         marker_current=index;
00262     }
00263     else
00264     {
00265         nomarker(marker);
00266         return;
00267     }
00268 
00269     for(a=0;a<4;a++)
00270     {
00271         if(moves[index].weight[a]>0)
00272         {
00273             int nextfield=moves[index].to[a];
00274             marker.x_next[a]=x_coord[nextfield];
00275             marker_next[a]=nextfield;
00276             if(nextfield<13) //upper half
00277                 marker.y_next[a]=0;
00278             else //lower half
00279                 marker.y_next[a]=195-2*offset;
00280             marker.visible_next[a]=true;
00281         }
00282         else
00283         {
00284             marker.x_next[a]=0;
00285             marker.y_next[a]=0;
00286             marker_next[a]=-1;
00287             marker.visible_next[a]=false;
00288         }
00289     }
00290     return;
00291 }
00292 
00293 void MoveEngine::reset()
00294 {
00295     int a=0;
00296     for(a=0;a<28;a++)
00297     {
00298         population[a].total=0;
00299     }
00300 
00301     int p1_index[]={1,1,12,12,12,12,12,17,17,17,19,19,19,19,19};
00302     int p2_index[]={24,24,13,13,13,13,13,8,8,8,6,6,6,6,6};
00303     //int p1_index[]={19,20,21,22,22,23,23,18,18,23,24,24,24,24,24};
00304     //int p2_index[]={6,5,4,3,3,2,2,2,2,2,1,7,7,1,1};
00305     for(a=0;a<15;a++)
00306     {
00307         population[p1_index[a]].total++;
00308         population[p2_index[a]].total--;
00309     }
00310 
00311     player=0;
00312     dice[0]=7;
00313     dice[1]=7;
00314     dice[2]=7;
00315     dice[3]=7;
00316 
00317     marker_current=-1;
00318     marker_next[0]=-1;
00319     marker_next[1]=-1;
00320     marker_next[2]=-1;
00321     marker_next[3]=-1;
00322     //allclear[0]==false;
00323     allclear[1]=false;
00324     allclear[2]=false;
00325     last_piece[1]=0;
00326     last_piece[2]=25;
00327 }
00328 
00329 void MoveEngine::loadGame(const LoadSave& load)
00330 {
00331     for(int a=0;a<28;a++)
00332     {
00333         population[a].total=load.pop[a].total;
00334     }
00335     checkstate();
00336 }
00337 
00338 LoadSave MoveEngine::saveGame()
00339 {
00340     LoadSave save;
00341     for(int a=0;a<28;a++)
00342     {
00343         save.pop[a].total=population[a].total;
00344     }
00345     return save;
00346 }
00347 
00348 AISettings MoveEngine::getAISettings()
00349 {
00350     return ai;
00351 }
00352 
00353 void MoveEngine::setAISettings(const AISettings& new_ai)
00354 {
00355     ai=new_ai;
00356 }
00357 
00358 void MoveEngine::setRules(Rules rules)
00359 {
00360   move_with_pieces_out=rules.move_with_pieces_out;
00361   nice_dice=rules.generous_dice;
00362 }
00363 
00364 
00365 int MoveEngine::getPossibleMoves()
00366 {
00367     int homezone[]={0,25,0};
00368     int lastToHomeZone=abs(last_piece[player]-homezone[player]);
00369     for(int field=0;field<26;field++)
00370     {
00371        
00372         for(int b=0;b<4;b++)
00373         {            
00374             int dice_tmp=dice[b];
00375             if(dice[b]!=7 && dice[b]> lastToHomeZone)
00376               dice_tmp=lastToHomeZone;
00377 
00378             int nextfield=(player==1) ? field+dice_tmp : field-dice_tmp;
00379            
00380             if(nice_dice)
00381             {
00382               if(player==1 && nextfield>homezone[1])
00383                 nextfield=homezone[1];
00384               else if(player==2 && nextfield<homezone[2])
00385                 nextfield=homezone[2];
00386             }
00387 
00388             moves[field].weight[b]=0;
00389             moves[field].to[b]=nextfield;
00390 
00391             int out_of_board[]={-1,0,25};
00392             if(!move_with_pieces_out && field!=out_of_board[player] && pieces_out[player])
00393             {
00394               continue;
00395             }
00396            
00397 
00398         
00399             if(dice[b]!=7 && fieldColor(field)==player )  //player can only move his own pieces
00400             {
00401                 if((player==1 && nextfield > homezone[1]) || (player==2 && nextfield < homezone[2]))
00402                 {
00403                   moves[field].weight[b]=0; //movement would be far out of board
00404                 }
00405                 else if(nextfield==homezone[player] && !allclear[player])
00406                 {
00407                   moves[field].weight[b]=0; //can not rescue pieces until all are in the endzone
00408                 }
00409                 else if(nextfield==homezone[player] && allclear[player])
00410                 {
00411                    moves[field].weight[b]=ai.rescue; //rescue your pieces : nuff said ;-)
00412                 }
00413                 else if(fieldColor(nextfield)==otherplayer)
00414                 {
00415                     if(abs(population[nextfield].total)>1) //can not move to this field
00416                         moves[field].weight[b]=0;
00417                     else if(abs(population[nextfield].total)==1) //eliminate opponent : very nice
00418                         moves[field].weight[b]=ai.eliminate;
00419                 }
00420                 else if(fieldColor(nextfield)==player) //nextfield already occupied by player
00421                 {
00422                     if(abs(population[field].total)==2) //expose own piece : not diserable
00423                         moves[field].weight[b]=ai.expose;
00424                     else if(abs(population[nextfield].total)>1) //own pices already there : safe
00425                         moves[field].weight[b]=ai.safe;
00426                     else if(abs(population[nextfield].total)==1) //protect own piece : most importatnt
00427                         moves[field].weight[b]=ai.protect;
00428                 }
00429                 else if(population[nextfield].total==0) //nextfield empty
00430                 {
00431                     if(abs(population[field].total)==2) //expose own piece : not diserable
00432                         moves[field].weight[b]=ai.expose;
00433                     else
00434                         moves[field].weight[b]=ai.empty;
00435                 }
00436                 else
00437                     moves[field].weight[b]=0; //default.
00438             }
00439 
00440 
00441 
00442             else
00443                 moves[field].weight[b]=0; //dice already used or field not used by player
00444         }
00445 
00446 
00447 
00448     }
00449 
00450     int total=0;
00451     for(int field=0;field<26;field++)
00452     {
00453         total+=moves[field].weight[0]+moves[field].weight[1]+moves[field].weight[2]+moves[field].weight[3];
00454     }
00455     return total;
00456 }
00457 
00458 void MoveEngine::move(const int& from, int to, const int& dice)
00459 {
00460     //odebug << "" << player << " moves from " << from << " to " << to << " (" << to-from << ") with dice " << dice << "" << oendl; 
00461 
00462     if(player==1 && to==25)
00463         to=26;
00464     if(player==2 && to==0)
00465         to=27;
00466 
00467     //if space is occupied by enemy move pieces to startzone
00468     if(fieldColor(to)==otherplayer)
00469     {
00470         population[to].total=0;
00471         if(otherplayer==1)
00472             population[0].total++;
00473         else
00474             population[25].total--;
00475     }
00476 
00477     if(player==1)
00478     {
00479         population[from].total--;
00480         population[to].total++;
00481     }
00482     else  //player=2
00483     {
00484         population[from].total++;
00485         population[to].total--;
00486     }
00487 
00488     if(dice==1)
00489         emit done_dice1();
00490     else if(dice==2)
00491         emit done_dice2();
00492     else if(dice==3)
00493         emit done_dice3();
00494     else
00495         emit done_dice4();
00496 
00497     if(abs(population[26].total)==15)
00498         emit player_finished(1);
00499     if(abs(population[27].total)==15)
00500         emit player_finished(2);
00501 }
00502 
00503 void MoveEngine::checkstate()
00504 {
00505     //check if pieces are out
00506     pieces_out[1]=(population[0].total>0) ? true : false;
00507     pieces_out[2]=(population[25].total<0) ? true : false;
00508     
00509     //check if all pieces are in the endzones
00510     allclear[1]=true;
00511     allclear[2]=true;
00512 
00513     last_piece[1]=25;
00514     bool found_last_piece1=false;
00515     last_piece[2]=0;
00516     
00517     for(int a=0;a<26;a++)
00518     {
00519         if(a<19 && population[a].total>0)
00520             allclear[1]=false;
00521         if(a>6 && population[a].total<0)
00522             allclear[2]=false;
00523             
00524         if(population[a].total>0 && !found_last_piece1)
00525         {
00526           last_piece[1]=a;
00527           found_last_piece1=true;
00528         }
00529         if(population[a].total<0)
00530           last_piece[2]=a;
00531     }
00532 }
00533 
00534 void MoveEngine::nomarker(Marker& marker)
00535 {
00536     marker.visible_current=false;
00537     marker_current=-1;
00538     for(int a=0;a<4;a++)
00539     {
00540         marker.x_next[a]=0;
00541         marker.y_next[a]=0;
00542         marker_next[a]=-1;
00543         marker.visible_next[a]=false;
00544     }
00545 }
00546 
00547 int MoveEngine::fieldColor(const int& index) const
00548 {
00549     if(population[index].total>0)
00550         return 1;
00551     else if(population[index].total<0)
00552         return 2;
00553     else
00554         return 0;
00555 }
00556 
00557 

Generated on Sat Nov 5 16:17:18 2005 for OPIE by  doxygen 1.4.2