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

kcheckers.cpp

Go to the documentation of this file.
00001 
00002 #include <qimage.h>
00003 #include <qlayout.h>
00004 #include <qmenubar.h>
00005 #include <qtoolbar.h>
00006 #include <qpe/config.h>
00007 #include <qwhatsthis.h>
00008 #include <qtoolbutton.h>
00009 #include <qmessagebox.h>
00010 #include <qapplication.h>
00011 
00012 #include "kcheckers.h"
00013 #include "echeckers.h"
00014 #include "rcheckers.h"
00015 
00016 #include "pics/logo.xpm"
00017 #include "pics/undo.xpm"
00018 #include "pics/exit.xpm"
00019 #include "pics/help.xpm"
00020 #include "pics/wood1.xpm"
00021 #include "pics/wood2.xpm"
00022 #include "pics/wood3.xpm"
00023 #include "pics/green1.xpm"
00024 #include "pics/green2.xpm"
00025 #include "pics/green3.xpm"
00026 #include "pics/marble1.xpm"
00027 #include "pics/marble2.xpm"
00028 #include "pics/marble3.xpm"
00029 #include "pics/biglogo.xpm"
00030 #include "pics/man_black.xpm"
00031 #include "pics/man_white.xpm"
00032 #include "pics/king_black.xpm"
00033 #include "pics/king_white.xpm"
00034 #include "pics/contexthelp.xpm"
00035 
00036 
00037 QString KCheckers::enNumeration="1 2 3 4 5 6 7 8 9 1011121314151617181920212223242526272829303132";
00038 QString KCheckers::ruNumeration="B8D8F8H8A7C7E7G7B6D6F6H6A5C5E5G5B4D4F4H4A3C3E3G3B2D2F2H2A1C1E1G1";
00039 
00040 const int KCheckers::t[]={6,7,8,9,11,12,13,14,17,18,19,20,22,23,
00041           24,25,28,29,30,31,33,34,35,36,39,40,41,42,44,45,46,47};
00042 
00043 
00044 KCheckers::KCheckers(QWidget *p, const char* n, WFlags )
00045     :QMainWindow(p,n,WStyle_DialogBorder)
00046 {
00047   setCaption(tr("KCheckers") );
00048   setIcon(QPixmap(biglogo_xpm));
00049 
00050   setToolBarsMovable(false);
00051 
00052   // Make a menubar
00053 
00054   gameMenu=new QPopupMenu;
00055   CHECK_PTR(gameMenu);
00056 
00057   gameMenu->insertItem(QPixmap(logo_xpm),tr("&New"),this,SLOT(newGame()),CTRL+Key_N);
00058   gameMenu->insertSeparator();
00059   undoID=gameMenu->insertItem(QPixmap(undo_xpm),tr("&Undo Move"),this,SLOT(undoMove()),CTRL+Key_Z);
00060   gameMenu->insertSeparator();
00061   gameMenu->insertItem(QPixmap(exit_xpm),tr("&Quit"),qApp,SLOT(closeAllWindows()),CTRL+Key_Q);
00062 
00063   skillMenu=new QPopupMenu;
00064   CHECK_PTR(skillMenu);
00065 
00066   skillMenu->insertItem(tr("&Beginner"),this,SLOT(setSkillBeginner()),CTRL+Key_1,BEGINNER);
00067   skillMenu->insertItem(tr("&Novice"),  this,SLOT(setSkillNovice()),  CTRL+Key_2,NOVICE);
00068   skillMenu->insertItem(tr("&Average"), this,SLOT(setSkillAverage()), CTRL+Key_3,AVERAGE);
00069   skillMenu->insertItem(tr("&Good"),    this,SLOT(setSkillGood()),    CTRL+Key_4,GOOD);
00070   skillMenu->insertItem(tr("&Expert"),  this,SLOT(setSkillExpert()),  CTRL+Key_5,EXPERT);
00071   skillMenu->insertItem(tr("&Master"),  this,SLOT(setSkillMaster()),  CTRL+Key_6,MASTER);
00072 
00073   optionsMenu=new QPopupMenu;
00074   CHECK_PTR(optionsMenu);
00075 
00076   numID=optionsMenu->insertItem(tr("&Show Numeration"),this,SLOT(showNumeration()));
00077   optionsMenu->insertSeparator();
00078   optionsMenu->insertItem(tr("&English Rules"),this,SLOT(setRulesEnglish()),0,ENGLISH);
00079   optionsMenu->insertItem(tr("&Russian Rules"),this,SLOT(setRulesRussian()),0,RUSSIAN);
00080   optionsMenu->insertSeparator();
00081   optionsMenu->insertItem(tr("&Green Board"), this,SLOT(setPatternGreen()), 0,GREEN);
00082   optionsMenu->insertItem(tr("&Marble Board"),this,SLOT(setPatternMarble()),0,MARBLE);
00083   optionsMenu->insertItem(tr("&Wooden Board"),this,SLOT(setPatternWooden()),0,WOODEN);
00084 
00085   QPopupMenu* helpMenu=new QPopupMenu;
00086   CHECK_PTR(helpMenu);
00087 
00088   helpMenu->insertItem(QPixmap(contexthelp_xpm),tr("What's This"),this,SLOT(whatsThis()),SHIFT+Key_F1);
00089   helpMenu->insertItem(QPixmap(help_xpm),tr("&Rules of Play"),this,SLOT(help()),Key_F1);
00090   helpMenu->insertSeparator();
00091   helpMenu->insertItem(QPixmap(logo_xpm),tr("&About KCheckers"),this,SLOT(about()));
00092   helpMenu->insertItem(tr("About &Qt"),this,SLOT(aboutQt()));
00093 
00094   QToolBar* menuToolBar=new QToolBar(this);
00095   CHECK_PTR(menuToolBar);
00096   QMenuBar* menuBar=new QMenuBar(menuToolBar);
00097   CHECK_PTR(menuBar);
00098 
00099   menuBar->insertItem(tr("&Game"),   gameMenu);
00100   menuBar->insertItem(tr("&Skill"),  skillMenu);
00101   menuBar->insertItem(tr("&Options"),optionsMenu);
00102   menuBar->insertItem(tr("&Help"),   helpMenu);
00103 
00104   // Restore a settings
00105 
00106   readConfig();
00107 
00108   skillMenu->setItemChecked(skill,true);
00109   optionsMenu->setItemChecked(rules,true);
00110   optionsMenu->setItemChecked(numID,false);
00111 
00112   // Make a toolbar
00113 
00114   QToolBar* emptyToolBar=new QToolBar(this);
00115   emptyToolBar->setHorizontalStretchable(true);
00116 
00117   QToolBar* toolBar=new QToolBar(this);
00118   CHECK_PTR(toolBar);
00119 
00120   QSize buttonSize(24,24);
00121 
00122   QToolButton* gameButton=new QToolButton(QPixmap(logo_xpm),tr(" New Game ") ,"",this,SLOT(newGame()),toolBar);
00123   CHECK_PTR(gameButton);
00124   gameButton->setMinimumSize(buttonSize);
00125 
00126   undoButton=new QToolButton(QPixmap(undo_xpm),tr(" Undo Move "),"",this,SLOT(undoMove()),toolBar);
00127   CHECK_PTR(undoButton);
00128   undoButton->setMinimumSize(buttonSize);
00129 
00130   QToolButton* helpButton=new QToolButton(QPixmap(help_xpm),tr(" Rules of Play "),"",this,SLOT(help()),toolBar);
00131   CHECK_PTR(helpButton);
00132   helpButton->setMinimumSize(buttonSize);
00133 
00134   // Make a checkers board
00135 
00136   imageMan1=new QImage(man_black_xpm);   CHECK_PTR(imageMan1);
00137   imageMan2=new QImage(man_white_xpm);   CHECK_PTR(imageMan2);
00138   imageKing1=new QImage(king_black_xpm); CHECK_PTR(imageKing1);
00139   imageKing2=new QImage(king_white_xpm); CHECK_PTR(imageKing2);
00140 
00141   imageWood1=new QImage(wood1_xpm);      CHECK_PTR(imageWood1);
00142   imageWood2=new QImage(wood2_xpm);      CHECK_PTR(imageWood2);
00143   imageWood3=new QImage(wood3_xpm);      CHECK_PTR(imageWood3);
00144   imageGreen1=new QImage(green1_xpm);    CHECK_PTR(imageGreen1);
00145   imageGreen2=new QImage(green2_xpm);    CHECK_PTR(imageGreen2);
00146   imageGreen3=new QImage(green3_xpm);    CHECK_PTR(imageGreen3);
00147   imageMarble1=new QImage(marble1_xpm);  CHECK_PTR(imageMarble1);
00148   imageMarble2=new QImage(marble2_xpm);  CHECK_PTR(imageMarble2);
00149   imageMarble3=new QImage(marble3_xpm);  CHECK_PTR(imageMarble3);
00150 
00151   QWidget* centralWidget=new QWidget(this);
00152   setCentralWidget(centralWidget);
00153 
00154   QFrame* frame=new QFrame(centralWidget);
00155   CHECK_PTR(frame);
00156   frame->setFrameStyle(QFrame::Box|QFrame::Plain);
00157   frame->setFixedSize(SIZE*8+2,SIZE*8+2);
00158 
00159   statusLabel = new QLabel(centralWidget);
00160   statusLabel->setAlignment(Qt::AlignHCenter);
00161 
00162   QVBoxLayout* vlayout=new QVBoxLayout(centralWidget);
00163 
00164   vlayout->addStretch();
00165   vlayout->addWidget(frame);
00166   vlayout->addStretch();
00167   vlayout->addWidget(statusLabel);
00168   vlayout->addStretch();
00169 
00170   for(int i=0;i<64;i++)
00171   {
00172     field[i]=new Field(frame,i);
00173     CHECK_PTR(field[i]);
00174   }
00175 
00176   QGridLayout* grid=new QGridLayout(frame,8,8,1,0);
00177   CHECK_PTR(grid);
00178 
00179   for(int i=0;i<4;i++)
00180   {
00181     for(int k=0;k<4;k++)
00182     {
00183       grid->addWidget(field[i*8+k+32],i*2,  k*2  );
00184       grid->addWidget(field[i*8+k   ],i*2,  k*2+1);
00185       grid->addWidget(field[i*8+k+4 ],i*2+1,k*2  );
00186       grid->addWidget(field[i*8+k+36],i*2+1,k*2+1);
00187     }
00188   }
00189 
00190   for(int i=0;i<32;i++)
00191     connect(field[i],SIGNAL(click(int)),this,SLOT(click(int)));
00192 
00193   selected=false;
00194 
00195   setPattern(pattern);
00196 
00197   QWhatsThis::add(frame,"A checkers board");
00198 
00199   userFirst=false;
00200 
00201   game=NULL;
00202   newGame();
00203 }
00204 
00205 
00206 void KCheckers::readConfig()
00207 {
00208   Config config("KCheckers");
00209   config.setGroup("KCheckers");
00210   QString entry;
00211 
00212   entry=config.readEntry("skill","novice");
00213   if(entry=="beginner")     skill=BEGINNER;
00214   else if(entry=="average") skill=AVERAGE;
00215   else if(entry=="good")    skill=GOOD;
00216   else if(entry=="expert")  skill=EXPERT;
00217   else if(entry=="master")  skill=MASTER;
00218   else skill=NOVICE;
00219 
00220   entry=config.readEntry("rules","english");
00221   if(entry=="russian") rules=RUSSIAN;
00222   else rules=ENGLISH;
00223 
00224   entry=config.readEntry("theme","wooden");
00225   if(entry=="green")       pattern=GREEN;
00226   else if(entry=="marble") pattern=MARBLE;
00227   else pattern=WOODEN;
00228 }
00229 
00230 
00231 void KCheckers::closeEvent(QCloseEvent* event)
00232 {
00233   Config config("KCheckers");
00234   config.setGroup("KCheckers");
00235   QString entry;
00236 
00237   if(skill==BEGINNER) entry="beginner";
00238   if(skill==NOVICE)   entry="novice";
00239   if(skill==AVERAGE)  entry="average";
00240   if(skill==GOOD)     entry="good";
00241   if(skill==EXPERT)   entry="expert";
00242   if(skill==MASTER)   entry="master";
00243   config.writeEntry("skill",entry);
00244 
00245   if(rules==ENGLISH) entry="english";
00246   if(rules==RUSSIAN) entry="russian";
00247   config.writeEntry("rules",entry);
00248 
00249   if(pattern==GREEN)  entry="green";
00250   if(pattern==MARBLE) entry="marble";
00251   if(pattern==WOODEN) entry="wooden";
00252   config.writeEntry("theme",entry);
00253 
00254   event->accept();
00255 }
00256 
00257 
00258 void KCheckers::setSkill(int set)
00259 {
00260   skillMenu->setItemChecked(skill,false);
00261 
00262   skill=set;
00263   skillMenu->setItemChecked(skill,true);
00264 
00265   game->setLevel(skill);
00266 }
00267 
00268 
00269 void KCheckers::setRules(int set)
00270 {
00271   optionsMenu->setItemChecked(rules,false);
00272 
00273   rules=set;
00274   optionsMenu->setItemChecked(rules,true);
00275 
00276   colorChange();
00277   newGame();
00278 }
00279 
00280 
00281 void KCheckers::setPattern(int set)
00282 {
00283   optionsMenu->setItemChecked(pattern,false);
00284 
00285   pattern=set;
00286   optionsMenu->setItemChecked(pattern,true);
00287 
00288   switch(pattern)
00289   {
00290     case GREEN:
00291       imagePat1=imageGreen1;
00292       imagePat2=imageGreen2;
00293       imageFrame=imageGreen3;
00294       break;
00295     case MARBLE:
00296       imagePat1=imageMarble1;
00297       imagePat2=imageMarble2;
00298       imageFrame=imageMarble3;
00299       break;
00300     case WOODEN:
00301       imagePat1=imageWood1;
00302       imagePat2=imageWood2;
00303       imageFrame=imageWood3;
00304   }
00305 
00306   for(int i=0; i<32;i++) field[i]->setPattern(imagePat2);
00307   for(int i=32;i<64;i++) field[i]->setPattern(imagePat1);
00308 
00309   if(selected) field[from]->setFrame(imageFrame);
00310 }
00311 
00312 
00313 void KCheckers::showNumeration()
00314 {
00315   if(optionsMenu->isItemChecked(numID))
00316   {
00317     optionsMenu->setItemChecked(numID,false);
00318     for(int i=0;i<32;i++) field[i]->setLabel("");
00319   }
00320   else
00321   {
00322     optionsMenu->setItemChecked(numID,true);
00323     drawNumeration();
00324   }
00325 }
00326 
00327 
00328 void KCheckers::drawNumeration()
00329 {
00330   if(rules==ENGLISH)
00331   {
00332     if(userFirst)
00333       for(int i=0;i<32;i++)
00334         field[i]->setLabel(enNumeration.mid(i*2,2));
00335     else
00336       for(int i=0;i<32;i++)
00337         field[i]->setLabel(enNumeration.mid(62-i*2,2));
00338   }
00339   else
00340   {
00341     if(userFirst)
00342       for(int i=0;i<32;i++)
00343         field[i]->setLabel(ruNumeration.mid(i*2,2));
00344     else
00345       for(int i=0;i<32;i++)
00346         field[i]->setLabel(ruNumeration.mid(62-i*2,2));
00347   }
00348 }
00349 
00350 
00351 void KCheckers::drawBoard(int i)
00352 {
00353   switch(game->board[t[i]])
00354   {
00355     case MAN1:
00356       field[i]->setPicture(imageMan1);
00357       break;
00358     case MAN2:
00359       field[i]->setPicture(imageMan2);
00360       break;
00361     case KING1:
00362       field[i]->setPicture(imageKing1);
00363       break;
00364     case KING2:
00365       field[i]->setPicture(imageKing2);
00366       break;
00367     default:
00368       field[i]->setPicture(NULL);
00369   }
00370 }
00371 
00372 
00373 void KCheckers::help()
00374 {
00375   QMessageBox::information(this,"Rules of Play",
00376     "In the beginning of game you have\n"
00377     "12 checkers (men).\n"
00378     "The men move forward only.\n"
00379     "The men can capture:\n"
00380     "- by jumping forward only (english\n"
00381     "  rules);\n"
00382     "- by jumping forward or backward\n"
00383     "  (russian rules).\n"
00384     "A man which reaches the far side of\n"
00385     "the board becomes a king.\n"
00386     "The kings move forward or\n"
00387     "backward:\n"
00388     "- to one square only (english rules);\n"
00389     "- to any number of squares (russian\n"
00390     "  rules).\n"
00391     "The kings capture by jumping\n"
00392     "forward or backward.\n"
00393     "Whenever a player is able to make a\n"
00394     "capture he must do so.",
00395     QMessageBox::Ok|QMessageBox::Default);
00396 }
00397 
00398 
00399 void KCheckers::about()
00400 {
00401   QMessageBox::about(this,"About KCheckers",
00402     "KCheckers, a board game. Ver 0.3\n"
00403     "(C) 2002, A. Peredri <andi@ukr.net>\n\n"
00404     "http://kcheckers.tuxfamily.org\n\n"
00405     "Contributors:\n"
00406     "S. Rosen <srosen@erols.com>\n\n"
00407     "Qtopia version: S.Prud'homme\n"
00408     "<prudhomme@laposte.net>\n\n"
00409     "This program is distributed under the\n"
00410     "terms of the GNU General Public\n"
00411     "License.");
00412 }
00413 
00414 
00415 void KCheckers::aboutQt()
00416 {
00417   QMessageBox::aboutQt(this);
00418 }
00419 
00420 
00421 void KCheckers::newGame()
00422 {
00423   if(game) delete game;
00424 
00425   switch(rules)
00426   {
00427     case ENGLISH:
00428       game=new ECheckers(skill);
00429       CHECK_PTR(game);
00430       break;
00431 
00432     case RUSSIAN:
00433       game=new RCheckers(skill);
00434       CHECK_PTR(game);
00435   }
00436 
00437   unselect();
00438   gameOver=false;
00439 
00440   gameMenu->setItemEnabled(undoID,false);
00441   undoButton->setEnabled(false);
00442 
00443   colorChange();
00444 
00445   for(int i=0;i<32;i++) drawBoard(i);
00446   if(optionsMenu->isItemChecked(numID)) drawNumeration();
00447 
00448   if(!userFirst) compGo();
00449 
00450   statusLabel->setText(tr("Go!"));
00451 }
00452 
00453 
00454 // Undo the last computer and user moves
00455 
00456 void KCheckers::undoMove()
00457 {
00458   for(int i=0;i<32;i++)
00459   {
00460     game->board[t[i]]=undoBoard[i];
00461     drawBoard(i);
00462   }
00463 
00464   unselect();
00465   gameOver=false;
00466 
00467   gameMenu->setItemEnabled(undoID,false);
00468   undoButton->setEnabled(false);
00469 
00470   statusLabel->setText(tr("Go!"));
00471 }
00472 
00473 
00474 void KCheckers::colorChange()
00475 {
00476   userFirst=!userFirst;
00477 
00478   QImage* image;
00479   image=imageMan1;
00480   imageMan1=imageMan2;
00481   imageMan2=image;
00482   image=imageKing1;
00483   imageKing1=imageKing2;
00484   imageKing2=image;
00485 }
00486 
00487 
00488 void KCheckers::unselect()
00489 {
00490   if(selected) field[from]->setFrame(NULL);
00491   selected=false;
00492 }
00493 
00494 
00495 void KCheckers::click(int fieldNumber)
00496 {
00497   if(gameOver) return;
00498   switch(game->board[t[fieldNumber]])
00499   {
00500     case MAN1:
00501     case KING1:
00502       // User selected
00503       if(!selected)
00504       {
00505         from=fieldNumber;
00506         selected=true;
00507         field[fieldNumber]->setFrame(imageFrame);
00508         return;
00509       }
00510       // User reselected
00511       else
00512       {
00513         field[from]->setFrame(NULL);
00514         from=fieldNumber;
00515         field[fieldNumber]->setFrame(imageFrame);
00516         return;
00517       }
00518     case FREE:
00519       if(!selected) return;
00520 
00521       if(!userGo(fieldNumber)) return;
00522 
00523       unselect();
00524 
00525       if(!(game->checkMove2() || game->checkCapture2()))
00526       {
00527         gameOver=true;
00528         statusLabel->setText(tr("Congratulation! You have won!"));
00529         return;
00530       }
00531 
00532       statusLabel->setText(tr("Please wait..."));
00533       qApp->processEvents();
00534 
00535       compGo();
00536       if(!(game->checkMove1() || game->checkCapture1()))
00537       {
00538         gameOver=true;
00539         statusLabel->setText(tr("You have lost. Game over."));
00540         return;
00541       }
00542       statusLabel->setText(tr("Go!"));
00543   }
00544 }
00545 
00546 
00547 void KCheckers::compGo()
00548 {
00549   int save[32];
00550   for(int i=0;i<32;i++) save[i]=game->board[t[i]];
00551 
00552   game->go2();
00553 
00554   for(int i=0;i<32;i++)
00555   {
00556     if(game->board[t[i]]==save[i]) continue;
00557     drawBoard(i);
00558   }
00559 }
00560 
00561 
00562 bool KCheckers::userGo(int to)
00563 {
00564   int save[32];
00565   for(int i=0;i<32;i++) save[i]=game->board[t[i]];
00566 
00567   if(!game->go1(t[from],t[to]))
00568   {
00569     statusLabel->setText(tr("Incorrect course."));
00570     return false;
00571   }
00572 
00573   for(int i=0;i<32;i++) undoBoard[i]=save[i];
00574   gameMenu->setItemEnabled(undoID,true);
00575   undoButton->setEnabled(true);
00576 
00577   for(int i=0;i<32;i++)
00578   {
00579     if(game->board[t[i]]==save[i]) continue;
00580     drawBoard(i);
00581   }
00582 
00583   return true;
00584 }
00585 
00586 

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