summaryrefslogtreecommitdiff
path: root/noncore/games/wordgame/wordgame.cpp
Unidiff
Diffstat (limited to 'noncore/games/wordgame/wordgame.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/wordgame/wordgame.cpp71
1 files changed, 57 insertions, 14 deletions
diff --git a/noncore/games/wordgame/wordgame.cpp b/noncore/games/wordgame/wordgame.cpp
index ca4352d..16d37b3 100644
--- a/noncore/games/wordgame/wordgame.cpp
+++ b/noncore/games/wordgame/wordgame.cpp
@@ -1,395 +1,417 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 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 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 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 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. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21 21
22#include "wordgame.h" 22#include "wordgame.h"
23 23
24#include <qpe/applnk.h> 24#include <qpe/applnk.h>
25#include <qpe/global.h> 25#include <qpe/global.h>
26#include <qpe/filemanager.h> 26#include <qpe/filemanager.h>
27#include <qpe/resource.h> 27#include <qpe/resource.h>
28#include <qpe/config.h> 28#include <qpe/config.h>
29 29
30#include <qapplication.h> 30#include <qapplication.h>
31#include <qmessagebox.h> 31#include <qmessagebox.h>
32#include <qcombobox.h> 32#include <qcombobox.h>
33#include <qdatetime.h> 33#include <qdatetime.h>
34#include <qfileinfo.h> 34#include <qfileinfo.h>
35#include <qfile.h> 35#include <qfile.h>
36#include <qdir.h> 36#include <qdir.h>
37#include <qiconset.h> 37#include <qiconset.h>
38#include <qlabel.h> 38#include <qlabel.h>
39#include <qlineedit.h> 39#include <qlineedit.h>
40#include <qpushbutton.h> 40#include <qpushbutton.h>
41#include <qtextstream.h> 41#include <qtextstream.h>
42#include <qtimer.h> 42#include <qtimer.h>
43#include <qpe/qpetoolbar.h> 43#include <qpe/qpetoolbar.h>
44#include <qtoolbutton.h> 44#include <qtoolbutton.h>
45#include <qvbox.h> 45#include <qvbox.h>
46#include <qwidgetstack.h> 46#include <qwidgetstack.h>
47#include <qpainter.h> 47#include <qpainter.h>
48#include <qlayout.h> 48#include <qlayout.h>
49#include <qregexp.h> 49#include <qregexp.h>
50 50
51#include <stdlib.h> 51#include <stdlib.h>
52#include <unistd.h> 52#include <unistd.h>
53#include <pwd.h> 53#include <pwd.h>
54#include <sys/types.h> 54#include <sys/types.h>
55 55
56enum RuleEffects { 56enum RuleEffects {
57 Multiplier=15, 57 Multiplier=15,
58 MultiplyAll=64, 58 MultiplyAll=64,
59 Start=128 59 Start=128
60}; 60};
61 61
62static int tile_smallw = 16;
63static int tile_smallh = 16;
64static int tile_bigw = 22;
65static int tile_bigh = 22;
66static int tile_stweak = -2;
67static int tile_btweak = -1;
68
62static const int rack_tiles=7; 69static const int rack_tiles=7;
63 70
64const char* sampleWGR= 71const char* sampleWGR=
65 "wordgame_shapes\n" 72 "wordgame_shapes\n"
66 "15 15\n" 73 "15 15\n"
67 "400001040100004\n" 74 "400001040100004\n"
68 "030000000000030\n" 75 "030000000000030\n"
69 "002002000200200\n" 76 "002002000200200\n"
70 "000300020003000\n" 77 "000300020003000\n"
71 "000020000020000\n" 78 "000020000020000\n"
72 "102001000100201\n" 79 "102001000100201\n"
73 "000000202000000\n" 80 "000000202000000\n"
74 "400200050002004\n" 81 "400200050002004\n"
75 "000000202000000\n" 82 "000000202000000\n"
76 "102001000100201\n" 83 "102001000100201\n"
77 "000020000020000\n" 84 "000020000020000\n"
78 "000300020003000\n" 85 "000300020003000\n"
79 "002002000200200\n" 86 "002002000200200\n"
80 "030000000000030\n" 87 "030000000000030\n"
81 "400001040100004\n" 88 "400001040100004\n"
82 "1 2 3 66 67 194 100 0\n" 89 "1 2 3 66 67 194 100 0\n"
83 "1 j 8\n" 90 "1 j 8\n"
84 "1 q 7\n" 91 "1 q 7\n"
85 "1 x 6\n" 92 "1 x 6\n"
86 "1 z 6\n" 93 "1 z 6\n"
87 "1 w 4\n" 94 "1 w 4\n"
88 "1 k 4\n" 95 "1 k 4\n"
89 "1 v 3\n" 96 "1 v 3\n"
90 "1 f 3\n" 97 "1 f 3\n"
91 "2 y 3\n" 98 "2 y 3\n"
92 "2 h 2\n" 99 "2 h 2\n"
93 "2 b 2\n" 100 "2 b 2\n"
94 "2 m 2\n" 101 "2 m 2\n"
95 "3 p 2\n" 102 "3 p 2\n"
96 "3 g 2\n" 103 "3 g 2\n"
97 "3 u 2\n" 104 "3 u 2\n"
98 "4 d 2\n" 105 "4 d 2\n"
99 "4 c 2\n" 106 "4 c 2\n"
100 "5 l 1\n" 107 "5 l 1\n"
101 "5 o 1\n" 108 "5 o 1\n"
102 "7 t 1\n" 109 "7 t 1\n"
103 "7 n 1\n" 110 "7 n 1\n"
104 "7 a 1\n" 111 "7 a 1\n"
105 "7 r 1\n" 112 "7 r 1\n"
106 "8 s 1\n" 113 "8 s 1\n"
107 "8 i 1\n" 114 "8 i 1\n"
108 "11 e 1\n" 115 "11 e 1\n"
109 "0\n"; 116 "0\n";
110 117
111WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) : 118WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) :
112 QMainWindow(parent, name, fl) 119 QMainWindow(parent, name, fl)
113{ 120{
121 if ( qApp->desktop()->width() < 240 ) {
122 tile_smallw = 10;
123 tile_smallh = 10;
124 tile_bigw = 16;
125 tile_bigh = 16;
126 tile_stweak = 0;
127 tile_btweak = 0;
128 }
129
114 setIcon( Resource::loadPixmap( "wordgame" ) ); 130 setIcon( Resource::loadPixmap( "wordgame" ) );
115 setCaption( tr("Word Game") ); 131 setCaption( tr("Word Game") );
116 132
117 setToolBarsMovable( FALSE ); 133 setToolBarsMovable( FALSE );
118 vbox = new QVBox(this); 134 vbox = new QVBox(this);
119 135
120 setCentralWidget(vbox); 136 setCentralWidget(vbox);
121 toolbar = new QPEToolBar(this); 137 toolbar = new QPEToolBar(this);
122 addToolBar(toolbar, Bottom); 138 addToolBar(toolbar, Bottom);
123 reset = new QToolButton(Resource::loadPixmap("back"), tr("Back"), "", this, SLOT(resetTurn()), toolbar); 139 reset = new QToolButton(Resource::loadPixmap("back"), tr("Back"), "", this, SLOT(resetTurn()), toolbar);
124 done = new QToolButton(Resource::loadPixmap("done"), tr("Done"), "", this, SLOT(endTurn()), toolbar); 140 done = new QToolButton(Resource::loadPixmap("done"), tr("Done"), "", this, SLOT(endTurn()), toolbar);
125 scoreinfo = new ScoreInfo(toolbar); 141 scoreinfo = new ScoreInfo(toolbar);
126 scoreinfo->setFont(QFont("Helvetica",10)); 142 scoreinfo->setFont(QFont("Helvetica",10));
127 new QToolButton(Resource::loadPixmap("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar); 143 new QToolButton(Resource::loadPixmap("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar);
128 toolbar->setStretchableWidget(scoreinfo); 144 toolbar->setStretchableWidget(scoreinfo);
129 145
130 cpu = 0; 146 cpu = 0;
131 board = 0; 147 board = 0;
132 bag = 0; 148 bag = 0;
133 racks = 0; 149 racks = 0;
134 150
135 aiheart = new QTimer(this); 151 aiheart = new QTimer(this);
136 connect(aiheart, SIGNAL(timeout()), this, SLOT(think())); 152 connect(aiheart, SIGNAL(timeout()), this, SLOT(think()));
137 153
138 readConfig(); 154 readConfig();
139} 155}
140 156
141WordGame::~WordGame() 157WordGame::~WordGame()
142{ 158{
143 writeConfig(); 159 writeConfig();
144} 160}
145 161
146void WordGame::writeConfig() 162void WordGame::writeConfig()
147{ 163{
148 Config cfg("WordGame"); 164 Config cfg("WordGame");
149 cfg.setGroup("Game"); 165 cfg.setGroup("Game");
150 cfg.writeEntry("NameList",namelist,';'); 166 cfg.writeEntry("NameList",namelist,';');
151 cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1); 167 cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1);
152 if ( !gameover ) { 168 if ( !gameover ) {
153 cfg.writeEntry("Rules",rules); 169 cfg.writeEntry("Rules",rules);
154 bag->writeConfig(cfg); 170 bag->writeConfig(cfg);
155 board->writeConfig(cfg); 171 board->writeConfig(cfg);
156 scoreinfo->writeConfig(cfg); 172 scoreinfo->writeConfig(cfg);
157 } 173 }
158 for (int p=0; p<nplayers; p++) { 174 for (int p=0; p<nplayers; p++) {
159 cfg.setGroup("Player"+QString::number(p+1)); 175 cfg.setGroup("Player"+QString::number(p+1));
160 if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg); 176 if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg);
161 } 177 }
162} 178}
163 179
164void WordGame::readConfig() 180void WordGame::readConfig()
165{ 181{
166 Config cfg("WordGame"); 182 Config cfg("WordGame");
167 cfg.setGroup("Game"); 183 cfg.setGroup("Game");
168 int currentplayer = cfg.readNumEntry("CurrentPlayer",0); 184 int currentplayer = cfg.readNumEntry("CurrentPlayer",0);
169 QStringList pnames = cfg.readListEntry("NameList",';'); 185 QStringList pnames = cfg.readListEntry("NameList",';');
170 if ( currentplayer ) { 186 if ( currentplayer ) {
171 gameover = FALSE; 187 gameover = FALSE;
172 rules = cfg.readEntry("Rules"); 188 rules = cfg.readEntry("Rules");
173 if ( rules.find("x-wordgamerules") >= 0 ) { 189 if ( rules.find("x-wordgamerules") >= 0 ) {
174 // rules files moved 190 // rules files moved
175 rules = "Sample.rules"; 191 rules = "Sample.rules";
176 } 192 }
177 if ( loadRules(rules) ) { 193 if ( loadRules(rules) ) {
178 startGame(pnames); 194 startGame(pnames);
179 bag->readConfig(cfg); 195 bag->readConfig(cfg);
180 board->readConfig(cfg); 196 board->readConfig(cfg);
181 scoreinfo->readConfig(cfg); 197 scoreinfo->readConfig(cfg);
182 for (int p=0; p<nplayers; p++) { 198 for (int p=0; p<nplayers; p++) {
183 cfg.setGroup("Player"+QString::number(p+1)); 199 cfg.setGroup("Player"+QString::number(p+1));
184 rack(p)->readConfig(cfg); 200 rack(p)->readConfig(cfg);
185 } 201 }
186 player=currentplayer-1; 202 player=currentplayer-1;
187 readyRack(player); 203 readyRack(player);
188 return; 204 return;
189 } 205 }
190 } 206 }
191 // fall-back 207 // fall-back
192 openGameSelector(pnames); 208 openGameSelector(pnames);
193} 209}
194 210
195void WordGame::openGameSelector(const QStringList& initnames) 211void WordGame::openGameSelector(const QStringList& initnames)
196{ 212{
197 toolbar->hide(); 213 toolbar->hide();
198 gameover = FALSE; 214 gameover = FALSE;
199 215
200 delete board; 216 delete board;
201 board = 0; 217 board = 0;
202 delete racks; 218 delete racks;
203 racks = 0; 219 racks = 0;
204 220
205 delete cpu; 221 delete cpu;
206 cpu = 0; 222 cpu = 0;
207 223
208 newgame = new NewGame(vbox); 224 newgame = new NewGame(vbox);
209 225
210 //Rules rules(this); 226 //Rules rules(this);
211 //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules())); 227 //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules()));
212 //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets())); 228 //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets()));
213 struct passwd* n = getpwuid(getuid()); 229 struct passwd* n = getpwuid(getuid());
214 QString playername = n ? n->pw_name : ""; 230 QString playername = n ? n->pw_name : "";
215 if ( playername.isEmpty() ) { 231 if ( playername.isEmpty() ) {
216 playername = "Player"; 232 playername = "Player";
217 } 233 }
218 newgame->player0->changeItem(playername,0); 234 newgame->player0->changeItem(playername,0);
219 newgame->player1->setCurrentItem(1); 235 newgame->player1->setCurrentItem(1);
220 newgame->updateRuleSets(); 236 newgame->updateRuleSets();
221 newgame->show(); 237 newgame->show();
222 238
223 connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame())); 239 connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame()));
224} 240}
225 241
226void WordGame::startGame() 242void WordGame::startGame()
227{ 243{
228 rules = newgame->ruleslist[newgame->rules->currentItem()]; 244 rules = newgame->ruleslist[newgame->rules->currentItem()];
229 if ( loadRules(rules) ) { 245 if ( loadRules(rules) ) {
230 QStringList names; 246 QStringList names;
231 names.append(newgame->player0->currentText()); 247 names.append(newgame->player0->currentText());
232 names.append(newgame->player1->currentText()); 248 names.append(newgame->player1->currentText());
233 names.append(newgame->player2->currentText()); 249 names.append(newgame->player2->currentText());
234 names.append(newgame->player3->currentText()); 250 names.append(newgame->player3->currentText());
235 names.append(newgame->player4->currentText()); 251 names.append(newgame->player4->currentText());
236 names.append(newgame->player5->currentText()); 252 names.append(newgame->player5->currentText());
237 delete newgame; 253 delete newgame;
238 startGame(names); 254 startGame(names);
239 } else { 255 } else {
240 // error... 256 // error...
241 delete newgame; 257 delete newgame;
242 close(); 258 close();
243 } 259 }
244} 260}
245 261
246void WordGame::startGame(const QStringList& playerlist) 262void WordGame::startGame(const QStringList& playerlist)
247{ 263{
248 toolbar->show(); 264 toolbar->show();
249 racks = new QWidgetStack(vbox); 265 racks = new QWidgetStack(vbox);
266 racks->setFixedHeight(TileItem::bigHeight()+2);
250 namelist.clear(); 267 namelist.clear();
251 nplayers=0; 268 nplayers=0;
252 for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it) 269 for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it)
253 addPlayer(*it); 270 addPlayer(*it);
254 scoreinfo->init(namelist); 271 scoreinfo->init(namelist);
255 272
256 if ( nplayers ) { 273 if ( nplayers ) {
257 player=0; 274 player=0;
258 readyRack(player); 275 readyRack(player);
259 } 276 }
260 277
261 board->show(); 278 board->show();
262 racks->show(); 279 racks->show();
263} 280}
264 281
265bool WordGame::loadRules(const QString &name) 282bool WordGame::loadRules(const QString &name)
266{ 283{
267 QString filename = Global::applicationFileName( "wordgame", name ); 284 QString filename = Global::applicationFileName( "wordgame", name );
268 QFile file( filename ); 285 QFile file( filename );
269 if ( !file.open( IO_ReadOnly ) ) 286 if ( !file.open( IO_ReadOnly ) )
270 return FALSE; 287 return FALSE;
271 288
272 QTextStream ts( &file ); 289 QTextStream ts( &file );
273 290
274 QString title = name; 291 QString title = name;
275 title.truncate( title.length() - 6 ); 292 title.truncate( title.length() - 6 );
276 setCaption( title ); 293 setCaption( title );
277 294
278 QString shapepixmap; 295 QString shapepixmap;
279 ts >> shapepixmap; 296 ts >> shapepixmap;
280 int htiles,vtiles; 297 int htiles,vtiles;
281 ts >> htiles >> vtiles; 298 ts >> htiles >> vtiles;
282 299
283 if ( htiles < 3 || vtiles < 3 ) 300 if ( htiles < 3 || vtiles < 3 )
284 return FALSE; 301 return FALSE;
285 302
286 QPixmap bgshapes = Resource::loadPixmap(shapepixmap);
287 QString rule_shapes; 303 QString rule_shapes;
288 for (int i=0; i<vtiles; i++) { 304 for (int i=0; i<vtiles; i++) {
289 QString line; 305 QString line;
290 ts >> line; 306 ts >> line;
291 rule_shapes += line; 307 rule_shapes += line;
292 } 308 }
293 static int rule_effects[12]; 309 static int rule_effects[12];
294 int re=0,e; 310 int re=0,e;
295 ts >> e; 311 ts >> e;
296 while ( e && re < 10 ) { 312 while ( e && re < 10 ) {
297 rule_effects[re] = e; 313 rule_effects[re] = e;
298 if ( re++ < 10 ) ts >> e; 314 if ( re++ < 10 ) ts >> e;
299 } 315 }
316
317 QImage shim = Resource::loadImage(shapepixmap);
318 shim = shim.smoothScale((re-1)*TileItem::smallWidth(),TileItem::smallHeight());
319 QPixmap bgshapes;
320 bgshapes.convertFromImage(shim);
321
300 rule_effects[re++] = 100; // default bonus 322 rule_effects[re++] = 100; // default bonus
301 board = new Board(bgshapes, htiles, vtiles, vbox); 323 board = new Board(bgshapes, htiles, vtiles, vbox);
302 board->setRules(rule_shapes, rule_effects); 324 board->setRules(rule_shapes, rule_effects);
303 connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int))); 325 connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int)));
304 326
305 bag = new Bag; 327 bag = new Bag;
306 328
307 int count; 329 int count;
308 ts >> count; 330 ts >> count;
309 while ( count ) { 331 while ( count ) {
310 QString text; 332 QString text;
311 int value; 333 int value;
312 ts >> text >> value; 334 ts >> text >> value;
313 if ( text == "_" ) 335 if ( text == "_" )
314 text = ""; 336 text = "";
315 337
316 Tile t(text, value); 338 Tile t(text, value);
317 for (int n=count; n--; ) 339 for (int n=count; n--; )
318 bag->add(t); 340 bag->add(t);
319 341
320 ts >> count; 342 ts >> count;
321 } 343 }
322 344
323 return TRUE; 345 return TRUE;
324} 346}
325 347
326 348
327NewGame::NewGame(QWidget* parent) : 349NewGame::NewGame(QWidget* parent) :
328 NewGameBase(parent) 350 NewGameBase(parent)
329{ 351{
330} 352}
331 353
332void NewGame::updateRuleSets() 354void NewGame::updateRuleSets()
333{ 355{
334 rules->clear(); 356 rules->clear();
335 357
336 QString rulesDir = Global::applicationFileName( "wordgame", "" ); 358 QString rulesDir = Global::applicationFileName( "wordgame", "" );
337 QDir dir( rulesDir, "*.rules" ); 359 QDir dir( rulesDir, "*.rules" );
338 ruleslist = dir.entryList(); 360 ruleslist = dir.entryList();
339 if ( ruleslist.isEmpty() ) { 361 if ( ruleslist.isEmpty() ) {
340 // Provide a sample 362 // Provide a sample
341 QFile file( rulesDir + "Sample.rules" ); 363 QFile file( rulesDir + "Sample.rules" );
342 if ( file.open( IO_WriteOnly ) ) { 364 if ( file.open( IO_WriteOnly ) ) {
343 file.writeBlock( sampleWGR, strlen(sampleWGR) ); 365 file.writeBlock( sampleWGR, strlen(sampleWGR) );
344 file.close(); 366 file.close();
345 updateRuleSets(); 367 updateRuleSets();
346 } 368 }
347 return; 369 return;
348 } 370 }
349 int newest=0; 371 int newest=0;
350 int newest_age=INT_MAX; 372 int newest_age=INT_MAX;
351 QDateTime now = QDateTime::currentDateTime(); 373 QDateTime now = QDateTime::currentDateTime();
352 QStringList::Iterator it; 374 QStringList::Iterator it;
353 for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) { 375 for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) {
354 QFileInfo fi((*it)); 376 QFileInfo fi((*it));
355 int age = fi.lastModified().secsTo(now); 377 int age = fi.lastModified().secsTo(now);
356 QString name = *it; 378 QString name = *it;
357 name.truncate( name.length()-6 ); // remove extension 379 name.truncate( name.length()-6 ); // remove extension
358 rules->insertItem( name ); 380 rules->insertItem( name );
359 if ( age < newest_age ) { 381 if ( age < newest_age ) {
360 newest_age = age; 382 newest_age = age;
361 newest = rules->count()-1; 383 newest = rules->count()-1;
362 } 384 }
363 } 385 }
364 rules->setCurrentItem(newest); 386 rules->setCurrentItem(newest);
365} 387}
366 388
367Rules::Rules(QWidget* parent) : 389Rules::Rules(QWidget* parent) :
368 RulesBase(parent,0,TRUE) 390 RulesBase(parent,0,TRUE)
369{ 391{
370} 392}
371 393
372void Rules::editRules() 394void Rules::editRules()
373{ 395{
374 if ( exec() ) { 396 if ( exec() ) {
375 // ### create a new set of rules 397 // ### create a new set of rules
376 emit rulesChanged(); 398 emit rulesChanged();
377 } 399 }
378} 400}
379 401
380void Rules::deleteRuleSet() 402void Rules::deleteRuleSet()
381{ 403{
382 // ### delete existing rule set 404 // ### delete existing rule set
383 emit rulesChanged(); 405 emit rulesChanged();
384} 406}
385 407
386void WordGame::addPlayer(const QString& name) 408void WordGame::addPlayer(const QString& name)
387{ 409{
388 if ( !name.isEmpty() ) { 410 if ( !name.isEmpty() ) {
389 int colon = name.find(':'); 411 int colon = name.find(':');
390 int cpu = (colon >=0 && name.left(2) == "AI") ? name.mid(2,1).toInt() : 0; 412 int cpu = (colon >=0 && name.left(2) == "AI") ? name.mid(2,1).toInt() : 0;
391 addPlayer(name,cpu); 413 addPlayer(name,cpu);
392 } 414 }
393} 415}
394 416
395void WordGame::addPlayer(const QString& name, int cpu) 417void WordGame::addPlayer(const QString& name, int cpu)
@@ -588,275 +610,291 @@ bool ComputerPlayer::step()
588 board->scoreTurn(best_start, best_n, best_dir); 610 board->scoreTurn(best_start, best_n, best_dir);
589 board->showTurn(); 611 board->showTurn();
590 } 612 }
591 return FALSE; 613 return FALSE;
592 } 614 }
593 dict++; 615 dict++;
594 across = FALSE; 616 across = FALSE;
595 current = QPoint(0,0); 617 current = QPoint(0,0);
596 } else { 618 } else {
597 across = TRUE; 619 across = TRUE;
598 current = QPoint(0,0); 620 current = QPoint(0,0);
599 } 621 }
600 } 622 }
601 } 623 }
602 return TRUE; 624 return TRUE;
603} 625}
604 626
605void ComputerPlayer::findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar* nletter, const Tile** tiles, int n, Tile* blankvalues, int blused) 627void ComputerPlayer::findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar* nletter, const Tile** tiles, int n, Tile* blankvalues, int blused)
606{ 628{
607 if ( !node ) 629 if ( !node )
608 return; 630 return;
609 QChar l = node->letter(); 631 QChar l = node->letter();
610 const Tile* cur = board->tile(at); 632 const Tile* cur = board->tile(at);
611 if ( cur ) { 633 if ( cur ) {
612 if ( cur->text()[0] == l ) { 634 if ( cur->text()[0] == l ) {
613 bool nextok = board->contains(at+d); 635 bool nextok = board->contains(at+d);
614 if ( node->isWord() && n && (!nextok || !board->tile(at+d)) ) 636 if ( node->isWord() && n && (!nextok || !board->tile(at+d)) )
615 noteChoice(tiles,n,d,blankvalues,blused); 637 noteChoice(tiles,n,d,blankvalues,blused);
616 if ( nextok ) 638 if ( nextok )
617 findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused); 639 findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);
618 // #### text()[1]... 640 // #### text()[1]...
619 } 641 }
620 } else { 642 } else {
621 if ( nletter[l.unicode()] || nletter[0] ) { 643 if ( nletter[l.unicode()] || nletter[0] ) {
622 int rc = rack->count(); 644 int rc = rack->count();
623 ulong msk = 1; 645 ulong msk = 1;
624 for ( int x=0; x<rc; x++ ) { 646 for ( int x=0; x<rc; x++ ) {
625 if ( !(used&msk) ) { 647 if ( !(used&msk) ) {
626 const Tile* t = rack->tileRef(x); 648 const Tile* t = rack->tileRef(x);
627 if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s 649 if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s
628 bool nextok = board->contains(at+d); 650 bool nextok = board->contains(at+d);
629 tiles[n++] = t; 651 tiles[n++] = t;
630 if ( t->isBlank() ) 652 if ( t->isBlank() )
631 blankvalues[blused++] = Tile(l,0); 653 blankvalues[blused++] = Tile(l,0);
632 if ( node->isWord() && (!nextok || !board->tile(at+d)) ) 654 if ( node->isWord() && (!nextok || !board->tile(at+d)) )
633 noteChoice(tiles,n,d,blankvalues,blused); 655 noteChoice(tiles,n,d,blankvalues,blused);
634 used |= msk; // mark 656 used |= msk; // mark
635 nletter[t->text()[0].unicode()]--; 657 nletter[t->text()[0].unicode()]--;
636 if ( nextok ) 658 if ( nextok )
637 findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused); 659 findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);
638 n--; 660 n--;
639 nletter[t->text()[0].unicode()]++; 661 nletter[t->text()[0].unicode()]++;
640 if ( t->isBlank() ) { 662 if ( t->isBlank() ) {
641 // keep looking 663 // keep looking
642 blused--; 664 blused--;
643 used &= ~msk; // unmark 665 used &= ~msk; // unmark
644 } else { 666 } else {
645 break; 667 break;
646 } 668 }
647 } 669 }
648 } 670 }
649 msk <<= 1; 671 msk <<= 1;
650 } 672 }
651 } 673 }
652 // #### text()[1]... 674 // #### text()[1]...
653 } 675 }
654 findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused); 676 findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused);
655} 677}
656 678
657void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused) 679void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused)
658{ 680{
659 int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0); 681 int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0);
660/* 682/*
661if (s>0 || current==QPoint(5,1)){ 683if (s>0 || current==QPoint(5,1)){
662QString st; 684QString st;
663for ( int i=0; i<n; i++ ) 685for ( int i=0; i<n; i++ )
664 st += tiles[i]->text(); 686 st += tiles[i]->text();
665qDebug("%d,%d: %s (%d) for %d",current.x(),current.y(),st.latin1(),n,s); 687qDebug("%d,%d: %s (%d) for %d",current.x(),current.y(),st.latin1(),n,s);
666} 688}
667*/ 689*/
668 if ( s > best_score ) { 690 if ( s > best_score ) {
669 int i; 691 int i;
670 for ( i=0; i<n; i++ ) 692 for ( i=0; i<n; i++ )
671 best[i] = tiles[i]; 693 best[i] = tiles[i];
672 for ( i=0; i<blused; i++ ) 694 for ( i=0; i<blused; i++ )
673 best_blankvalues[i] = blankvalues[i]; 695 best_blankvalues[i] = blankvalues[i];
674 best_n = n; 696 best_n = n;
675 best_blused = blused; 697 best_blused = blused;
676 best_score = s; 698 best_score = s;
677 best_dir = d; 699 best_dir = d;
678 best_start = current; 700 best_start = current;
679 } 701 }
680} 702}
681 703
682int TileItem::smallWidth() 704int TileItem::smallWidth()
683{ 705{
684 return 16; 706 return tile_smallw;
685} 707}
686 708
687int TileItem::smallHeight() 709int TileItem::smallHeight()
688{ 710{
689 return 16; 711 return tile_smallh;
690} 712}
691 713
692int TileItem::bigWidth() 714int TileItem::bigWidth()
693{ 715{
694 return 22; 716 return tile_bigw;
695} 717}
696 718
697int TileItem::bigHeight() 719int TileItem::bigHeight()
698{ 720{
699 return 22; 721 return tile_bigh;
700} 722}
701 723
702void TileItem::setState( State state ) 724void TileItem::setState( State state )
703{ 725{
704 hide(); 726 hide();
705 s = state; 727 s = state;
706 show(); // ### use update() in Qt 3.0 728 show(); // ### use update() in Qt 3.0
707} 729}
708 730
709void TileItem::setTile(const Tile& tile) 731void TileItem::setTile(const Tile& tile)
710{ 732{
711 hide(); 733 hide();
712 t = tile; 734 t = tile;
713 show(); // ### use update() in Qt 3.0 735 show(); // ### use update() in Qt 3.0
714} 736}
715 737
716void TileItem::setBig(bool b) 738void TileItem::setBig(bool b)
717{ 739{
718 big = b; 740 big = b;
719} 741}
720 742
721void TileItem::drawShape(QPainter& p) 743void TileItem::drawShape(QPainter& p)
722{ 744{
723 static QFont value_font("heletica",8); 745 static QFont *value_font=0;
724 static QFont big_font("smoothtimes",17); 746 static QFont *big_font=0;
725 static QFont small_font("smoothtimes",10); 747 static QFont *small_font=0;
748 if ( !value_font ) {
749 value_font = new QFont("helvetica",8);
750 if ( TileItem::bigWidth() < 20 ) {
751 big_font = new QFont("helvetica",12);
752 small_font = new QFont("helvetica",8);
753 } else {
754 big_font = new QFont("smoothtimes",17);
755 small_font = new QFont("smoothtimes",10);
756 }
757 }
726 758
727 QRect area(x(),y(),width(),height()); 759 QRect area(x(),y(),width(),height());
728 p.setBrush(s == Floating ? yellow/*lightGray*/ : white); 760 p.setBrush(s == Floating ? yellow/*lightGray*/ : white);
729 p.drawRect(area); 761 p.drawRect(area);
730 if ( big ) { 762 if ( big ) {
731 p.setFont(value_font); 763 p.setFont(*value_font);
732 QString n = QString::number(t.value()); 764 QString n = QString::number(t.value());
733 int w = p.fontMetrics().width('1'); 765 int w = p.fontMetrics().width('1');
734 int h = p.fontMetrics().height(); 766 int h = p.fontMetrics().height();
735 w *= n.length(); 767 w *= n.length();
736 QRect valuearea(x()+width()-w-2,y()+height()-h+1,w,h); 768 QRect valuearea(x()+width()-w-1,y()+height()-h,w,h);
737 p.drawText(valuearea,AlignCenter,n); 769 p.drawText(valuearea,AlignCenter,n);
738 p.setFont(big_font); 770 p.setFont(*big_font);
739 area = QRect(x(),y(),width()-2,height()-1); 771 area = QRect(x(),y()+tile_btweak,width()-4,height()-1);
740 } else { 772 } else {
741 p.setFont(small_font); 773 p.setFont(*small_font);
742 area = QRect(x(),y()+2,width(),height()-2); 774 area = QRect(x()+1+tile_stweak,y()+1,width(),height()-3);
743 } 775 }
744 if ( t.value() == 0 ) 776 if ( t.value() == 0 )
745 p.setPen(darkGray); 777 p.setPen(darkGray);
746 p.drawText(area,AlignCenter,t.text().upper()); 778 p.drawText(area,AlignCenter,t.text().upper());
747} 779}
748 780
749Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) : 781Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) :
750 QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()), 782 QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()),
751 parent) 783 parent)
752{ 784{
785 setFixedSize(w*TileItem::smallWidth(),h*TileItem::smallHeight());
753 grid = new TileItem*[w*h]; 786 grid = new TileItem*[w*h];
754 memset(grid,0,w*h*sizeof(TileItem*)); 787 memset(grid,0,w*h*sizeof(TileItem*));
755 setFrameStyle(0); 788 setFrameStyle(0);
756 setHScrollBarMode(AlwaysOff); 789 setHScrollBarMode(AlwaysOff);
757 setVScrollBarMode(AlwaysOff); 790 setVScrollBarMode(AlwaysOff);
758 current_rack = 0; 791 current_rack = 0;
759 shown_n = 0; 792 shown_n = 0;
760} 793}
761 794
762Board::~Board() 795Board::~Board()
763{ 796{
764 delete canvas(); 797 delete canvas();
765} 798}
766 799
800QSize Board::sizeHint() const
801{
802 return QSize(canvas()->width(),canvas()->height());
803}
804
767void Board::writeConfig(Config& cfg) 805void Board::writeConfig(Config& cfg)
768{ 806{
769 QStringList t; 807 QStringList t;
770 int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); 808 int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();
771 for (int i=0; i<n; i++) 809 for (int i=0; i<n; i++)
772 t.append( grid[i] ? grid[i]->tile().key() : QString(".") ); 810 t.append( grid[i] ? grid[i]->tile().key() : QString(".") );
773 cfg.writeEntry("Board",t,';'); 811 cfg.writeEntry("Board",t,';');
774} 812}
775 813
776void Board::readConfig(Config& cfg) 814void Board::readConfig(Config& cfg)
777{ 815{
778 clear(); 816 clear();
779 QStringList t = cfg.readListEntry("Board",';'); 817 QStringList t = cfg.readListEntry("Board",';');
780 int i=0; 818 int i=0;
781 int h=canvas()->tilesHorizontally(); 819 int h=canvas()->tilesHorizontally();
782 for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) { 820 for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) {
783 if ( *it != "." ) { 821 if ( *it != "." ) {
784 QPoint p(i%h,i/h); 822 QPoint p(i%h,i/h);
785 setTile(p,Tile(*it)); 823 setTile(p,Tile(*it));
786 } 824 }
787 i++; 825 i++;
788 } 826 }
789 canvas()->update(); 827 canvas()->update();
790} 828}
791 829
792void Board::clear() 830void Board::clear()
793{ 831{
794 int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); 832 int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();
795 for (int i=0; i<n; i++) { 833 for (int i=0; i<n; i++) {
796 delete grid[i]; 834 delete grid[i];
797 grid[i]=0; 835 grid[i]=0;
798 } 836 }
799} 837}
800 838
801 839
802void Board::setCurrentRack(Rack* r) 840void Board::setCurrentRack(Rack* r)
803{ 841{
804 turn_score = -1; 842 turn_score = -1;
805 current_rack = r; 843 current_rack = r;
806} 844}
807 845
808void Board::resetRack() 846void Board::resetRack()
809{ 847{
810 unshowTurn(); 848 unshowTurn();
811 canvas()->update(); 849 canvas()->update();
812} 850}
813 851
814void Board::contentsMousePressEvent(QMouseEvent* e) 852void Board::contentsMousePressEvent(QMouseEvent* e)
815{ 853{
816 dragstart = e->pos(); 854 dragstart = e->pos();
817} 855}
818 856
819void Board::contentsMouseMoveEvent(QMouseEvent* e) 857void Board::contentsMouseMoveEvent(QMouseEvent* e)
820{ 858{
821 if ( current_rack && !current_rack->computerized() ) { 859 if ( current_rack && !current_rack->computerized() ) {
822 QPoint d = e->pos() - dragstart; 860 QPoint d = e->pos() - dragstart;
823 if ( d.x() <= 0 && d.y() <= 0 ) { 861 if ( d.x() <= 0 && d.y() <= 0 ) {
824 // None 862 // None
825 resetRack(); 863 resetRack();
826 } else { 864 } else {
827 int n; 865 int n;
828 QPoint start=boardPos(dragstart); 866 QPoint start=boardPos(dragstart);
829 QPoint end=boardPos(e->pos()); 867 QPoint end=boardPos(e->pos());
830 QPoint diff=end-start; 868 QPoint diff=end-start;
831 QPoint dir; 869 QPoint dir;
832 if ( d.x() > d.y() ) { 870 if ( d.x() > d.y() ) {
833 n = diff.x()+1; 871 n = diff.x()+1;
834 dir = QPoint(1,0); 872 dir = QPoint(1,0);
835 } else { 873 } else {
836 n = diff.y()+1; 874 n = diff.y()+1;
837 dir = QPoint(0,1); 875 dir = QPoint(0,1);
838 } 876 }
839 877
840 unshowTurn(); 878 unshowTurn();
841 879
842 // Subtract existing tiles from n 880 // Subtract existing tiles from n
843 QPoint t = start; 881 QPoint t = start;
844 for ( int i=n; i--; ) { 882 for ( int i=n; i--; ) {
845 if ( contains(t) && tile(t) ) 883 if ( contains(t) && tile(t) )
846 n--; 884 n--;
847 t += dir; 885 t += dir;
848 } 886 }
849 887
850 // Move start back to real start 888 // Move start back to real start
851 while (contains(start-dir) && tile(start-dir)) 889 while (contains(start-dir) && tile(start-dir))
852 start -= dir; 890 start -= dir;
853 891
854 scoreTurn(start, n, dir); 892 scoreTurn(start, n, dir);
855 showTurn(); 893 showTurn();
856 } 894 }
857 } 895 }
858} 896}
859 897
860void Board::finalizeTurn() 898void Board::finalizeTurn()
861{ 899{
862 int i=0; 900 int i=0;
@@ -1088,192 +1126,197 @@ int Board::score(QPoint at, const Tile** tiles, int n, const Tile* blankvalue, c
1088 side += otherd; 1126 side += otherd;
1089 } 1127 }
1090 } 1128 }
1091 if ( sideword.length() > 1 ) { 1129 if ( sideword.length() > 1 ) {
1092 if ( words ) 1130 if ( words )
1093 words->append(sideword); 1131 words->append(sideword);
1094 if ( checkdict && !Global::fixedDawg().contains(sideword) 1132 if ( checkdict && !Global::fixedDawg().contains(sideword)
1095 && !Global::dawg("WordGame").contains(sideword) ) 1133 && !Global::dawg("WordGame").contains(sideword) )
1096 return -1; 1134 return -1;
1097 totalsidetotal += sidetotal * side_mult; 1135 totalsidetotal += sidetotal * side_mult;
1098 connected = TRUE; 1136 connected = TRUE;
1099 } 1137 }
1100 i++; 1138 i++;
1101 } 1139 }
1102 at += d; 1140 at += d;
1103 } 1141 }
1104 1142
1105 if ( words ) 1143 if ( words )
1106 words->append(mainword); 1144 words->append(mainword);
1107 if ( checkdict && !Global::fixedDawg().contains(mainword) 1145 if ( checkdict && !Global::fixedDawg().contains(mainword)
1108 && !Global::dawg("WordGame").contains(mainword) ) 1146 && !Global::dawg("WordGame").contains(mainword) )
1109 return -1; 1147 return -1;
1110 1148
1111 if ( n == rack_tiles ) 1149 if ( n == rack_tiles )
1112 totalsidetotal += rack_tiles_bonus; 1150 totalsidetotal += rack_tiles_bonus;
1113 1151
1114 return connected ? totalsidetotal + total * all_mult : -1; 1152 return connected ? totalsidetotal + total * all_mult : -1;
1115} 1153}
1116 1154
1117QPoint Board::boardPos(const QPoint& p) const 1155QPoint Board::boardPos(const QPoint& p) const
1118{ 1156{
1119 return QPoint(p.x()/canvas()->tileWidth(), p.y()/canvas()->tileHeight()); 1157 return QPoint(p.x()/canvas()->tileWidth(), p.y()/canvas()->tileHeight());
1120} 1158}
1121 1159
1122void Board::contentsMouseReleaseEvent(QMouseEvent*) 1160void Board::contentsMouseReleaseEvent(QMouseEvent*)
1123{ 1161{
1124 if ( current_rack ) { 1162 if ( current_rack ) {
1125 } 1163 }
1126} 1164}
1127 1165
1128 1166
1129void Board::setRules(const QString& shapes, const int* effects) 1167void Board::setRules(const QString& shapes, const int* effects)
1130{ 1168{
1131 rule_shape=shapes; rule_effect=effects; 1169 rule_shape=shapes; rule_effect=effects;
1132 int i=0; 1170 int i=0;
1133 int maxre=0; 1171 int maxre=0;
1134 for (int y=0; y<yTiles(); y++) { 1172 for (int y=0; y<yTiles(); y++) {
1135 for (int x=0; x<xTiles(); x++) { 1173 for (int x=0; x<xTiles(); x++) {
1136 int re = shapes[i++]-'0'; 1174 int re = shapes[i++]-'0';
1137 if ( re > maxre ) maxre = re; 1175 if ( re > maxre ) maxre = re;
1138 canvas()->setTile(x,y,re); 1176 canvas()->setTile(x,y,re);
1139 } 1177 }
1140 } 1178 }
1141 rack_tiles_bonus=effects[maxre+1]; 1179 rack_tiles_bonus=effects[maxre+1];
1142} 1180}
1143 1181
1144void Board::unsetTile(const QPoint& p) 1182void Board::unsetTile(const QPoint& p)
1145{ 1183{
1146 delete item(p); 1184 delete item(p);
1147 grid[idx(p)] = 0; 1185 grid[idx(p)] = 0;
1148} 1186}
1149 1187
1150void Board::setTile(const QPoint& p, const Tile& t) 1188void Board::setTile(const QPoint& p, const Tile& t)
1151{ 1189{
1152 TileItem* it=item(p); 1190 TileItem* it=item(p);
1153 if ( !it ) { 1191 if ( !it ) {
1154 it = grid[idx(p)] = new TileItem(t,FALSE,canvas()); 1192 it = grid[idx(p)] = new TileItem(t,FALSE,canvas());
1155 it->move(p.x()*canvas()->tileWidth(), p.y()*canvas()->tileHeight()); 1193 it->move(p.x()*canvas()->tileWidth(), p.y()*canvas()->tileHeight());
1156 it->show(); 1194 it->show();
1157 } else { 1195 } else {
1158 it->setTile(t); 1196 it->setTile(t);
1159 } 1197 }
1160} 1198}
1161 1199
1162Rack::Rack(int ntiles, QWidget* parent) : QCanvasView( 1200Rack::Rack(int ntiles, QWidget* parent) : QCanvasView(
1163 new QCanvas(ntiles*TileItem::bigWidth(),TileItem::bigHeight()), 1201 new QCanvas(ntiles*TileItem::bigWidth(),TileItem::bigHeight()),
1164 parent), 1202 parent),
1165 item(ntiles) 1203 item(ntiles)
1166{ 1204{
1167 setLineWidth(1); 1205 setLineWidth(1);
1168 setFixedHeight(sizeHint().height()); 1206 setFixedHeight(sizeHint().height());
1169 n = 0; 1207 n = 0;
1170 for (int i=0; i<ntiles; i++) 1208 for (int i=0; i<ntiles; i++)
1171 item[i]=0; 1209 item[i]=0;
1172 setHScrollBarMode(AlwaysOff); 1210 setHScrollBarMode(AlwaysOff);
1173 setVScrollBarMode(AlwaysOff); 1211 setVScrollBarMode(AlwaysOff);
1174 canvas()->setBackgroundColor(gray); 1212 canvas()->setBackgroundColor(gray);
1175 dragging = 0; 1213 dragging = 0;
1176} 1214}
1177 1215
1178Rack::~Rack() 1216Rack::~Rack()
1179{ 1217{
1180 clear(); 1218 clear();
1181 delete canvas(); 1219 delete canvas();
1182} 1220}
1183 1221
1222QSize Rack::sizeHint() const
1223{
1224 return QSize(-1,TileItem::bigHeight()+2);
1225}
1226
1184void Rack::clear() 1227void Rack::clear()
1185{ 1228{
1186 for (int i=0; i<n; i++) 1229 for (int i=0; i<n; i++)
1187 delete item[i]; 1230 delete item[i];
1188 n=0; 1231 n=0;
1189} 1232}
1190 1233
1191void Rack::writeConfig(Config& cfg) 1234void Rack::writeConfig(Config& cfg)
1192{ 1235{
1193 QStringList l; 1236 QStringList l;
1194 for (int i=0; i<n; i++) 1237 for (int i=0; i<n; i++)
1195 l.append(tile(i).key()); 1238 l.append(tile(i).key());
1196 cfg.writeEntry("Tiles",l,';'); 1239 cfg.writeEntry("Tiles",l,';');
1197} 1240}
1198 1241
1199void Rack::readConfig(Config& cfg) 1242void Rack::readConfig(Config& cfg)
1200{ 1243{
1201 clear(); 1244 clear();
1202 int x=0; 1245 int x=0;
1203 QStringList l = cfg.readListEntry("Tiles",';'); 1246 QStringList l = cfg.readListEntry("Tiles",';');
1204 for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) { 1247 for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) {
1205 TileItem *i = new TileItem(Tile(*it),TRUE,canvas()); 1248 TileItem *i = new TileItem(Tile(*it),TRUE,canvas());
1206 i->move(x++,0); 1249 i->move(x++,0);
1207 i->show(); 1250 i->show();
1208 item[n++] = i; 1251 item[n++] = i;
1209 } 1252 }
1210 layoutTiles(); 1253 layoutTiles();
1211} 1254}
1212 1255
1213static int cmp_tileitem(const void *a, const void *b) 1256static int cmp_tileitem(const void *a, const void *b)
1214{ 1257{
1215 const TileItem* ia = *(TileItem**)a; 1258 const TileItem* ia = *(TileItem**)a;
1216 const TileItem* ib = *(TileItem**)b; 1259 const TileItem* ib = *(TileItem**)b;
1217 return int(ia->x() - ib->x()); 1260 return int(ia->x() - ib->x());
1218} 1261}
1219 1262
1220void Rack::layoutTiles() 1263void Rack::layoutTiles()
1221{ 1264{
1222 int w = TileItem::bigWidth()+2; 1265 int w = TileItem::bigWidth()+2;
1223 1266
1224 if ( dragging ) dragging->moveBy(dragging_adj,0); 1267 if ( dragging ) dragging->moveBy(dragging_adj,0);
1225 qsort(item.data(), n, sizeof(TileItem*), cmp_tileitem); 1268 qsort(item.data(), n, sizeof(TileItem*), cmp_tileitem);
1226 if ( dragging ) dragging->moveBy(-dragging_adj,0); 1269 if ( dragging ) dragging->moveBy(-dragging_adj,0);
1227 1270
1228 for (int i=0; i<n ;i++) 1271 for (int i=0; i<n ;i++)
1229 if ( item[i] == dragging ) { 1272 if ( item[i] == dragging ) {
1230 item[i]->setZ(1); 1273 item[i]->setZ(1);
1231 } else { 1274 } else {
1232 item[i]->move(i*w, 0); 1275 item[i]->move(i*w, 0);
1233 item[i]->setZ(0); 1276 item[i]->setZ(0);
1234 } 1277 }
1235 canvas()->update(); 1278 canvas()->update();
1236} 1279}
1237 1280
1238void Rack::setBlanks(const Tile* bv) 1281void Rack::setBlanks(const Tile* bv)
1239{ 1282{
1240 for (int j=0; j<n; j++) { 1283 for (int j=0; j<n; j++) {
1241 Tile tt = item[j]->tile(); 1284 Tile tt = item[j]->tile();
1242 if ( tt.isBlank() ) { 1285 if ( tt.isBlank() ) {
1243 tt.setText(bv->text()); 1286 tt.setText(bv->text());
1244 item[j]->setTile(tt); 1287 item[j]->setTile(tt);
1245 bv++; 1288 bv++;
1246 } 1289 }
1247 } 1290 }
1248} 1291}
1249 1292
1250bool Rack::arrangeTiles(const Tile** s, int sn) 1293bool Rack::arrangeTiles(const Tile** s, int sn)
1251{ 1294{
1252 bool could = TRUE; 1295 bool could = TRUE;
1253 for (int j=0; j<n; j++) { 1296 for (int j=0; j<n; j++) {
1254 Tile tt = item[j]->tile(); 1297 Tile tt = item[j]->tile();
1255 int f=-1; 1298 int f=-1;
1256 for (int i=0; i<sn && f<0; i++) { 1299 for (int i=0; i<sn && f<0; i++) {
1257 if (s[i] && *s[i] == tt ) { 1300 if (s[i] && *s[i] == tt ) {
1258 s[i]=0; 1301 s[i]=0;
1259 f=i; 1302 f=i;
1260 } 1303 }
1261 } 1304 }
1262 if ( f >= 0 ) { 1305 if ( f >= 0 ) {
1263 item[j]->move(f-999,0); 1306 item[j]->move(f-999,0);
1264 } else { 1307 } else {
1265 could = FALSE; 1308 could = FALSE;
1266 } 1309 }
1267 } 1310 }
1268 layoutTiles(); 1311 layoutTiles();
1269 return could; 1312 return could;
1270} 1313}
1271 1314
1272void Rack::addTile(const Tile& t) 1315void Rack::addTile(const Tile& t)
1273{ 1316{
1274 TileItem *i = new TileItem(t,TRUE,canvas()); 1317 TileItem *i = new TileItem(t,TRUE,canvas());
1275 i->show(); 1318 i->show();
1276 item[n++] = i; 1319 item[n++] = i;
1277 layoutTiles(); 1320 layoutTiles();
1278} 1321}
1279 1322