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