author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /noncore/games/go/gowidget.cpp | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
Diffstat (limited to 'noncore/games/go/gowidget.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/games/go/gowidget.cpp | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/noncore/games/go/gowidget.cpp b/noncore/games/go/gowidget.cpp new file mode 100644 index 0000000..fca9797 --- a/dev/null +++ b/noncore/games/go/gowidget.cpp | |||
@@ -0,0 +1,449 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "gowidget.h" | ||
22 | |||
23 | #include <qpe/config.h> | ||
24 | #include <qpe/resource.h> | ||
25 | |||
26 | #include <qpainter.h> | ||
27 | #include <qpixmap.h> | ||
28 | #include <qpe/qpetoolbar.h> | ||
29 | #include <qpe/qpemenubar.h> | ||
30 | #include <qpopupmenu.h> | ||
31 | #include <qaction.h> | ||
32 | #include <qapplication.h> //processEvents() | ||
33 | #include <qlabel.h> | ||
34 | |||
35 | //#include <stdio.h> | ||
36 | |||
37 | #include "amigo.h" | ||
38 | #include "goplayutils.h" | ||
39 | |||
40 | static const enum bVal computer_color = BLACK; | ||
41 | |||
42 | static int current_handicap = 1; | ||
43 | |||
44 | static QBrush *goBrush; | ||
45 | //static QImage *newBlackStone; | ||
46 | //static QImage *blackStone; | ||
47 | //static QImage *whiteStone; | ||
48 | static QPixmap *newBlackStone; | ||
49 | static QPixmap *blackStone; | ||
50 | static QPixmap *whiteStone; | ||
51 | |||
52 | GoMainWidget::GoMainWidget( QWidget *parent, const char* name) : | ||
53 | QMainWindow( parent, name ) | ||
54 | { | ||
55 | setToolBarsMovable( FALSE ); | ||
56 | GoWidget *go = new GoWidget(this); | ||
57 | |||
58 | setCentralWidget(go); | ||
59 | toolbar = new QPEToolBar(this); | ||
60 | toolbar->setHorizontalStretchable( TRUE ); | ||
61 | addToolBar(toolbar); | ||
62 | |||
63 | QPEMenuBar *mb = new QPEMenuBar( toolbar ); | ||
64 | mb->setMargin(0); | ||
65 | QPopupMenu *file = new QPopupMenu( this ); | ||
66 | |||
67 | QAction *a = new QAction( tr( "New Game" ), QString::null, 0, this, 0 ); | ||
68 | connect( a, SIGNAL( activated() ), go, SLOT( newGame() ) ); | ||
69 | a->addTo( file ); | ||
70 | |||
71 | a = new QAction( tr( "Pass" ), Resource::loadPixmap( "pass" ), QString::null, 0, this, 0 ); | ||
72 | connect( a, SIGNAL( activated() ), go, SLOT( pass() ) ); | ||
73 | a->addTo( file ); | ||
74 | a->addTo( toolbar ); | ||
75 | |||
76 | |||
77 | a = new QAction( tr( "Resign" ), Resource::loadPixmap( "reset" ), QString::null, 0, this, 0 ); | ||
78 | connect( a, SIGNAL( activated() ), go, SLOT( resign() ) ); | ||
79 | a->addTo( file ); | ||
80 | |||
81 | a = new QAction( tr( "Two player option" ), QString::null, 0, this, 0 ); | ||
82 | a->setToggleAction( TRUE ); | ||
83 | connect( a, SIGNAL( toggled(bool) ), go, SLOT( setTwoplayer(bool) ) ); | ||
84 | a->addTo( file ); | ||
85 | |||
86 | mb->insertItem( tr( "Game" ), file ); | ||
87 | |||
88 | QLabel *turnLabel = new QLabel( toolbar ); | ||
89 | turnLabel->setBackgroundMode( PaletteButton ); | ||
90 | connect( go, SIGNAL(showTurn(const QPixmap&)), | ||
91 | turnLabel, SLOT(setPixmap(const QPixmap&)) ); | ||
92 | |||
93 | |||
94 | QLabel * scoreLabel = new QLabel( toolbar ); | ||
95 | scoreLabel->setBackgroundMode( PaletteButton ); | ||
96 | connect( go, SIGNAL(showScore(const QString&)), | ||
97 | scoreLabel, SLOT(setText(const QString&)) ); | ||
98 | |||
99 | toolbar->setStretchableWidget( scoreLabel ); | ||
100 | |||
101 | go->readConfig(); | ||
102 | } | ||
103 | |||
104 | void GoMainWidget::resizeEvent( QResizeEvent * ) | ||
105 | { | ||
106 | //### this won't work because of the text label... | ||
107 | /* | ||
108 | if ( width() > height() ) | ||
109 | moveToolBar( toolbar, Left ); | ||
110 | else | ||
111 | moveToolBar( toolbar, Top ); | ||
112 | */ | ||
113 | } | ||
114 | |||
115 | GoWidget *GoWidget::self = 0; | ||
116 | |||
117 | GoWidget::GoWidget( QWidget *parent, const char* name) : | ||
118 | QWidget( parent, name ) | ||
119 | { | ||
120 | if ( self ) | ||
121 | fatal( "Only one Go widget allowed" ); | ||
122 | self = this; | ||
123 | twoplayer = FALSE; | ||
124 | |||
125 | |||
126 | d = bx = by = 1; | ||
127 | |||
128 | QPixmap pix = Resource::loadPixmap( "pine" ); | ||
129 | goBrush = new QBrush( black, pix ); | ||
130 | /* | ||
131 | QString fn = Resource::findPixmap("Go-black"); | ||
132 | blackStone = new QImage( fn ); | ||
133 | fn = Resource::findPixmap("Go-black-highlight"); | ||
134 | newBlackStone = new QImage( fn ); | ||
135 | fn = Resource::findPixmap("Go-white"); | ||
136 | whiteStone = new QImage( fn ); | ||
137 | */ | ||
138 | blackStone = new QPixmap(Resource::loadPixmap( "Go-black" )); | ||
139 | whiteStone = new QPixmap(Resource::loadPixmap( "Go-white" )); | ||
140 | newBlackStone = new QPixmap(Resource::loadPixmap( "Go-black-highlight" )); | ||
141 | |||
142 | init(); | ||
143 | } | ||
144 | |||
145 | GoWidget::~GoWidget() | ||
146 | { | ||
147 | writeConfig(); | ||
148 | } | ||
149 | |||
150 | void GoWidget::writeConfig() | ||
151 | { | ||
152 | Config cfg("Go"); | ||
153 | cfg.setGroup("Game"); | ||
154 | cfg.writeEntry("TwoPlayer", twoplayer); | ||
155 | cfg.writeEntry("CurrentPlayer", currentPlayer); | ||
156 | cfg.writeEntry("NPassed", nPassed); | ||
157 | QString b; | ||
158 | for (int i=0; i<19; i++) | ||
159 | for (int j=0; j<19; j++) | ||
160 | b += board[i][j] == BLACK ? 'B' : board[i][j] == WHITE ? 'W' : '.'; | ||
161 | cfg.writeEntry("Board", b); | ||
162 | cfg.writeEntry("LastX", lastX); | ||
163 | cfg.writeEntry("LastY", lastY); | ||
164 | extern int blackPrisoners, whitePrisoners; | ||
165 | cfg.writeEntry("BlackPrisoners", blackPrisoners); | ||
166 | cfg.writeEntry("WhitePrisoners", whitePrisoners); | ||
167 | } | ||
168 | |||
169 | void GoWidget::readConfig() | ||
170 | { | ||
171 | init(); | ||
172 | Config cfg("Go"); | ||
173 | cfg.setGroup("Game"); | ||
174 | twoplayer = cfg.readBoolEntry("TwoPlayer"); | ||
175 | currentPlayer = (bVal)cfg.readNumEntry("CurrentPlayer",1); | ||
176 | nPassed = cfg.readNumEntry("NPassed",0); | ||
177 | QString b = cfg.readEntry("Board"); | ||
178 | if ( b.length() == 19*19 ) | ||
179 | for (int i=0; i<19; i++) | ||
180 | for (int j=0; j<19; j++) { | ||
181 | QChar ch = b[j+19*i]; | ||
182 | if ( ch != '.' ) | ||
183 | GoPlaceStone( ch == 'B' ? BLACK : WHITE, i, j ); | ||
184 | } | ||
185 | lastX = cfg.readNumEntry("LastX"); | ||
186 | lastY = cfg.readNumEntry("LastY"); | ||
187 | extern int blackPrisoners, whitePrisoners; | ||
188 | blackPrisoners = cfg.readNumEntry("BlackPrisoners",0); | ||
189 | whitePrisoners = cfg.readNumEntry("WhitePrisoners",0); | ||
190 | reportPrisoners(blackPrisoners,whitePrisoners); | ||
191 | emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone ); | ||
192 | } | ||
193 | |||
194 | void GoWidget::resizeEvent( QResizeEvent * ) | ||
195 | { | ||
196 | d = QMIN(width(),height())/19; | ||
197 | // int r = (d/2-1); | ||
198 | bx = (width() - 18*d)/2 ; | ||
199 | by = (height() - 18*d)/2 ; | ||
200 | } | ||
201 | |||
202 | void GoWidget::init() | ||
203 | { | ||
204 | lastX = lastY = newX = newY = -1; | ||
205 | nPassed = 0; | ||
206 | for ( int i = 0; i < 19; i++ ) | ||
207 | for ( int j = 0; j < 19; j++ ) | ||
208 | board[i][j]=-1; | ||
209 | gameActive = TRUE; | ||
210 | goRestart(current_handicap); | ||
211 | |||
212 | if ( twoplayer ) { | ||
213 | currentPlayer = BLACK; | ||
214 | } else { | ||
215 | doComputerMove(); | ||
216 | currentPlayer = WHITE; | ||
217 | } | ||
218 | emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone ); | ||
219 | } | ||
220 | |||
221 | void GoWidget::paintEvent( QPaintEvent *e ) | ||
222 | { | ||
223 | int i,j; | ||
224 | |||
225 | int r = whiteStone->width()/2; | ||
226 | |||
227 | QPainter p(this); | ||
228 | p.fillRect( bx - d/2, by - d/2, 19*d, 19*d, *goBrush ); | ||
229 | |||
230 | int xMin = QMAX( x2board(e->rect().left()), 0 ); | ||
231 | int xMax = QMIN( x2board(e->rect().right()), 18 ); | ||
232 | int yMin = QMAX( y2board(e->rect().top()), 0 ); | ||
233 | int yMax = QMIN( y2board(e->rect().bottom()), 18 ); | ||
234 | |||
235 | QColor pine( 255, 186, 89 ); | ||
236 | p.setPen( pine.dark() ); | ||
237 | |||
238 | for ( i = xMin; i < xMax+1 ; i ++ ) { | ||
239 | p.drawLine( bx+i*d, by, bx+i*d, by+18*d ); | ||
240 | } | ||
241 | for ( j = yMin; j < yMax+1 ; j ++ ) { | ||
242 | p.drawLine( bx, by+j*d, bx+18*d, by+j*d); | ||
243 | } | ||
244 | |||
245 | // dots are at (3,3), (3,9), (3,15) and so on | ||
246 | p.setBrush( black ); | ||
247 | for ( i = 3; i < xMax+1; i+=6 ) | ||
248 | for ( j = 3; j < yMax+1; j+=6 ) | ||
249 | p.drawEllipse( bx+i*d-2, by+j*d-2, 5, 5 ); | ||
250 | |||
251 | |||
252 | for ( i = xMin; i < xMax+1; i++ ) | ||
253 | for ( j = yMin; j < yMax+1; j++ ) { | ||
254 | if ( board[i][j] == WHITE || | ||
255 | currentPlayer==WHITE && newX == i && newY == j ) | ||
256 | p.drawPixmap( bx+i*d - r, by+j*d - r, *whiteStone ); | ||
257 | else if ( i == lastX && j == lastY ) | ||
258 | p.drawPixmap( bx+i*d - r, by+j*d - r, *newBlackStone ); | ||
259 | else if ( board[i][j] == BLACK || | ||
260 | currentPlayer==BLACK && newX == i && newY == j) | ||
261 | p.drawPixmap( bx+i*d - r, by+j*d - r, *blackStone ); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | void GoWidget::doMove( int x, int y ) | ||
266 | { | ||
267 | |||
268 | if ( !GoPlaceStone( currentPlayer, x, y ) ) { | ||
269 | //printf( "Illegal move (%d,%d)\n", x, y ); | ||
270 | return; | ||
271 | } | ||
272 | //printf( "you do (%d,%d)\n", x, y ); | ||
273 | nPassed = 0; | ||
274 | if ( twoplayer ) | ||
275 | currentPlayer = (currentPlayer==WHITE) ? BLACK : WHITE; | ||
276 | else | ||
277 | doComputerMove(); | ||
278 | |||
279 | emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone ); | ||
280 | |||
281 | } | ||
282 | |||
283 | void GoWidget::pass() | ||
284 | { | ||
285 | if ( !gameActive ) | ||
286 | return; | ||
287 | nPassed++; | ||
288 | if ( nPassed >= 2 ) | ||
289 | endGame(); | ||
290 | else if ( !twoplayer ) | ||
291 | doComputerMove(); | ||
292 | } | ||
293 | |||
294 | void GoWidget::resign() | ||
295 | { | ||
296 | if ( gameActive ) | ||
297 | endGame(); | ||
298 | } | ||
299 | |||
300 | |||
301 | void GoWidget::newGame() | ||
302 | { | ||
303 | init(); | ||
304 | update(); | ||
305 | } | ||
306 | |||
307 | |||
308 | void GoWidget::endGame() | ||
309 | { | ||
310 | gameActive = FALSE; | ||
311 | |||
312 | int w,b; | ||
313 | CountUp( &w, &b); | ||
314 | QString s = tr("White %1, Black %2. ").arg(w).arg(b); | ||
315 | if ( w > b ) | ||
316 | s += tr("White wins."); | ||
317 | else if ( w < b ) | ||
318 | s += tr("Black wins."); | ||
319 | else | ||
320 | s += tr("A draw."); | ||
321 | emit showScore( s ); | ||
322 | } | ||
323 | |||
324 | void GoWidget::doComputerMove() | ||
325 | { | ||
326 | int ox = lastX; | ||
327 | int oy = lastY; | ||
328 | lastX = lastY = -1; | ||
329 | emit showTurn( *blackStone ); | ||
330 | refresh( ox, oy); | ||
331 | qApp->processEvents(); | ||
332 | short int x,y; | ||
333 | if ( genMove( computer_color, &x, &y ) ) { | ||
334 | lastX = x; | ||
335 | lastY = y; | ||
336 | //printf( "I do (%d,%d)\n", x, y ); | ||
337 | GoPlaceStone(computer_color,x,y); | ||
338 | nPassed = 0; | ||
339 | } else { | ||
340 | emit showScore( tr("I pass") ); | ||
341 | nPassed++; | ||
342 | if ( nPassed >= 2 ) | ||
343 | endGame(); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | void GoWidget::mousePressEvent( QMouseEvent *me ) | ||
348 | { | ||
349 | if ( !gameActive ) | ||
350 | return; | ||
351 | int x = x2board(me->x()); | ||
352 | int y = y2board(me->y()); | ||
353 | showStone(x,y,currentPlayer); | ||
354 | } | ||
355 | |||
356 | void GoWidget::mouseMoveEvent( QMouseEvent *me ) | ||
357 | { | ||
358 | if ( !gameActive ) | ||
359 | return; | ||
360 | int x = x2board(me->x()); | ||
361 | int y = y2board(me->y()); | ||
362 | if ( x != newX || y != newY ) | ||
363 | showStone(x,y,currentPlayer); | ||
364 | } | ||
365 | |||
366 | void GoWidget::showStone( int x, int y, enum bVal c ) | ||
367 | { | ||
368 | |||
369 | if ( newX > -1 ) { | ||
370 | refresh( newX, newY ); | ||
371 | newY = newX = -1; | ||
372 | } | ||
373 | if ( x < 0 || x > 18 || y < 0 || y > 18 ) { | ||
374 | newX = newY = -1; | ||
375 | return; | ||
376 | } | ||
377 | if ( board[x][y] == -1 && !Suicide( c, x, y ) ) { | ||
378 | newX = x; | ||
379 | newY = y; | ||
380 | refresh(x,y); | ||
381 | } | ||
382 | |||
383 | } | ||
384 | |||
385 | void GoWidget::mouseReleaseEvent( QMouseEvent * ) | ||
386 | { | ||
387 | if ( gameActive && newX > -1 ) | ||
388 | doMove( newX, newY ); | ||
389 | newX = newY = -1; | ||
390 | } | ||
391 | |||
392 | void GoWidget::refresh( int x, int y ) | ||
393 | { | ||
394 | update( bx+d*x-d/2-1, by+d*y-d/2-1, d+2, d+2 ); | ||
395 | } | ||
396 | |||
397 | void GoWidget::removeStone(short x, short y) | ||
398 | { | ||
399 | board[x][y]=-1; | ||
400 | refresh( x, y ); | ||
401 | } | ||
402 | |||
403 | void GoWidget::placeStone (enum bVal c, short x, short y ) | ||
404 | { | ||
405 | board[x][y]=c; | ||
406 | refresh( x, y ); | ||
407 | } | ||
408 | |||
409 | void GoWidget::reportPrisoners( int blackcnt, int whitecnt ) | ||
410 | { | ||
411 | QString s = tr( "Prisoners: black %1, white %2" ).arg(blackcnt).arg(whitecnt); | ||
412 | emit showScore( s ); | ||
413 | } | ||
414 | |||
415 | void GoWidget::setTwoplayer( bool b ) | ||
416 | { | ||
417 | twoplayer = b; | ||
418 | } | ||
419 | |||
420 | void GoWidget::setHandicap( int h ) | ||
421 | { | ||
422 | current_handicap = h; | ||
423 | } | ||
424 | |||
425 | |||
426 | extern "C" { | ||
427 | |||
428 | voidremovestone(short x, short y) | ||
429 | { | ||
430 | GoWidget::self->removeStone(x,y); | ||
431 | } | ||
432 | |||
433 | voidplacestone (enum bVal c, short x, short y ) | ||
434 | { | ||
435 | GoWidget::self->placeStone(c,x,y); | ||
436 | } | ||
437 | |||
438 | voidintrMoveReport(enum bVal c ,char *coord ,char *reason ) | ||
439 | { | ||
440 | qDebug( "intrMoveReport colour %d, %s %s", c, coord, reason ); | ||
441 | } | ||
442 | |||
443 | voidintrPrisonerReport( short blackcnt, short whitecnt ) | ||
444 | { | ||
445 | GoWidget::self->reportPrisoners(blackcnt,whitecnt); | ||
446 | } | ||
447 | |||
448 | } | ||
449 | |||