Diffstat (limited to 'noncore/games/kcheckers/kcheckers.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/games/kcheckers/kcheckers.cpp | 382 |
1 files changed, 382 insertions, 0 deletions
diff --git a/noncore/games/kcheckers/kcheckers.cpp b/noncore/games/kcheckers/kcheckers.cpp new file mode 100644 index 0000000..3df744e --- a/dev/null +++ b/noncore/games/kcheckers/kcheckers.cpp | |||
@@ -0,0 +1,382 @@ | |||
1 | |||
2 | #include <qimage.h> | ||
3 | #include <qframe.h> | ||
4 | #include <qlayout.h> | ||
5 | #include <qmenubar.h> | ||
6 | #include <qwhatsthis.h> | ||
7 | #include <qmessagebox.h> | ||
8 | #include <qapplication.h> | ||
9 | |||
10 | #include "kcheckers.h" | ||
11 | #include "echeckers.h" | ||
12 | #include "rcheckers.h" | ||
13 | |||
14 | #include "pics/exit.xpm" | ||
15 | #include "pics/logo.xpm" | ||
16 | #include "pics/wood1.xpm" | ||
17 | #include "pics/wood2.xpm" | ||
18 | #include "pics/wood3.xpm" | ||
19 | #include "pics/marble1.xpm" | ||
20 | #include "pics/marble2.xpm" | ||
21 | #include "pics/marble3.xpm" | ||
22 | #include "pics/biglogo.xpm" | ||
23 | #include "pics/man_black.xpm" | ||
24 | #include "pics/man_white.xpm" | ||
25 | #include "pics/king_black.xpm" | ||
26 | #include "pics/king_white.xpm" | ||
27 | #include "pics/contexthelp.xpm" | ||
28 | |||
29 | |||
30 | const int KCheckers::t[]={6,7,8,9,11,12,13,14,17,18,19,20,22,23, | ||
31 | 24,25,28,29,30,31,33,34,35,36,39,40,41,42,44,45,46,47}; | ||
32 | |||
33 | KCheckers::KCheckers():QMainWindow(0,0,WStyle_DialogBorder) | ||
34 | { | ||
35 | setCaption("KCheckers"); | ||
36 | setIcon(QPixmap(biglogo)); | ||
37 | showMaximized(); | ||
38 | |||
39 | QPopupMenu* gameMenu=new QPopupMenu; | ||
40 | gameMenu->insertItem(QPixmap(logo),tr("New"),this,SLOT(newGame())); | ||
41 | gameMenu->insertSeparator(); | ||
42 | gameMenu->insertItem(QPixmap(exit),tr("Quit"),qApp,SLOT(quit())); | ||
43 | |||
44 | skillMenu=new QPopupMenu; | ||
45 | |||
46 | skillMenu->insertItem(tr("Beginner"),this,SLOT(setSkillBeginner()),0,BEGINNER); | ||
47 | skillMenu->insertItem(tr("Novice"), this,SLOT(setSkillNovice()), 0,NOVICE); | ||
48 | skillMenu->insertItem(tr("Average"), this,SLOT(setSkillAverage()), 0,AVERAGE); | ||
49 | skillMenu->insertItem(tr("Good"), this,SLOT(setSkillGood()), 0,GOOD); | ||
50 | skillMenu->insertItem(tr("Expert"), this,SLOT(setSkillExpert()), 0,EXPERT); | ||
51 | skillMenu->insertItem(tr("Master"), this,SLOT(setSkillMaster()), 0,MASTER); | ||
52 | |||
53 | optionsMenu=new QPopupMenu; | ||
54 | |||
55 | optionsMenu->insertItem(tr("English Rules"),this,SLOT(setRulesEnglish()),0,ENGLISH); | ||
56 | optionsMenu->insertItem(tr("Russian Rules"),this,SLOT(setRulesRussian()),0,RUSSIAN); | ||
57 | optionsMenu->insertSeparator(); | ||
58 | optionsMenu->insertItem(tr("Marble Board"),this,SLOT(setPatternMarble()),0,MARBLE); | ||
59 | optionsMenu->insertItem(tr("Wooden Board"),this,SLOT(setPatternWood()), 0,WOOD); | ||
60 | |||
61 | QPopupMenu* helpMenu=new QPopupMenu; | ||
62 | |||
63 | helpMenu->insertItem(QPixmap(contexthelp),tr("What's This"),this,SLOT(whatsThis())); | ||
64 | helpMenu->insertSeparator(); | ||
65 | helpMenu->insertItem(QPixmap(logo),tr("About KCheckers"),this,SLOT(about())); | ||
66 | helpMenu->insertItem(tr("About &Qt"),this,SLOT(aboutQt())); | ||
67 | |||
68 | menuBar()->insertItem(tr("Game"), gameMenu); | ||
69 | menuBar()->insertItem(tr("Skill"), skillMenu); | ||
70 | menuBar()->insertItem(tr("Options"),optionsMenu); | ||
71 | menuBar()->insertItem(tr("Help"), helpMenu); | ||
72 | |||
73 | skill=NOVICE; | ||
74 | skillMenu->setItemChecked(skill,true); | ||
75 | |||
76 | rules=ENGLISH; | ||
77 | optionsMenu->setItemChecked(rules,true); | ||
78 | |||
79 | pattern=WOOD; | ||
80 | optionsMenu->setItemChecked(pattern,true); | ||
81 | |||
82 | imageMan1=new QImage(man_black); | ||
83 | imageMan2=new QImage(man_white); | ||
84 | imageKing1=new QImage(king_black); | ||
85 | imageKing2=new QImage(king_white); | ||
86 | |||
87 | imageWood1=new QImage(wood1); | ||
88 | imageWood2=new QImage(wood2); | ||
89 | imageWood3=new QImage(wood3); | ||
90 | imageMarble1=new QImage(marble1); | ||
91 | imageMarble2=new QImage(marble2); | ||
92 | imageMarble3=new QImage(marble3); | ||
93 | |||
94 | imagePat1=imageWood1; | ||
95 | imagePat2=imageWood2; | ||
96 | imageFrame=imageWood3; | ||
97 | |||
98 | QWidget* centralWidget=new QWidget(this); | ||
99 | setCentralWidget(centralWidget); | ||
100 | |||
101 | QFrame* frame=new QFrame(centralWidget); | ||
102 | frame->setFrameStyle(QFrame::Box|QFrame::Plain); | ||
103 | frame->setFixedSize(SIZE*8+2,SIZE*8+2); | ||
104 | |||
105 | QVBoxLayout* vlayout=new QVBoxLayout(centralWidget); | ||
106 | vlayout->addWidget(frame); | ||
107 | |||
108 | statusLabel = new QLabel(centralWidget); | ||
109 | vlayout->addWidget(statusLabel); | ||
110 | |||
111 | for(int i=0;i<64;i++) field[i]=new Field(frame,i); | ||
112 | |||
113 | QGridLayout* grid=new QGridLayout(frame,8,8,1,0); | ||
114 | |||
115 | for(int i=0;i<4;i++) | ||
116 | { | ||
117 | for(int k=0;k<4;k++) | ||
118 | { | ||
119 | grid->addWidget(field[i*8+k+32],i*2, k*2 ); | ||
120 | grid->addWidget(field[i*8+k ],i*2, k*2+1); | ||
121 | grid->addWidget(field[i*8+k+4 ],i*2+1,k*2 ); | ||
122 | grid->addWidget(field[i*8+k+36],i*2+1,k*2+1); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | for(int i=0;i<32;i++) | ||
127 | connect(field[i],SIGNAL(click(int)),this,SLOT(click(int))); | ||
128 | |||
129 | userFirst=false; | ||
130 | |||
131 | game=NULL; | ||
132 | newGame(); | ||
133 | } | ||
134 | |||
135 | |||
136 | void KCheckers::setSkill(int set) | ||
137 | { | ||
138 | skillMenu->setItemChecked(skill,false); | ||
139 | |||
140 | skill=set; | ||
141 | skillMenu->setItemChecked(skill,true); | ||
142 | |||
143 | game->setLevel(skill); | ||
144 | } | ||
145 | |||
146 | |||
147 | void KCheckers::setRules(int set) | ||
148 | { | ||
149 | optionsMenu->setItemChecked(rules,false); | ||
150 | |||
151 | rules=set; | ||
152 | optionsMenu->setItemChecked(rules,true); | ||
153 | |||
154 | colorChange(); | ||
155 | newGame(); | ||
156 | } | ||
157 | |||
158 | |||
159 | void KCheckers::setPattern(int set) | ||
160 | { | ||
161 | optionsMenu->setItemChecked(pattern,false); | ||
162 | |||
163 | pattern=set; | ||
164 | optionsMenu->setItemChecked(pattern,true); | ||
165 | |||
166 | switch(pattern) | ||
167 | { | ||
168 | case MARBLE: | ||
169 | imagePat1=imageMarble1; | ||
170 | imagePat2=imageMarble2; | ||
171 | imageFrame=imageMarble3; | ||
172 | break; | ||
173 | case WOOD: | ||
174 | imagePat1=imageWood1; | ||
175 | imagePat2=imageWood2; | ||
176 | imageFrame=imageWood3; | ||
177 | } | ||
178 | |||
179 | drawBoard(); | ||
180 | |||
181 | if(selected) field[from]->draw(imageFrame); | ||
182 | } | ||
183 | |||
184 | |||
185 | void KCheckers::about() | ||
186 | { | ||
187 | QMessageBox::about(this, "About", | ||
188 | "KCheckers, a board game. Ver 0.2\n" | ||
189 | "(C) 2002, A. Peredri <andi@ukr.net>\n\n" | ||
190 | "http://kcheckers.tuxfamily.org\n\n" | ||
191 | "Opie version by S.Prud'homme\n" | ||
192 | "<prudhomme@laposte.net>\n\n" | ||
193 | "http://opie.handhelds.org\n\n" | ||
194 | "This program is distributed under the\n" | ||
195 | "terms of the GNU General Public\n" | ||
196 | "License."); | ||
197 | } | ||
198 | |||
199 | |||
200 | void KCheckers::aboutQt() | ||
201 | { | ||
202 | QMessageBox::aboutQt(this); | ||
203 | } | ||
204 | |||
205 | |||
206 | void KCheckers::newGame() | ||
207 | { | ||
208 | if(game) | ||
209 | { | ||
210 | delete game; | ||
211 | QWhatsThis::remove(this); | ||
212 | } | ||
213 | |||
214 | switch(rules) | ||
215 | { | ||
216 | case ENGLISH: | ||
217 | game=new ECheckers(skill); | ||
218 | QWhatsThis::add(this, | ||
219 | "<b>Rules of English Checkers</b>" | ||
220 | "<ul>" | ||
221 | "<li>In the beginning of game you have<br>12 checkers (men)." | ||
222 | "<li>Men move forward only." | ||
223 | "<li>Men capture by jumping forward only." | ||
224 | "<li>A man which reaches the far side of<br>the board becomes a king." | ||
225 | "<li>Kings move forward or backward to<br>one square." | ||
226 | "<li>Kings capture by jumping forward or<br>backward." | ||
227 | "<li>Whenever a player is able to make<br> a capture he must do so." | ||
228 | "</ul>"); | ||
229 | break; | ||
230 | case RUSSIAN: | ||
231 | game=new RCheckers(skill); | ||
232 | QWhatsThis::add(this, | ||
233 | "<b>Rules of Russian Checkers</b>" | ||
234 | "<ul>" | ||
235 | "<li>In the beginning of game you have<br> 12 checkers (men)." | ||
236 | "<li>Men move forward only." | ||
237 | "<li>Men capture by jumping forward or<br>backward." | ||
238 | "<li>A man which reaches the far side of<br> the board becomes a king." | ||
239 | "<li>Kings move forward or backward to<br>any number of squares." | ||
240 | "<li>Kings capture by jumping forward or<br>backward." | ||
241 | "<li>Whenever a player is able to make<br> a capture he must do so." | ||
242 | "</ul>"); | ||
243 | } | ||
244 | |||
245 | selected=false; | ||
246 | gameOver=false; | ||
247 | |||
248 | colorChange(); | ||
249 | drawBoard(); | ||
250 | |||
251 | if(!userFirst) compGo(); | ||
252 | |||
253 | statusLabel->setText(tr("Go!")); | ||
254 | } | ||
255 | |||
256 | |||
257 | void KCheckers::colorChange() | ||
258 | { | ||
259 | userFirst=!userFirst; | ||
260 | |||
261 | QImage* image; | ||
262 | image=imageMan1; | ||
263 | imageMan1=imageMan2; | ||
264 | imageMan2=image; | ||
265 | image=imageKing1; | ||
266 | imageKing1=imageKing2; | ||
267 | imageKing2=image; | ||
268 | } | ||
269 | |||
270 | |||
271 | void KCheckers::drawBoard() | ||
272 | { | ||
273 | // Drawing of start position | ||
274 | for(int i=0;i<32;i++) | ||
275 | { | ||
276 | field[i]->draw(imagePat2); | ||
277 | if(game->getBoard(t[i])==MAN1) field[i]->draw(imageMan1); | ||
278 | else if(game->getBoard(t[i])==MAN2) field[i]->draw(imageMan2); | ||
279 | else if(game->getBoard(t[i])==KING1) field[i]->draw(imageKing1); | ||
280 | else if(game->getBoard(t[i])==KING2) field[i]->draw(imageKing2); | ||
281 | } | ||
282 | |||
283 | for(int i=32;i<64;i++) field[i]->draw(imagePat1); | ||
284 | } | ||
285 | |||
286 | |||
287 | void KCheckers::click(int fieldNumber) | ||
288 | { | ||
289 | if(gameOver) return; | ||
290 | switch(game->getBoard(t[fieldNumber])) | ||
291 | { | ||
292 | case MAN1: | ||
293 | case KING1: | ||
294 | // User selected | ||
295 | if(!selected) | ||
296 | { | ||
297 | from=fieldNumber; | ||
298 | selected=true; | ||
299 | field[fieldNumber]->draw(imageFrame); | ||
300 | return; | ||
301 | } | ||
302 | // User reselected | ||
303 | else | ||
304 | { | ||
305 | field[from]->draw(imagePat2); | ||
306 | if(game->getBoard(t[from])==MAN1) field[from]->draw(imageMan1); | ||
307 | else field[from]->draw(imageKing1); | ||
308 | from=fieldNumber; | ||
309 | field[fieldNumber]->draw(imageFrame); | ||
310 | return; | ||
311 | } | ||
312 | case FREE: | ||
313 | if(!selected) return; | ||
314 | |||
315 | if(!userGo(fieldNumber)) return; | ||
316 | selected=false; | ||
317 | |||
318 | if(!(game->checkMove2() || game->checkCapture2())) | ||
319 | { | ||
320 | gameOver=true; | ||
321 | statusLabel->setText(tr("Congratulation! You have won!")); | ||
322 | return; | ||
323 | } | ||
324 | |||
325 | statusLabel->setText(tr("Please wait...")); | ||
326 | qApp->processEvents(); | ||
327 | |||
328 | compGo(); | ||
329 | if(!(game->checkMove1() || game->checkCapture1())) | ||
330 | { | ||
331 | gameOver=true; | ||
332 | statusLabel->setText(tr("You have lost. Game over.")); | ||
333 | return; | ||
334 | } | ||
335 | statusLabel->setText(tr("Go!")); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | |||
340 | void KCheckers::compGo() | ||
341 | { | ||
342 | int save[32]; | ||
343 | for(int i=0;i<32;i++) save[i]=game->getBoard(t[i]); | ||
344 | |||
345 | game->go2(); | ||
346 | |||
347 | for(int i=0;i<32;i++) | ||
348 | { | ||
349 | if(game->getBoard(t[i])==save[i]) continue; | ||
350 | field[i]->draw(imagePat2); | ||
351 | if(game->getBoard(t[i])==MAN1) field[i]->draw(imageMan1); | ||
352 | else if(game->getBoard(t[i])==MAN2) field[i]->draw(imageMan2); | ||
353 | else if(game->getBoard(t[i])==KING1) field[i]->draw(imageKing1); | ||
354 | else if(game->getBoard(t[i])==KING2) field[i]->draw(imageKing2); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | |||
359 | bool KCheckers::userGo(int to) | ||
360 | { | ||
361 | int save[32]; | ||
362 | for(int i=0;i<32;i++) save[i]=game->getBoard(t[i]); | ||
363 | |||
364 | if(!game->go1(t[from],t[to])) | ||
365 | { | ||
366 | statusLabel->setText(tr("Incorrect course.")); | ||
367 | return false; | ||
368 | } | ||
369 | |||
370 | for(int i=0;i<32;i++) | ||
371 | { | ||
372 | if(game->getBoard(t[i])==save[i]) continue; | ||
373 | field[i]->draw(imagePat2); | ||
374 | if(game->getBoard(t[i])==MAN1) field[i]->draw(imageMan1); | ||
375 | else if(game->getBoard(t[i])==MAN2) field[i]->draw(imageMan2); | ||
376 | else if(game->getBoard(t[i])==KING1) field[i]->draw(imageKing1); | ||
377 | else if(game->getBoard(t[i])==KING2) field[i]->draw(imageKing2); | ||
378 | } | ||
379 | return true; | ||
380 | } | ||
381 | |||
382 | |||