-rw-r--r-- | noncore/games/tictac/tictac.cpp | 282 |
1 files changed, 143 insertions, 139 deletions
diff --git a/noncore/games/tictac/tictac.cpp b/noncore/games/tictac/tictac.cpp index 20cc942..3d727ac 100644 --- a/noncore/games/tictac/tictac.cpp +++ b/noncore/games/tictac/tictac.cpp | |||
@@ -1,12 +1,12 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | ** $Id$ | 2 | ** $Id$ |
3 | ** | 3 | ** |
4 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. | 4 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. |
5 | ** | 5 | ** |
6 | ** This file is part of an example program for Qt. This example | 6 | ** This file is part of an example program for Qt. This example |
7 | ** program may be used, distributed and modified without limitation. | 7 | ** program may be used, distributed and modified without limitation. |
8 | ** | 8 | ** |
9 | *****************************************************************************/ | 9 | *****************************************************************************/ |
10 | 10 | ||
11 | #include "tictac.h" | 11 | #include "tictac.h" |
12 | #include <qpe/qpeapplication.h> | 12 | #include <qpe/qpeapplication.h> |
@@ -16,8 +16,9 @@ | |||
16 | #include <qcheckbox.h> | 16 | #include <qcheckbox.h> |
17 | #include <qlabel.h> | 17 | #include <qlabel.h> |
18 | #include <qlayout.h> | 18 | #include <qlayout.h> |
19 | #include <stdlib.h> // rand() function | 19 | #include <stdlib.h> // rand() function |
20 | #include <qdatetime.h> // seed for rand() | 20 | #include <qdatetime.h> // seed for rand() |
21 | #include <qstringlist.h> //needed for proper internationalization | ||
21 | 22 | ||
22 | 23 | ||
23 | //*************************************************************************** | 24 | //*************************************************************************** |
@@ -30,7 +31,7 @@ | |||
30 | 31 | ||
31 | TicTacButton::TicTacButton( QWidget *parent ) : QPushButton( parent ) | 32 | TicTacButton::TicTacButton( QWidget *parent ) : QPushButton( parent ) |
32 | { | 33 | { |
33 | t = Blank; // initial type | 34 | t = Blank; // initial type |
34 | } | 35 | } |
35 | 36 | ||
36 | // -------------------------------------------------------------------------- | 37 | // -------------------------------------------------------------------------- |
@@ -40,12 +41,12 @@ TicTacButton::TicTacButton( QWidget *parent ) : QPushButton( parent ) | |||
40 | void TicTacButton::drawButtonLabel( QPainter *p ) | 41 | void TicTacButton::drawButtonLabel( QPainter *p ) |
41 | { | 42 | { |
42 | QRect r = rect(); | 43 | QRect r = rect(); |
43 | p->setPen( QPen( white,2 ) ); // set fat pen | 44 | p->setPen( QPen( white,2 ) ); // set fat pen |
44 | if ( t == Circle ) { | 45 | if ( t == Circle ) { |
45 | p->drawEllipse( r.left()+4, r.top()+4, r.width()-8, r.height()-8 ); | 46 | p->drawEllipse( r.left()+4, r.top()+4, r.width()-8, r.height()-8 ); |
46 | } else if ( t == Cross ) { // draw cross | 47 | } else if ( t == Cross ) { // draw cross |
47 | p->drawLine( r.topLeft() +QPoint(4,4), r.bottomRight()-QPoint(4,4)); | 48 | p->drawLine( r.topLeft() +QPoint(4,4), r.bottomRight()-QPoint(4,4)); |
48 | p->drawLine( r.bottomLeft()+QPoint(4,-4),r.topRight() -QPoint(4,-4)); | 49 | p->drawLine( r.bottomLeft()+QPoint(4,-4),r.topRight() -QPoint(4,-4)); |
49 | } | 50 | } |
50 | } | 51 | } |
51 | 52 | ||
@@ -60,27 +61,27 @@ void TicTacButton::drawButtonLabel( QPainter *p ) | |||
60 | // | 61 | // |
61 | 62 | ||
62 | TicTacGameBoard::TicTacGameBoard( int n, QWidget *parent, const char *name ) | 63 | TicTacGameBoard::TicTacGameBoard( int n, QWidget *parent, const char *name ) |
63 | : QWidget( parent, name ) | 64 | : QWidget( parent, name ) |
64 | { | 65 | { |
65 | showMaximized(); | 66 | showMaximized(); |
66 | st = Init; // initial state | 67 | st = Init; // initial state |
67 | nBoard = n; | 68 | nBoard = n; |
68 | n *= n; // make square | 69 | n *= n; // make square |
69 | comp_starts = FALSE; // human starts | 70 | comp_starts = FALSE; // human starts |
70 | buttons = new TicTacButtons(n); // create real buttons | 71 | buttons = new TicTacButtons(n); // create real buttons |
71 | btArray = new TicTacArray(n); // create button model | 72 | btArray = new TicTacArray(n); // create button model |
72 | QGridLayout * grid = new QGridLayout( this, 3, 3, 4 ); | 73 | QGridLayout * grid = new QGridLayout( this, 3, 3, 4 ); |
73 | QPalette p( blue ); | 74 | QPalette p( blue ); |
74 | for ( int i=0; i<n; i++ ) { // create and connect buttons | 75 | for ( int i=0; i<n; i++ ) { // create and connect buttons |
75 | TicTacButton *ttb = new TicTacButton( this ); | 76 | TicTacButton *ttb = new TicTacButton( this ); |
76 | ttb->setPalette( p ); | 77 | ttb->setPalette( p ); |
77 | ttb->setEnabled( FALSE ); | 78 | ttb->setEnabled( FALSE ); |
78 | connect( ttb, SIGNAL(clicked()), SLOT(buttonClicked()) ); | 79 | connect( ttb, SIGNAL(clicked()), SLOT(buttonClicked()) ); |
79 | grid->addWidget( ttb, i%3, i/3 ); | 80 | grid->addWidget( ttb, i%3, i/3 ); |
80 | buttons->insert( i, ttb ); | 81 | buttons->insert( i, ttb ); |
81 | btArray->at(i) = TicTacButton::Blank;// initial button type | 82 | btArray->at(i) = TicTacButton::Blank; // initial button type |
82 | } | 83 | } |
83 | QTime t = QTime::currentTime(); // set random seed | 84 | QTime t = QTime::currentTime(); // set random seed |
84 | srand( t.hour()*12+t.minute()*60+t.second()*60 ); | 85 | srand( t.hour()*12+t.minute()*60+t.second()*60 ); |
85 | } | 86 | } |
86 | 87 | ||
@@ -113,16 +114,16 @@ void TicTacGameBoard::newGame() | |||
113 | { | 114 | { |
114 | st = HumansTurn; | 115 | st = HumansTurn; |
115 | for ( int i=0; i<nBoard*nBoard; i++ ) | 116 | for ( int i=0; i<nBoard*nBoard; i++ ) |
116 | btArray->at(i) = TicTacButton::Blank; | 117 | btArray->at(i) = TicTacButton::Blank; |
117 | if ( comp_starts ) | 118 | if ( comp_starts ) |
118 | computerMove(); | 119 | computerMove(); |
119 | else | 120 | else |
120 | updateButtons(); | 121 | updateButtons(); |
121 | } | 122 | } |
122 | 123 | ||
123 | 124 | ||
124 | // -------------------------------------------------------------------------- | 125 | // -------------------------------------------------------------------------- |
125 | // TicTacGameBoard::buttonClicked() - SLOT | 126 | // TicTacGameBoard::buttonClicked() - SLOT |
126 | // | 127 | // |
127 | // This slot is activated when a TicTacButton emits the signal "clicked()", | 128 | // This slot is activated when a TicTacButton emits the signal "clicked()", |
128 | // i.e. the user has clicked on a TicTacButton. | 129 | // i.e. the user has clicked on a TicTacButton. |
@@ -130,20 +131,20 @@ void TicTacGameBoard::newGame() | |||
130 | 131 | ||
131 | void TicTacGameBoard::buttonClicked() | 132 | void TicTacGameBoard::buttonClicked() |
132 | { | 133 | { |
133 | if ( st != HumansTurn ) // not ready | 134 | if ( st != HumansTurn ) // not ready |
134 | return; | 135 | return; |
135 | int i = buttons->findRef( (TicTacButton*)sender() ); | 136 | int i = buttons->findRef( (TicTacButton*)sender() ); |
136 | TicTacButton *b = buttons->at(i); // get piece that was pressed | 137 | TicTacButton *b = buttons->at(i); // get piece that was pressed |
137 | if ( b->type() == TicTacButton::Blank ) {// empty piece? | 138 | if ( b->type() == TicTacButton::Blank ) { // empty piece? |
138 | btArray->at(i) = TicTacButton::Circle; | 139 | btArray->at(i) = TicTacButton::Circle; |
139 | updateButtons(); | 140 | updateButtons(); |
140 | if ( checkBoard( btArray ) == 0 )// not a winning move? | 141 | if ( checkBoard( btArray ) == 0 ) // not a winning move? |
141 | computerMove(); | 142 | computerMove(); |
142 | int s = checkBoard( btArray ); | 143 | int s = checkBoard( btArray ); |
143 | if ( s ) { // any winners yet? | 144 | if ( s ) { // any winners yet? |
144 | st = s == TicTacButton::Circle ? HumanWon : ComputerWon; | 145 | st = s == TicTacButton::Circle ? HumanWon : ComputerWon; |
145 | emit finished(); | 146 | emit finished(); |
146 | } | 147 | } |
147 | } | 148 | } |
148 | } | 149 | } |
149 | 150 | ||
@@ -157,10 +158,10 @@ void TicTacGameBoard::buttonClicked() | |||
157 | void TicTacGameBoard::updateButtons() | 158 | void TicTacGameBoard::updateButtons() |
158 | { | 159 | { |
159 | for ( int i=0; i<nBoard*nBoard; i++ ) { | 160 | for ( int i=0; i<nBoard*nBoard; i++ ) { |
160 | if ( buttons->at(i)->type() != btArray->at(i) ) | 161 | if ( buttons->at(i)->type() != btArray->at(i) ) |
161 | buttons->at(i)->setType( (TicTacButton::Type)btArray->at(i) ); | 162 | buttons->at(i)->setType( (TicTacButton::Type)btArray->at(i) ); |
162 | buttons->at(i)->setEnabled( buttons->at(i)->type() == | 163 | buttons->at(i)->setEnabled( buttons->at(i)->type() == |
163 | TicTacButton::Blank ); | 164 | TicTacButton::Blank ); |
164 | } | 165 | } |
165 | } | 166 | } |
166 | 167 | ||
@@ -181,51 +182,51 @@ int TicTacGameBoard::checkBoard( TicTacArray *a ) | |||
181 | int t = 0; | 182 | int t = 0; |
182 | int row, col; | 183 | int row, col; |
183 | bool won = FALSE; | 184 | bool won = FALSE; |
184 | for ( row=0; row<nBoard && !won; row++ ) {// check horizontal | 185 | for ( row=0; row<nBoard && !won; row++ ) { // check horizontal |
185 | t = a->at(row*nBoard); | 186 | t = a->at(row*nBoard); |
186 | if ( t == TicTacButton::Blank ) | 187 | if ( t == TicTacButton::Blank ) |
187 | continue; | 188 | continue; |
188 | col = 1; | 189 | col = 1; |
189 | while ( col<nBoard && a->at(row*nBoard+col) == t ) | 190 | while ( col<nBoard && a->at(row*nBoard+col) == t ) |
190 | col++; | 191 | col++; |
191 | if ( col == nBoard ) | 192 | if ( col == nBoard ) |
192 | won = TRUE; | 193 | won = TRUE; |
193 | } | 194 | } |
194 | for ( col=0; col<nBoard && !won; col++ ) {// check vertical | 195 | for ( col=0; col<nBoard && !won; col++ ) { // check vertical |
195 | t = a->at(col); | 196 | t = a->at(col); |
196 | if ( t == TicTacButton::Blank ) | 197 | if ( t == TicTacButton::Blank ) |
197 | continue; | 198 | continue; |
198 | row = 1; | 199 | row = 1; |
199 | while ( row<nBoard && a->at(row*nBoard+col) == t ) | 200 | while ( row<nBoard && a->at(row*nBoard+col) == t ) |
200 | row++; | 201 | row++; |
201 | if ( row == nBoard ) | 202 | if ( row == nBoard ) |
202 | won = TRUE; | 203 | won = TRUE; |
203 | } | 204 | } |
204 | if ( !won ) { // check diagonal top left | 205 | if ( !won ) { // check diagonal top left |
205 | t = a->at(0); // to bottom right | 206 | t = a->at(0); // to bottom right |
206 | if ( t != TicTacButton::Blank ) { | 207 | if ( t != TicTacButton::Blank ) { |
207 | int i = 1; | 208 | int i = 1; |
208 | while ( i<nBoard && a->at(i*nBoard+i) == t ) | 209 | while ( i<nBoard && a->at(i*nBoard+i) == t ) |
209 | i++; | 210 | i++; |
210 | if ( i == nBoard ) | 211 | if ( i == nBoard ) |
211 | won = TRUE; | 212 | won = TRUE; |
212 | } | 213 | } |
213 | } | 214 | } |
214 | if ( !won ) { // check diagonal bottom left | 215 | if ( !won ) { // check diagonal bottom left |
215 | int j = nBoard-1; // to top right | 216 | int j = nBoard-1; // to top right |
216 | int i = 0; | 217 | int i = 0; |
217 | t = a->at(i+j*nBoard); | 218 | t = a->at(i+j*nBoard); |
218 | if ( t != TicTacButton::Blank ) { | 219 | if ( t != TicTacButton::Blank ) { |
219 | i++; j--; | 220 | i++; j--; |
220 | while ( i<nBoard && a->at(i+j*nBoard) == t ) { | 221 | while ( i<nBoard && a->at(i+j*nBoard) == t ) { |
221 | i++; j--; | 222 | i++; j--; |
222 | } | 223 | } |
223 | if ( i == nBoard ) | 224 | if ( i == nBoard ) |
224 | won = TRUE; | 225 | won = TRUE; |
225 | } | 226 | } |
226 | } | 227 | } |
227 | if ( !won ) // no winner | 228 | if ( !won ) // no winner |
228 | t = 0; | 229 | t = 0; |
229 | return t; | 230 | return t; |
230 | } | 231 | } |
231 | 232 | ||
@@ -239,41 +240,41 @@ int TicTacGameBoard::checkBoard( TicTacArray *a ) | |||
239 | void TicTacGameBoard::computerMove() | 240 | void TicTacGameBoard::computerMove() |
240 | { | 241 | { |
241 | int numButtons = nBoard*nBoard; | 242 | int numButtons = nBoard*nBoard; |
242 | int *altv = new int[numButtons]; // buttons alternatives | 243 | int *altv = new int[numButtons]; // buttons alternatives |
243 | int altc = 0; | 244 | int altc = 0; |
244 | int stopHuman = -1; | 245 | int stopHuman = -1; |
245 | TicTacArray a = btArray->copy(); | 246 | TicTacArray a = btArray->copy(); |
246 | int i; | 247 | int i; |
247 | for ( i=0; i<numButtons; i++ ) { // try all positions | 248 | for ( i=0; i<numButtons; i++ ) { // try all positions |
248 | if ( a[i] != TicTacButton::Blank )// already a piece there | 249 | if ( a[i] != TicTacButton::Blank ) // already a piece there |
249 | continue; | 250 | continue; |
250 | a[i] = TicTacButton::Cross; // test if computer wins | 251 | a[i] = TicTacButton::Cross; // test if computer wins |
251 | if ( checkBoard(&a) == a[i] ) { // computer will win | 252 | if ( checkBoard(&a) == a[i] ) { // computer will win |
252 | st = ComputerWon; | 253 | st = ComputerWon; |
253 | stopHuman = -1; | 254 | stopHuman = -1; |
254 | break; | 255 | break; |
255 | } | 256 | } |
256 | a[i] = TicTacButton::Circle; // test if human wins | 257 | a[i] = TicTacButton::Circle; // test if human wins |
257 | if ( checkBoard(&a) == a[i] ) { // oops... | 258 | if ( checkBoard(&a) == a[i] ) { // oops... |
258 | stopHuman = i; // remember position | 259 | stopHuman = i; // remember position |
259 | a[i] = TicTacButton::Blank; // restore button | 260 | a[i] = TicTacButton::Blank; // restore button |
260 | continue; // computer still might win | 261 | continue; // computer still might win |
261 | } | 262 | } |
262 | a[i] = TicTacButton::Blank; // restore button | 263 | a[i] = TicTacButton::Blank; // restore button |
263 | altv[altc++] = i; // remember alternative | 264 | altv[altc++] = i; // remember alternative |
264 | } | 265 | } |
265 | if ( stopHuman >= 0 ) // must stop human from winning | 266 | if ( stopHuman >= 0 ) // must stop human from winning |
266 | a[stopHuman] = TicTacButton::Cross; | 267 | a[stopHuman] = TicTacButton::Cross; |
267 | else if ( i == numButtons ) { // tried all alternatives | 268 | else if ( i == numButtons ) { // tried all alternatives |
268 | if ( altc > 0 ) // set random piece | 269 | if ( altc > 0 ) // set random piece |
269 | a[altv[rand()%(altc--)]] = TicTacButton::Cross; | 270 | a[altv[rand()%(altc--)]] = TicTacButton::Cross; |
270 | if ( altc == 0 ) { // no more blanks | 271 | if ( altc == 0 ) { // no more blanks |
271 | st = NobodyWon; | 272 | st = NobodyWon; |
272 | emit finished(); | 273 | emit finished(); |
273 | } | 274 | } |
274 | } | 275 | } |
275 | *btArray = a; // update model | 276 | *btArray = a; // update model |
276 | updateButtons(); // update buttons | 277 | updateButtons(); // update buttons |
277 | delete[] altv; | 278 | delete[] altv; |
278 | } | 279 | } |
279 | 280 | ||
@@ -288,40 +289,40 @@ void TicTacGameBoard::computerMove() | |||
288 | // | 289 | // |
289 | 290 | ||
290 | TicTacToe::TicTacToe( int boardSize, QWidget *parent, const char *name ) | 291 | TicTacToe::TicTacToe( int boardSize, QWidget *parent, const char *name ) |
291 | : QWidget( parent, name ) | 292 | : QWidget( parent, name ) |
292 | { | 293 | { |
293 | QVBoxLayout * l = new QVBoxLayout( this, 6 ); | 294 | QVBoxLayout * l = new QVBoxLayout( this, 6 ); |
294 | 295 | ||
295 | // Create a message label | 296 | // Create a message label |
296 | 297 | ||
297 | message = new QLabel( this ); | 298 | message = new QLabel( this ); |
298 | message->setFrameStyle( QFrame::WinPanel | QFrame::Sunken ); | 299 | message->setFrameStyle( QFrame::WinPanel | QFrame::Sunken ); |
299 | message->setAlignment( AlignCenter ); | 300 | message->setAlignment( AlignCenter ); |
300 | l->addWidget( message ); | 301 | l->addWidget( message ); |
301 | 302 | ||
302 | // Create the game board and connect the signal finished() to this | 303 | // Create the game board and connect the signal finished() to this |
303 | // gameOver() slot | 304 | // gameOver() slot |
304 | 305 | ||
305 | board = new TicTacGameBoard( boardSize, this ); | 306 | board = new TicTacGameBoard( boardSize, this ); |
306 | connect( board, SIGNAL(finished()), SLOT(gameOver()) ); | 307 | connect( board, SIGNAL(finished()), SLOT(gameOver()) ); |
307 | l->addWidget( board ); | 308 | l->addWidget( board ); |
308 | 309 | ||
309 | // Create a horizontal frame line | 310 | // Create a horizontal frame line |
310 | 311 | ||
311 | QFrame *line = new QFrame( this ); | 312 | QFrame *line = new QFrame( this ); |
312 | line->setFrameStyle( QFrame::HLine | QFrame::Sunken ); | 313 | line->setFrameStyle( QFrame::HLine | QFrame::Sunken ); |
313 | l->addWidget( line ); | 314 | l->addWidget( line ); |
314 | 315 | ||
315 | // Create the combo box for deciding who should start, and | 316 | // Create the combo box for deciding who should start, and |
316 | // connect its clicked() signals to the buttonClicked() slot | 317 | // connect its clicked() signals to the buttonClicked() slot |
317 | 318 | ||
318 | whoStarts = new QComboBox( this ); | 319 | whoStarts = new QComboBox( this ); |
319 | whoStarts->insertItem( tr( "Computer starts" ) ); | 320 | whoStarts->insertItem( tr( "Computer starts" ) ); |
320 | whoStarts->insertItem( tr( "Human starts" ) ); | 321 | whoStarts->insertItem( tr( "Human starts" ) ); |
321 | l->addWidget( whoStarts ); | 322 | l->addWidget( whoStarts ); |
322 | 323 | ||
323 | // Create the push buttons and connect their clicked() signals | 324 | // Create the push buttons and connect their clicked() signals |
324 | // to this right slots. | 325 | // to this right slots. |
325 | 326 | ||
326 | newGame = new QPushButton( tr( "Play!" ), this ); | 327 | newGame = new QPushButton( tr( "Play!" ), this ); |
327 | connect( newGame, SIGNAL(clicked()), SLOT(newGameClicked()) ); | 328 | connect( newGame, SIGNAL(clicked()), SLOT(newGameClicked()) ); |
@@ -331,13 +332,13 @@ TicTacToe::TicTacToe( int boardSize, QWidget *parent, const char *name ) | |||
331 | l->addLayout( b ); | 332 | l->addLayout( b ); |
332 | b->addWidget( newGame ); | 333 | b->addWidget( newGame ); |
333 | b->addWidget( quit ); | 334 | b->addWidget( quit ); |
334 | showMaximized(); | 335 | showMaximized(); |
335 | newState(); | 336 | newState(); |
336 | } | 337 | } |
337 | 338 | ||
338 | 339 | ||
339 | // -------------------------------------------------------------------------- | 340 | // -------------------------------------------------------------------------- |
340 | // TicTacToe::newGameClicked() - SLOT | 341 | // TicTacToe::newGameClicked() - SLOT |
341 | // | 342 | // |
342 | // This slot is activated when the new game button is clicked. | 343 | // This slot is activated when the new game button is clicked. |
343 | // | 344 | // |
@@ -351,7 +352,7 @@ void TicTacToe::newGameClicked() | |||
351 | 352 | ||
352 | 353 | ||
353 | // -------------------------------------------------------------------------- | 354 | // -------------------------------------------------------------------------- |
354 | // TicTacToe::gameOver() - SLOT | 355 | // TicTacToe::gameOver() - SLOT |
355 | // | 356 | // |
356 | // This slot is activated when the TicTacGameBoard emits the signal | 357 | // This slot is activated when the TicTacGameBoard emits the signal |
357 | // "finished()", i.e. when a player has won or when it is a draw. | 358 | // "finished()", i.e. when a player has won or when it is a draw. |
@@ -359,7 +360,7 @@ void TicTacToe::newGameClicked() | |||
359 | 360 | ||
360 | void TicTacToe::gameOver() | 361 | void TicTacToe::gameOver() |
361 | { | 362 | { |
362 | newState(); // update text box | 363 | newState(); // update text box |
363 | } | 364 | } |
364 | 365 | ||
365 | 366 | ||
@@ -369,9 +370,12 @@ void TicTacToe::gameOver() | |||
369 | 370 | ||
370 | void TicTacToe::newState() | 371 | void TicTacToe::newState() |
371 | { | 372 | { |
372 | static const char *msg[] = { // TicTacGameBoard::State texts | 373 | QStringList msg; |
373 | "Click Play to start", "Make your move", | 374 | msg << tr( "Click Play to start") |
374 | "You won!", "Computer won!", "It's a draw" }; | 375 | << tr("Make your move") |
376 | << tr("You won!") | ||
377 | << tr("Computer won!") | ||
378 | << tr("It's a draw"); | ||
375 | message->setText( msg[board->state()] ); | 379 | message->setText( msg[board->state()] ); |
376 | return; | 380 | return; |
377 | } | 381 | } |