summaryrefslogtreecommitdiff
path: root/noncore/games/go/gowidget.cpp
Unidiff
Diffstat (limited to 'noncore/games/go/gowidget.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/go/gowidget.cpp449
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
40static const enum bVal computer_color = BLACK;
41
42static int current_handicap = 1;
43
44static QBrush *goBrush;
45//static QImage *newBlackStone;
46//static QImage *blackStone;
47//static QImage *whiteStone;
48static QPixmap *newBlackStone;
49static QPixmap *blackStone;
50static QPixmap *whiteStone;
51
52GoMainWidget::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
104void 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
115GoWidget *GoWidget::self = 0;
116
117GoWidget::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
145GoWidget::~GoWidget()
146{
147 writeConfig();
148}
149
150void 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
169void 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
194void 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
202void 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
221void 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
265void 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
283void GoWidget::pass()
284{
285 if ( !gameActive )
286 return;
287 nPassed++;
288 if ( nPassed >= 2 )
289 endGame();
290 else if ( !twoplayer )
291 doComputerMove();
292}
293
294void GoWidget::resign()
295{
296 if ( gameActive )
297 endGame();
298}
299
300
301void GoWidget::newGame()
302{
303 init();
304 update();
305}
306
307
308void 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
324void 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
347void 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
356void 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
366void 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
385void GoWidget::mouseReleaseEvent( QMouseEvent * )
386{
387 if ( gameActive && newX > -1 )
388 doMove( newX, newY );
389 newX = newY = -1;
390}
391
392void 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
397void GoWidget::removeStone(short x, short y)
398{
399 board[x][y]=-1;
400 refresh( x, y );
401}
402
403void GoWidget::placeStone (enum bVal c, short x, short y )
404{
405 board[x][y]=c;
406 refresh( x, y );
407}
408
409void 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
415void GoWidget::setTwoplayer( bool b )
416{
417 twoplayer = b;
418}
419
420void GoWidget::setHandicap( int h )
421{
422 current_handicap = h;
423}
424
425
426extern "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