Diffstat (limited to 'noncore/games/wordgame/wordgame.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/games/wordgame/wordgame.cpp | 71 |
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 | ||
56 | enum RuleEffects { | 56 | enum RuleEffects { |
57 | Multiplier=15, | 57 | Multiplier=15, |
58 | MultiplyAll=64, | 58 | MultiplyAll=64, |
59 | Start=128 | 59 | Start=128 |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static int tile_smallw = 16; | ||
63 | static int tile_smallh = 16; | ||
64 | static int tile_bigw = 22; | ||
65 | static int tile_bigh = 22; | ||
66 | static int tile_stweak = -2; | ||
67 | static int tile_btweak = -1; | ||
68 | |||
62 | static const int rack_tiles=7; | 69 | static const int rack_tiles=7; |
63 | 70 | ||
64 | const char* sampleWGR= | 71 | const 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 | ||
111 | WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) : | 118 | WordGame::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 | ||
141 | WordGame::~WordGame() | 157 | WordGame::~WordGame() |
142 | { | 158 | { |
143 | writeConfig(); | 159 | writeConfig(); |
144 | } | 160 | } |
145 | 161 | ||
146 | void WordGame::writeConfig() | 162 | void 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 | ||
164 | void WordGame::readConfig() | 180 | void 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 | ||
195 | void WordGame::openGameSelector(const QStringList& initnames) | 211 | void 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 | ||
226 | void WordGame::startGame() | 242 | void 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 | ||
246 | void WordGame::startGame(const QStringList& playerlist) | 262 | void 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 | ||
265 | bool WordGame::loadRules(const QString &name) | 282 | bool 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 | ||
327 | NewGame::NewGame(QWidget* parent) : | 349 | NewGame::NewGame(QWidget* parent) : |
328 | NewGameBase(parent) | 350 | NewGameBase(parent) |
329 | { | 351 | { |
330 | } | 352 | } |
331 | 353 | ||
332 | void NewGame::updateRuleSets() | 354 | void 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 | ||
367 | Rules::Rules(QWidget* parent) : | 389 | Rules::Rules(QWidget* parent) : |
368 | RulesBase(parent,0,TRUE) | 390 | RulesBase(parent,0,TRUE) |
369 | { | 391 | { |
370 | } | 392 | } |
371 | 393 | ||
372 | void Rules::editRules() | 394 | void 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 | ||
380 | void Rules::deleteRuleSet() | 402 | void Rules::deleteRuleSet() |
381 | { | 403 | { |
382 | // ### delete existing rule set | 404 | // ### delete existing rule set |
383 | emit rulesChanged(); | 405 | emit rulesChanged(); |
384 | } | 406 | } |
385 | 407 | ||
386 | void WordGame::addPlayer(const QString& name) | 408 | void 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 | ||
395 | void WordGame::addPlayer(const QString& name, int cpu) | 417 | void 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 | ||
605 | void ComputerPlayer::findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar* nletter, const Tile** tiles, int n, Tile* blankvalues, int blused) | 627 | void 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 | ||
657 | void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused) | 679 | void 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 | /* |
661 | if (s>0 || current==QPoint(5,1)){ | 683 | if (s>0 || current==QPoint(5,1)){ |
662 | QString st; | 684 | QString st; |
663 | for ( int i=0; i<n; i++ ) | 685 | for ( int i=0; i<n; i++ ) |
664 | st += tiles[i]->text(); | 686 | st += tiles[i]->text(); |
665 | qDebug("%d,%d: %s (%d) for %d",current.x(),current.y(),st.latin1(),n,s); | 687 | qDebug("%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 | ||
682 | int TileItem::smallWidth() | 704 | int TileItem::smallWidth() |
683 | { | 705 | { |
684 | return 16; | 706 | return tile_smallw; |
685 | } | 707 | } |
686 | 708 | ||
687 | int TileItem::smallHeight() | 709 | int TileItem::smallHeight() |
688 | { | 710 | { |
689 | return 16; | 711 | return tile_smallh; |
690 | } | 712 | } |
691 | 713 | ||
692 | int TileItem::bigWidth() | 714 | int TileItem::bigWidth() |
693 | { | 715 | { |
694 | return 22; | 716 | return tile_bigw; |
695 | } | 717 | } |
696 | 718 | ||
697 | int TileItem::bigHeight() | 719 | int TileItem::bigHeight() |
698 | { | 720 | { |
699 | return 22; | 721 | return tile_bigh; |
700 | } | 722 | } |
701 | 723 | ||
702 | void TileItem::setState( State state ) | 724 | void 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 | ||
709 | void TileItem::setTile(const Tile& tile) | 731 | void 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 | ||
716 | void TileItem::setBig(bool b) | 738 | void TileItem::setBig(bool b) |
717 | { | 739 | { |
718 | big = b; | 740 | big = b; |
719 | } | 741 | } |
720 | 742 | ||
721 | void TileItem::drawShape(QPainter& p) | 743 | void 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 | ||
749 | Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) : | 781 | Board::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 | ||
762 | Board::~Board() | 795 | Board::~Board() |
763 | { | 796 | { |
764 | delete canvas(); | 797 | delete canvas(); |
765 | } | 798 | } |
766 | 799 | ||
800 | QSize Board::sizeHint() const | ||
801 | { | ||
802 | return QSize(canvas()->width(),canvas()->height()); | ||
803 | } | ||
804 | |||
767 | void Board::writeConfig(Config& cfg) | 805 | void 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 | ||
776 | void Board::readConfig(Config& cfg) | 814 | void 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 | ||
792 | void Board::clear() | 830 | void 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 | ||
802 | void Board::setCurrentRack(Rack* r) | 840 | void 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 | ||
808 | void Board::resetRack() | 846 | void Board::resetRack() |
809 | { | 847 | { |
810 | unshowTurn(); | 848 | unshowTurn(); |
811 | canvas()->update(); | 849 | canvas()->update(); |
812 | } | 850 | } |
813 | 851 | ||
814 | void Board::contentsMousePressEvent(QMouseEvent* e) | 852 | void Board::contentsMousePressEvent(QMouseEvent* e) |
815 | { | 853 | { |
816 | dragstart = e->pos(); | 854 | dragstart = e->pos(); |
817 | } | 855 | } |
818 | 856 | ||
819 | void Board::contentsMouseMoveEvent(QMouseEvent* e) | 857 | void 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 | ||
860 | void Board::finalizeTurn() | 898 | void 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 | ||
1117 | QPoint Board::boardPos(const QPoint& p) const | 1155 | QPoint 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 | ||
1122 | void Board::contentsMouseReleaseEvent(QMouseEvent*) | 1160 | void Board::contentsMouseReleaseEvent(QMouseEvent*) |
1123 | { | 1161 | { |
1124 | if ( current_rack ) { | 1162 | if ( current_rack ) { |
1125 | } | 1163 | } |
1126 | } | 1164 | } |
1127 | 1165 | ||
1128 | 1166 | ||
1129 | void Board::setRules(const QString& shapes, const int* effects) | 1167 | void 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 | ||
1144 | void Board::unsetTile(const QPoint& p) | 1182 | void 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 | ||
1150 | void Board::setTile(const QPoint& p, const Tile& t) | 1188 | void 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 | ||
1162 | Rack::Rack(int ntiles, QWidget* parent) : QCanvasView( | 1200 | Rack::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 | ||
1178 | Rack::~Rack() | 1216 | Rack::~Rack() |
1179 | { | 1217 | { |
1180 | clear(); | 1218 | clear(); |
1181 | delete canvas(); | 1219 | delete canvas(); |
1182 | } | 1220 | } |
1183 | 1221 | ||
1222 | QSize Rack::sizeHint() const | ||
1223 | { | ||
1224 | return QSize(-1,TileItem::bigHeight()+2); | ||
1225 | } | ||
1226 | |||
1184 | void Rack::clear() | 1227 | void 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 | ||
1191 | void Rack::writeConfig(Config& cfg) | 1234 | void 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 | ||
1199 | void Rack::readConfig(Config& cfg) | 1242 | void 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 | ||
1213 | static int cmp_tileitem(const void *a, const void *b) | 1256 | static 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 | ||
1220 | void Rack::layoutTiles() | 1263 | void 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 | ||
1238 | void Rack::setBlanks(const Tile* bv) | 1281 | void 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 | ||
1250 | bool Rack::arrangeTiles(const Tile** s, int sn) | 1293 | bool 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 | ||
1272 | void Rack::addTile(const Tile& t) | 1315 | void 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 | ||