-rw-r--r-- | noncore/games/wordgame/wordgame.cpp | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/noncore/games/wordgame/wordgame.cpp b/noncore/games/wordgame/wordgame.cpp index 16d37b3..d3160f4 100644 --- a/noncore/games/wordgame/wordgame.cpp +++ b/noncore/games/wordgame/wordgame.cpp | |||
@@ -1,1085 +1,1085 @@ | |||
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; | 62 | static int tile_smallw = 16; |
63 | static int tile_smallh = 16; | 63 | static int tile_smallh = 16; |
64 | static int tile_bigw = 22; | 64 | static int tile_bigw = 22; |
65 | static int tile_bigh = 22; | 65 | static int tile_bigh = 22; |
66 | static int tile_stweak = -2; | 66 | static int tile_stweak = -2; |
67 | static int tile_btweak = -1; | 67 | static int tile_btweak = -1; |
68 | 68 | ||
69 | static const int rack_tiles=7; | 69 | static const int rack_tiles=7; |
70 | 70 | ||
71 | const char* sampleWGR= | 71 | const char* sampleWGR= |
72 | "wordgame_shapes\n" | 72 | "wordgame_shapes\n" |
73 | "15 15\n" | 73 | "15 15\n" |
74 | "400001040100004\n" | 74 | "400001040100004\n" |
75 | "030000000000030\n" | 75 | "030000000000030\n" |
76 | "002002000200200\n" | 76 | "002002000200200\n" |
77 | "000300020003000\n" | 77 | "000300020003000\n" |
78 | "000020000020000\n" | 78 | "000020000020000\n" |
79 | "102001000100201\n" | 79 | "102001000100201\n" |
80 | "000000202000000\n" | 80 | "000000202000000\n" |
81 | "400200050002004\n" | 81 | "400200050002004\n" |
82 | "000000202000000\n" | 82 | "000000202000000\n" |
83 | "102001000100201\n" | 83 | "102001000100201\n" |
84 | "000020000020000\n" | 84 | "000020000020000\n" |
85 | "000300020003000\n" | 85 | "000300020003000\n" |
86 | "002002000200200\n" | 86 | "002002000200200\n" |
87 | "030000000000030\n" | 87 | "030000000000030\n" |
88 | "400001040100004\n" | 88 | "400001040100004\n" |
89 | "1 2 3 66 67 194 100 0\n" | 89 | "1 2 3 66 67 194 100 0\n" |
90 | "1 j 8\n" | 90 | "1 j 8\n" |
91 | "1 q 7\n" | 91 | "1 q 7\n" |
92 | "1 x 6\n" | 92 | "1 x 6\n" |
93 | "1 z 6\n" | 93 | "1 z 6\n" |
94 | "1 w 4\n" | 94 | "1 w 4\n" |
95 | "1 k 4\n" | 95 | "1 k 4\n" |
96 | "1 v 3\n" | 96 | "1 v 3\n" |
97 | "1 f 3\n" | 97 | "1 f 3\n" |
98 | "2 y 3\n" | 98 | "2 y 3\n" |
99 | "2 h 2\n" | 99 | "2 h 2\n" |
100 | "2 b 2\n" | 100 | "2 b 2\n" |
101 | "2 m 2\n" | 101 | "2 m 2\n" |
102 | "3 p 2\n" | 102 | "3 p 2\n" |
103 | "3 g 2\n" | 103 | "3 g 2\n" |
104 | "3 u 2\n" | 104 | "3 u 2\n" |
105 | "4 d 2\n" | 105 | "4 d 2\n" |
106 | "4 c 2\n" | 106 | "4 c 2\n" |
107 | "5 l 1\n" | 107 | "5 l 1\n" |
108 | "5 o 1\n" | 108 | "5 o 1\n" |
109 | "7 t 1\n" | 109 | "7 t 1\n" |
110 | "7 n 1\n" | 110 | "7 n 1\n" |
111 | "7 a 1\n" | 111 | "7 a 1\n" |
112 | "7 r 1\n" | 112 | "7 r 1\n" |
113 | "8 s 1\n" | 113 | "8 s 1\n" |
114 | "8 i 1\n" | 114 | "8 i 1\n" |
115 | "11 e 1\n" | 115 | "11 e 1\n" |
116 | "0\n"; | 116 | "0\n"; |
117 | 117 | ||
118 | WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) : | 118 | WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) : |
119 | QMainWindow(parent, name, fl) | 119 | QMainWindow(parent, name, fl) |
120 | { | 120 | { |
121 | if ( qApp->desktop()->width() < 240 ) { | 121 | if ( qApp->desktop()->width() < 240 ) { |
122 | tile_smallw = 10; | 122 | tile_smallw = 10; |
123 | tile_smallh = 10; | 123 | tile_smallh = 10; |
124 | tile_bigw = 16; | 124 | tile_bigw = 16; |
125 | tile_bigh = 16; | 125 | tile_bigh = 16; |
126 | tile_stweak = 0; | 126 | tile_stweak = 0; |
127 | tile_btweak = 0; | 127 | tile_btweak = 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | setIcon( Resource::loadPixmap( "wordgame" ) ); | 130 | setIcon( Resource::loadPixmap( "wordgame/WordGame.png" ) ); |
131 | setCaption( tr("Word Game") ); | 131 | setCaption( tr("Word Game") ); |
132 | 132 | ||
133 | setToolBarsMovable( FALSE ); | 133 | setToolBarsMovable( FALSE ); |
134 | vbox = new QVBox(this); | 134 | vbox = new QVBox(this); |
135 | 135 | ||
136 | setCentralWidget(vbox); | 136 | setCentralWidget(vbox); |
137 | toolbar = new QPEToolBar(this); | 137 | toolbar = new QPEToolBar(this); |
138 | addToolBar(toolbar, Bottom); | 138 | addToolBar(toolbar, Bottom); |
139 | 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); |
140 | 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); |
141 | scoreinfo = new ScoreInfo(toolbar); | 141 | scoreinfo = new ScoreInfo(toolbar); |
142 | scoreinfo->setFont(QFont("Helvetica",10)); | 142 | scoreinfo->setFont(QFont("Helvetica",10)); |
143 | new QToolButton(Resource::loadPixmap("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar); | 143 | new QToolButton(Resource::loadPixmap("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar); |
144 | toolbar->setStretchableWidget(scoreinfo); | 144 | toolbar->setStretchableWidget(scoreinfo); |
145 | 145 | ||
146 | cpu = 0; | 146 | cpu = 0; |
147 | board = 0; | 147 | board = 0; |
148 | bag = 0; | 148 | bag = 0; |
149 | racks = 0; | 149 | racks = 0; |
150 | 150 | ||
151 | aiheart = new QTimer(this); | 151 | aiheart = new QTimer(this); |
152 | connect(aiheart, SIGNAL(timeout()), this, SLOT(think())); | 152 | connect(aiheart, SIGNAL(timeout()), this, SLOT(think())); |
153 | 153 | ||
154 | readConfig(); | 154 | readConfig(); |
155 | } | 155 | } |
156 | 156 | ||
157 | WordGame::~WordGame() | 157 | WordGame::~WordGame() |
158 | { | 158 | { |
159 | writeConfig(); | 159 | writeConfig(); |
160 | } | 160 | } |
161 | 161 | ||
162 | void WordGame::writeConfig() | 162 | void WordGame::writeConfig() |
163 | { | 163 | { |
164 | Config cfg("WordGame"); | 164 | Config cfg("WordGame"); |
165 | cfg.setGroup("Game"); | 165 | cfg.setGroup("Game"); |
166 | cfg.writeEntry("NameList",namelist,';'); | 166 | cfg.writeEntry("NameList",namelist,';'); |
167 | cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1); | 167 | cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1); |
168 | if ( !gameover ) { | 168 | if ( !gameover ) { |
169 | cfg.writeEntry("Rules",rules); | 169 | cfg.writeEntry("Rules",rules); |
170 | bag->writeConfig(cfg); | 170 | bag->writeConfig(cfg); |
171 | board->writeConfig(cfg); | 171 | board->writeConfig(cfg); |
172 | scoreinfo->writeConfig(cfg); | 172 | scoreinfo->writeConfig(cfg); |
173 | } | 173 | } |
174 | for (int p=0; p<nplayers; p++) { | 174 | for (int p=0; p<nplayers; p++) { |
175 | cfg.setGroup("Player"+QString::number(p+1)); | 175 | cfg.setGroup("Player"+QString::number(p+1)); |
176 | if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg); | 176 | if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg); |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | void WordGame::readConfig() | 180 | void WordGame::readConfig() |
181 | { | 181 | { |
182 | Config cfg("WordGame"); | 182 | Config cfg("WordGame"); |
183 | cfg.setGroup("Game"); | 183 | cfg.setGroup("Game"); |
184 | int currentplayer = cfg.readNumEntry("CurrentPlayer",0); | 184 | int currentplayer = cfg.readNumEntry("CurrentPlayer",0); |
185 | QStringList pnames = cfg.readListEntry("NameList",';'); | 185 | QStringList pnames = cfg.readListEntry("NameList",';'); |
186 | if ( currentplayer ) { | 186 | if ( currentplayer ) { |
187 | gameover = FALSE; | 187 | gameover = FALSE; |
188 | rules = cfg.readEntry("Rules"); | 188 | rules = cfg.readEntry("Rules"); |
189 | if ( rules.find("x-wordgamerules") >= 0 ) { | 189 | if ( rules.find("x-wordgamerules") >= 0 ) { |
190 | // rules files moved | 190 | // rules files moved |
191 | rules = "Sample.rules"; | 191 | rules = "Sample.rules"; |
192 | } | 192 | } |
193 | if ( loadRules(rules) ) { | 193 | if ( loadRules(rules) ) { |
194 | startGame(pnames); | 194 | startGame(pnames); |
195 | bag->readConfig(cfg); | 195 | bag->readConfig(cfg); |
196 | board->readConfig(cfg); | 196 | board->readConfig(cfg); |
197 | scoreinfo->readConfig(cfg); | 197 | scoreinfo->readConfig(cfg); |
198 | for (int p=0; p<nplayers; p++) { | 198 | for (int p=0; p<nplayers; p++) { |
199 | cfg.setGroup("Player"+QString::number(p+1)); | 199 | cfg.setGroup("Player"+QString::number(p+1)); |
200 | rack(p)->readConfig(cfg); | 200 | rack(p)->readConfig(cfg); |
201 | } | 201 | } |
202 | player=currentplayer-1; | 202 | player=currentplayer-1; |
203 | readyRack(player); | 203 | readyRack(player); |
204 | return; | 204 | return; |
205 | } | 205 | } |
206 | } | 206 | } |
207 | // fall-back | 207 | // fall-back |
208 | openGameSelector(pnames); | 208 | openGameSelector(pnames); |
209 | } | 209 | } |
210 | 210 | ||
211 | void WordGame::openGameSelector(const QStringList& initnames) | 211 | void WordGame::openGameSelector(const QStringList& initnames) |
212 | { | 212 | { |
213 | toolbar->hide(); | 213 | toolbar->hide(); |
214 | gameover = FALSE; | 214 | gameover = FALSE; |
215 | 215 | ||
216 | delete board; | 216 | delete board; |
217 | board = 0; | 217 | board = 0; |
218 | delete racks; | 218 | delete racks; |
219 | racks = 0; | 219 | racks = 0; |
220 | 220 | ||
221 | delete cpu; | 221 | delete cpu; |
222 | cpu = 0; | 222 | cpu = 0; |
223 | 223 | ||
224 | newgame = new NewGame(vbox); | 224 | newgame = new NewGame(vbox); |
225 | 225 | ||
226 | //Rules rules(this); | 226 | //Rules rules(this); |
227 | //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules())); | 227 | //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules())); |
228 | //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets())); | 228 | //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets())); |
229 | struct passwd* n = getpwuid(getuid()); | 229 | struct passwd* n = getpwuid(getuid()); |
230 | QString playername = n ? n->pw_name : ""; | 230 | QString playername = n ? n->pw_name : ""; |
231 | if ( playername.isEmpty() ) { | 231 | if ( playername.isEmpty() ) { |
232 | playername = "Player"; | 232 | playername = "Player"; |
233 | } | 233 | } |
234 | newgame->player0->changeItem(playername,0); | 234 | newgame->player0->changeItem(playername,0); |
235 | newgame->player1->setCurrentItem(1); | 235 | newgame->player1->setCurrentItem(1); |
236 | newgame->updateRuleSets(); | 236 | newgame->updateRuleSets(); |
237 | newgame->show(); | 237 | newgame->show(); |
238 | 238 | ||
239 | connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame())); | 239 | connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame())); |
240 | } | 240 | } |
241 | 241 | ||
242 | void WordGame::startGame() | 242 | void WordGame::startGame() |
243 | { | 243 | { |
244 | rules = newgame->ruleslist[newgame->rules->currentItem()]; | 244 | rules = newgame->ruleslist[newgame->rules->currentItem()]; |
245 | if ( loadRules(rules) ) { | 245 | if ( loadRules(rules) ) { |
246 | QStringList names; | 246 | QStringList names; |
247 | names.append(newgame->player0->currentText()); | 247 | names.append(newgame->player0->currentText()); |
248 | names.append(newgame->player1->currentText()); | 248 | names.append(newgame->player1->currentText()); |
249 | names.append(newgame->player2->currentText()); | 249 | names.append(newgame->player2->currentText()); |
250 | names.append(newgame->player3->currentText()); | 250 | names.append(newgame->player3->currentText()); |
251 | names.append(newgame->player4->currentText()); | 251 | names.append(newgame->player4->currentText()); |
252 | names.append(newgame->player5->currentText()); | 252 | names.append(newgame->player5->currentText()); |
253 | delete newgame; | 253 | delete newgame; |
254 | startGame(names); | 254 | startGame(names); |
255 | } else { | 255 | } else { |
256 | // error... | 256 | // error... |
257 | delete newgame; | 257 | delete newgame; |
258 | close(); | 258 | close(); |
259 | } | 259 | } |
260 | } | 260 | } |
261 | 261 | ||
262 | void WordGame::startGame(const QStringList& playerlist) | 262 | void WordGame::startGame(const QStringList& playerlist) |
263 | { | 263 | { |
264 | toolbar->show(); | 264 | toolbar->show(); |
265 | racks = new QWidgetStack(vbox); | 265 | racks = new QWidgetStack(vbox); |
266 | racks->setFixedHeight(TileItem::bigHeight()+2); | 266 | racks->setFixedHeight(TileItem::bigHeight()+2); |
267 | namelist.clear(); | 267 | namelist.clear(); |
268 | nplayers=0; | 268 | nplayers=0; |
269 | for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it) | 269 | for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it) |
270 | addPlayer(*it); | 270 | addPlayer(*it); |
271 | scoreinfo->init(namelist); | 271 | scoreinfo->init(namelist); |
272 | 272 | ||
273 | if ( nplayers ) { | 273 | if ( nplayers ) { |
274 | player=0; | 274 | player=0; |
275 | readyRack(player); | 275 | readyRack(player); |
276 | } | 276 | } |
277 | 277 | ||
278 | board->show(); | 278 | board->show(); |
279 | racks->show(); | 279 | racks->show(); |
280 | } | 280 | } |
281 | 281 | ||
282 | bool WordGame::loadRules(const QString &name) | 282 | bool WordGame::loadRules(const QString &name) |
283 | { | 283 | { |
284 | QString filename = Global::applicationFileName( "wordgame", name ); | 284 | QString filename = Global::applicationFileName( "wordgame", name ); |
285 | QFile file( filename ); | 285 | QFile file( filename ); |
286 | if ( !file.open( IO_ReadOnly ) ) | 286 | if ( !file.open( IO_ReadOnly ) ) |
287 | return FALSE; | 287 | return FALSE; |
288 | 288 | ||
289 | QTextStream ts( &file ); | 289 | QTextStream ts( &file ); |
290 | 290 | ||
291 | QString title = name; | 291 | QString title = name; |
292 | title.truncate( title.length() - 6 ); | 292 | title.truncate( title.length() - 6 ); |
293 | setCaption( title ); | 293 | setCaption( title ); |
294 | 294 | ||
295 | QString shapepixmap; | 295 | QString shapepixmap; |
296 | ts >> shapepixmap; | 296 | ts >> shapepixmap; |
297 | int htiles,vtiles; | 297 | int htiles,vtiles; |
298 | ts >> htiles >> vtiles; | 298 | ts >> htiles >> vtiles; |
299 | 299 | ||
300 | if ( htiles < 3 || vtiles < 3 ) | 300 | if ( htiles < 3 || vtiles < 3 ) |
301 | return FALSE; | 301 | return FALSE; |
302 | 302 | ||
303 | QString rule_shapes; | 303 | QString rule_shapes; |
304 | for (int i=0; i<vtiles; i++) { | 304 | for (int i=0; i<vtiles; i++) { |
305 | QString line; | 305 | QString line; |
306 | ts >> line; | 306 | ts >> line; |
307 | rule_shapes += line; | 307 | rule_shapes += line; |
308 | } | 308 | } |
309 | static int rule_effects[12]; | 309 | static int rule_effects[12]; |
310 | int re=0,e; | 310 | int re=0,e; |
311 | ts >> e; | 311 | ts >> e; |
312 | while ( e && re < 10 ) { | 312 | while ( e && re < 10 ) { |
313 | rule_effects[re] = e; | 313 | rule_effects[re] = e; |
314 | if ( re++ < 10 ) ts >> e; | 314 | if ( re++ < 10 ) ts >> e; |
315 | } | 315 | } |
316 | 316 | ||
317 | QImage shim = Resource::loadImage(shapepixmap); | 317 | QImage shim = Resource::loadImage("wordgame/wordgame_shapes.xpm"); |
318 | shim = shim.smoothScale((re-1)*TileItem::smallWidth(),TileItem::smallHeight()); | 318 | shim = shim.smoothScale((re-1)*TileItem::smallWidth(),TileItem::smallHeight()); |
319 | QPixmap bgshapes; | 319 | QPixmap bgshapes; |
320 | bgshapes.convertFromImage(shim); | 320 | bgshapes.convertFromImage(shim); |
321 | 321 | ||
322 | rule_effects[re++] = 100; // default bonus | 322 | rule_effects[re++] = 100; // default bonus |
323 | board = new Board(bgshapes, htiles, vtiles, vbox); | 323 | board = new Board(bgshapes, htiles, vtiles, vbox); |
324 | board->setRules(rule_shapes, rule_effects); | 324 | board->setRules(rule_shapes, rule_effects); |
325 | connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int))); | 325 | connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int))); |
326 | 326 | ||
327 | bag = new Bag; | 327 | bag = new Bag; |
328 | 328 | ||
329 | int count; | 329 | int count; |
330 | ts >> count; | 330 | ts >> count; |
331 | while ( count ) { | 331 | while ( count ) { |
332 | QString text; | 332 | QString text; |
333 | int value; | 333 | int value; |
334 | ts >> text >> value; | 334 | ts >> text >> value; |
335 | if ( text == "_" ) | 335 | if ( text == "_" ) |
336 | text = ""; | 336 | text = ""; |
337 | 337 | ||
338 | Tile t(text, value); | 338 | Tile t(text, value); |
339 | for (int n=count; n--; ) | 339 | for (int n=count; n--; ) |
340 | bag->add(t); | 340 | bag->add(t); |
341 | 341 | ||
342 | ts >> count; | 342 | ts >> count; |
343 | } | 343 | } |
344 | 344 | ||
345 | return TRUE; | 345 | return TRUE; |
346 | } | 346 | } |
347 | 347 | ||
348 | 348 | ||
349 | NewGame::NewGame(QWidget* parent) : | 349 | NewGame::NewGame(QWidget* parent) : |
350 | NewGameBase(parent) | 350 | NewGameBase(parent) |
351 | { | 351 | { |
352 | } | 352 | } |
353 | 353 | ||
354 | void NewGame::updateRuleSets() | 354 | void NewGame::updateRuleSets() |
355 | { | 355 | { |
356 | rules->clear(); | 356 | rules->clear(); |
357 | 357 | ||
358 | QString rulesDir = Global::applicationFileName( "wordgame", "" ); | 358 | QString rulesDir = Global::applicationFileName( "wordgame", "" ); |
359 | QDir dir( rulesDir, "*.rules" ); | 359 | QDir dir( rulesDir, "*.rules" ); |
360 | ruleslist = dir.entryList(); | 360 | ruleslist = dir.entryList(); |
361 | if ( ruleslist.isEmpty() ) { | 361 | if ( ruleslist.isEmpty() ) { |
362 | // Provide a sample | 362 | // Provide a sample |
363 | QFile file( rulesDir + "Sample.rules" ); | 363 | QFile file( rulesDir + "Sample.rules" ); |
364 | if ( file.open( IO_WriteOnly ) ) { | 364 | if ( file.open( IO_WriteOnly ) ) { |
365 | file.writeBlock( sampleWGR, strlen(sampleWGR) ); | 365 | file.writeBlock( sampleWGR, strlen(sampleWGR) ); |
366 | file.close(); | 366 | file.close(); |
367 | updateRuleSets(); | 367 | updateRuleSets(); |
368 | } | 368 | } |
369 | return; | 369 | return; |
370 | } | 370 | } |
371 | int newest=0; | 371 | int newest=0; |
372 | int newest_age=INT_MAX; | 372 | int newest_age=INT_MAX; |
373 | QDateTime now = QDateTime::currentDateTime(); | 373 | QDateTime now = QDateTime::currentDateTime(); |
374 | QStringList::Iterator it; | 374 | QStringList::Iterator it; |
375 | for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) { | 375 | for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) { |
376 | QFileInfo fi((*it)); | 376 | QFileInfo fi((*it)); |
377 | int age = fi.lastModified().secsTo(now); | 377 | int age = fi.lastModified().secsTo(now); |
378 | QString name = *it; | 378 | QString name = *it; |
379 | name.truncate( name.length()-6 ); // remove extension | 379 | name.truncate( name.length()-6 ); // remove extension |
380 | rules->insertItem( name ); | 380 | rules->insertItem( name ); |
381 | if ( age < newest_age ) { | 381 | if ( age < newest_age ) { |
382 | newest_age = age; | 382 | newest_age = age; |
383 | newest = rules->count()-1; | 383 | newest = rules->count()-1; |
384 | } | 384 | } |
385 | } | 385 | } |
386 | rules->setCurrentItem(newest); | 386 | rules->setCurrentItem(newest); |
387 | } | 387 | } |
388 | 388 | ||
389 | Rules::Rules(QWidget* parent) : | 389 | Rules::Rules(QWidget* parent) : |
390 | RulesBase(parent,0,TRUE) | 390 | RulesBase(parent,0,TRUE) |
391 | { | 391 | { |
392 | } | 392 | } |
393 | 393 | ||
394 | void Rules::editRules() | 394 | void Rules::editRules() |
395 | { | 395 | { |
396 | if ( exec() ) { | 396 | if ( exec() ) { |
397 | // ### create a new set of rules | 397 | // ### create a new set of rules |
398 | emit rulesChanged(); | 398 | emit rulesChanged(); |
399 | } | 399 | } |
400 | } | 400 | } |
401 | 401 | ||
402 | void Rules::deleteRuleSet() | 402 | void Rules::deleteRuleSet() |
403 | { | 403 | { |
404 | // ### delete existing rule set | 404 | // ### delete existing rule set |
405 | emit rulesChanged(); | 405 | emit rulesChanged(); |
406 | } | 406 | } |
407 | 407 | ||
408 | void WordGame::addPlayer(const QString& name) | 408 | void WordGame::addPlayer(const QString& name) |
409 | { | 409 | { |
410 | if ( !name.isEmpty() ) { | 410 | if ( !name.isEmpty() ) { |
411 | int colon = name.find(':'); | 411 | int colon = name.find(':'); |
412 | 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; |
413 | addPlayer(name,cpu); | 413 | addPlayer(name,cpu); |
414 | } | 414 | } |
415 | } | 415 | } |
416 | 416 | ||
417 | void WordGame::addPlayer(const QString& name, int cpu) | 417 | void WordGame::addPlayer(const QString& name, int cpu) |
418 | { | 418 | { |
419 | Rack* r = new Rack(rack_tiles,racks); | 419 | Rack* r = new Rack(rack_tiles,racks); |
420 | r->setPlayerName(name); | 420 | r->setPlayerName(name); |
421 | r->setComputerization(cpu); | 421 | r->setComputerization(cpu); |
422 | racks->addWidget(r, nplayers); | 422 | racks->addWidget(r, nplayers); |
423 | refillRack(nplayers); | 423 | refillRack(nplayers); |
424 | namelist.append(name); | 424 | namelist.append(name); |
425 | 425 | ||
426 | ++nplayers; | 426 | ++nplayers; |
427 | } | 427 | } |
428 | 428 | ||
429 | void WordGame::nextPlayer() | 429 | void WordGame::nextPlayer() |
430 | { | 430 | { |
431 | if ( !refillRack(player) ) { | 431 | if ( !refillRack(player) ) { |
432 | endGame(); | 432 | endGame(); |
433 | } else { | 433 | } else { |
434 | player = (player+1)%nplayers; | 434 | player = (player+1)%nplayers; |
435 | scoreinfo->setBoldOne(player); | 435 | scoreinfo->setBoldOne(player); |
436 | readyRack(player); | 436 | readyRack(player); |
437 | } | 437 | } |
438 | } | 438 | } |
439 | 439 | ||
440 | bool WordGame::mayEndGame() | 440 | bool WordGame::mayEndGame() |
441 | { | 441 | { |
442 | int out=-1; | 442 | int out=-1; |
443 | int i; | 443 | int i; |
444 | for (i=0; i<nplayers; i++) | 444 | for (i=0; i<nplayers; i++) |
445 | if ( !rack(i)->count() ) | 445 | if ( !rack(i)->count() ) |
446 | out = i; | 446 | out = i; |
447 | if ( out<0 ) { | 447 | if ( out<0 ) { |
448 | if ( QMessageBox::warning(this,tr("End game"), | 448 | if ( QMessageBox::warning(this,tr("End game"), |
449 | tr("Do you want to end the game early?"), | 449 | tr("Do you want to end the game early?"), |
450 | tr("Yes"), tr("No") )!=0 ) | 450 | tr("Yes"), tr("No") )!=0 ) |
451 | { | 451 | { |
452 | return FALSE; | 452 | return FALSE; |
453 | } | 453 | } |
454 | } | 454 | } |
455 | return TRUE; | 455 | return TRUE; |
456 | } | 456 | } |
457 | 457 | ||
458 | void WordGame::endGame() | 458 | void WordGame::endGame() |
459 | { | 459 | { |
460 | if ( gameover ) { | 460 | if ( gameover ) { |
461 | close(); | 461 | close(); |
462 | return; | 462 | return; |
463 | } | 463 | } |
464 | 464 | ||
465 | if ( !mayEndGame() ) | 465 | if ( !mayEndGame() ) |
466 | return; | 466 | return; |
467 | int out=-1; | 467 | int out=-1; |
468 | int totalleft=0; | 468 | int totalleft=0; |
469 | int i; | 469 | int i; |
470 | for (i=0; i<nplayers; i++) { | 470 | for (i=0; i<nplayers; i++) { |
471 | Rack* r = rack(i); | 471 | Rack* r = rack(i); |
472 | int c = r->count(); | 472 | int c = r->count(); |
473 | if ( c ) { | 473 | if ( c ) { |
474 | int lose=0; | 474 | int lose=0; |
475 | for ( int j=0; j<c; j++ ) | 475 | for ( int j=0; j<c; j++ ) |
476 | lose += r->tileRef(j)->value(); | 476 | lose += r->tileRef(j)->value(); |
477 | totalleft += lose; | 477 | totalleft += lose; |
478 | scoreinfo->addScore(i,-lose); | 478 | scoreinfo->addScore(i,-lose); |
479 | } else { | 479 | } else { |
480 | out = i; | 480 | out = i; |
481 | } | 481 | } |
482 | } | 482 | } |
483 | int highest=0; | 483 | int highest=0; |
484 | int winner=0; | 484 | int winner=0; |
485 | for (i=0; i<nplayers; i++) { | 485 | for (i=0; i<nplayers; i++) { |
486 | int s = scoreinfo->playerScore(i); | 486 | int s = scoreinfo->playerScore(i); |
487 | if ( s > highest ) { | 487 | if ( s > highest ) { |
488 | highest = s; | 488 | highest = s; |
489 | winner = i; | 489 | winner = i; |
490 | } | 490 | } |
491 | } | 491 | } |
492 | if ( out >= 0 ) | 492 | if ( out >= 0 ) |
493 | scoreinfo->addScore(out,totalleft); | 493 | scoreinfo->addScore(out,totalleft); |
494 | scoreinfo->setBoldOne(winner); | 494 | scoreinfo->setBoldOne(winner); |
495 | gameover = TRUE; | 495 | gameover = TRUE; |
496 | done->setEnabled(TRUE); | 496 | done->setEnabled(TRUE); |
497 | reset->setEnabled(FALSE); | 497 | reset->setEnabled(FALSE); |
498 | } | 498 | } |
499 | 499 | ||
500 | void WordGame::endTurn() | 500 | void WordGame::endTurn() |
501 | { | 501 | { |
502 | if ( gameover ) { | 502 | if ( gameover ) { |
503 | openGameSelector(namelist); | 503 | openGameSelector(namelist); |
504 | } else { | 504 | } else { |
505 | if ( board->checkTurn() ) { | 505 | if ( board->checkTurn() ) { |
506 | if ( board->turnScore() >= 0 ) { | 506 | if ( board->turnScore() >= 0 ) { |
507 | scoreinfo->addScore(player,board->turnScore()); | 507 | scoreinfo->addScore(player,board->turnScore()); |
508 | board->finalizeTurn(); | 508 | board->finalizeTurn(); |
509 | } else { | 509 | } else { |
510 | QApplication::beep(); | 510 | QApplication::beep(); |
511 | } | 511 | } |
512 | nextPlayer(); | 512 | nextPlayer(); |
513 | } | 513 | } |
514 | } | 514 | } |
515 | } | 515 | } |
516 | 516 | ||
517 | void WordGame::resetTurn() | 517 | void WordGame::resetTurn() |
518 | { | 518 | { |
519 | board->resetRack(); | 519 | board->resetRack(); |
520 | } | 520 | } |
521 | 521 | ||
522 | void WordGame::passTurn() | 522 | void WordGame::passTurn() |
523 | { | 523 | { |
524 | // ######## trade? | 524 | // ######## trade? |
525 | nextPlayer(); | 525 | nextPlayer(); |
526 | } | 526 | } |
527 | 527 | ||
528 | bool WordGame::refillRack(int i) | 528 | bool WordGame::refillRack(int i) |
529 | { | 529 | { |
530 | Rack* r = rack(i); | 530 | Rack* r = rack(i); |
531 | while ( !bag->isEmpty() && !r->isFull() ) { | 531 | while ( !bag->isEmpty() && !r->isFull() ) { |
532 | r->addTile(bag->takeRandom()); | 532 | r->addTile(bag->takeRandom()); |
533 | } | 533 | } |
534 | return r->count() != 0; | 534 | return r->count() != 0; |
535 | } | 535 | } |
536 | 536 | ||
537 | void WordGame::readyRack(int i) | 537 | void WordGame::readyRack(int i) |
538 | { | 538 | { |
539 | Rack* r = rack(i); | 539 | Rack* r = rack(i); |
540 | racks->raiseWidget(i); | 540 | racks->raiseWidget(i); |
541 | board->setCurrentRack(r); | 541 | board->setCurrentRack(r); |
542 | 542 | ||
543 | done->setEnabled( !r->computerized() ); | 543 | done->setEnabled( !r->computerized() ); |
544 | reset->setEnabled( !r->computerized() ); | 544 | reset->setEnabled( !r->computerized() ); |
545 | 545 | ||
546 | if ( r->computerized() ) { | 546 | if ( r->computerized() ) { |
547 | cpu = new ComputerPlayer(board, r); | 547 | cpu = new ComputerPlayer(board, r); |
548 | aiheart->start(0); | 548 | aiheart->start(0); |
549 | } | 549 | } |
550 | } | 550 | } |
551 | 551 | ||
552 | Rack* WordGame::rack(int i) const | 552 | Rack* WordGame::rack(int i) const |
553 | { | 553 | { |
554 | return (Rack*)racks->widget(i); | 554 | return (Rack*)racks->widget(i); |
555 | } | 555 | } |
556 | 556 | ||
557 | void WordGame::think() | 557 | void WordGame::think() |
558 | { | 558 | { |
559 | if ( !cpu->step() ) { | 559 | if ( !cpu->step() ) { |
560 | delete cpu; | 560 | delete cpu; |
561 | cpu = 0; | 561 | cpu = 0; |
562 | aiheart->stop(); | 562 | aiheart->stop(); |
563 | if ( board->turnScore() < 0 ) | 563 | if ( board->turnScore() < 0 ) |
564 | passTurn(); | 564 | passTurn(); |
565 | else | 565 | else |
566 | endTurn(); | 566 | endTurn(); |
567 | } | 567 | } |
568 | } | 568 | } |
569 | 569 | ||
570 | ComputerPlayer::ComputerPlayer(Board* b, Rack* r) : | 570 | ComputerPlayer::ComputerPlayer(Board* b, Rack* r) : |
571 | board(b), rack(r), best(new const Tile*[rack_tiles]), | 571 | board(b), rack(r), best(new const Tile*[rack_tiles]), |
572 | best_blankvalues(new Tile[rack_tiles]) | 572 | best_blankvalues(new Tile[rack_tiles]) |
573 | { | 573 | { |
574 | best_score = -1; | 574 | best_score = -1; |
575 | across=FALSE; | 575 | across=FALSE; |
576 | dict=0; | 576 | dict=0; |
577 | } | 577 | } |
578 | 578 | ||
579 | ComputerPlayer::~ComputerPlayer() | 579 | ComputerPlayer::~ComputerPlayer() |
580 | { | 580 | { |
581 | delete [] best; | 581 | delete [] best; |
582 | delete [] best_blankvalues; | 582 | delete [] best_blankvalues; |
583 | } | 583 | } |
584 | 584 | ||
585 | bool ComputerPlayer::step() | 585 | bool ComputerPlayer::step() |
586 | { | 586 | { |
587 | const QDawg::Node* root = dict ? Global::dawg("WordGame").root() | 587 | const QDawg::Node* root = dict ? Global::dawg("WordGame").root() |
588 | : Global::fixedDawg().root(); | 588 | : Global::fixedDawg().root(); |
589 | QPoint d = across ? QPoint(1,0) : QPoint(0,1); | 589 | QPoint d = across ? QPoint(1,0) : QPoint(0,1); |
590 | const Tile* tiles[99]; // ### max board size | 590 | const Tile* tiles[99]; // ### max board size |
591 | uchar nletter[4095]; // QDawg only handles 0..4095 | 591 | uchar nletter[4095]; // QDawg only handles 0..4095 |
592 | memset(nletter,0,4096); | 592 | memset(nletter,0,4096); |
593 | for (int i=0; i<rack->count(); i++) { | 593 | for (int i=0; i<rack->count(); i++) { |
594 | const Tile* r = rack->tileRef(i); | 594 | const Tile* r = rack->tileRef(i); |
595 | if ( r->isBlank() ) | 595 | if ( r->isBlank() ) |
596 | nletter[0]++; | 596 | nletter[0]++; |
597 | else | 597 | else |
598 | nletter[r->text()[0].unicode()]++; | 598 | nletter[r->text()[0].unicode()]++; |
599 | } | 599 | } |
600 | Tile blankvalues[99]; // ### max blanks | 600 | Tile blankvalues[99]; // ### max blanks |
601 | findBest(current, d, root, 0, nletter, tiles, 0, blankvalues, 0); | 601 | findBest(current, d, root, 0, nletter, tiles, 0, blankvalues, 0); |
602 | if ( ++current.rx() == board->xTiles() ) { | 602 | if ( ++current.rx() == board->xTiles() ) { |
603 | current.rx() = 0; | 603 | current.rx() = 0; |
604 | if ( ++current.ry() == board->yTiles() ) { | 604 | if ( ++current.ry() == board->yTiles() ) { |
605 | if ( across ) { | 605 | if ( across ) { |
606 | if ( dict == 1 ) { | 606 | if ( dict == 1 ) { |
607 | if ( best_score >= 0 ) { | 607 | if ( best_score >= 0 ) { |
608 | rack->arrangeTiles(best,best_n); | 608 | rack->arrangeTiles(best,best_n); |
609 | rack->setBlanks(best_blankvalues); | 609 | rack->setBlanks(best_blankvalues); |
610 | board->scoreTurn(best_start, best_n, best_dir); | 610 | board->scoreTurn(best_start, best_n, best_dir); |
611 | board->showTurn(); | 611 | board->showTurn(); |
612 | } | 612 | } |
613 | return FALSE; | 613 | return FALSE; |
614 | } | 614 | } |
615 | dict++; | 615 | dict++; |
616 | across = FALSE; | 616 | across = FALSE; |
617 | current = QPoint(0,0); | 617 | current = QPoint(0,0); |
618 | } else { | 618 | } else { |
619 | across = TRUE; | 619 | across = TRUE; |
620 | current = QPoint(0,0); | 620 | current = QPoint(0,0); |
621 | } | 621 | } |
622 | } | 622 | } |
623 | } | 623 | } |
624 | return TRUE; | 624 | return TRUE; |
625 | } | 625 | } |
626 | 626 | ||
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) | 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) |
628 | { | 628 | { |
629 | if ( !node ) | 629 | if ( !node ) |
630 | return; | 630 | return; |
631 | QChar l = node->letter(); | 631 | QChar l = node->letter(); |
632 | const Tile* cur = board->tile(at); | 632 | const Tile* cur = board->tile(at); |
633 | if ( cur ) { | 633 | if ( cur ) { |
634 | if ( cur->text()[0] == l ) { | 634 | if ( cur->text()[0] == l ) { |
635 | bool nextok = board->contains(at+d); | 635 | bool nextok = board->contains(at+d); |
636 | if ( node->isWord() && n && (!nextok || !board->tile(at+d)) ) | 636 | if ( node->isWord() && n && (!nextok || !board->tile(at+d)) ) |
637 | noteChoice(tiles,n,d,blankvalues,blused); | 637 | noteChoice(tiles,n,d,blankvalues,blused); |
638 | if ( nextok ) | 638 | if ( nextok ) |
639 | 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); |
640 | // #### text()[1]... | 640 | // #### text()[1]... |
641 | } | 641 | } |
642 | } else { | 642 | } else { |
643 | if ( nletter[l.unicode()] || nletter[0] ) { | 643 | if ( nletter[l.unicode()] || nletter[0] ) { |
644 | int rc = rack->count(); | 644 | int rc = rack->count(); |
645 | ulong msk = 1; | 645 | ulong msk = 1; |
646 | for ( int x=0; x<rc; x++ ) { | 646 | for ( int x=0; x<rc; x++ ) { |
647 | if ( !(used&msk) ) { | 647 | if ( !(used&msk) ) { |
648 | const Tile* t = rack->tileRef(x); | 648 | const Tile* t = rack->tileRef(x); |
649 | if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s | 649 | if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s |
650 | bool nextok = board->contains(at+d); | 650 | bool nextok = board->contains(at+d); |
651 | tiles[n++] = t; | 651 | tiles[n++] = t; |
652 | if ( t->isBlank() ) | 652 | if ( t->isBlank() ) |
653 | blankvalues[blused++] = Tile(l,0); | 653 | blankvalues[blused++] = Tile(l,0); |
654 | if ( node->isWord() && (!nextok || !board->tile(at+d)) ) | 654 | if ( node->isWord() && (!nextok || !board->tile(at+d)) ) |
655 | noteChoice(tiles,n,d,blankvalues,blused); | 655 | noteChoice(tiles,n,d,blankvalues,blused); |
656 | used |= msk; // mark | 656 | used |= msk; // mark |
657 | nletter[t->text()[0].unicode()]--; | 657 | nletter[t->text()[0].unicode()]--; |
658 | if ( nextok ) | 658 | if ( nextok ) |
659 | 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); |
660 | n--; | 660 | n--; |
661 | nletter[t->text()[0].unicode()]++; | 661 | nletter[t->text()[0].unicode()]++; |
662 | if ( t->isBlank() ) { | 662 | if ( t->isBlank() ) { |
663 | // keep looking | 663 | // keep looking |
664 | blused--; | 664 | blused--; |
665 | used &= ~msk; // unmark | 665 | used &= ~msk; // unmark |
666 | } else { | 666 | } else { |
667 | break; | 667 | break; |
668 | } | 668 | } |
669 | } | 669 | } |
670 | } | 670 | } |
671 | msk <<= 1; | 671 | msk <<= 1; |
672 | } | 672 | } |
673 | } | 673 | } |
674 | // #### text()[1]... | 674 | // #### text()[1]... |
675 | } | 675 | } |
676 | findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused); | 676 | findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused); |
677 | } | 677 | } |
678 | 678 | ||
679 | 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) |
680 | { | 680 | { |
681 | int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0); | 681 | int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0); |
682 | /* | 682 | /* |
683 | if (s>0 || current==QPoint(5,1)){ | 683 | if (s>0 || current==QPoint(5,1)){ |
684 | QString st; | 684 | QString st; |
685 | for ( int i=0; i<n; i++ ) | 685 | for ( int i=0; i<n; i++ ) |
686 | st += tiles[i]->text(); | 686 | st += tiles[i]->text(); |
687 | 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); |
688 | } | 688 | } |
689 | */ | 689 | */ |
690 | if ( s > best_score ) { | 690 | if ( s > best_score ) { |
691 | int i; | 691 | int i; |
692 | for ( i=0; i<n; i++ ) | 692 | for ( i=0; i<n; i++ ) |
693 | best[i] = tiles[i]; | 693 | best[i] = tiles[i]; |
694 | for ( i=0; i<blused; i++ ) | 694 | for ( i=0; i<blused; i++ ) |
695 | best_blankvalues[i] = blankvalues[i]; | 695 | best_blankvalues[i] = blankvalues[i]; |
696 | best_n = n; | 696 | best_n = n; |
697 | best_blused = blused; | 697 | best_blused = blused; |
698 | best_score = s; | 698 | best_score = s; |
699 | best_dir = d; | 699 | best_dir = d; |
700 | best_start = current; | 700 | best_start = current; |
701 | } | 701 | } |
702 | } | 702 | } |
703 | 703 | ||
704 | int TileItem::smallWidth() | 704 | int TileItem::smallWidth() |
705 | { | 705 | { |
706 | return tile_smallw; | 706 | return tile_smallw; |
707 | } | 707 | } |
708 | 708 | ||
709 | int TileItem::smallHeight() | 709 | int TileItem::smallHeight() |
710 | { | 710 | { |
711 | return tile_smallh; | 711 | return tile_smallh; |
712 | } | 712 | } |
713 | 713 | ||
714 | int TileItem::bigWidth() | 714 | int TileItem::bigWidth() |
715 | { | 715 | { |
716 | return tile_bigw; | 716 | return tile_bigw; |
717 | } | 717 | } |
718 | 718 | ||
719 | int TileItem::bigHeight() | 719 | int TileItem::bigHeight() |
720 | { | 720 | { |
721 | return tile_bigh; | 721 | return tile_bigh; |
722 | } | 722 | } |
723 | 723 | ||
724 | void TileItem::setState( State state ) | 724 | void TileItem::setState( State state ) |
725 | { | 725 | { |
726 | hide(); | 726 | hide(); |
727 | s = state; | 727 | s = state; |
728 | show(); // ### use update() in Qt 3.0 | 728 | show(); // ### use update() in Qt 3.0 |
729 | } | 729 | } |
730 | 730 | ||
731 | void TileItem::setTile(const Tile& tile) | 731 | void TileItem::setTile(const Tile& tile) |
732 | { | 732 | { |
733 | hide(); | 733 | hide(); |
734 | t = tile; | 734 | t = tile; |
735 | show(); // ### use update() in Qt 3.0 | 735 | show(); // ### use update() in Qt 3.0 |
736 | } | 736 | } |
737 | 737 | ||
738 | void TileItem::setBig(bool b) | 738 | void TileItem::setBig(bool b) |
739 | { | 739 | { |
740 | big = b; | 740 | big = b; |
741 | } | 741 | } |
742 | 742 | ||
743 | void TileItem::drawShape(QPainter& p) | 743 | void TileItem::drawShape(QPainter& p) |
744 | { | 744 | { |
745 | static QFont *value_font=0; | 745 | static QFont *value_font=0; |
746 | static QFont *big_font=0; | 746 | static QFont *big_font=0; |
747 | static QFont *small_font=0; | 747 | static QFont *small_font=0; |
748 | if ( !value_font ) { | 748 | if ( !value_font ) { |
749 | value_font = new QFont("helvetica",8); | 749 | value_font = new QFont("helvetica",8); |
750 | if ( TileItem::bigWidth() < 20 ) { | 750 | if ( TileItem::bigWidth() < 20 ) { |
751 | big_font = new QFont("helvetica",12); | 751 | big_font = new QFont("helvetica",12); |
752 | small_font = new QFont("helvetica",8); | 752 | small_font = new QFont("helvetica",8); |
753 | } else { | 753 | } else { |
754 | big_font = new QFont("smoothtimes",17); | 754 | big_font = new QFont("smoothtimes",17); |
755 | small_font = new QFont("smoothtimes",10); | 755 | small_font = new QFont("smoothtimes",10); |
756 | } | 756 | } |
757 | } | 757 | } |
758 | 758 | ||
759 | QRect area(x(),y(),width(),height()); | 759 | QRect area(x(),y(),width(),height()); |
760 | p.setBrush(s == Floating ? yellow/*lightGray*/ : white); | 760 | p.setBrush(s == Floating ? yellow/*lightGray*/ : white); |
761 | p.drawRect(area); | 761 | p.drawRect(area); |
762 | if ( big ) { | 762 | if ( big ) { |
763 | p.setFont(*value_font); | 763 | p.setFont(*value_font); |
764 | QString n = QString::number(t.value()); | 764 | QString n = QString::number(t.value()); |
765 | int w = p.fontMetrics().width('1'); | 765 | int w = p.fontMetrics().width('1'); |
766 | int h = p.fontMetrics().height(); | 766 | int h = p.fontMetrics().height(); |
767 | w *= n.length(); | 767 | w *= n.length(); |
768 | QRect valuearea(x()+width()-w-1,y()+height()-h,w,h); | 768 | QRect valuearea(x()+width()-w-1,y()+height()-h,w,h); |
769 | p.drawText(valuearea,AlignCenter,n); | 769 | p.drawText(valuearea,AlignCenter,n); |
770 | p.setFont(*big_font); | 770 | p.setFont(*big_font); |
771 | area = QRect(x(),y()+tile_btweak,width()-4,height()-1); | 771 | area = QRect(x(),y()+tile_btweak,width()-4,height()-1); |
772 | } else { | 772 | } else { |
773 | p.setFont(*small_font); | 773 | p.setFont(*small_font); |
774 | area = QRect(x()+1+tile_stweak,y()+1,width(),height()-3); | 774 | area = QRect(x()+1+tile_stweak,y()+1,width(),height()-3); |
775 | } | 775 | } |
776 | if ( t.value() == 0 ) | 776 | if ( t.value() == 0 ) |
777 | p.setPen(darkGray); | 777 | p.setPen(darkGray); |
778 | p.drawText(area,AlignCenter,t.text().upper()); | 778 | p.drawText(area,AlignCenter,t.text().upper()); |
779 | } | 779 | } |
780 | 780 | ||
781 | Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) : | 781 | Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) : |
782 | QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()), | 782 | QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()), |
783 | parent) | 783 | parent) |
784 | { | 784 | { |
785 | setFixedSize(w*TileItem::smallWidth(),h*TileItem::smallHeight()); | 785 | setFixedSize(w*TileItem::smallWidth(),h*TileItem::smallHeight()); |
786 | grid = new TileItem*[w*h]; | 786 | grid = new TileItem*[w*h]; |
787 | memset(grid,0,w*h*sizeof(TileItem*)); | 787 | memset(grid,0,w*h*sizeof(TileItem*)); |
788 | setFrameStyle(0); | 788 | setFrameStyle(0); |
789 | setHScrollBarMode(AlwaysOff); | 789 | setHScrollBarMode(AlwaysOff); |
790 | setVScrollBarMode(AlwaysOff); | 790 | setVScrollBarMode(AlwaysOff); |
791 | current_rack = 0; | 791 | current_rack = 0; |
792 | shown_n = 0; | 792 | shown_n = 0; |
793 | } | 793 | } |
794 | 794 | ||
795 | Board::~Board() | 795 | Board::~Board() |
796 | { | 796 | { |
797 | delete canvas(); | 797 | delete canvas(); |
798 | } | 798 | } |
799 | 799 | ||
800 | QSize Board::sizeHint() const | 800 | QSize Board::sizeHint() const |
801 | { | 801 | { |
802 | return QSize(canvas()->width(),canvas()->height()); | 802 | return QSize(canvas()->width(),canvas()->height()); |
803 | } | 803 | } |
804 | 804 | ||
805 | void Board::writeConfig(Config& cfg) | 805 | void Board::writeConfig(Config& cfg) |
806 | { | 806 | { |
807 | QStringList t; | 807 | QStringList t; |
808 | int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); | 808 | int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); |
809 | for (int i=0; i<n; i++) | 809 | for (int i=0; i<n; i++) |
810 | t.append( grid[i] ? grid[i]->tile().key() : QString(".") ); | 810 | t.append( grid[i] ? grid[i]->tile().key() : QString(".") ); |
811 | cfg.writeEntry("Board",t,';'); | 811 | cfg.writeEntry("Board",t,';'); |
812 | } | 812 | } |
813 | 813 | ||
814 | void Board::readConfig(Config& cfg) | 814 | void Board::readConfig(Config& cfg) |
815 | { | 815 | { |
816 | clear(); | 816 | clear(); |
817 | QStringList t = cfg.readListEntry("Board",';'); | 817 | QStringList t = cfg.readListEntry("Board",';'); |
818 | int i=0; | 818 | int i=0; |
819 | int h=canvas()->tilesHorizontally(); | 819 | int h=canvas()->tilesHorizontally(); |
820 | for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) { | 820 | for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) { |
821 | if ( *it != "." ) { | 821 | if ( *it != "." ) { |
822 | QPoint p(i%h,i/h); | 822 | QPoint p(i%h,i/h); |
823 | setTile(p,Tile(*it)); | 823 | setTile(p,Tile(*it)); |
824 | } | 824 | } |
825 | i++; | 825 | i++; |
826 | } | 826 | } |
827 | canvas()->update(); | 827 | canvas()->update(); |
828 | } | 828 | } |
829 | 829 | ||
830 | void Board::clear() | 830 | void Board::clear() |
831 | { | 831 | { |
832 | int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); | 832 | int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); |
833 | for (int i=0; i<n; i++) { | 833 | for (int i=0; i<n; i++) { |
834 | delete grid[i]; | 834 | delete grid[i]; |
835 | grid[i]=0; | 835 | grid[i]=0; |
836 | } | 836 | } |
837 | } | 837 | } |
838 | 838 | ||
839 | 839 | ||
840 | void Board::setCurrentRack(Rack* r) | 840 | void Board::setCurrentRack(Rack* r) |
841 | { | 841 | { |
842 | turn_score = -1; | 842 | turn_score = -1; |
843 | current_rack = r; | 843 | current_rack = r; |
844 | } | 844 | } |
845 | 845 | ||
846 | void Board::resetRack() | 846 | void Board::resetRack() |
847 | { | 847 | { |
848 | unshowTurn(); | 848 | unshowTurn(); |
849 | canvas()->update(); | 849 | canvas()->update(); |
850 | } | 850 | } |
851 | 851 | ||
852 | void Board::contentsMousePressEvent(QMouseEvent* e) | 852 | void Board::contentsMousePressEvent(QMouseEvent* e) |
853 | { | 853 | { |
854 | dragstart = e->pos(); | 854 | dragstart = e->pos(); |
855 | } | 855 | } |
856 | 856 | ||
857 | void Board::contentsMouseMoveEvent(QMouseEvent* e) | 857 | void Board::contentsMouseMoveEvent(QMouseEvent* e) |
858 | { | 858 | { |
859 | if ( current_rack && !current_rack->computerized() ) { | 859 | if ( current_rack && !current_rack->computerized() ) { |
860 | QPoint d = e->pos() - dragstart; | 860 | QPoint d = e->pos() - dragstart; |
861 | if ( d.x() <= 0 && d.y() <= 0 ) { | 861 | if ( d.x() <= 0 && d.y() <= 0 ) { |
862 | // None | 862 | // None |
863 | resetRack(); | 863 | resetRack(); |
864 | } else { | 864 | } else { |
865 | int n; | 865 | int n; |
866 | QPoint start=boardPos(dragstart); | 866 | QPoint start=boardPos(dragstart); |
867 | QPoint end=boardPos(e->pos()); | 867 | QPoint end=boardPos(e->pos()); |
868 | QPoint diff=end-start; | 868 | QPoint diff=end-start; |
869 | QPoint dir; | 869 | QPoint dir; |
870 | if ( d.x() > d.y() ) { | 870 | if ( d.x() > d.y() ) { |
871 | n = diff.x()+1; | 871 | n = diff.x()+1; |
872 | dir = QPoint(1,0); | 872 | dir = QPoint(1,0); |
873 | } else { | 873 | } else { |
874 | n = diff.y()+1; | 874 | n = diff.y()+1; |
875 | dir = QPoint(0,1); | 875 | dir = QPoint(0,1); |
876 | } | 876 | } |
877 | 877 | ||
878 | unshowTurn(); | 878 | unshowTurn(); |
879 | 879 | ||
880 | // Subtract existing tiles from n | 880 | // Subtract existing tiles from n |
881 | QPoint t = start; | 881 | QPoint t = start; |
882 | for ( int i=n; i--; ) { | 882 | for ( int i=n; i--; ) { |
883 | if ( contains(t) && tile(t) ) | 883 | if ( contains(t) && tile(t) ) |
884 | n--; | 884 | n--; |
885 | t += dir; | 885 | t += dir; |
886 | } | 886 | } |
887 | 887 | ||
888 | // Move start back to real start | 888 | // Move start back to real start |
889 | while (contains(start-dir) && tile(start-dir)) | 889 | while (contains(start-dir) && tile(start-dir)) |
890 | start -= dir; | 890 | start -= dir; |
891 | 891 | ||
892 | scoreTurn(start, n, dir); | 892 | scoreTurn(start, n, dir); |
893 | showTurn(); | 893 | showTurn(); |
894 | } | 894 | } |
895 | } | 895 | } |
896 | } | 896 | } |
897 | 897 | ||
898 | void Board::finalizeTurn() | 898 | void Board::finalizeTurn() |
899 | { | 899 | { |
900 | int i=0; | 900 | int i=0; |
901 | QPoint at = shown_at; | 901 | QPoint at = shown_at; |
902 | while ( i<shown_n && contains(at) ) { | 902 | while ( i<shown_n && contains(at) ) { |
903 | if ( item(at) && item(at)->state() == TileItem::Floating ) { | 903 | if ( item(at) && item(at)->state() == TileItem::Floating ) { |
904 | current_rack->remove(item(at)->tile()); | 904 | current_rack->remove(item(at)->tile()); |
905 | setTileState(at,TileItem::Firm); | 905 | setTileState(at,TileItem::Firm); |
906 | i++; | 906 | i++; |
907 | } | 907 | } |
908 | at += shown_step; | 908 | at += shown_step; |
909 | } | 909 | } |
910 | canvas()->update(); | 910 | canvas()->update(); |
911 | } | 911 | } |
912 | 912 | ||
913 | void Board::unshowTurn() | 913 | void Board::unshowTurn() |
914 | { | 914 | { |
915 | int i=0; | 915 | int i=0; |
916 | QPoint at = shown_at; | 916 | QPoint at = shown_at; |
917 | while ( i<shown_n && i<current_rack->count() && contains(at) ) { | 917 | while ( i<shown_n && i<current_rack->count() && contains(at) ) { |
918 | if ( item(at) && item(at)->state() == TileItem::Floating ) { | 918 | if ( item(at) && item(at)->state() == TileItem::Floating ) { |
919 | unsetTile(at); | 919 | unsetTile(at); |
920 | i++; | 920 | i++; |
921 | } | 921 | } |
922 | at += shown_step; | 922 | at += shown_step; |
923 | } | 923 | } |
924 | } | 924 | } |
925 | 925 | ||
926 | void Board::showTurn() | 926 | void Board::showTurn() |
927 | { | 927 | { |
928 | unshowTurn(); | 928 | unshowTurn(); |
929 | QPoint at = shown_at; | 929 | QPoint at = shown_at; |
930 | int i=0; | 930 | int i=0; |
931 | while ( i<shown_n && i<current_rack->count() && contains(at) ) { | 931 | while ( i<shown_n && i<current_rack->count() && contains(at) ) { |
932 | if ( !tile(at) ) { | 932 | if ( !tile(at) ) { |
933 | Tile t = current_rack->tile(i); | 933 | Tile t = current_rack->tile(i); |
934 | setTile(at,t); | 934 | setTile(at,t); |
935 | setTileState(at,TileItem::Floating); | 935 | setTileState(at,TileItem::Floating); |
936 | i++; | 936 | i++; |
937 | } | 937 | } |
938 | at += shown_step; | 938 | at += shown_step; |
939 | } | 939 | } |
940 | canvas()->update(); | 940 | canvas()->update(); |
941 | } | 941 | } |
942 | 942 | ||
943 | int Board::bonussedValue(const QPoint& at, int base, int& all_mult) const | 943 | int Board::bonussedValue(const QPoint& at, int base, int& all_mult) const |
944 | { | 944 | { |
945 | int rule = rule_shape[idx(at)]-'0'; | 945 | int rule = rule_shape[idx(at)]-'0'; |
946 | int effect = rule_effect[rule]; | 946 | int effect = rule_effect[rule]; |
947 | int mult = effect&Multiplier; | 947 | int mult = effect&Multiplier; |
948 | if ( effect & MultiplyAll ) { | 948 | if ( effect & MultiplyAll ) { |
949 | all_mult *= mult; | 949 | all_mult *= mult; |
950 | return base; | 950 | return base; |
951 | } else { | 951 | } else { |
952 | return base * mult; | 952 | return base * mult; |
953 | } | 953 | } |
954 | } | 954 | } |
955 | 955 | ||
956 | bool Board::isStart(const QPoint& at) const | 956 | bool Board::isStart(const QPoint& at) const |
957 | { | 957 | { |
958 | int rule = rule_shape[idx(at)]-'0'; | 958 | int rule = rule_shape[idx(at)]-'0'; |
959 | int effect = rule_effect[rule]; | 959 | int effect = rule_effect[rule]; |
960 | return effect&Start; | 960 | return effect&Start; |
961 | } | 961 | } |
962 | 962 | ||
963 | bool Board::checkTurn() | 963 | bool Board::checkTurn() |
964 | { | 964 | { |
965 | if ( current_rack->computerized() ) | 965 | if ( current_rack->computerized() ) |
966 | return TRUE; // computer doesn't cheat, and has already set blanks. | 966 | return TRUE; // computer doesn't cheat, and has already set blanks. |
967 | 967 | ||
968 | QPoint at = shown_at; | 968 | QPoint at = shown_at; |
969 | int n = shown_n; | 969 | int n = shown_n; |
970 | QPoint d = shown_step; | 970 | QPoint d = shown_step; |
971 | const Tile* tiles[99]; | 971 | const Tile* tiles[99]; |
972 | Tile blankvalues[99]; | 972 | Tile blankvalues[99]; |
973 | if ( n > current_rack->count() ) | 973 | if ( n > current_rack->count() ) |
974 | n = current_rack->count(); | 974 | n = current_rack->count(); |
975 | 975 | ||
976 | QDialog check(this,0,TRUE); | 976 | QDialog check(this,0,TRUE); |
977 | (new QVBoxLayout(&check))->setAutoAdd(TRUE); | 977 | (new QVBoxLayout(&check))->setAutoAdd(TRUE); |
978 | 978 | ||
979 | QHBox mw(&check); | 979 | QHBox mw(&check); |
980 | new QLabel(tr("Blanks: "),&mw); | 980 | new QLabel(tr("Blanks: "),&mw); |
981 | 981 | ||
982 | int bl=0; | 982 | int bl=0; |
983 | QLineEdit* le[99]; | 983 | QLineEdit* le[99]; |
984 | for (int i=0; i<n; i++) { | 984 | for (int i=0; i<n; i++) { |
985 | tiles[i] = current_rack->tileRef(i); | 985 | tiles[i] = current_rack->tileRef(i); |
986 | if ( tiles[i]->isBlank() ) { | 986 | if ( tiles[i]->isBlank() ) { |
987 | QLineEdit *l = new QLineEdit(&mw); | 987 | QLineEdit *l = new QLineEdit(&mw); |
988 | le[bl++] = l; | 988 | le[bl++] = l; |
989 | l->setMaxLength(1); | 989 | l->setMaxLength(1); |
990 | l->setFixedSize(l->minimumSizeHint()); | 990 | l->setFixedSize(l->minimumSizeHint()); |
991 | } | 991 | } |
992 | } | 992 | } |
993 | 993 | ||
994 | QHBox btns(&check); | 994 | QHBox btns(&check); |
995 | connect(new QPushButton(tr("OK"),&btns), SIGNAL(clicked()), &check, SLOT(accept())); | 995 | connect(new QPushButton(tr("OK"),&btns), SIGNAL(clicked()), &check, SLOT(accept())); |
996 | connect(new QPushButton(tr("Cancel"),&btns), SIGNAL(clicked()), &check, SLOT(reject())); | 996 | connect(new QPushButton(tr("Cancel"),&btns), SIGNAL(clicked()), &check, SLOT(reject())); |
997 | 997 | ||
998 | if ( bl ) { | 998 | if ( bl ) { |
999 | retry: | 999 | retry: |
1000 | if ( !check.exec() ) { | 1000 | if ( !check.exec() ) { |
1001 | unshowTurn(); | 1001 | unshowTurn(); |
1002 | canvas()->update(); | 1002 | canvas()->update(); |
1003 | return FALSE; | 1003 | return FALSE; |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | for (int b=0; b<bl; b++) { | 1006 | for (int b=0; b<bl; b++) { |
1007 | QString v = le[b]->text(); | 1007 | QString v = le[b]->text(); |
1008 | blankvalues[b]=Tile(v,0); | 1008 | blankvalues[b]=Tile(v,0); |
1009 | if ( v.length() != 1 ) | 1009 | if ( v.length() != 1 ) |
1010 | goto retry; | 1010 | goto retry; |
1011 | } | 1011 | } |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | QStringList words; | 1014 | QStringList words; |
1015 | unshowTurn(); | 1015 | unshowTurn(); |
1016 | turn_score = score(at,tiles,n,blankvalues,d,FALSE,&words); | 1016 | turn_score = score(at,tiles,n,blankvalues,d,FALSE,&words); |
1017 | showTurn(); | 1017 | showTurn(); |
1018 | QStringList to_add; | 1018 | QStringList to_add; |
1019 | for (QStringList::Iterator it=words.begin(); it!=words.end(); ++it) { | 1019 | for (QStringList::Iterator it=words.begin(); it!=words.end(); ++it) { |
1020 | if ( !Global::fixedDawg().contains(*it) | 1020 | if ( !Global::fixedDawg().contains(*it) |
1021 | && !Global::dawg("WordGame").contains(*it) ) { | 1021 | && !Global::dawg("WordGame").contains(*it) ) { |
1022 | switch (QMessageBox::warning(this, tr("Unknown word"), | 1022 | switch (QMessageBox::warning(this, tr("Unknown word"), |
1023 | tr("<p>The word \"%1\" is not in the dictionary.").arg(*it), | 1023 | tr("<p>The word \"%1\" is not in the dictionary.").arg(*it), |
1024 | tr("Add"), tr("Ignore"), tr("Cancel"))) | 1024 | tr("Add"), tr("Ignore"), tr("Cancel"))) |
1025 | { | 1025 | { |
1026 | case 0: | 1026 | case 0: |
1027 | // ####### add to wordgame dictionary | 1027 | // ####### add to wordgame dictionary |
1028 | to_add.append(*it); | 1028 | to_add.append(*it); |
1029 | break; | 1029 | break; |
1030 | case 1: | 1030 | case 1: |
1031 | break; | 1031 | break; |
1032 | case 2: | 1032 | case 2: |
1033 | unshowTurn(); | 1033 | unshowTurn(); |
1034 | canvas()->update(); | 1034 | canvas()->update(); |
1035 | return FALSE; | 1035 | return FALSE; |
1036 | } | 1036 | } |
1037 | } | 1037 | } |
1038 | } | 1038 | } |
1039 | if ( to_add.count() ) | 1039 | if ( to_add.count() ) |
1040 | Global::addWords("WordGame",to_add); | 1040 | Global::addWords("WordGame",to_add); |
1041 | return TRUE; | 1041 | return TRUE; |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | void Board::scoreTurn(const QPoint& at, int n, const QPoint& d) | 1044 | void Board::scoreTurn(const QPoint& at, int n, const QPoint& d) |
1045 | { | 1045 | { |
1046 | unshowTurn(); | 1046 | unshowTurn(); |
1047 | shown_at = at; | 1047 | shown_at = at; |
1048 | shown_n = n; | 1048 | shown_n = n; |
1049 | shown_step = d; | 1049 | shown_step = d; |
1050 | const Tile* tiles[99]; | 1050 | const Tile* tiles[99]; |
1051 | if ( n > current_rack->count() ) | 1051 | if ( n > current_rack->count() ) |
1052 | n = current_rack->count(); | 1052 | n = current_rack->count(); |
1053 | for (int i=0; i<n; i++) | 1053 | for (int i=0; i<n; i++) |
1054 | tiles[i] = current_rack->tileRef(i); | 1054 | tiles[i] = current_rack->tileRef(i); |
1055 | turn_score = score(at,tiles,n,0,d,FALSE,0); | 1055 | turn_score = score(at,tiles,n,0,d,FALSE,0); |
1056 | emit temporaryScore(turn_score); | 1056 | emit temporaryScore(turn_score); |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | int Board::score(QPoint at, const Tile** tiles, int n, const Tile* blankvalue, const QPoint& d, bool checkdict, QStringList* words) const | 1059 | int Board::score(QPoint at, const Tile** tiles, int n, const Tile* blankvalue, const QPoint& d, bool checkdict, QStringList* words) const |
1060 | { | 1060 | { |
1061 | int total=0; | 1061 | int total=0; |
1062 | int totalsidetotal=0; | 1062 | int totalsidetotal=0; |
1063 | 1063 | ||
1064 | // words gets filled with words made | 1064 | // words gets filled with words made |
1065 | 1065 | ||
1066 | // mainword==0 -> | 1066 | // mainword==0 -> |
1067 | // Checks side words, but not main word | 1067 | // Checks side words, but not main word |
1068 | 1068 | ||
1069 | // -1 means words not in dict, or illegally positioned (eg. not connected) | 1069 | // -1 means words not in dict, or illegally positioned (eg. not connected) |
1070 | 1070 | ||
1071 | // text is assumed to fit on board. | 1071 | // text is assumed to fit on board. |
1072 | 1072 | ||
1073 | if ( words ) *words=QStringList(); | 1073 | if ( words ) *words=QStringList(); |
1074 | 1074 | ||
1075 | QPoint otherd(d.y(), d.x()); | 1075 | QPoint otherd(d.y(), d.x()); |
1076 | 1076 | ||
1077 | int all_mult = 1; | 1077 | int all_mult = 1; |
1078 | int bl=0; | 1078 | int bl=0; |
1079 | 1079 | ||
1080 | bool connected = FALSE; | 1080 | bool connected = FALSE; |
1081 | 1081 | ||
1082 | QString mainword=""; | 1082 | QString mainword=""; |
1083 | 1083 | ||
1084 | if ( contains(at-d) && tile(at-d) ) { | 1084 | if ( contains(at-d) && tile(at-d) ) { |
1085 | return -1; // preceeding tiles | 1085 | return -1; // preceeding tiles |