-rw-r--r-- | noncore/games/wordgame/wordgame.cpp | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/noncore/games/wordgame/wordgame.cpp b/noncore/games/wordgame/wordgame.cpp index 52e2be2..8cf92ef 100644 --- a/noncore/games/wordgame/wordgame.cpp +++ b/noncore/games/wordgame/wordgame.cpp | |||
@@ -1,1518 +1,1518 @@ | |||
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 <opie2/oresource.h> | 24 | #include <opie2/oresource.h> |
25 | 25 | ||
26 | #include <qpe/global.h> | 26 | #include <qpe/global.h> |
27 | #include <qpe/config.h> | 27 | #include <qpe/config.h> |
28 | 28 | ||
29 | #include <qapplication.h> | 29 | #include <qapplication.h> |
30 | #include <qmessagebox.h> | 30 | #include <qmessagebox.h> |
31 | #include <qcombobox.h> | 31 | #include <qcombobox.h> |
32 | #include <qdir.h> | 32 | #include <qdir.h> |
33 | #include <qlineedit.h> | 33 | #include <qlineedit.h> |
34 | #include <qpushbutton.h> | 34 | #include <qpushbutton.h> |
35 | #include <qtextstream.h> | 35 | #include <qtextstream.h> |
36 | #include <qtimer.h> | 36 | #include <qtimer.h> |
37 | #include <qtoolbar.h> | 37 | #include <qtoolbar.h> |
38 | #include <qtoolbutton.h> | 38 | #include <qtoolbutton.h> |
39 | #include <qvbox.h> | 39 | #include <qvbox.h> |
40 | #include <qwidgetstack.h> | 40 | #include <qwidgetstack.h> |
41 | #include <qlayout.h> | 41 | #include <qlayout.h> |
42 | 42 | ||
43 | #include <stdlib.h> | 43 | #include <stdlib.h> |
44 | #include <unistd.h> | 44 | #include <unistd.h> |
45 | #include <pwd.h> | 45 | #include <pwd.h> |
46 | #include <sys/types.h> | 46 | #include <sys/types.h> |
47 | 47 | ||
48 | enum RuleEffects { | 48 | enum RuleEffects { |
49 | Multiplier=15, | 49 | Multiplier=15, |
50 | MultiplyAll=64, | 50 | MultiplyAll=64, |
51 | Start=128 | 51 | Start=128 |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static int tile_smallw = 16; | 54 | static int tile_smallw = 16; |
55 | static int tile_smallh = 16; | 55 | static int tile_smallh = 16; |
56 | static int tile_bigw = 22; | 56 | static int tile_bigw = 22; |
57 | static int tile_bigh = 22; | 57 | static int tile_bigh = 22; |
58 | static int tile_stweak = -2; | 58 | static int tile_stweak = -2; |
59 | static int tile_btweak = -1; | 59 | static int tile_btweak = -1; |
60 | 60 | ||
61 | static const int rack_tiles=7; | 61 | static const int rack_tiles=7; |
62 | 62 | ||
63 | const char* sampleWGR= | 63 | const char* sampleWGR= |
64 | "wordgame_shapes\n" | 64 | "wordgame_shapes\n" |
65 | "15 15\n" | 65 | "15 15\n" |
66 | "400001040100004\n" | 66 | "400001040100004\n" |
67 | "030000000000030\n" | 67 | "030000000000030\n" |
68 | "002002000200200\n" | 68 | "002002000200200\n" |
69 | "000300020003000\n" | 69 | "000300020003000\n" |
70 | "000020000020000\n" | 70 | "000020000020000\n" |
71 | "102001000100201\n" | 71 | "102001000100201\n" |
72 | "000000202000000\n" | 72 | "000000202000000\n" |
73 | "400200050002004\n" | 73 | "400200050002004\n" |
74 | "000000202000000\n" | 74 | "000000202000000\n" |
75 | "102001000100201\n" | 75 | "102001000100201\n" |
76 | "000020000020000\n" | 76 | "000020000020000\n" |
77 | "000300020003000\n" | 77 | "000300020003000\n" |
78 | "002002000200200\n" | 78 | "002002000200200\n" |
79 | "030000000000030\n" | 79 | "030000000000030\n" |
80 | "400001040100004\n" | 80 | "400001040100004\n" |
81 | "1 2 3 66 67 194 100 0\n" | 81 | "1 2 3 66 67 194 100 0\n" |
82 | "1 j 8\n" | 82 | "1 j 8\n" |
83 | "1 q 7\n" | 83 | "1 q 7\n" |
84 | "1 x 6\n" | 84 | "1 x 6\n" |
85 | "1 z 6\n" | 85 | "1 z 6\n" |
86 | "1 w 4\n" | 86 | "1 w 4\n" |
87 | "1 k 4\n" | 87 | "1 k 4\n" |
88 | "1 v 3\n" | 88 | "1 v 3\n" |
89 | "1 f 3\n" | 89 | "1 f 3\n" |
90 | "2 y 3\n" | 90 | "2 y 3\n" |
91 | "2 h 2\n" | 91 | "2 h 2\n" |
92 | "2 b 2\n" | 92 | "2 b 2\n" |
93 | "2 m 2\n" | 93 | "2 m 2\n" |
94 | "3 p 2\n" | 94 | "3 p 2\n" |
95 | "3 g 2\n" | 95 | "3 g 2\n" |
96 | "3 u 2\n" | 96 | "3 u 2\n" |
97 | "4 d 2\n" | 97 | "4 d 2\n" |
98 | "4 c 2\n" | 98 | "4 c 2\n" |
99 | "5 l 1\n" | 99 | "5 l 1\n" |
100 | "5 o 1\n" | 100 | "5 o 1\n" |
101 | "7 t 1\n" | 101 | "7 t 1\n" |
102 | "7 n 1\n" | 102 | "7 n 1\n" |
103 | "7 a 1\n" | 103 | "7 a 1\n" |
104 | "7 r 1\n" | 104 | "7 r 1\n" |
105 | "8 s 1\n" | 105 | "8 s 1\n" |
106 | "8 i 1\n" | 106 | "8 i 1\n" |
107 | "11 e 1\n" | 107 | "11 e 1\n" |
108 | "0\n"; | 108 | "0\n"; |
109 | 109 | ||
110 | WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) : | 110 | WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) : |
111 | QMainWindow(parent, name, fl) | 111 | QMainWindow(parent, name, fl) |
112 | { | 112 | { |
113 | if ( qApp->desktop()->width() < 240 ) { | 113 | if ( qApp->desktop()->width() < 240 ) { |
114 | tile_smallw = 10; | 114 | tile_smallw = 10; |
115 | tile_smallh = 10; | 115 | tile_smallh = 10; |
116 | tile_bigw = 16; | 116 | tile_bigw = 16; |
117 | tile_bigh = 16; | 117 | tile_bigh = 16; |
118 | tile_stweak = 0; | 118 | tile_stweak = 0; |
119 | tile_btweak = 0; | 119 | tile_btweak = 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | setIcon( Opie::Core::OResource::loadPixmap( "wordgame/WordGame" ) ); | 122 | setIcon( Opie::Core::OResource::loadPixmap( "wordgame/WordGame" ) ); |
123 | setCaption( tr("Word Game") ); | 123 | setCaption( tr("Word Game") ); |
124 | 124 | ||
125 | setToolBarsMovable( FALSE ); | 125 | setToolBarsMovable( FALSE ); |
126 | vbox = new QVBox(this); | 126 | vbox = new QVBox(this); |
127 | 127 | ||
128 | setCentralWidget(vbox); | 128 | setCentralWidget(vbox); |
129 | toolbar = new QToolBar(this); | 129 | toolbar = new QToolBar(this); |
130 | addToolBar(toolbar, Bottom); | 130 | addToolBar(toolbar, Bottom); |
131 | bool useBigIcon = qApp->desktop()->size().width() > 330; | 131 | bool useBigIcon = qApp->desktop()->size().width() > 330; |
132 | reset = new QToolButton(Opie::Core::OResource::loadPixmap("back", Opie::Core::OResource::SmallIcon), | 132 | reset = new QToolButton(Opie::Core::OResource::loadPixmap("back", Opie::Core::OResource::SmallIcon), |
133 | tr("Back"), "", this, SLOT(resetTurn()), toolbar); | 133 | tr("Back"), "", this, SLOT(resetTurn()), toolbar); |
134 | reset->setUsesBigPixmap( useBigIcon ); | 134 | reset->setUsesBigPixmap( useBigIcon ); |
135 | done = new QToolButton(Opie::Core::OResource::loadPixmap("done", Opie::Core::OResource::SmallIcon), | 135 | done = new QToolButton(Opie::Core::OResource::loadPixmap("done", Opie::Core::OResource::SmallIcon), |
136 | tr("Done"), "", this, SLOT(endTurn()), toolbar); | 136 | tr("Done"), "", this, SLOT(endTurn()), toolbar); |
137 | done->setUsesBigPixmap( useBigIcon ); | 137 | done->setUsesBigPixmap( useBigIcon ); |
138 | scoreinfo = new ScoreInfo(toolbar); | 138 | scoreinfo = new ScoreInfo(toolbar); |
139 | scoreinfo->setFont(QFont("Helvetica",10)); | 139 | scoreinfo->setFont(QFont("Helvetica",10)); |
140 | QToolButton *btn = new QToolButton(Opie::Core::OResource::loadPixmap("finish", Opie::Core::OResource::SmallIcon), | 140 | QToolButton *btn = new QToolButton(Opie::Core::OResource::loadPixmap("finish", Opie::Core::OResource::SmallIcon), |
141 | tr("Close"), "", this, SLOT(endGame()), toolbar); | 141 | tr("Close"), "", this, SLOT(endGame()), toolbar); |
142 | btn->setUsesBigPixmap( useBigIcon ); | 142 | btn->setUsesBigPixmap( useBigIcon ); |
143 | toolbar->setStretchableWidget(scoreinfo); | 143 | toolbar->setStretchableWidget(scoreinfo); |
144 | 144 | ||
145 | cpu = 0; | 145 | cpu = 0; |
146 | board = 0; | 146 | board = 0; |
147 | bag = 0; | 147 | bag = 0; |
148 | racks = 0; | 148 | racks = 0; |
149 | 149 | ||
150 | aiheart = new QTimer(this); | 150 | aiheart = new QTimer(this); |
151 | connect(aiheart, SIGNAL(timeout()), this, SLOT(think())); | 151 | connect(aiheart, SIGNAL(timeout()), this, SLOT(think())); |
152 | 152 | ||
153 | readConfig(); | 153 | readConfig(); |
154 | } | 154 | } |
155 | 155 | ||
156 | WordGame::~WordGame() | 156 | WordGame::~WordGame() |
157 | { | 157 | { |
158 | writeConfig(); | 158 | writeConfig(); |
159 | } | 159 | } |
160 | 160 | ||
161 | void WordGame::writeConfig() | 161 | void WordGame::writeConfig() |
162 | { | 162 | { |
163 | Config cfg("WordGame"); | 163 | Config cfg("WordGame"); |
164 | cfg.setGroup("Game"); | 164 | cfg.setGroup("Game"); |
165 | cfg.writeEntry("NameList",namelist,';'); | 165 | cfg.writeEntry("NameList",namelist,';'); |
166 | cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1); | 166 | cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1); |
167 | if ( !gameover ) { | 167 | if ( !gameover ) { |
168 | cfg.writeEntry("Rules",rules); | 168 | cfg.writeEntry("Rules",rules); |
169 | bag->writeConfig(cfg); | 169 | bag->writeConfig(cfg); |
170 | board->writeConfig(cfg); | 170 | board->writeConfig(cfg); |
171 | scoreinfo->writeConfig(cfg); | 171 | scoreinfo->writeConfig(cfg); |
172 | } | 172 | } |
173 | for (int p=0; p<nplayers; p++) { | 173 | for (int p=0; p<nplayers; p++) { |
174 | cfg.setGroup("Player"+QString::number(p+1)); | 174 | cfg.setGroup("Player"+QString::number(p+1)); |
175 | if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg); | 175 | if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg); |
176 | } | 176 | } |
177 | } | 177 | } |
178 | 178 | ||
179 | void WordGame::readConfig() | 179 | void WordGame::readConfig() |
180 | { | 180 | { |
181 | Config cfg("WordGame"); | 181 | Config cfg("WordGame"); |
182 | cfg.setGroup("Game"); | 182 | cfg.setGroup("Game"); |
183 | int currentplayer = cfg.readNumEntry("CurrentPlayer",0); | 183 | int currentplayer = cfg.readNumEntry("CurrentPlayer",0); |
184 | QStringList pnames = cfg.readListEntry("NameList",';'); | 184 | QStringList pnames = cfg.readListEntry("NameList",';'); |
185 | if ( currentplayer ) { | 185 | if ( currentplayer ) { |
186 | gameover = FALSE; | 186 | gameover = FALSE; |
187 | rules = cfg.readEntry("Rules"); | 187 | rules = cfg.readEntry("Rules"); |
188 | if ( rules.find("x-wordgamerules") >= 0 ) { | 188 | if ( rules.find("x-wordgamerules") >= 0 ) { |
189 | // rules files moved | 189 | // rules files moved |
190 | rules = "Sample.rules"; | 190 | rules = "Sample.rules"; |
191 | } | 191 | } |
192 | if ( loadRules(rules) ) { | 192 | if ( loadRules(rules) ) { |
193 | startGame(pnames); | 193 | startGame(pnames); |
194 | bag->readConfig(cfg); | 194 | bag->readConfig(cfg); |
195 | board->readConfig(cfg); | 195 | board->readConfig(cfg); |
196 | scoreinfo->readConfig(cfg); | 196 | scoreinfo->readConfig(cfg); |
197 | for (int p=0; p<nplayers; p++) { | 197 | for (int p=0; p<nplayers; p++) { |
198 | cfg.setGroup("Player"+QString::number(p+1)); | 198 | cfg.setGroup("Player"+QString::number(p+1)); |
199 | rack(p)->readConfig(cfg); | 199 | rack(p)->readConfig(cfg); |
200 | } | 200 | } |
201 | player=currentplayer-1; | 201 | player=currentplayer-1; |
202 | readyRack(player); | 202 | readyRack(player); |
203 | return; | 203 | return; |
204 | } | 204 | } |
205 | } | 205 | } |
206 | // fall-back | 206 | // fall-back |
207 | openGameSelector(pnames); | 207 | openGameSelector(pnames); |
208 | } | 208 | } |
209 | 209 | ||
210 | void WordGame::openGameSelector(const QStringList& initnames) | 210 | void WordGame::openGameSelector(const QStringList& initnames) |
211 | { | 211 | { |
212 | toolbar->hide(); | 212 | toolbar->hide(); |
213 | gameover = FALSE; | 213 | gameover = FALSE; |
214 | 214 | ||
215 | delete board; | 215 | delete board; |
216 | board = 0; | 216 | board = 0; |
217 | delete racks; | 217 | delete racks; |
218 | racks = 0; | 218 | racks = 0; |
219 | 219 | ||
220 | delete cpu; | 220 | delete cpu; |
221 | cpu = 0; | 221 | cpu = 0; |
222 | 222 | ||
223 | newgame = new NewGame(vbox); | 223 | newgame = new NewGame(vbox); |
224 | 224 | ||
225 | //Rules rules(this); | 225 | //Rules rules(this); |
226 | //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules())); | 226 | //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules())); |
227 | //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets())); | 227 | //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets())); |
228 | struct passwd* n = getpwuid(getuid()); | 228 | struct passwd* n = getpwuid(getuid()); |
229 | QString playername = n ? n->pw_name : ""; | 229 | QString playername = n ? n->pw_name : ""; |
230 | if ( playername.isEmpty() ) { | 230 | if ( playername.isEmpty() ) { |
231 | playername = "Player"; | 231 | playername = "Player"; |
232 | } | 232 | } |
233 | newgame->player0->changeItem(playername,0); | 233 | newgame->player0->changeItem(playername,0); |
234 | newgame->player1->setCurrentItem(1); | 234 | newgame->player1->setCurrentItem(1); |
235 | newgame->updateRuleSets(); | 235 | newgame->updateRuleSets(); |
236 | newgame->show(); | 236 | newgame->show(); |
237 | 237 | ||
238 | connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame())); | 238 | connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame())); |
239 | } | 239 | } |
240 | 240 | ||
241 | void WordGame::startGame() | 241 | void WordGame::startGame() |
242 | { | 242 | { |
243 | rules = newgame->ruleslist[newgame->rules->currentItem()]; | 243 | rules = newgame->ruleslist[newgame->rules->currentItem()]; |
244 | if ( loadRules(rules) ) { | 244 | if ( loadRules(rules) ) { |
245 | QStringList names; | 245 | QStringList names; |
246 | names.append(newgame->player0->currentText()); | 246 | names.append(newgame->player0->currentText()); |
247 | names.append(newgame->player1->currentText()); | 247 | names.append(newgame->player1->currentText()); |
248 | names.append(newgame->player2->currentText()); | 248 | names.append(newgame->player2->currentText()); |
249 | names.append(newgame->player3->currentText()); | 249 | names.append(newgame->player3->currentText()); |
250 | names.append(newgame->player4->currentText()); | 250 | names.append(newgame->player4->currentText()); |
251 | names.append(newgame->player5->currentText()); | 251 | names.append(newgame->player5->currentText()); |
252 | delete newgame; | 252 | delete newgame; |
253 | startGame(names); | 253 | startGame(names); |
254 | } else { | 254 | } else { |
255 | // error... | 255 | // error... |
256 | delete newgame; | 256 | delete newgame; |
257 | close(); | 257 | close(); |
258 | } | 258 | } |
259 | } | 259 | } |
260 | 260 | ||
261 | void WordGame::startGame(const QStringList& playerlist) | 261 | void WordGame::startGame(const QStringList& playerlist) |
262 | { | 262 | { |
263 | toolbar->show(); | 263 | toolbar->show(); |
264 | racks = new QWidgetStack(vbox); | 264 | racks = new QWidgetStack(vbox); |
265 | racks->setFixedHeight(TileItem::bigHeight()+2); | 265 | racks->setFixedHeight(TileItem::bigHeight()+2); |
266 | namelist.clear(); | 266 | namelist.clear(); |
267 | nplayers=0; | 267 | nplayers=0; |
268 | for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it) | 268 | for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it) |
269 | addPlayer(*it); | 269 | addPlayer(*it); |
270 | scoreinfo->init(namelist); | 270 | scoreinfo->init(namelist); |
271 | 271 | ||
272 | if ( nplayers ) { | 272 | if ( nplayers ) { |
273 | player=0; | 273 | player=0; |
274 | readyRack(player); | 274 | readyRack(player); |
275 | } | 275 | } |
276 | 276 | ||
277 | board->show(); | 277 | board->show(); |
278 | racks->show(); | 278 | racks->show(); |
279 | } | 279 | } |
280 | 280 | ||
281 | bool WordGame::loadRules(const QString &name) | 281 | bool WordGame::loadRules(const QString &name) |
282 | { | 282 | { |
283 | QString filename = Global::applicationFileName( "wordgame", name ); | 283 | QString filename = Global::applicationFileName( "wordgame", name ); |
284 | QFile file( filename ); | 284 | QFile file( filename ); |
285 | if ( !file.open( IO_ReadOnly ) ) | 285 | if ( !file.open( IO_ReadOnly ) ) |
286 | return FALSE; | 286 | return FALSE; |
287 | 287 | ||
288 | QTextStream ts( &file ); | 288 | QTextStream ts( &file ); |
289 | 289 | ||
290 | QString title = name; | 290 | QString title = name; |
291 | title.truncate( title.length() - 6 ); | 291 | title.truncate( title.length() - 6 ); |
292 | //setCaption( title ); | 292 | //setCaption( title ); |
293 | 293 | ||
294 | QString shapepixmap; | 294 | QString shapepixmap; |
295 | ts >> shapepixmap; | 295 | ts >> shapepixmap; |
296 | int htiles,vtiles; | 296 | int htiles,vtiles; |
297 | ts >> htiles >> vtiles; | 297 | ts >> htiles >> vtiles; |
298 | 298 | ||
299 | if ( htiles < 3 || vtiles < 3 ) | 299 | if ( htiles < 3 || vtiles < 3 ) |
300 | return FALSE; | 300 | return FALSE; |
301 | 301 | ||
302 | QString rule_shapes; | 302 | QString rule_shapes; |
303 | for (int i=0; i<vtiles; i++) { | 303 | for (int i=0; i<vtiles; i++) { |
304 | QString line; | 304 | QString line; |
305 | ts >> line; | 305 | ts >> line; |
306 | rule_shapes += line; | 306 | rule_shapes += line; |
307 | } | 307 | } |
308 | static int rule_effects[12]; | 308 | static int rule_effects[12]; |
309 | int re=0,e; | 309 | int re=0,e; |
310 | ts >> e; | 310 | ts >> e; |
311 | while ( e && re < 10 ) { | 311 | while ( e && re < 10 ) { |
312 | rule_effects[re] = e; | 312 | rule_effects[re] = e; |
313 | if ( re++ < 10 ) ts >> e; | 313 | if ( re++ < 10 ) ts >> e; |
314 | } | 314 | } |
315 | 315 | ||
316 | QImage shim = Opie::Core::OResource::loadImage("wordgame/wordgame_shapes"); | 316 | QImage shim = Opie::Core::OResource::loadImage("wordgame/wordgame_shapes"); |
317 | shim = shim.smoothScale((re-1)*TileItem::smallWidth(),TileItem::smallHeight()); | 317 | shim = shim.smoothScale((re-1)*TileItem::smallWidth(),TileItem::smallHeight()); |
318 | QPixmap bgshapes; | 318 | QPixmap bgshapes; |
319 | bgshapes.convertFromImage(shim); | 319 | bgshapes.convertFromImage(shim); |
320 | 320 | ||
321 | rule_effects[re++] = 100; // default bonus | 321 | rule_effects[re++] = 100; // default bonus |
322 | board = new Board(bgshapes, htiles, vtiles, vbox); | 322 | board = new Board(bgshapes, htiles, vtiles, vbox); |
323 | board->setRules(rule_shapes, rule_effects); | 323 | board->setRules(rule_shapes, rule_effects); |
324 | connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int))); | 324 | connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int))); |
325 | 325 | ||
326 | bag = new Bag; | 326 | bag = new Bag; |
327 | 327 | ||
328 | int count; | 328 | int count; |
329 | ts >> count; | 329 | ts >> count; |
330 | while ( count ) { | 330 | while ( count ) { |
331 | QString text; | 331 | QString text; |
332 | int value; | 332 | int value; |
333 | ts >> text >> value; | 333 | ts >> text >> value; |
334 | if ( text == "_" ) | 334 | if ( text == "_" ) |
335 | text = ""; | 335 | text = ""; |
336 | 336 | ||
337 | Tile t(text, value); | 337 | Tile t(text, value); |
338 | for (int n=count; n--; ) | 338 | for (int n=count; n--; ) |
339 | bag->add(t); | 339 | bag->add(t); |
340 | 340 | ||
341 | ts >> count; | 341 | ts >> count; |
342 | } | 342 | } |
343 | 343 | ||
344 | return TRUE; | 344 | return TRUE; |
345 | } | 345 | } |
346 | 346 | ||
347 | 347 | ||
348 | NewGame::NewGame(QWidget* parent) : | 348 | NewGame::NewGame(QWidget* parent) : |
349 | NewGameBase(parent) | 349 | NewGameBase(parent) |
350 | { | 350 | { |
351 | } | 351 | } |
352 | 352 | ||
353 | void NewGame::updateRuleSets() | 353 | void NewGame::updateRuleSets() |
354 | { | 354 | { |
355 | rules->clear(); | 355 | rules->clear(); |
356 | 356 | ||
357 | QString rulesDir = Global::applicationFileName( "wordgame", "" ); | 357 | QString rulesDir = Global::applicationFileName( "wordgame", "" ); |
358 | QDir dir( rulesDir, "*.rules" ); | 358 | QDir dir( rulesDir, "*.rules" ); |
359 | ruleslist = dir.entryList(); | 359 | ruleslist = dir.entryList(); |
360 | if ( ruleslist.isEmpty() ) { | 360 | if ( ruleslist.isEmpty() ) { |
361 | // Provide a sample | 361 | // Provide a sample |
362 | QFile file( rulesDir + "Sample.rules" ); | 362 | QFile file( rulesDir + "Sample.rules" ); |
363 | if ( file.open( IO_WriteOnly ) ) { | 363 | if ( file.open( IO_WriteOnly ) ) { |
364 | file.writeBlock( sampleWGR, strlen(sampleWGR) ); | 364 | file.writeBlock( sampleWGR, strlen(sampleWGR) ); |
365 | file.close(); | 365 | file.close(); |
366 | updateRuleSets(); | 366 | updateRuleSets(); |
367 | } | 367 | } |
368 | return; | 368 | return; |
369 | } | 369 | } |
370 | int newest=0; | 370 | int newest=0; |
371 | int newest_age=INT_MAX; | 371 | int newest_age=INT_MAX; |
372 | QDateTime now = QDateTime::currentDateTime(); | 372 | QDateTime now = QDateTime::currentDateTime(); |
373 | QStringList::Iterator it; | 373 | QStringList::Iterator it; |
374 | for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) { | 374 | for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) { |
375 | QFileInfo fi((*it)); | 375 | QFileInfo fi((*it)); |
376 | int age = fi.lastModified().secsTo(now); | 376 | int age = fi.lastModified().secsTo(now); |
377 | QString name = *it; | 377 | QString name = *it; |
378 | name.truncate( name.length()-6 ); // remove extension | 378 | name.truncate( name.length()-6 ); // remove extension |
379 | rules->insertItem( name ); | 379 | rules->insertItem( name ); |
380 | if ( age < newest_age ) { | 380 | if ( age < newest_age ) { |
381 | newest_age = age; | 381 | newest_age = age; |
382 | newest = rules->count()-1; | 382 | newest = rules->count()-1; |
383 | } | 383 | } |
384 | } | 384 | } |
385 | rules->setCurrentItem(newest); | 385 | rules->setCurrentItem(newest); |
386 | } | 386 | } |
387 | 387 | ||
388 | Rules::Rules(QWidget* parent) : | 388 | Rules::Rules(QWidget* parent) : |
389 | RulesBase(parent,0,TRUE) | 389 | RulesBase(parent,0,TRUE) |
390 | { | 390 | { |
391 | } | 391 | } |
392 | 392 | ||
393 | void Rules::editRules() | 393 | void Rules::editRules() |
394 | { | 394 | { |
395 | if ( exec() ) { | 395 | if ( exec() ) { |
396 | // ### create a new set of rules | 396 | // ### create a new set of rules |
397 | emit rulesChanged(); | 397 | emit rulesChanged(); |
398 | } | 398 | } |
399 | } | 399 | } |
400 | 400 | ||
401 | void Rules::deleteRuleSet() | 401 | void Rules::deleteRuleSet() |
402 | { | 402 | { |
403 | // ### delete existing rule set | 403 | // ### delete existing rule set |
404 | emit rulesChanged(); | 404 | emit rulesChanged(); |
405 | } | 405 | } |
406 | 406 | ||
407 | void WordGame::addPlayer(const QString& name) | 407 | void WordGame::addPlayer(const QString& name) |
408 | { | 408 | { |
409 | if ( !name.isEmpty() ) { | 409 | if ( !name.isEmpty() ) { |
410 | int colon = name.find(':'); | 410 | int colon = name.find(':'); |
411 | int cpu = (colon >=0 && name.left(2) == "AI") ? name.mid(2,1).toInt() : 0; | 411 | int cpu = (colon >=0 && name.left(2) == "AI") ? name.mid(2,1).toInt() : 0; |
412 | addPlayer(name,cpu); | 412 | addPlayer(name,cpu); |
413 | } | 413 | } |
414 | } | 414 | } |
415 | 415 | ||
416 | void WordGame::addPlayer(const QString& name, int cpu) | 416 | void WordGame::addPlayer(const QString& name, int cpu) |
417 | { | 417 | { |
418 | Rack* r = new Rack(rack_tiles,racks); | 418 | Rack* r = new Rack(rack_tiles,racks); |
419 | r->setPlayerName(name); | 419 | r->setPlayerName(name); |
420 | r->setComputerization(cpu); | 420 | r->setComputerization(cpu); |
421 | racks->addWidget(r, nplayers); | 421 | racks->addWidget(r, nplayers); |
422 | refillRack(nplayers); | 422 | refillRack(nplayers); |
423 | namelist.append(name); | 423 | namelist.append(name); |
424 | 424 | ||
425 | ++nplayers; | 425 | ++nplayers; |
426 | } | 426 | } |
427 | 427 | ||
428 | void WordGame::nextPlayer() | 428 | void WordGame::nextPlayer() |
429 | { | 429 | { |
430 | if ( !refillRack(player) ) { | 430 | if ( !refillRack(player) ) { |
431 | endGame(); | 431 | endGame(); |
432 | } else { | 432 | } else { |
433 | player = (player+1)%nplayers; | 433 | player = (player+1)%nplayers; |
434 | scoreinfo->setBoldOne(player); | 434 | scoreinfo->setBoldOne(player); |
435 | readyRack(player); | 435 | readyRack(player); |
436 | } | 436 | } |
437 | } | 437 | } |
438 | 438 | ||
439 | bool WordGame::mayEndGame() | 439 | bool WordGame::mayEndGame() |
440 | { | 440 | { |
441 | int out=-1; | 441 | int out=-1; |
442 | int i; | 442 | int i; |
443 | for (i=0; i<nplayers; i++) | 443 | for (i=0; i<nplayers; i++) |
444 | if ( !rack(i)->count() ) | 444 | if ( !rack(i)->count() ) |
445 | out = i; | 445 | out = i; |
446 | if ( out<0 ) { | 446 | if ( out<0 ) { |
447 | if ( QMessageBox::warning(this,tr("End game"), | 447 | if ( QMessageBox::warning(this,tr("End game"), |
448 | tr("Do you want to end the game early?"), | 448 | tr("Do you want to end the game early?"), |
449 | tr("Yes"), tr("No") )!=0 ) | 449 | tr("Yes"), tr("No") )!=0 ) |
450 | { | 450 | { |
451 | return FALSE; | 451 | return FALSE; |
452 | } | 452 | } |
453 | } | 453 | } |
454 | return TRUE; | 454 | return TRUE; |
455 | } | 455 | } |
456 | 456 | ||
457 | void WordGame::endGame() | 457 | void WordGame::endGame() |
458 | { | 458 | { |
459 | if ( gameover ) { | 459 | if ( gameover ) { |
460 | close(); | 460 | close(); |
461 | return; | 461 | return; |
462 | } | 462 | } |
463 | 463 | ||
464 | if ( !mayEndGame() ) | 464 | if ( !mayEndGame() ) |
465 | return; | 465 | return; |
466 | int out=-1; | 466 | int out=-1; |
467 | int totalleft=0; | 467 | int totalleft=0; |
468 | int i; | 468 | int i; |
469 | for (i=0; i<nplayers; i++) { | 469 | for (i=0; i<nplayers; i++) { |
470 | Rack* r = rack(i); | 470 | Rack* r = rack(i); |
471 | int c = r->count(); | 471 | int c = r->count(); |
472 | if ( c ) { | 472 | if ( c ) { |
473 | int lose=0; | 473 | int lose=0; |
474 | for ( int j=0; j<c; j++ ) | 474 | for ( int j=0; j<c; j++ ) |
475 | lose += r->tileRef(j)->value(); | 475 | lose += r->tileRef(j)->value(); |
476 | totalleft += lose; | 476 | totalleft += lose; |
477 | scoreinfo->addScore(i,-lose); | 477 | scoreinfo->addScore(i,-lose); |
478 | } else { | 478 | } else { |
479 | out = i; | 479 | out = i; |
480 | } | 480 | } |
481 | } | 481 | } |
482 | int highest=0; | 482 | int highest=0; |
483 | int winner=0; | 483 | int winner=0; |
484 | for (i=0; i<nplayers; i++) { | 484 | for (i=0; i<nplayers; i++) { |
485 | int s = scoreinfo->playerScore(i); | 485 | int s = scoreinfo->playerScore(i); |
486 | if ( s > highest ) { | 486 | if ( s > highest ) { |
487 | highest = s; | 487 | highest = s; |
488 | winner = i; | 488 | winner = i; |
489 | } | 489 | } |
490 | } | 490 | } |
491 | if ( out >= 0 ) | 491 | if ( out >= 0 ) |
492 | scoreinfo->addScore(out,totalleft); | 492 | scoreinfo->addScore(out,totalleft); |
493 | scoreinfo->setBoldOne(winner); | 493 | scoreinfo->setBoldOne(winner); |
494 | gameover = TRUE; | 494 | gameover = TRUE; |
495 | done->setEnabled(TRUE); | 495 | done->setEnabled(TRUE); |
496 | reset->setEnabled(FALSE); | 496 | reset->setEnabled(FALSE); |
497 | } | 497 | } |
498 | 498 | ||
499 | void WordGame::endTurn() | 499 | void WordGame::endTurn() |
500 | { | 500 | { |
501 | if ( gameover ) { | 501 | if ( gameover ) { |
502 | openGameSelector(namelist); | 502 | openGameSelector(namelist); |
503 | } else { | 503 | } else { |
504 | if ( board->checkTurn() ) { | 504 | if ( board->checkTurn() ) { |
505 | if ( board->turnScore() >= 0 ) { | 505 | if ( board->turnScore() >= 0 ) { |
506 | scoreinfo->addScore(player,board->turnScore()); | 506 | scoreinfo->addScore(player,board->turnScore()); |
507 | board->finalizeTurn(); | 507 | board->finalizeTurn(); |
508 | } else { | 508 | } else { |
509 | QApplication::beep(); | 509 | QApplication::beep(); |
510 | } | 510 | } |
511 | nextPlayer(); | 511 | nextPlayer(); |
512 | } | 512 | } |
513 | } | 513 | } |
514 | } | 514 | } |
515 | 515 | ||
516 | void WordGame::resetTurn() | 516 | void WordGame::resetTurn() |
517 | { | 517 | { |
518 | board->resetRack(); | 518 | board->resetRack(); |
519 | } | 519 | } |
520 | 520 | ||
521 | void WordGame::passTurn() | 521 | void WordGame::passTurn() |
522 | { | 522 | { |
523 | // ######## trade? | 523 | // ######## trade? |
524 | nextPlayer(); | 524 | nextPlayer(); |
525 | } | 525 | } |
526 | 526 | ||
527 | bool WordGame::refillRack(int i) | 527 | bool WordGame::refillRack(int i) |
528 | { | 528 | { |
529 | Rack* r = rack(i); | 529 | Rack* r = rack(i); |
530 | while ( !bag->isEmpty() && !r->isFull() ) { | 530 | while ( !bag->isEmpty() && !r->isFull() ) { |
531 | r->addTile(bag->takeRandom()); | 531 | r->addTile(bag->takeRandom()); |
532 | } | 532 | } |
533 | return r->count() != 0; | 533 | return r->count() != 0; |
534 | } | 534 | } |
535 | 535 | ||
536 | void WordGame::readyRack(int i) | 536 | void WordGame::readyRack(int i) |
537 | { | 537 | { |
538 | Rack* r = rack(i); | 538 | Rack* r = rack(i); |
539 | racks->raiseWidget(i); | 539 | racks->raiseWidget(i); |
540 | board->setCurrentRack(r); | 540 | board->setCurrentRack(r); |
541 | 541 | ||
542 | done->setEnabled( !r->computerized() ); | 542 | done->setEnabled( !r->computerized() ); |
543 | reset->setEnabled( !r->computerized() ); | 543 | reset->setEnabled( !r->computerized() ); |
544 | 544 | ||
545 | if ( r->computerized() ) { | 545 | if ( r->computerized() ) { |
546 | cpu = new ComputerPlayer(board, r); | 546 | cpu = new ComputerPlayer(board, r); |
547 | aiheart->start(0); | 547 | aiheart->start(0); |
548 | } | 548 | } |
549 | } | 549 | } |
550 | 550 | ||
551 | Rack* WordGame::rack(int i) const | 551 | Rack* WordGame::rack(int i) const |
552 | { | 552 | { |
553 | return (Rack*)racks->widget(i); | 553 | return (Rack*)racks->widget(i); |
554 | } | 554 | } |
555 | 555 | ||
556 | void WordGame::think() | 556 | void WordGame::think() |
557 | { | 557 | { |
558 | if ( !cpu->step() ) { | 558 | if ( !cpu->step() ) { |
559 | delete cpu; | 559 | delete cpu; |
560 | cpu = 0; | 560 | cpu = 0; |
561 | aiheart->stop(); | 561 | aiheart->stop(); |
562 | if ( board->turnScore() < 0 ) | 562 | if ( board->turnScore() < 0 ) |
563 | passTurn(); | 563 | passTurn(); |
564 | else | 564 | else |
565 | endTurn(); | 565 | endTurn(); |
566 | } | 566 | } |
567 | } | 567 | } |
568 | 568 | ||
569 | ComputerPlayer::ComputerPlayer(Board* b, Rack* r) : | 569 | ComputerPlayer::ComputerPlayer(Board* b, Rack* r) : |
570 | board(b), rack(r), best(new const Tile*[rack_tiles]), | 570 | board(b), rack(r), best(new const Tile*[rack_tiles]), |
571 | best_blankvalues(new Tile[rack_tiles]) | 571 | best_blankvalues(new Tile[rack_tiles]) |
572 | { | 572 | { |
573 | best_score = -1; | 573 | best_score = -1; |
574 | across=FALSE; | 574 | across=FALSE; |
575 | dict=0; | 575 | dict=0; |
576 | } | 576 | } |
577 | 577 | ||
578 | ComputerPlayer::~ComputerPlayer() | 578 | ComputerPlayer::~ComputerPlayer() |
579 | { | 579 | { |
580 | delete [] best; | 580 | delete [] best; |
581 | delete [] best_blankvalues; | 581 | delete [] best_blankvalues; |
582 | } | 582 | } |
583 | 583 | ||
584 | bool ComputerPlayer::step() | 584 | bool ComputerPlayer::step() |
585 | { | 585 | { |
586 | const QDawg::Node* root = dict ? Global::dawg("WordGame").root() | 586 | const QDawg::Node* root = dict ? Global::dawg("WordGame").root() |
587 | : Global::fixedDawg().root(); | 587 | : Global::fixedDawg().root(); |
588 | QPoint d = across ? QPoint(1,0) : QPoint(0,1); | 588 | QPoint d = across ? QPoint(1,0) : QPoint(0,1); |
589 | const Tile* tiles[99]; // ### max board size | 589 | const Tile* tiles[99]; // ### max board size |
590 | uchar nletter[4095]; // QDawg only handles 0..4095 | 590 | uchar nletter[4095]; // QDawg only handles 0..4095 |
591 | memset(nletter,0,4096); | 591 | memset(nletter,0,4095); |
592 | for (int i=0; i<rack->count(); i++) { | 592 | for (int i=0; i<rack->count(); i++) { |
593 | const Tile* r = rack->tileRef(i); | 593 | const Tile* r = rack->tileRef(i); |
594 | if ( r->isBlank() ) | 594 | if ( r->isBlank() ) |
595 | nletter[0]++; | 595 | nletter[0]++; |
596 | else | 596 | else |
597 | nletter[r->text()[0].unicode()]++; | 597 | nletter[r->text()[0].unicode()]++; |
598 | } | 598 | } |
599 | Tile blankvalues[99]; // ### max blanks | 599 | Tile blankvalues[99]; // ### max blanks |
600 | findBest(current, d, root, 0, nletter, tiles, 0, blankvalues, 0); | 600 | findBest(current, d, root, 0, nletter, tiles, 0, blankvalues, 0); |
601 | if ( ++current.rx() == board->xTiles() ) { | 601 | if ( ++current.rx() == board->xTiles() ) { |
602 | current.rx() = 0; | 602 | current.rx() = 0; |
603 | if ( ++current.ry() == board->yTiles() ) { | 603 | if ( ++current.ry() == board->yTiles() ) { |
604 | if ( across ) { | 604 | if ( across ) { |
605 | if ( dict == 1 ) { | 605 | if ( dict == 1 ) { |
606 | if ( best_score >= 0 ) { | 606 | if ( best_score >= 0 ) { |
607 | rack->arrangeTiles(best,best_n); | 607 | rack->arrangeTiles(best,best_n); |
608 | rack->setBlanks(best_blankvalues); | 608 | rack->setBlanks(best_blankvalues); |
609 | board->scoreTurn(best_start, best_n, best_dir); | 609 | board->scoreTurn(best_start, best_n, best_dir); |
610 | board->showTurn(); | 610 | board->showTurn(); |
611 | } | 611 | } |
612 | return FALSE; | 612 | return FALSE; |
613 | } | 613 | } |
614 | dict++; | 614 | dict++; |
615 | across = FALSE; | 615 | across = FALSE; |
616 | current = QPoint(0,0); | 616 | current = QPoint(0,0); |
617 | } else { | 617 | } else { |
618 | across = TRUE; | 618 | across = TRUE; |
619 | current = QPoint(0,0); | 619 | current = QPoint(0,0); |
620 | } | 620 | } |
621 | } | 621 | } |
622 | } | 622 | } |
623 | return TRUE; | 623 | return TRUE; |
624 | } | 624 | } |
625 | 625 | ||
626 | 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) | 626 | 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 | { | 627 | { |
628 | if ( !node ) | 628 | if ( !node ) |
629 | return; | 629 | return; |
630 | QChar l = node->letter(); | 630 | QChar l = node->letter(); |
631 | const Tile* cur = board->tile(at); | 631 | const Tile* cur = board->tile(at); |
632 | if ( cur ) { | 632 | if ( cur ) { |
633 | if ( cur->text()[0] == l ) { | 633 | if ( cur->text()[0] == l ) { |
634 | bool nextok = board->contains(at+d); | 634 | bool nextok = board->contains(at+d); |
635 | if ( node->isWord() && n && (!nextok || !board->tile(at+d)) ) | 635 | if ( node->isWord() && n && (!nextok || !board->tile(at+d)) ) |
636 | noteChoice(tiles,n,d,blankvalues,blused); | 636 | noteChoice(tiles,n,d,blankvalues,blused); |
637 | if ( nextok ) | 637 | if ( nextok ) |
638 | findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused); | 638 | findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused); |
639 | // #### text()[1]... | 639 | // #### text()[1]... |
640 | } | 640 | } |
641 | } else { | 641 | } else { |
642 | if ( nletter[l.unicode()] || nletter[0] ) { | 642 | if ( nletter[l.unicode()] || nletter[0] ) { |
643 | int rc = rack->count(); | 643 | int rc = rack->count(); |
644 | ulong msk = 1; | 644 | ulong msk = 1; |
645 | for ( int x=0; x<rc; x++ ) { | 645 | for ( int x=0; x<rc; x++ ) { |
646 | if ( !(used&msk) ) { | 646 | if ( !(used&msk) ) { |
647 | const Tile* t = rack->tileRef(x); | 647 | const Tile* t = rack->tileRef(x); |
648 | if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s | 648 | if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s |
649 | bool nextok = board->contains(at+d); | 649 | bool nextok = board->contains(at+d); |
650 | tiles[n++] = t; | 650 | tiles[n++] = t; |
651 | if ( t->isBlank() ) | 651 | if ( t->isBlank() ) |
652 | blankvalues[blused++] = Tile(l,0); | 652 | blankvalues[blused++] = Tile(l,0); |
653 | if ( node->isWord() && (!nextok || !board->tile(at+d)) ) | 653 | if ( node->isWord() && (!nextok || !board->tile(at+d)) ) |
654 | noteChoice(tiles,n,d,blankvalues,blused); | 654 | noteChoice(tiles,n,d,blankvalues,blused); |
655 | used |= msk; // mark | 655 | used |= msk; // mark |
656 | nletter[t->text()[0].unicode()]--; | 656 | nletter[t->text()[0].unicode()]--; |
657 | if ( nextok ) | 657 | if ( nextok ) |
658 | findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused); | 658 | findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused); |
659 | n--; | 659 | n--; |
660 | nletter[t->text()[0].unicode()]++; | 660 | nletter[t->text()[0].unicode()]++; |
661 | if ( t->isBlank() ) { | 661 | if ( t->isBlank() ) { |
662 | // keep looking | 662 | // keep looking |
663 | blused--; | 663 | blused--; |
664 | used &= ~msk; // unmark | 664 | used &= ~msk; // unmark |
665 | } else { | 665 | } else { |
666 | break; | 666 | break; |
667 | } | 667 | } |
668 | } | 668 | } |
669 | } | 669 | } |
670 | msk <<= 1; | 670 | msk <<= 1; |
671 | } | 671 | } |
672 | } | 672 | } |
673 | // #### text()[1]... | 673 | // #### text()[1]... |
674 | } | 674 | } |
675 | findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused); | 675 | findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused); |
676 | } | 676 | } |
677 | 677 | ||
678 | void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused) | 678 | void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused) |
679 | { | 679 | { |
680 | int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0); | 680 | int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0); |
681 | /* | 681 | /* |
682 | if (s>0 || current==QPoint(5,1)){ | 682 | if (s>0 || current==QPoint(5,1)){ |
683 | QString st; | 683 | QString st; |
684 | for ( int i=0; i<n; i++ ) | 684 | for ( int i=0; i<n; i++ ) |
685 | st += tiles[i]->text(); | 685 | st += tiles[i]->text(); |
686 | odebug << "" << current.x() << "," << current.y() << ": " << st.latin1() << " (" << n << ") for " << s << "" << oendl; | 686 | odebug << "" << current.x() << "," << current.y() << ": " << st.latin1() << " (" << n << ") for " << s << "" << oendl; |
687 | } | 687 | } |
688 | */ | 688 | */ |
689 | if ( s > best_score ) { | 689 | if ( s > best_score ) { |
690 | int i; | 690 | int i; |
691 | for ( i=0; i<n; i++ ) | 691 | for ( i=0; i<n; i++ ) |
692 | best[i] = tiles[i]; | 692 | best[i] = tiles[i]; |
693 | for ( i=0; i<blused; i++ ) | 693 | for ( i=0; i<blused; i++ ) |
694 | best_blankvalues[i] = blankvalues[i]; | 694 | best_blankvalues[i] = blankvalues[i]; |
695 | best_n = n; | 695 | best_n = n; |
696 | best_blused = blused; | 696 | best_blused = blused; |
697 | best_score = s; | 697 | best_score = s; |
698 | best_dir = d; | 698 | best_dir = d; |
699 | best_start = current; | 699 | best_start = current; |
700 | } | 700 | } |
701 | } | 701 | } |
702 | 702 | ||
703 | int TileItem::smallWidth() | 703 | int TileItem::smallWidth() |
704 | { | 704 | { |
705 | return tile_smallw; | 705 | return tile_smallw; |
706 | } | 706 | } |
707 | 707 | ||
708 | int TileItem::smallHeight() | 708 | int TileItem::smallHeight() |
709 | { | 709 | { |
710 | return tile_smallh; | 710 | return tile_smallh; |
711 | } | 711 | } |
712 | 712 | ||
713 | int TileItem::bigWidth() | 713 | int TileItem::bigWidth() |
714 | { | 714 | { |
715 | return tile_bigw; | 715 | return tile_bigw; |
716 | } | 716 | } |
717 | 717 | ||
718 | int TileItem::bigHeight() | 718 | int TileItem::bigHeight() |
719 | { | 719 | { |
720 | return tile_bigh; | 720 | return tile_bigh; |
721 | } | 721 | } |
722 | 722 | ||
723 | void TileItem::setState( State state ) | 723 | void TileItem::setState( State state ) |
724 | { | 724 | { |
725 | hide(); | 725 | hide(); |
726 | s = state; | 726 | s = state; |
727 | show(); // ### use update() in Qt 3.0 | 727 | show(); // ### use update() in Qt 3.0 |
728 | } | 728 | } |
729 | 729 | ||
730 | void TileItem::setTile(const Tile& tile) | 730 | void TileItem::setTile(const Tile& tile) |
731 | { | 731 | { |
732 | hide(); | 732 | hide(); |
733 | t = tile; | 733 | t = tile; |
734 | show(); // ### use update() in Qt 3.0 | 734 | show(); // ### use update() in Qt 3.0 |
735 | } | 735 | } |
736 | 736 | ||
737 | void TileItem::setBig(bool b) | 737 | void TileItem::setBig(bool b) |
738 | { | 738 | { |
739 | big = b; | 739 | big = b; |
740 | } | 740 | } |
741 | 741 | ||
742 | void TileItem::drawShape(QPainter& p) | 742 | void TileItem::drawShape(QPainter& p) |
743 | { | 743 | { |
744 | static QFont *value_font=0; | 744 | static QFont *value_font=0; |
745 | static QFont *big_font=0; | 745 | static QFont *big_font=0; |
746 | static QFont *small_font=0; | 746 | static QFont *small_font=0; |
747 | if ( !value_font ) { | 747 | if ( !value_font ) { |
748 | value_font = new QFont("helvetica",8); | 748 | value_font = new QFont("helvetica",8); |
749 | if ( TileItem::bigWidth() < 20 ) { | 749 | if ( TileItem::bigWidth() < 20 ) { |
750 | big_font = new QFont("helvetica",12); | 750 | big_font = new QFont("helvetica",12); |
751 | small_font = new QFont("helvetica",8); | 751 | small_font = new QFont("helvetica",8); |
752 | } else { | 752 | } else { |
753 | big_font = new QFont("smoothtimes",17); | 753 | big_font = new QFont("smoothtimes",17); |
754 | small_font = new QFont("smoothtimes",10); | 754 | small_font = new QFont("smoothtimes",10); |
755 | } | 755 | } |
756 | } | 756 | } |
757 | 757 | ||
758 | QRect area(x(),y(),width(),height()); | 758 | QRect area(x(),y(),width(),height()); |
759 | p.setBrush(s == Floating ? yellow/*lightGray*/ : white); | 759 | p.setBrush(s == Floating ? yellow/*lightGray*/ : white); |
760 | p.drawRect(area); | 760 | p.drawRect(area); |
761 | if ( big ) { | 761 | if ( big ) { |
762 | p.setFont(*value_font); | 762 | p.setFont(*value_font); |
763 | QString n = QString::number(t.value()); | 763 | QString n = QString::number(t.value()); |
764 | int w = p.fontMetrics().width('1'); | 764 | int w = p.fontMetrics().width('1'); |
765 | int h = p.fontMetrics().height(); | 765 | int h = p.fontMetrics().height(); |
766 | w *= n.length(); | 766 | w *= n.length(); |
767 | QRect valuearea(x()+width()-w-1,y()+height()-h,w,h); | 767 | QRect valuearea(x()+width()-w-1,y()+height()-h,w,h); |
768 | p.drawText(valuearea,AlignCenter,n); | 768 | p.drawText(valuearea,AlignCenter,n); |
769 | p.setFont(*big_font); | 769 | p.setFont(*big_font); |
770 | area = QRect(x(),y()+tile_btweak,width()-4,height()-1); | 770 | area = QRect(x(),y()+tile_btweak,width()-4,height()-1); |
771 | } else { | 771 | } else { |
772 | p.setFont(*small_font); | 772 | p.setFont(*small_font); |
773 | area = QRect(x()+1+tile_stweak,y()+1,width(),height()-3); | 773 | area = QRect(x()+1+tile_stweak,y()+1,width(),height()-3); |
774 | } | 774 | } |
775 | if ( t.value() == 0 ) | 775 | if ( t.value() == 0 ) |
776 | p.setPen(darkGray); | 776 | p.setPen(darkGray); |
777 | p.drawText(area,AlignCenter,t.text().upper()); | 777 | p.drawText(area,AlignCenter,t.text().upper()); |
778 | } | 778 | } |
779 | 779 | ||
780 | Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) : | 780 | Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) : |
781 | QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()), | 781 | QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()), |
782 | parent) | 782 | parent) |
783 | { | 783 | { |
784 | setFixedSize(w*TileItem::smallWidth(),h*TileItem::smallHeight()); | 784 | setFixedSize(w*TileItem::smallWidth(),h*TileItem::smallHeight()); |
785 | grid = new TileItem*[w*h]; | 785 | grid = new TileItem*[w*h]; |
786 | memset(grid,0,w*h*sizeof(TileItem*)); | 786 | memset(grid,0,w*h*sizeof(TileItem*)); |
787 | setFrameStyle(0); | 787 | setFrameStyle(0); |
788 | setHScrollBarMode(AlwaysOff); | 788 | setHScrollBarMode(AlwaysOff); |
789 | setVScrollBarMode(AlwaysOff); | 789 | setVScrollBarMode(AlwaysOff); |
790 | current_rack = 0; | 790 | current_rack = 0; |
791 | shown_n = 0; | 791 | shown_n = 0; |
792 | } | 792 | } |
793 | 793 | ||
794 | Board::~Board() | 794 | Board::~Board() |
795 | { | 795 | { |
796 | delete canvas(); | 796 | delete canvas(); |
797 | } | 797 | } |
798 | 798 | ||
799 | QSize Board::sizeHint() const | 799 | QSize Board::sizeHint() const |
800 | { | 800 | { |
801 | return QSize(canvas()->width(),canvas()->height()); | 801 | return QSize(canvas()->width(),canvas()->height()); |
802 | } | 802 | } |
803 | 803 | ||
804 | void Board::writeConfig(Config& cfg) | 804 | void Board::writeConfig(Config& cfg) |
805 | { | 805 | { |
806 | QStringList t; | 806 | QStringList t; |
807 | int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); | 807 | int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); |
808 | for (int i=0; i<n; i++) | 808 | for (int i=0; i<n; i++) |
809 | t.append( grid[i] ? grid[i]->tile().key() : QString(".") ); | 809 | t.append( grid[i] ? grid[i]->tile().key() : QString(".") ); |
810 | cfg.writeEntry("Board",t,';'); | 810 | cfg.writeEntry("Board",t,';'); |
811 | } | 811 | } |
812 | 812 | ||
813 | void Board::readConfig(Config& cfg) | 813 | void Board::readConfig(Config& cfg) |
814 | { | 814 | { |
815 | clear(); | 815 | clear(); |
816 | QStringList t = cfg.readListEntry("Board",';'); | 816 | QStringList t = cfg.readListEntry("Board",';'); |
817 | int i=0; | 817 | int i=0; |
818 | int h=canvas()->tilesHorizontally(); | 818 | int h=canvas()->tilesHorizontally(); |
819 | for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) { | 819 | for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) { |
820 | if ( *it != "." ) { | 820 | if ( *it != "." ) { |
821 | QPoint p(i%h,i/h); | 821 | QPoint p(i%h,i/h); |
822 | setTile(p,Tile(*it)); | 822 | setTile(p,Tile(*it)); |
823 | } | 823 | } |
824 | i++; | 824 | i++; |
825 | } | 825 | } |
826 | canvas()->update(); | 826 | canvas()->update(); |
827 | } | 827 | } |
828 | 828 | ||
829 | void Board::clear() | 829 | void Board::clear() |
830 | { | 830 | { |
831 | int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); | 831 | int n=canvas()->tilesHorizontally()*canvas()->tilesVertically(); |
832 | for (int i=0; i<n; i++) { | 832 | for (int i=0; i<n; i++) { |
833 | delete grid[i]; | 833 | delete grid[i]; |
834 | grid[i]=0; | 834 | grid[i]=0; |
835 | } | 835 | } |
836 | } | 836 | } |
837 | 837 | ||
838 | 838 | ||
839 | void Board::setCurrentRack(Rack* r) | 839 | void Board::setCurrentRack(Rack* r) |
840 | { | 840 | { |
841 | turn_score = -1; | 841 | turn_score = -1; |
842 | current_rack = r; | 842 | current_rack = r; |
843 | } | 843 | } |
844 | 844 | ||
845 | void Board::resetRack() | 845 | void Board::resetRack() |
846 | { | 846 | { |
847 | unshowTurn(); | 847 | unshowTurn(); |
848 | canvas()->update(); | 848 | canvas()->update(); |
849 | } | 849 | } |
850 | 850 | ||
851 | void Board::contentsMousePressEvent(QMouseEvent* e) | 851 | void Board::contentsMousePressEvent(QMouseEvent* e) |
852 | { | 852 | { |
853 | dragstart = e->pos(); | 853 | dragstart = e->pos(); |
854 | } | 854 | } |
855 | 855 | ||
856 | void Board::contentsMouseMoveEvent(QMouseEvent* e) | 856 | void Board::contentsMouseMoveEvent(QMouseEvent* e) |
857 | { | 857 | { |
858 | if ( current_rack && !current_rack->computerized() ) { | 858 | if ( current_rack && !current_rack->computerized() ) { |
859 | QPoint d = e->pos() - dragstart; | 859 | QPoint d = e->pos() - dragstart; |
860 | if ( d.x() <= 0 && d.y() <= 0 ) { | 860 | if ( d.x() <= 0 && d.y() <= 0 ) { |
861 | // None | 861 | // None |
862 | resetRack(); | 862 | resetRack(); |
863 | } else { | 863 | } else { |
864 | int n; | 864 | int n; |
865 | QPoint start=boardPos(dragstart); | 865 | QPoint start=boardPos(dragstart); |
866 | QPoint end=boardPos(e->pos()); | 866 | QPoint end=boardPos(e->pos()); |
867 | QPoint diff=end-start; | 867 | QPoint diff=end-start; |
868 | QPoint dir; | 868 | QPoint dir; |
869 | if ( d.x() > d.y() ) { | 869 | if ( d.x() > d.y() ) { |
870 | n = diff.x()+1; | 870 | n = diff.x()+1; |
871 | dir = QPoint(1,0); | 871 | dir = QPoint(1,0); |
872 | } else { | 872 | } else { |
873 | n = diff.y()+1; | 873 | n = diff.y()+1; |
874 | dir = QPoint(0,1); | 874 | dir = QPoint(0,1); |
875 | } | 875 | } |
876 | 876 | ||
877 | unshowTurn(); | 877 | unshowTurn(); |
878 | 878 | ||
879 | // Subtract existing tiles from n | 879 | // Subtract existing tiles from n |
880 | QPoint t = start; | 880 | QPoint t = start; |
881 | for ( int i=n; i--; ) { | 881 | for ( int i=n; i--; ) { |
882 | if ( contains(t) && tile(t) ) | 882 | if ( contains(t) && tile(t) ) |
883 | n--; | 883 | n--; |
884 | t += dir; | 884 | t += dir; |
885 | } | 885 | } |
886 | 886 | ||
887 | // Move start back to real start | 887 | // Move start back to real start |
888 | while (contains(start-dir) && tile(start-dir)) | 888 | while (contains(start-dir) && tile(start-dir)) |
889 | start -= dir; | 889 | start -= dir; |
890 | 890 | ||
891 | scoreTurn(start, n, dir); | 891 | scoreTurn(start, n, dir); |
892 | showTurn(); | 892 | showTurn(); |
893 | } | 893 | } |
894 | } | 894 | } |
895 | } | 895 | } |
896 | 896 | ||
897 | void Board::finalizeTurn() | 897 | void Board::finalizeTurn() |
898 | { | 898 | { |
899 | int i=0; | 899 | int i=0; |
900 | QPoint at = shown_at; | 900 | QPoint at = shown_at; |
901 | while ( i<shown_n && contains(at) ) { | 901 | while ( i<shown_n && contains(at) ) { |
902 | if ( item(at) && item(at)->state() == TileItem::Floating ) { | 902 | if ( item(at) && item(at)->state() == TileItem::Floating ) { |
903 | current_rack->remove(item(at)->tile()); | 903 | current_rack->remove(item(at)->tile()); |
904 | setTileState(at,TileItem::Firm); | 904 | setTileState(at,TileItem::Firm); |
905 | i++; | 905 | i++; |
906 | } | 906 | } |
907 | at += shown_step; | 907 | at += shown_step; |
908 | } | 908 | } |
909 | canvas()->update(); | 909 | canvas()->update(); |
910 | } | 910 | } |
911 | 911 | ||
912 | void Board::unshowTurn() | 912 | void Board::unshowTurn() |
913 | { | 913 | { |
914 | int i=0; | 914 | int i=0; |
915 | QPoint at = shown_at; | 915 | QPoint at = shown_at; |
916 | while ( i<shown_n && i<current_rack->count() && contains(at) ) { | 916 | while ( i<shown_n && i<current_rack->count() && contains(at) ) { |
917 | if ( item(at) && item(at)->state() == TileItem::Floating ) { | 917 | if ( item(at) && item(at)->state() == TileItem::Floating ) { |
918 | unsetTile(at); | 918 | unsetTile(at); |
919 | i++; | 919 | i++; |
920 | } | 920 | } |
921 | at += shown_step; | 921 | at += shown_step; |
922 | } | 922 | } |
923 | } | 923 | } |
924 | 924 | ||
925 | void Board::showTurn() | 925 | void Board::showTurn() |
926 | { | 926 | { |
927 | unshowTurn(); | 927 | unshowTurn(); |
928 | QPoint at = shown_at; | 928 | QPoint at = shown_at; |
929 | int i=0; | 929 | int i=0; |
930 | while ( i<shown_n && i<current_rack->count() && contains(at) ) { | 930 | while ( i<shown_n && i<current_rack->count() && contains(at) ) { |
931 | if ( !tile(at) ) { | 931 | if ( !tile(at) ) { |
932 | Tile t = current_rack->tile(i); | 932 | Tile t = current_rack->tile(i); |
933 | setTile(at,t); | 933 | setTile(at,t); |
934 | setTileState(at,TileItem::Floating); | 934 | setTileState(at,TileItem::Floating); |
935 | i++; | 935 | i++; |
936 | } | 936 | } |
937 | at += shown_step; | 937 | at += shown_step; |
938 | } | 938 | } |
939 | canvas()->update(); | 939 | canvas()->update(); |
940 | } | 940 | } |
941 | 941 | ||
942 | int Board::bonussedValue(const QPoint& at, int base, int& all_mult) const | 942 | int Board::bonussedValue(const QPoint& at, int base, int& all_mult) const |
943 | { | 943 | { |
944 | int rule = rule_shape[idx(at)]-'0'; | 944 | int rule = rule_shape[idx(at)]-'0'; |
945 | int effect = rule_effect[rule]; | 945 | int effect = rule_effect[rule]; |
946 | int mult = effect&Multiplier; | 946 | int mult = effect&Multiplier; |
947 | if ( effect & MultiplyAll ) { | 947 | if ( effect & MultiplyAll ) { |
948 | all_mult *= mult; | 948 | all_mult *= mult; |
949 | return base; | 949 | return base; |
950 | } else { | 950 | } else { |
951 | return base * mult; | 951 | return base * mult; |
952 | } | 952 | } |
953 | } | 953 | } |
954 | 954 | ||
955 | bool Board::isStart(const QPoint& at) const | 955 | bool Board::isStart(const QPoint& at) const |
956 | { | 956 | { |
957 | int rule = rule_shape[idx(at)]-'0'; | 957 | int rule = rule_shape[idx(at)]-'0'; |
958 | int effect = rule_effect[rule]; | 958 | int effect = rule_effect[rule]; |
959 | return effect&Start; | 959 | return effect&Start; |
960 | } | 960 | } |
961 | 961 | ||
962 | bool Board::checkTurn() | 962 | bool Board::checkTurn() |
963 | { | 963 | { |
964 | if ( current_rack->computerized() ) | 964 | if ( current_rack->computerized() ) |
965 | return TRUE; // computer doesn't cheat, and has already set blanks. | 965 | return TRUE; // computer doesn't cheat, and has already set blanks. |
966 | 966 | ||
967 | QPoint at = shown_at; | 967 | QPoint at = shown_at; |
968 | int n = shown_n; | 968 | int n = shown_n; |
969 | QPoint d = shown_step; | 969 | QPoint d = shown_step; |
970 | const Tile* tiles[99]; | 970 | const Tile* tiles[99]; |
971 | Tile blankvalues[99]; | 971 | Tile blankvalues[99]; |
972 | if ( n > current_rack->count() ) | 972 | if ( n > current_rack->count() ) |
973 | n = current_rack->count(); | 973 | n = current_rack->count(); |
974 | 974 | ||
975 | QDialog check(this,0,TRUE); | 975 | QDialog check(this,0,TRUE); |
976 | (new QVBoxLayout(&check))->setAutoAdd(TRUE); | 976 | (new QVBoxLayout(&check))->setAutoAdd(TRUE); |
977 | 977 | ||
978 | QHBox mw(&check); | 978 | QHBox mw(&check); |
979 | new QLabel(tr("Blanks: "),&mw); | 979 | new QLabel(tr("Blanks: "),&mw); |
980 | 980 | ||
981 | int bl=0; | 981 | int bl=0; |
982 | QLineEdit* le[99]; | 982 | QLineEdit* le[99]; |
983 | for (int i=0; i<n; i++) { | 983 | for (int i=0; i<n; i++) { |
984 | tiles[i] = current_rack->tileRef(i); | 984 | tiles[i] = current_rack->tileRef(i); |
985 | if ( tiles[i]->isBlank() ) { | 985 | if ( tiles[i]->isBlank() ) { |
986 | QLineEdit *l = new QLineEdit(&mw); | 986 | QLineEdit *l = new QLineEdit(&mw); |
987 | le[bl++] = l; | 987 | le[bl++] = l; |
988 | l->setMaxLength(1); | 988 | l->setMaxLength(1); |
989 | l->setFixedSize(l->minimumSizeHint()); | 989 | l->setFixedSize(l->minimumSizeHint()); |
990 | } | 990 | } |
991 | } | 991 | } |
992 | 992 | ||
993 | QHBox btns(&check); | 993 | QHBox btns(&check); |
994 | connect(new QPushButton(tr("OK"),&btns), SIGNAL(clicked()), &check, SLOT(accept())); | 994 | connect(new QPushButton(tr("OK"),&btns), SIGNAL(clicked()), &check, SLOT(accept())); |
995 | connect(new QPushButton(tr("Cancel"),&btns), SIGNAL(clicked()), &check, SLOT(reject())); | 995 | connect(new QPushButton(tr("Cancel"),&btns), SIGNAL(clicked()), &check, SLOT(reject())); |
996 | 996 | ||
997 | if ( bl ) { | 997 | if ( bl ) { |
998 | retry: | 998 | retry: |
999 | if ( !check.exec() ) { | 999 | if ( !check.exec() ) { |
1000 | unshowTurn(); | 1000 | unshowTurn(); |
1001 | canvas()->update(); | 1001 | canvas()->update(); |
1002 | return FALSE; | 1002 | return FALSE; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | for (int b=0; b<bl; b++) { | 1005 | for (int b=0; b<bl; b++) { |
1006 | QString v = le[b]->text(); | 1006 | QString v = le[b]->text(); |
1007 | blankvalues[b]=Tile(v,0); | 1007 | blankvalues[b]=Tile(v,0); |
1008 | if ( v.length() != 1 ) | 1008 | if ( v.length() != 1 ) |
1009 | goto retry; | 1009 | goto retry; |
1010 | } | 1010 | } |
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | QStringList words; | 1013 | QStringList words; |
1014 | unshowTurn(); | 1014 | unshowTurn(); |
1015 | turn_score = score(at,tiles,n,blankvalues,d,FALSE,&words); | 1015 | turn_score = score(at,tiles,n,blankvalues,d,FALSE,&words); |
1016 | showTurn(); | 1016 | showTurn(); |
1017 | QStringList to_add; | 1017 | QStringList to_add; |
1018 | for (QStringList::Iterator it=words.begin(); it!=words.end(); ++it) { | 1018 | for (QStringList::Iterator it=words.begin(); it!=words.end(); ++it) { |
1019 | if ( !Global::fixedDawg().contains(*it) | 1019 | if ( !Global::fixedDawg().contains(*it) |
1020 | && !Global::dawg("WordGame").contains(*it) ) { | 1020 | && !Global::dawg("WordGame").contains(*it) ) { |
1021 | switch (QMessageBox::warning(this, tr("Unknown word"), | 1021 | switch (QMessageBox::warning(this, tr("Unknown word"), |
1022 | tr("<p>The word \"%1\" is not in the dictionary.").arg(*it), | 1022 | tr("<p>The word \"%1\" is not in the dictionary.").arg(*it), |
1023 | tr("Add"), tr("Ignore"), tr("Cancel"))) | 1023 | tr("Add"), tr("Ignore"), tr("Cancel"))) |
1024 | { | 1024 | { |
1025 | case 0: | 1025 | case 0: |
1026 | // ####### add to wordgame dictionary | 1026 | // ####### add to wordgame dictionary |
1027 | to_add.append(*it); | 1027 | to_add.append(*it); |
1028 | break; | 1028 | break; |
1029 | case 1: | 1029 | case 1: |
1030 | break; | 1030 | break; |
1031 | case 2: | 1031 | case 2: |
1032 | unshowTurn(); | 1032 | unshowTurn(); |
1033 | canvas()->update(); | 1033 | canvas()->update(); |
1034 | return FALSE; | 1034 | return FALSE; |
1035 | } | 1035 | } |
1036 | } | 1036 | } |
1037 | } | 1037 | } |
1038 | if ( to_add.count() ) | 1038 | if ( to_add.count() ) |
1039 | Global::addWords("WordGame",to_add); | 1039 | Global::addWords("WordGame",to_add); |
1040 | return TRUE; | 1040 | return TRUE; |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | void Board::scoreTurn(const QPoint& at, int n, const QPoint& d) | 1043 | void Board::scoreTurn(const QPoint& at, int n, const QPoint& d) |
1044 | { | 1044 | { |
1045 | unshowTurn(); | 1045 | unshowTurn(); |
1046 | shown_at = at; | 1046 | shown_at = at; |
1047 | shown_n = n; | 1047 | shown_n = n; |
1048 | shown_step = d; | 1048 | shown_step = d; |
1049 | const Tile* tiles[99]; | 1049 | const Tile* tiles[99]; |
1050 | if ( n > current_rack->count() ) | 1050 | if ( n > current_rack->count() ) |
1051 | n = current_rack->count(); | 1051 | n = current_rack->count(); |
1052 | for (int i=0; i<n; i++) | 1052 | for (int i=0; i<n; i++) |
1053 | tiles[i] = current_rack->tileRef(i); | 1053 | tiles[i] = current_rack->tileRef(i); |
1054 | turn_score = score(at,tiles,n,0,d,FALSE,0); | 1054 | turn_score = score(at,tiles,n,0,d,FALSE,0); |
1055 | emit temporaryScore(turn_score); | 1055 | emit temporaryScore(turn_score); |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | int Board::score(QPoint at, const Tile** tiles, int n, const Tile* blankvalue, const QPoint& d, bool checkdict, QStringList* words) const | 1058 | int Board::score(QPoint at, const Tile** tiles, int n, const Tile* blankvalue, const QPoint& d, bool checkdict, QStringList* words) const |
1059 | { | 1059 | { |
1060 | int total=0; | 1060 | int total=0; |
1061 | int totalsidetotal=0; | 1061 | int totalsidetotal=0; |
1062 | 1062 | ||
1063 | // words gets filled with words made | 1063 | // words gets filled with words made |
1064 | 1064 | ||
1065 | // mainword==0 -> | 1065 | // mainword==0 -> |
1066 | // Checks side words, but not main word | 1066 | // Checks side words, but not main word |
1067 | 1067 | ||
1068 | // -1 means words not in dict, or illegally positioned (eg. not connected) | 1068 | // -1 means words not in dict, or illegally positioned (eg. not connected) |
1069 | 1069 | ||
1070 | // text is assumed to fit on board. | 1070 | // text is assumed to fit on board. |
1071 | 1071 | ||
1072 | if ( words ) *words=QStringList(); | 1072 | if ( words ) *words=QStringList(); |
1073 | 1073 | ||
1074 | QPoint otherd(d.y(), d.x()); | 1074 | QPoint otherd(d.y(), d.x()); |
1075 | 1075 | ||
1076 | int all_mult = 1; | 1076 | int all_mult = 1; |
1077 | int bl=0; | 1077 | int bl=0; |
1078 | 1078 | ||
1079 | bool connected = FALSE; | 1079 | bool connected = FALSE; |
1080 | 1080 | ||
1081 | QString mainword=""; | 1081 | QString mainword=""; |
1082 | 1082 | ||
1083 | if ( contains(at-d) && tile(at-d) ) { | 1083 | if ( contains(at-d) && tile(at-d) ) { |
1084 | return -1; // preceeding tiles | 1084 | return -1; // preceeding tiles |
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | const Tile* t; | 1087 | const Tile* t; |
1088 | for (int i=0; contains(at) && ((t=tile(at)) || i<n); ) { | 1088 | for (int i=0; contains(at) && ((t=tile(at)) || i<n); ) { |
1089 | if ( t ) { | 1089 | if ( t ) { |
1090 | if ( checkdict || words ) mainword += t->text(); | 1090 | if ( checkdict || words ) mainword += t->text(); |
1091 | total += t->value(); | 1091 | total += t->value(); |
1092 | connected = TRUE; | 1092 | connected = TRUE; |
1093 | } else { | 1093 | } else { |
1094 | QString sideword; | 1094 | QString sideword; |
1095 | QString tt; | 1095 | QString tt; |
1096 | if ( tiles[i]->isBlank() ) { | 1096 | if ( tiles[i]->isBlank() ) { |
1097 | if ( blankvalue ) | 1097 | if ( blankvalue ) |
1098 | tt = blankvalue[bl++].text(); | 1098 | tt = blankvalue[bl++].text(); |
1099 | } else { | 1099 | } else { |
1100 | tt = tiles[i]->text(); | 1100 | tt = tiles[i]->text(); |
1101 | } | 1101 | } |
1102 | sideword=tt; | 1102 | sideword=tt; |
1103 | if ( checkdict || words ) mainword += tt; | 1103 | if ( checkdict || words ) mainword += tt; |
1104 | int side_mult = 1; | 1104 | int side_mult = 1; |
1105 | int tilevalue = bonussedValue(at,tiles[i]->value(),side_mult); | 1105 | int tilevalue = bonussedValue(at,tiles[i]->value(),side_mult); |
1106 | all_mult *= side_mult; | 1106 | all_mult *= side_mult; |
1107 | if ( !connected && isStart(at) ) | 1107 | if ( !connected && isStart(at) ) |
1108 | connected = TRUE; | 1108 | connected = TRUE; |
1109 | total += tilevalue; | 1109 | total += tilevalue; |
1110 | int sidetotal = tilevalue; | 1110 | int sidetotal = tilevalue; |
1111 | { | 1111 | { |
1112 | QPoint side = at-otherd; | 1112 | QPoint side = at-otherd; |
1113 | 1113 | ||
1114 | while ( contains(side) && (t=tile(side)) ) { | 1114 | while ( contains(side) && (t=tile(side)) ) { |
1115 | sidetotal += t->value(); | 1115 | sidetotal += t->value(); |
1116 | sideword.prepend(t->text()); | 1116 | sideword.prepend(t->text()); |
1117 | side -= otherd; | 1117 | side -= otherd; |
1118 | } | 1118 | } |
1119 | } | 1119 | } |
1120 | { | 1120 | { |
1121 | QPoint side = at+otherd; | 1121 | QPoint side = at+otherd; |
1122 | while ( contains(side) && (t=tile(side)) ) { | 1122 | while ( contains(side) && (t=tile(side)) ) { |
1123 | sidetotal += t->value(); | 1123 | sidetotal += t->value(); |
1124 | sideword.append(t->text()); | 1124 | sideword.append(t->text()); |
1125 | side += otherd; | 1125 | side += otherd; |
1126 | } | 1126 | } |
1127 | } | 1127 | } |
1128 | if ( sideword.length() > 1 ) { | 1128 | if ( sideword.length() > 1 ) { |
1129 | if ( words ) | 1129 | if ( words ) |
1130 | words->append(sideword); | 1130 | words->append(sideword); |
1131 | if ( checkdict && !Global::fixedDawg().contains(sideword) | 1131 | if ( checkdict && !Global::fixedDawg().contains(sideword) |
1132 | && !Global::dawg("WordGame").contains(sideword) ) | 1132 | && !Global::dawg("WordGame").contains(sideword) ) |
1133 | return -1; | 1133 | return -1; |
1134 | totalsidetotal += sidetotal * side_mult; | 1134 | totalsidetotal += sidetotal * side_mult; |
1135 | connected = TRUE; | 1135 | connected = TRUE; |
1136 | } | 1136 | } |
1137 | i++; | 1137 | i++; |
1138 | } | 1138 | } |
1139 | at += d; | 1139 | at += d; |
1140 | } | 1140 | } |
1141 | 1141 | ||
1142 | if ( words ) | 1142 | if ( words ) |
1143 | words->append(mainword); | 1143 | words->append(mainword); |
1144 | if ( checkdict && !Global::fixedDawg().contains(mainword) | 1144 | if ( checkdict && !Global::fixedDawg().contains(mainword) |
1145 | && !Global::dawg("WordGame").contains(mainword) ) | 1145 | && !Global::dawg("WordGame").contains(mainword) ) |
1146 | return -1; | 1146 | return -1; |
1147 | 1147 | ||
1148 | if ( n == rack_tiles ) | 1148 | if ( n == rack_tiles ) |
1149 | totalsidetotal += rack_tiles_bonus; | 1149 | totalsidetotal += rack_tiles_bonus; |
1150 | 1150 | ||
1151 | return connected ? totalsidetotal + total * all_mult : -1; | 1151 | return connected ? totalsidetotal + total * all_mult : -1; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | QPoint Board::boardPos(const QPoint& p) const | 1154 | QPoint Board::boardPos(const QPoint& p) const |
1155 | { | 1155 | { |
1156 | return QPoint(p.x()/canvas()->tileWidth(), p.y()/canvas()->tileHeight()); | 1156 | return QPoint(p.x()/canvas()->tileWidth(), p.y()/canvas()->tileHeight()); |
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | void Board::contentsMouseReleaseEvent(QMouseEvent*) | 1159 | void Board::contentsMouseReleaseEvent(QMouseEvent*) |
1160 | { | 1160 | { |
1161 | if ( current_rack ) { | 1161 | if ( current_rack ) { |
1162 | } | 1162 | } |
1163 | } | 1163 | } |
1164 | 1164 | ||
1165 | 1165 | ||
1166 | void Board::setRules(const QString& shapes, const int* effects) | 1166 | void Board::setRules(const QString& shapes, const int* effects) |
1167 | { | 1167 | { |
1168 | rule_shape=shapes; rule_effect=effects; | 1168 | rule_shape=shapes; rule_effect=effects; |
1169 | int i=0; | 1169 | int i=0; |
1170 | int maxre=0; | 1170 | int maxre=0; |
1171 | for (int y=0; y<yTiles(); y++) { | 1171 | for (int y=0; y<yTiles(); y++) { |
1172 | for (int x=0; x<xTiles(); x++) { | 1172 | for (int x=0; x<xTiles(); x++) { |
1173 | int re = shapes[i++]-'0'; | 1173 | int re = shapes[i++]-'0'; |
1174 | if ( re > maxre ) maxre = re; | 1174 | if ( re > maxre ) maxre = re; |
1175 | canvas()->setTile(x,y,re); | 1175 | canvas()->setTile(x,y,re); |
1176 | } | 1176 | } |
1177 | } | 1177 | } |
1178 | rack_tiles_bonus=effects[maxre+1]; | 1178 | rack_tiles_bonus=effects[maxre+1]; |
1179 | } | 1179 | } |
1180 | 1180 | ||
1181 | void Board::unsetTile(const QPoint& p) | 1181 | void Board::unsetTile(const QPoint& p) |
1182 | { | 1182 | { |
1183 | delete item(p); | 1183 | delete item(p); |
1184 | grid[idx(p)] = 0; | 1184 | grid[idx(p)] = 0; |
1185 | } | 1185 | } |
1186 | 1186 | ||
1187 | void Board::setTile(const QPoint& p, const Tile& t) | 1187 | void Board::setTile(const QPoint& p, const Tile& t) |
1188 | { | 1188 | { |
1189 | TileItem* it=item(p); | 1189 | TileItem* it=item(p); |
1190 | if ( !it ) { | 1190 | if ( !it ) { |
1191 | it = grid[idx(p)] = new TileItem(t,FALSE,canvas()); | 1191 | it = grid[idx(p)] = new TileItem(t,FALSE,canvas()); |
1192 | it->move(p.x()*canvas()->tileWidth(), p.y()*canvas()->tileHeight()); | 1192 | it->move(p.x()*canvas()->tileWidth(), p.y()*canvas()->tileHeight()); |
1193 | it->show(); | 1193 | it->show(); |
1194 | } else { | 1194 | } else { |
1195 | it->setTile(t); | 1195 | it->setTile(t); |
1196 | } | 1196 | } |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | Rack::Rack(int ntiles, QWidget* parent) : QCanvasView( | 1199 | Rack::Rack(int ntiles, QWidget* parent) : QCanvasView( |
1200 | new QCanvas(ntiles*TileItem::bigWidth(),TileItem::bigHeight()), | 1200 | new QCanvas(ntiles*TileItem::bigWidth(),TileItem::bigHeight()), |
1201 | parent), | 1201 | parent), |
1202 | item(ntiles) | 1202 | item(ntiles) |
1203 | { | 1203 | { |
1204 | setLineWidth(1); | 1204 | setLineWidth(1); |
1205 | setFixedHeight(sizeHint().height()); | 1205 | setFixedHeight(sizeHint().height()); |
1206 | n = 0; | 1206 | n = 0; |
1207 | for (int i=0; i<ntiles; i++) | 1207 | for (int i=0; i<ntiles; i++) |
1208 | item[i]=0; | 1208 | item[i]=0; |
1209 | setHScrollBarMode(AlwaysOff); | 1209 | setHScrollBarMode(AlwaysOff); |
1210 | setVScrollBarMode(AlwaysOff); | 1210 | setVScrollBarMode(AlwaysOff); |
1211 | canvas()->setBackgroundColor(gray); | 1211 | canvas()->setBackgroundColor(gray); |
1212 | dragging = 0; | 1212 | dragging = 0; |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | Rack::~Rack() | 1215 | Rack::~Rack() |
1216 | { | 1216 | { |
1217 | clear(); | 1217 | clear(); |
1218 | delete canvas(); | 1218 | delete canvas(); |
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | QSize Rack::sizeHint() const | 1221 | QSize Rack::sizeHint() const |
1222 | { | 1222 | { |
1223 | return QSize(-1,TileItem::bigHeight()+2); | 1223 | return QSize(-1,TileItem::bigHeight()+2); |
1224 | } | 1224 | } |
1225 | 1225 | ||
1226 | void Rack::clear() | 1226 | void Rack::clear() |
1227 | { | 1227 | { |
1228 | for (int i=0; i<n; i++) | 1228 | for (int i=0; i<n; i++) |
1229 | delete item[i]; | 1229 | delete item[i]; |
1230 | n=0; | 1230 | n=0; |
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | void Rack::writeConfig(Config& cfg) | 1233 | void Rack::writeConfig(Config& cfg) |
1234 | { | 1234 | { |
1235 | QStringList l; | 1235 | QStringList l; |
1236 | for (int i=0; i<n; i++) | 1236 | for (int i=0; i<n; i++) |
1237 | l.append(tile(i).key()); | 1237 | l.append(tile(i).key()); |
1238 | cfg.writeEntry("Tiles",l,';'); | 1238 | cfg.writeEntry("Tiles",l,';'); |
1239 | } | 1239 | } |
1240 | 1240 | ||
1241 | void Rack::readConfig(Config& cfg) | 1241 | void Rack::readConfig(Config& cfg) |
1242 | { | 1242 | { |
1243 | clear(); | 1243 | clear(); |
1244 | int x=0; | 1244 | int x=0; |
1245 | QStringList l = cfg.readListEntry("Tiles",';'); | 1245 | QStringList l = cfg.readListEntry("Tiles",';'); |
1246 | for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) { | 1246 | for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) { |
1247 | TileItem *i = new TileItem(Tile(*it),TRUE,canvas()); | 1247 | TileItem *i = new TileItem(Tile(*it),TRUE,canvas()); |
1248 | i->move(x++,0); | 1248 | i->move(x++,0); |
1249 | i->show(); | 1249 | i->show(); |
1250 | item[n++] = i; | 1250 | item[n++] = i; |
1251 | } | 1251 | } |
1252 | layoutTiles(); | 1252 | layoutTiles(); |
1253 | } | 1253 | } |
1254 | 1254 | ||
1255 | static int cmp_tileitem(const void *a, const void *b) | 1255 | static int cmp_tileitem(const void *a, const void *b) |
1256 | { | 1256 | { |
1257 | const TileItem* ia = *(TileItem**)a; | 1257 | const TileItem* ia = *(TileItem**)a; |
1258 | const TileItem* ib = *(TileItem**)b; | 1258 | const TileItem* ib = *(TileItem**)b; |
1259 | return int(ia->x() - ib->x()); | 1259 | return int(ia->x() - ib->x()); |
1260 | } | 1260 | } |
1261 | 1261 | ||
1262 | void Rack::layoutTiles() | 1262 | void Rack::layoutTiles() |
1263 | { | 1263 | { |
1264 | int w = TileItem::bigWidth()+2; | 1264 | int w = TileItem::bigWidth()+2; |
1265 | 1265 | ||
1266 | if ( dragging ) dragging->moveBy(dragging_adj,0); | 1266 | if ( dragging ) dragging->moveBy(dragging_adj,0); |
1267 | qsort(item.data(), n, sizeof(TileItem*), cmp_tileitem); | 1267 | qsort(item.data(), n, sizeof(TileItem*), cmp_tileitem); |
1268 | if ( dragging ) dragging->moveBy(-dragging_adj,0); | 1268 | if ( dragging ) dragging->moveBy(-dragging_adj,0); |
1269 | 1269 | ||
1270 | for (int i=0; i<n ;i++) | 1270 | for (int i=0; i<n ;i++) |
1271 | if ( item[i] == dragging ) { | 1271 | if ( item[i] == dragging ) { |
1272 | item[i]->setZ(1); | 1272 | item[i]->setZ(1); |
1273 | } else { | 1273 | } else { |
1274 | item[i]->move(i*w, 0); | 1274 | item[i]->move(i*w, 0); |
1275 | item[i]->setZ(0); | 1275 | item[i]->setZ(0); |
1276 | } | 1276 | } |
1277 | canvas()->update(); | 1277 | canvas()->update(); |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | void Rack::setBlanks(const Tile* bv) | 1280 | void Rack::setBlanks(const Tile* bv) |
1281 | { | 1281 | { |
1282 | for (int j=0; j<n; j++) { | 1282 | for (int j=0; j<n; j++) { |
1283 | Tile tt = item[j]->tile(); | 1283 | Tile tt = item[j]->tile(); |
1284 | if ( tt.isBlank() ) { | 1284 | if ( tt.isBlank() ) { |
1285 | tt.setText(bv->text()); | 1285 | tt.setText(bv->text()); |
1286 | item[j]->setTile(tt); | 1286 | item[j]->setTile(tt); |
1287 | bv++; | 1287 | bv++; |
1288 | } | 1288 | } |
1289 | } | 1289 | } |
1290 | } | 1290 | } |
1291 | 1291 | ||
1292 | bool Rack::arrangeTiles(const Tile** s, int sn) | 1292 | bool Rack::arrangeTiles(const Tile** s, int sn) |
1293 | { | 1293 | { |
1294 | bool could = TRUE; | 1294 | bool could = TRUE; |
1295 | for (int j=0; j<n; j++) { | 1295 | for (int j=0; j<n; j++) { |
1296 | Tile tt = item[j]->tile(); | 1296 | Tile tt = item[j]->tile(); |
1297 | int f=-1; | 1297 | int f=-1; |
1298 | for (int i=0; i<sn && f<0; i++) { | 1298 | for (int i=0; i<sn && f<0; i++) { |
1299 | if (s[i] && *s[i] == tt ) { | 1299 | if (s[i] && *s[i] == tt ) { |
1300 | s[i]=0; | 1300 | s[i]=0; |
1301 | f=i; | 1301 | f=i; |
1302 | } | 1302 | } |
1303 | } | 1303 | } |
1304 | if ( f >= 0 ) { | 1304 | if ( f >= 0 ) { |
1305 | item[j]->move(f-999,0); | 1305 | item[j]->move(f-999,0); |
1306 | } else { | 1306 | } else { |
1307 | could = FALSE; | 1307 | could = FALSE; |
1308 | } | 1308 | } |
1309 | } | 1309 | } |
1310 | layoutTiles(); | 1310 | layoutTiles(); |
1311 | return could; | 1311 | return could; |
1312 | } | 1312 | } |
1313 | 1313 | ||
1314 | void Rack::addTile(const Tile& t) | 1314 | void Rack::addTile(const Tile& t) |
1315 | { | 1315 | { |
1316 | TileItem *i = new TileItem(t,TRUE,canvas()); | 1316 | TileItem *i = new TileItem(t,TRUE,canvas()); |
1317 | i->show(); | 1317 | i->show(); |
1318 | item[n++] = i; | 1318 | item[n++] = i; |
1319 | layoutTiles(); | 1319 | layoutTiles(); |
1320 | } | 1320 | } |
1321 | 1321 | ||
1322 | void Rack::remove(Tile t) | 1322 | void Rack::remove(Tile t) |
1323 | { | 1323 | { |
1324 | for (int i=0; i<n ;i++) | 1324 | for (int i=0; i<n ;i++) |
1325 | if ( item[i]->tile() == t ) { | 1325 | if ( item[i]->tile() == t ) { |
1326 | remove(i); | 1326 | remove(i); |
1327 | return; | 1327 | return; |
1328 | } | 1328 | } |
1329 | } | 1329 | } |
1330 | 1330 | ||
1331 | void Rack::remove(int i) | 1331 | void Rack::remove(int i) |
1332 | { | 1332 | { |
1333 | delete item[i]; | 1333 | delete item[i]; |
1334 | n--; | 1334 | n--; |
1335 | for (;i<n;i++) | 1335 | for (;i<n;i++) |
1336 | item[i]=item[i+1]; | 1336 | item[i]=item[i+1]; |
1337 | layoutTiles(); | 1337 | layoutTiles(); |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | void Rack::resizeEvent(QResizeEvent* e) | 1340 | void Rack::resizeEvent(QResizeEvent* e) |
1341 | { | 1341 | { |
1342 | canvas()->resize(width()-frameWidth()*2,height()-frameWidth()*2); | 1342 | canvas()->resize(width()-frameWidth()*2,height()-frameWidth()*2); |
1343 | QCanvasView::resizeEvent(e); | 1343 | QCanvasView::resizeEvent(e); |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | void Rack::contentsMousePressEvent(QMouseEvent* e) | 1346 | void Rack::contentsMousePressEvent(QMouseEvent* e) |
1347 | { | 1347 | { |
1348 | if ( computerized() ) | 1348 | if ( computerized() ) |
1349 | return; | 1349 | return; |
1350 | QCanvasItemList list = canvas()->collisions(e->pos()); | 1350 | QCanvasItemList list = canvas()->collisions(e->pos()); |
1351 | if (list.count()) { | 1351 | if (list.count()) { |
1352 | dragging = list.first(); | 1352 | dragging = list.first(); |
1353 | dragstart = e->pos()-QPoint(int(dragging->x()),int(dragging->y())); | 1353 | dragstart = e->pos()-QPoint(int(dragging->x()),int(dragging->y())); |
1354 | } else { | 1354 | } else { |
1355 | dragging = 0; | 1355 | dragging = 0; |
1356 | } | 1356 | } |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | void Rack::contentsMouseMoveEvent(QMouseEvent* e) | 1359 | void Rack::contentsMouseMoveEvent(QMouseEvent* e) |
1360 | { | 1360 | { |
1361 | if ( computerized() ) | 1361 | if ( computerized() ) |
1362 | return; | 1362 | return; |
1363 | //int w = TileItem::bigWidth()+2; | 1363 | //int w = TileItem::bigWidth()+2; |
1364 | if ( dragging ) { | 1364 | if ( dragging ) { |
1365 | dragging_adj = TileItem::bigWidth()/2; | 1365 | dragging_adj = TileItem::bigWidth()/2; |
1366 | if ( dragging->x() > e->x()-dragstart.x() ) | 1366 | if ( dragging->x() > e->x()-dragstart.x() ) |
1367 | dragging_adj = -dragging_adj; | 1367 | dragging_adj = -dragging_adj; |
1368 | dragging->move(e->x()-dragstart.x(),0); | 1368 | dragging->move(e->x()-dragstart.x(),0); |
1369 | layoutTiles(); | 1369 | layoutTiles(); |
1370 | } | 1370 | } |
1371 | } | 1371 | } |
1372 | 1372 | ||
1373 | void Rack::contentsMouseReleaseEvent(QMouseEvent* /*e*/) | 1373 | void Rack::contentsMouseReleaseEvent(QMouseEvent* /*e*/) |
1374 | { | 1374 | { |
1375 | if ( computerized() ) | 1375 | if ( computerized() ) |
1376 | return; | 1376 | return; |
1377 | if ( dragging ) { | 1377 | if ( dragging ) { |
1378 | dragging=0; | 1378 | dragging=0; |
1379 | layoutTiles(); | 1379 | layoutTiles(); |
1380 | } | 1380 | } |
1381 | } | 1381 | } |
1382 | 1382 | ||
1383 | Tile::Tile(const QString& key) | 1383 | Tile::Tile(const QString& key) |
1384 | { | 1384 | { |
1385 | int a=key.find('@'); | 1385 | int a=key.find('@'); |
1386 | txt = key.left(a); | 1386 | txt = key.left(a); |
1387 | val = key.mid(a+1).toInt(); | 1387 | val = key.mid(a+1).toInt(); |
1388 | blank = txt.isEmpty(); | 1388 | blank = txt.isEmpty(); |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | QString Tile::key() const | 1391 | QString Tile::key() const |
1392 | { | 1392 | { |
1393 | return txt+"@"+QString::number(val); | 1393 | return txt+"@"+QString::number(val); |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | Bag::Bag() | 1396 | Bag::Bag() |
1397 | { | 1397 | { |
1398 | tiles.setAutoDelete(TRUE); | 1398 | tiles.setAutoDelete(TRUE); |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | void Bag::writeConfig(Config& cfg) | 1401 | void Bag::writeConfig(Config& cfg) |
1402 | { | 1402 | { |
1403 | QStringList t; | 1403 | QStringList t; |
1404 | for (QListIterator<Tile> it(tiles); it; ++it) | 1404 | for (QListIterator<Tile> it(tiles); it; ++it) |
1405 | t.append((*it)->key()); | 1405 | t.append((*it)->key()); |
1406 | cfg.writeEntry("Tiles",t,';'); | 1406 | cfg.writeEntry("Tiles",t,';'); |
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | void Bag::readConfig(Config& cfg) | 1409 | void Bag::readConfig(Config& cfg) |
1410 | { | 1410 | { |
1411 | tiles.clear(); | 1411 | tiles.clear(); |
1412 | QStringList t = cfg.readListEntry("Tiles",';'); | 1412 | QStringList t = cfg.readListEntry("Tiles",';'); |
1413 | for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it ) | 1413 | for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it ) |
1414 | add(Tile(*it)); | 1414 | add(Tile(*it)); |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | void Bag::add(const Tile& t) | 1417 | void Bag::add(const Tile& t) |
1418 | { | 1418 | { |
1419 | tiles.append(new Tile(t)); | 1419 | tiles.append(new Tile(t)); |
1420 | } | 1420 | } |
1421 | 1421 | ||
1422 | Tile Bag::takeRandom() | 1422 | Tile Bag::takeRandom() |
1423 | { | 1423 | { |
1424 | Tile* rp = tiles.take(random()%tiles.count()); | 1424 | Tile* rp = tiles.take(random()%tiles.count()); |
1425 | Tile r=*rp; | 1425 | Tile r=*rp; |
1426 | return r; | 1426 | return r; |
1427 | } | 1427 | } |
1428 | 1428 | ||
1429 | ScoreInfo::ScoreInfo( QWidget* parent, const char* name, WFlags fl ) : | 1429 | ScoreInfo::ScoreInfo( QWidget* parent, const char* name, WFlags fl ) : |
1430 | QLabel("<P>",parent,name,fl) | 1430 | QLabel("<P>",parent,name,fl) |
1431 | { | 1431 | { |
1432 | score=0; | 1432 | score=0; |
1433 | msgtimer = new QTimer(this); | 1433 | msgtimer = new QTimer(this); |
1434 | connect(msgtimer, SIGNAL(timeout()), this, SLOT(showScores())); | 1434 | connect(msgtimer, SIGNAL(timeout()), this, SLOT(showScores())); |
1435 | setBackgroundMode( PaletteButton ); | 1435 | setBackgroundMode( PaletteButton ); |
1436 | } | 1436 | } |
1437 | 1437 | ||
1438 | ScoreInfo::~ScoreInfo() | 1438 | ScoreInfo::~ScoreInfo() |
1439 | { | 1439 | { |
1440 | if ( score ) delete [] score; | 1440 | if ( score ) delete [] score; |
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | void ScoreInfo::writeConfig(Config& cfg) | 1443 | void ScoreInfo::writeConfig(Config& cfg) |
1444 | { | 1444 | { |
1445 | QStringList l; | 1445 | QStringList l; |
1446 | for (int i=0; i<(int)names.count(); i++) | 1446 | for (int i=0; i<(int)names.count(); i++) |
1447 | l.append(QString::number(score[i])); | 1447 | l.append(QString::number(score[i])); |
1448 | cfg.writeEntry("Scores",l,';'); | 1448 | cfg.writeEntry("Scores",l,';'); |
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | void ScoreInfo::readConfig(Config& cfg) | 1451 | void ScoreInfo::readConfig(Config& cfg) |
1452 | { | 1452 | { |
1453 | QStringList l = cfg.readListEntry("Scores",';'); | 1453 | QStringList l = cfg.readListEntry("Scores",';'); |
1454 | int i=0; | 1454 | int i=0; |
1455 | for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it ) | 1455 | for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it ) |
1456 | score[i++]=(*it).toInt(); | 1456 | score[i++]=(*it).toInt(); |
1457 | showScores(); | 1457 | showScores(); |
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | 1460 | ||
1461 | QSize ScoreInfo::sizeHint() const | 1461 | QSize ScoreInfo::sizeHint() const |
1462 | { | 1462 | { |
1463 | return QSize(QLabel::sizeHint().width(),fontMetrics().height()); | 1463 | return QSize(QLabel::sizeHint().width(),fontMetrics().height()); |
1464 | } | 1464 | } |
1465 | 1465 | ||
1466 | void ScoreInfo::init(const QStringList& namelist) | 1466 | void ScoreInfo::init(const QStringList& namelist) |
1467 | { | 1467 | { |
1468 | names = namelist; | 1468 | names = namelist; |
1469 | if ( score ) delete [] score; | 1469 | if ( score ) delete [] score; |
1470 | score = new int[names.count()]; | 1470 | score = new int[names.count()]; |
1471 | memset(score,0,sizeof(int)*names.count()); | 1471 | memset(score,0,sizeof(int)*names.count()); |
1472 | boldone = -1; | 1472 | boldone = -1; |
1473 | showScores(); | 1473 | showScores(); |
1474 | } | 1474 | } |
1475 | 1475 | ||
1476 | void ScoreInfo::addScore(int player, int change) | 1476 | void ScoreInfo::addScore(int player, int change) |
1477 | { | 1477 | { |
1478 | score[player] += change; | 1478 | score[player] += change; |
1479 | showScores(); | 1479 | showScores(); |
1480 | } | 1480 | } |
1481 | 1481 | ||
1482 | void ScoreInfo::setBoldOne(int b) | 1482 | void ScoreInfo::setBoldOne(int b) |
1483 | { | 1483 | { |
1484 | boldone=b; | 1484 | boldone=b; |
1485 | showScores(); | 1485 | showScores(); |
1486 | } | 1486 | } |
1487 | 1487 | ||
1488 | void ScoreInfo::showScores() | 1488 | void ScoreInfo::showScores() |
1489 | { | 1489 | { |
1490 | QString r="<p>"; | 1490 | QString r="<p>"; |
1491 | int i=0; | 1491 | int i=0; |
1492 | //int spl=(names.count()+1)/2; // 2 lines | 1492 | //int spl=(names.count()+1)/2; // 2 lines |
1493 | for (QStringList::ConstIterator it=names.begin(); it!=names.end(); ) { | 1493 | for (QStringList::ConstIterator it=names.begin(); it!=names.end(); ) { |
1494 | if ( i==boldone ) r += "<b>"; | 1494 | if ( i==boldone ) r += "<b>"; |
1495 | QString n = *it; | 1495 | QString n = *it; |
1496 | n.replace(QRegExp(":.*"),""); | 1496 | n.replace(QRegExp(":.*"),""); |
1497 | r += n; | 1497 | r += n; |
1498 | r += ":"; | 1498 | r += ":"; |
1499 | r += QString::number(score[i]); | 1499 | r += QString::number(score[i]); |
1500 | if ( i==boldone ) r += "</b>"; | 1500 | if ( i==boldone ) r += "</b>"; |
1501 | 1501 | ||
1502 | ++i; | 1502 | ++i; |
1503 | ++it; | 1503 | ++it; |
1504 | if ( it != names.end() ) | 1504 | if ( it != names.end() ) |
1505 | r += " "; | 1505 | r += " "; |
1506 | } | 1506 | } |
1507 | setText(r); | 1507 | setText(r); |
1508 | } | 1508 | } |
1509 | 1509 | ||
1510 | void ScoreInfo::showTemporaryScore(int amount) | 1510 | void ScoreInfo::showTemporaryScore(int amount) |
1511 | { | 1511 | { |
1512 | if ( amount < 0 ) | 1512 | if ( amount < 0 ) |
1513 | setText(tr("<P>Invalid move")); | 1513 | setText(tr("<P>Invalid move")); |
1514 | else | 1514 | else |
1515 | setText(tr("<P>Score: ")+QString::number(amount)); | 1515 | setText(tr("<P>Score: ")+QString::number(amount)); |
1516 | msgtimer->start(3000,TRUE); | 1516 | msgtimer->start(3000,TRUE); |
1517 | } | 1517 | } |
1518 | 1518 | ||