author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /noncore/games | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
145 files changed, 21180 insertions, 0 deletions
diff --git a/noncore/games/chess/Makefile.in b/noncore/games/chess/Makefile.in new file mode 100644 index 0000000..7354d76 --- a/dev/null +++ b/noncore/games/chess/Makefile.in | |||
@@ -0,0 +1,134 @@ | |||
1 | ############################################################################# | ||
2 | |||
3 | ####### Compiler, tools and options | ||
4 | |||
5 | CXX =$(SYSCONF_CXX) $(QT_CXX_MT) | ||
6 | CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) -DQCONFIG=\"qpe\" | ||
7 | CC =$(SYSCONF_CC) $(QT_C_MT) | ||
8 | CFLAGS =$(SYSCONF_CFLAGS) -DQCONFIG=\"qpe\" | ||
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 | |||
17 | DESTDIR = ../bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= chess | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =chess.h | ||
27 | SOURCES =chess.cpp \ | ||
28 | main.cpp | ||
29 | OBJECTS =chess.o \ | ||
30 | main.o \ | ||
31 | mainwindow.o | ||
32 | INTERFACES = mainwindow.ui | ||
33 | UICDECLS = mainwindow.h | ||
34 | UICIMPLS = mainwindow.cpp | ||
35 | SRCMOC =moc_chess.cpp \ | ||
36 | moc_mainwindow.cpp | ||
37 | OBJMOC =moc_chess.o \ | ||
38 | moc_mainwindow.o | ||
39 | |||
40 | |||
41 | ####### Implicit rules | ||
42 | |||
43 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
44 | |||
45 | .cpp.o: | ||
46 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
47 | |||
48 | .cxx.o: | ||
49 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
50 | |||
51 | .cc.o: | ||
52 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
53 | |||
54 | .C.o: | ||
55 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
56 | |||
57 | .c.o: | ||
58 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
59 | |||
60 | ####### Build rules | ||
61 | |||
62 | |||
63 | all: $(DESTDIR)$(TARGET) | ||
64 | |||
65 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
66 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
67 | |||
68 | moc: $(SRCMOC) | ||
69 | |||
70 | tmake: | ||
71 | tmake chess.pro | ||
72 | |||
73 | clean: | ||
74 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
75 | -rm -f *~ core | ||
76 | -rm -f allmoc.cpp | ||
77 | |||
78 | ####### Extension Modules | ||
79 | |||
80 | listpromodules: | ||
81 | @echo | ||
82 | |||
83 | listallmodules: | ||
84 | @echo | ||
85 | |||
86 | listaddonpromodules: | ||
87 | @echo | ||
88 | |||
89 | listaddonentmodules: | ||
90 | @echo | ||
91 | |||
92 | |||
93 | REQUIRES= | ||
94 | |||
95 | ####### Sub-libraries | ||
96 | |||
97 | |||
98 | ###### Combined headers | ||
99 | |||
100 | |||
101 | |||
102 | ####### Compile | ||
103 | |||
104 | chess.o: chess.cpp \ | ||
105 | $(QPEDIR)/include/qpe/config.h \ | ||
106 | $(QPEDIR)/include/qpe/resource.h \ | ||
107 | chess.h | ||
108 | |||
109 | main.o: main.cpp \ | ||
110 | mainwindow.h | ||
111 | |||
112 | mainwindow.h: mainwindow.ui | ||
113 | $(UIC) mainwindow.ui -o $(INTERFACE_DECL_PATH)/mainwindow.h | ||
114 | |||
115 | mainwindow.cpp: mainwindow.ui | ||
116 | $(UIC) mainwindow.ui -i mainwindow.h -o mainwindow.cpp | ||
117 | |||
118 | mainwindow.o: mainwindow.cpp \ | ||
119 | mainwindow.h \ | ||
120 | mainwindow.ui | ||
121 | |||
122 | moc_chess.o: moc_chess.cpp \ | ||
123 | chess.h | ||
124 | |||
125 | moc_mainwindow.o: moc_mainwindow.cpp \ | ||
126 | mainwindow.h | ||
127 | |||
128 | moc_chess.cpp: chess.h | ||
129 | $(MOC) chess.h -o moc_chess.cpp | ||
130 | |||
131 | moc_mainwindow.cpp: mainwindow.h | ||
132 | $(MOC) mainwindow.h -o moc_mainwindow.cpp | ||
133 | |||
134 | |||
diff --git a/noncore/games/chess/boardview.cw b/noncore/games/chess/boardview.cw new file mode 100644 index 0000000..020af96 --- a/dev/null +++ b/noncore/games/chess/boardview.cw | |||
@@ -0,0 +1,23 @@ | |||
1 | <!DOCTYPE CW><CW> | ||
2 | <customwidgets> | ||
3 | <customwidget> | ||
4 | <class>BoardView</class> | ||
5 | <header location="global">/home/luke/depot/qpe/chess/chess.h</header> | ||
6 | <sizehint> | ||
7 | <width>-1</width> | ||
8 | <height>-1</height> | ||
9 | </sizehint> | ||
10 | <container>0</container> | ||
11 | <sizepolicy> | ||
12 | <hordata>5</hordata> | ||
13 | <verdata>5</verdata> | ||
14 | </sizepolicy> | ||
15 | <pixmap> | ||
16 | <data format="XPM.GZ" length="4605">789c6dd7d96ee33a1206e0fb7e8aa0ebae31a863c9966d613017d9e3ecce9e0ce6a228c94b6c67f192d83998771f9af517e10493b4daf89a25b258a428f75f7fb61e2ecfb6fefcf56b3697f9b0d82a0632ddfa532e2693d5bffff3afbf7ffd4ed3adf027d94a7fffe3d76ff7b9556c9dbfbe5401ef9bf8d8c464136f9b186ee27513cf9bd8dec47c13d30d74bfb52c3d28cdd322a9058fd6aee7f5a29e047f697bbd96b483573fe2173ffc82fbdbb87fb0762389fdcdd6ee859fe0716ccfd7e6def7fed8c5f1d5c5f77c58c2788959ea70230dfd3982dba9de7f6ff9693b757ee4dbb7f9a3fdf5473d7aea464dfb23fa3e3fdafe319f3d75a3a1edbc0fb7913f9991df8b19f7977081f1ae83c5da89cd8dd0bf34601bffceaced14facfd22c53f36db484f95570a9e3398ed6f1c27ec8c4e239877378d79c85bd4f477089f117d1219ee666c4d7d4cd04fddd98d1de5ebb995abc3ca863fb04467eb26746fc398c7ce5c0aced7c1dade3bfc2983f5766acf7be19f59f466b3d4b752bc1fd9a9f58ffd28311cf6d33f2b9323735ff17752bc17855b4f697c119f2cbcd884fe15cd757d6c711b5ea2dd48766708efd959871ffb319f53c86ad1e67d1fafc89ba9d60bcaf68edffca8ce7ab8033c4b7a2b57e3bc1ae95b7eac1db70091fa9db895a6e61ab472b3af4277730e6cb5d33e69bc3781e6865c6f31ce6d3f6f9b75c881738d3f5e2b119ed27708ef655b4aedf0d6cf5fc50e709f27d84510fb930e3f94a615bdf6bb3f627f7b0cd47f3f5f36d877a5103b67af6cddace23759e20fe00b6e77da016acb77370a6e71df5cc18bf1fadfb610c0bcef304ae6aeab619ef83f57b92f286e5c3cfd1a1de3c803378095bbd9bea98cf305af7430b16d47319adf53f34637daee00af9f7d52ed57c692f5acf7fbdbfc8f3bc113c834be43b35a37d185d84feeed482fd47e77086fdbf0b57d81f75b54b311f8ad6f95e9a319f1adc44fed3689ddf132c589f8e59e385a3b5fdcc8cf1bb30d697a2311eea53a07e1cce7b6948a2f52007676ad956bb14e7e53e6cebb382adff67339eb7a5dac6930f33ce87266cf5388dd6f50ccf83f87a8baed77bb4aed78edaa5c877085738ff3fcdd89f13b58d4f68b7f1e5d48cfd589a118ff10bd49b9ea235fe12aef0fc55669c6fe17c718d42701ececcfafea2118cfb3935e3bcf98cd6f18ecc785fbd99f1beabab4bab77c38cef2b613d5c5908ced357b8c2799aa9637c12ade32dcc787fedc04d7c1fb935e33c7b8cd6f509df578aac10acef02aef0bc76ccbade7caeb6fb656ec6fe1c98f1fc5ec2a82f9f9931bf5ab4e67b0263bf70d80f455956e8efc6acf9d185ba4a51bfb119e779789f97be7f9d1fbda9637b19adf73b33e21fe026ea7162c6f31ad6a7acaad4e9fe1fc1d6be1badf53b36a39e4fb0e5771f1dda257c7fa89a668a76657013b6f509eb5bf99f225bbb3b5fff32b1b0e3c25fffefb3d4288de78a7bdce7010ffdf5cca38dabef7fc73ce1177fcf6b8c77fcc6ef3cf56d6f3ce3392ff8833f79c92bfee26ddef1f1bbbcc785c6f3be8f3be0433ef2b11d3ee6133ee5333ee70bbee42e5ff135dff02ddff13d5388179fc5d4f7f4c08ffcc4354e38e53a3738f39f4d6e719b73ce898958d7a7c74312725450491537a9477d1ad0909e69e4e39b34a609bdf01dbdb2d6abf0fd3ff8e8377aa729cd684e8b704de8833e69e97f57f4e5fbdf8efd3fd30eed724a7bb44f733ff6fa3ae0aebf6be5a30f7d2f473ebe8378f1f1c77442a77416fb3ea70bba0c77f47c465dbaa2eb6ffddfd0adefddfabea37b7aa0477aa21a25beff25a5a17fcbff994a4ea88ebe1b9451d3d734a116b529f7d15df1cbefe71bfbe753ba145af72d224e7ca5f84c4aa9bc7b7edca5f4bfe72f03df3ea485f83b652463bf0a19d765e2df012febfcb9f53d7f79f5f16ff22e5399c95c16f2219f7ec512ffe9eb232bf9fa96ff48b67ddb8eecca9eef719fbb72208772b45ee175fda523c7dff2efcb899cfad57a973339478de672219721ba2b573fea3fe61db9f6792eb9292c37722b77d4926558dbaecfa62ff73eff4eec7fc2d7f2208f612dfde5ef3c44e493cfa523354924953af22fa5e1f7f7adaf9dff4f9d5fcb25aeae7468202d1fdd96dcb123ddcfe179d9f3fbef3a5c95131abbf54fc1fe0deb3771e9a32bd7e35e7cbefc4e757d377043f78c6be4af71f87be25edcab7b73ef6eaaf16eb67e92dddc2ddc87fbf4ff6e9f9ffe73e93f57eecb6dfb081ff7fbbffffcf53f54dd2532</data> | ||
17 | </pixmap> | ||
18 | <slot access="public">newGame()</slot> | ||
19 | <slot access="public">swapSides()</slot> | ||
20 | <slot access="public">setTheme(QString)</slot> | ||
21 | </customwidget> | ||
22 | </customwidgets> | ||
23 | </CW> | ||
diff --git a/noncore/games/chess/chess.cpp b/noncore/games/chess/chess.cpp new file mode 100644 index 0000000..96a838a --- a/dev/null +++ b/noncore/games/chess/chess.cpp | |||
@@ -0,0 +1,358 @@ | |||
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 | // human is not offered a promotion yet | ||
23 | |||
24 | #include <qcanvas.h> | ||
25 | #include <qmainwindow.h> | ||
26 | #include <qlist.h> | ||
27 | #include <qimage.h> | ||
28 | #include <qpainter.h> | ||
29 | #include <qmessagebox.h> | ||
30 | #include <qregexp.h> | ||
31 | |||
32 | #include <qpe/config.h> | ||
33 | #include <qpe/resource.h> | ||
34 | |||
35 | #include "chess.h" | ||
36 | |||
37 | #define CHESS_DEBUG | ||
38 | |||
39 | int pieceSize = 40; | ||
40 | static QVector < QImage > imgList; | ||
41 | int timeMoves, timeTime; | ||
42 | |||
43 | int BoardView::convertToRank(int r) | ||
44 | { | ||
45 | r = r / pieceSize; | ||
46 | if (humanSide == sideWhite) | ||
47 | r = 8 - r; | ||
48 | else | ||
49 | r++; | ||
50 | return r; | ||
51 | } | ||
52 | |||
53 | char BoardView::convertToFile(int f) | ||
54 | { | ||
55 | f = f / pieceSize; | ||
56 | if (humanSide == sideWhite) | ||
57 | return f + 'a'; | ||
58 | else | ||
59 | return 'h' - f; | ||
60 | } | ||
61 | |||
62 | int BoardView::convertFromFile(char f) | ||
63 | { | ||
64 | if (humanSide == sideWhite) | ||
65 | f = f - 'a'; | ||
66 | else | ||
67 | f = 'h' - f; | ||
68 | return f * pieceSize; | ||
69 | } | ||
70 | |||
71 | int BoardView::convertFromRank(int r) | ||
72 | { | ||
73 | if (humanSide == sideWhite) | ||
74 | r = 8 - r; | ||
75 | else | ||
76 | r--; | ||
77 | return r * pieceSize; | ||
78 | } | ||
79 | |||
80 | // Pieces | ||
81 | Piece::Piece(QCanvas * canvas, int t):QCanvasRectangle(canvas) | ||
82 | { | ||
83 | type = t; | ||
84 | setSize(pieceSize, pieceSize); | ||
85 | show(); | ||
86 | } | ||
87 | |||
88 | Piece *BoardView::newPiece(int t, char f, int r) | ||
89 | { | ||
90 | Piece *tmpPiece = new Piece(canvas(), t); | ||
91 | tmpPiece->move(convertFromFile(f), convertFromRank(r)); | ||
92 | list.append(tmpPiece); | ||
93 | return tmpPiece; | ||
94 | } | ||
95 | |||
96 | void BoardView::deletePiece(Piece * p) | ||
97 | { | ||
98 | list.remove(p); | ||
99 | canvas()->update(); | ||
100 | } | ||
101 | |||
102 | void Piece::drawShape(QPainter & p) | ||
103 | { | ||
104 | p.drawImage(int (x()), int (y()), *(imgList[type])); | ||
105 | } | ||
106 | |||
107 | void BoardView::buildImages(QImage theme) | ||
108 | { | ||
109 | imgList.resize(12); | ||
110 | int x; | ||
111 | int y = 0; | ||
112 | |||
113 | for (int j = 0; j < 2; j++) { | ||
114 | x = 0; | ||
115 | for (int i = 0; i < 6; i++) { | ||
116 | imgList.insert(i + (j * 6), | ||
117 | new QImage(theme. | ||
118 | copy(x, y, pieceSize, pieceSize))); | ||
119 | x += pieceSize; | ||
120 | } | ||
121 | y += pieceSize; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | void BoardView::readStdout() | ||
126 | { | ||
127 | QString input( crafty->readStdout() ); | ||
128 | #ifdef CHESS_DEBUG | ||
129 | qDebug("received this string from crafty->\n%s\n", input.latin1()); | ||
130 | #endif | ||
131 | |||
132 | int startPosition = input.find("setboard"); | ||
133 | if (startPosition != -1) | ||
134 | decodePosition(input.remove(0, startPosition + 9)); | ||
135 | |||
136 | if (input.contains("Black mates")) { | ||
137 | playingGame = FALSE; | ||
138 | emit(showMessage("Black mates")); | ||
139 | } else if (input.contains("White mates")) { | ||
140 | playingGame = FALSE; | ||
141 | emit(showMessage("White mates")); | ||
142 | } else if (input.contains(" resigns")) { | ||
143 | playingGame = FALSE; | ||
144 | emit(showMessage("Computer resigns")); | ||
145 | } else if (input.contains("Draw")) { | ||
146 | playingGame = FALSE; | ||
147 | emit(showMessage("Draw")); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | // this is pretty close to getting done right | ||
152 | // maybe dont use sprites and just draw a picture | ||
153 | // there'll be lots of drawing done anyway | ||
154 | // eg creating pictures for the webpages, | ||
155 | // and presenting options for promotions | ||
156 | void BoardView::decodePosition(const QString & t) | ||
157 | { | ||
158 | qDebug("decode copped %s \n", t.latin1()); | ||
159 | |||
160 | int count = 0; | ||
161 | int stringPos = 0; | ||
162 | for (int file = 0; file < 8; file++) { | ||
163 | for (int rank = 0; rank < 8; rank++) { | ||
164 | if (count) | ||
165 | count--; | ||
166 | else { | ||
167 | if (t.at(stringPos).isNumber()) | ||
168 | count = t.at(stringPos).digitValue(); | ||
169 | else { | ||
170 | newPiece(t.at(stringPos).latin1(), 'a' + file, | ||
171 | rank + 1); | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | void BoardView::undo() | ||
179 | { | ||
180 | crafty->writeToStdin("undo\n"); | ||
181 | crafty->writeToStdin("savepos\nclock\n"); | ||
182 | } | ||
183 | |||
184 | void BoardView::emitErrorMessage() | ||
185 | { | ||
186 | if (activeSide != humanSide) | ||
187 | emit(showMessage("Not your move")); | ||
188 | else | ||
189 | emit(showMessage("You are not playing a game")); | ||
190 | } | ||
191 | |||
192 | void BoardView::annotateGame() | ||
193 | { | ||
194 | crafty-> | ||
195 | writeToStdin | ||
196 | ("savegame game.save\nannotateh game.save bw 0 1.0 1\n"); | ||
197 | emit(showMessage("Annotating game")); | ||
198 | } | ||
199 | |||
200 | Piece *BoardView::findPiece(char f, int r) | ||
201 | { | ||
202 | QListIterator < Piece > it(list); | ||
203 | Piece *tmpPiece; | ||
204 | for (; it.current(); ++it) { | ||
205 | tmpPiece = it.current(); | ||
206 | if (convertToRank(tmpPiece->x()) == r | ||
207 | && convertToFile(tmpPiece->y()) == f) | ||
208 | return tmpPiece; | ||
209 | } | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | void BoardView::newGame() | ||
214 | { | ||
215 | activeSide = sideWhite; | ||
216 | emit(showMessage("New game")); | ||
217 | crafty->writeToStdin("new\n"); | ||
218 | crafty->writeToStdin("savepos\n"); | ||
219 | crafty->writeToStdin("time " + | ||
220 | QString::number(timeMoves) + | ||
221 | "/" + QString::number(timeTime) + "\n"); | ||
222 | activeSide = sideWhite; | ||
223 | if (humanSide == sideBlack) | ||
224 | crafty->writeToStdin("go\n"); | ||
225 | } | ||
226 | |||
227 | void BoardView::setTheme(QString filename) | ||
228 | { | ||
229 | QImage theme = Resource::loadImage(QString("chess/") + filename); | ||
230 | pieceSize = theme.height() / 2; | ||
231 | setFrameStyle(QFrame::Plain); | ||
232 | setFixedSize(8 * pieceSize, 8 * pieceSize); | ||
233 | canvas()->setBackgroundColor(Qt::red); | ||
234 | canvas()->resize(8 * pieceSize, 8 * pieceSize); | ||
235 | whiteSquare = theme.copy(6 * pieceSize, 0, pieceSize, pieceSize); | ||
236 | activeWhiteSquare = theme.copy(7 * pieceSize, 0, pieceSize, pieceSize); | ||
237 | blackSquare = | ||
238 | theme.copy(6 * pieceSize, pieceSize, pieceSize, pieceSize); | ||
239 | activeBlackSquare = | ||
240 | theme.copy(7 * pieceSize, pieceSize, pieceSize, pieceSize); | ||
241 | buildImages(theme); | ||
242 | drawBackgroundImage(QPoint(-1, -1)); | ||
243 | } | ||
244 | |||
245 | |||
246 | // sets the bg to the default background image for the current theme | ||
247 | // also resposible for drawing the "active" marker | ||
248 | void BoardView::drawBackgroundImage(QPoint activeSquare) | ||
249 | { | ||
250 | bg = QPixmap(8 * pieceSize, 8 * pieceSize); | ||
251 | QPainter p(&bg); | ||
252 | bool col = FALSE; | ||
253 | for (int i = 0; i < 8; i++) { | ||
254 | for (int j = 0; j < 8; j++) { | ||
255 | QPoint point(i * pieceSize, j * pieceSize); | ||
256 | if (col) { | ||
257 | if (point.x() == activeSquare.x() | ||
258 | && point.y() == activeSquare.y()) | ||
259 | p.drawImage(point, activeBlackSquare); | ||
260 | else | ||
261 | p.drawImage(point, blackSquare); | ||
262 | col = FALSE; | ||
263 | } else { | ||
264 | if (point.x() == activeSquare.x() | ||
265 | && point.y() == activeSquare.y()) | ||
266 | p.drawImage(point, activeWhiteSquare); | ||
267 | else | ||
268 | p.drawImage(point, whiteSquare); | ||
269 | col = TRUE; | ||
270 | } | ||
271 | } | ||
272 | col = !col; | ||
273 | } | ||
274 | canvas()->setBackgroundPixmap(bg); | ||
275 | canvas()->update(); | ||
276 | } | ||
277 | |||
278 | |||
279 | // Board view widget | ||
280 | void BoardView::contentsMousePressEvent(QMouseEvent * e) | ||
281 | { | ||
282 | QCanvasItemList cList = canvas()->collisions(e->pos()); | ||
283 | if (activeSide == humanSide && playingGame) { | ||
284 | if (!activePiece) { | ||
285 | if (cList.count()) { | ||
286 | activePiece = (Piece *) (*(cList.at(0))); | ||
287 | drawBackgroundImage(QPoint | ||
288 | (activePiece->x(), activePiece->y())); | ||
289 | } | ||
290 | } else { | ||
291 | if (!(activePiece == (Piece *) (*(cList.at(0))))) { | ||
292 | char fromFile = convertToFile(activePiece->x()); | ||
293 | int fromRank = convertToRank(activePiece->y()); | ||
294 | char toFile = convertToFile(e->pos().x()); | ||
295 | int toRank = convertToRank(e->pos().y()); | ||
296 | QString moveS; | ||
297 | moveS.append(fromFile); | ||
298 | moveS.append(moveS.number(fromRank)); | ||
299 | moveS.append(toFile); | ||
300 | moveS.append(moveS.number(toRank)); | ||
301 | if ((activePiece->type == wPawn | ||
302 | && fromRank == 7 && toRank == 8) | ||
303 | || (activePiece->type == bPawn | ||
304 | && fromRank == 2 && toRank == 1)) { | ||
305 | // offer a promotion | ||
306 | emit(showMessage | ||
307 | ("you are meant to be offered a promotion here")); | ||
308 | char promoteTo = wQueen;// doesnt matter for now | ||
309 | moveS.append(promoteTo); | ||
310 | moveS.append("\n"); | ||
311 | crafty->writeToStdin(moveS.latin1()); | ||
312 | } | ||
313 | } | ||
314 | activePiece = 0; | ||
315 | drawBackgroundImage(QPoint(-1, -1)); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | else { | ||
320 | emitErrorMessage(); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | void BoardView::swapSides() | ||
325 | { | ||
326 | if (activeSide == humanSide && playingGame) { | ||
327 | humanSide = !humanSide; | ||
328 | crafty->writeToStdin("savepos\ngo\n"); | ||
329 | } else | ||
330 | emitErrorMessage(); | ||
331 | } | ||
332 | |||
333 | BoardView::BoardView(QCanvas *c, QWidget *w, const char *name) | ||
334 | : QCanvasView(c, w, name) { | ||
335 | humanSide = sideWhite; | ||
336 | activeSide = sideWhite; | ||
337 | playingGame = TRUE; | ||
338 | activePiece = 0; | ||
339 | list.setAutoDelete(TRUE); | ||
340 | setCanvas(new QCanvas()); | ||
341 | Config c("Chess", Config::User); | ||
342 | c.setGroup("Theme"); | ||
343 | QString theme = c.readEntry("imagefile", "simple-28"); | ||
344 | setTheme(theme); | ||
345 | crafty = new CraftyProcess(this); | ||
346 | crafty->addArgument("crafty"); | ||
347 | if (!crafty->start()) { | ||
348 | QMessageBox::critical(0, | ||
349 | tr("Could not find crafty chess engine"), | ||
350 | tr("Quit")); | ||
351 | exit(-1); | ||
352 | } | ||
353 | |||
354 | connect(crafty, SIGNAL(readyReadStdout()), this, SLOT(readStdout())); | ||
355 | connect(crafty, SIGNAL(processExited()), this, SLOT(craftyDied())); | ||
356 | // crafty->writeToStdin("xboard\nics\nkibitz=2\n"); | ||
357 | newGame(); | ||
358 | } | ||
diff --git a/noncore/games/chess/chess.db b/noncore/games/chess/chess.db new file mode 100644 index 0000000..b520b30 --- a/dev/null +++ b/noncore/games/chess/chess.db | |||
@@ -0,0 +1,2 @@ | |||
1 | <!DOCTYPE DB><DB version="1.0"> | ||
2 | </DB> | ||
diff --git a/noncore/games/chess/chess.h b/noncore/games/chess/chess.h new file mode 100644 index 0000000..067b2f8 --- a/dev/null +++ b/noncore/games/chess/chess.h | |||
@@ -0,0 +1,128 @@ | |||
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 | ** $Id$ | ||
20 | ** | ||
21 | **********************************************************************/ | ||
22 | #ifndef CHESS_H | ||
23 | #define CHESS_H | ||
24 | |||
25 | #include <qwidget.h> | ||
26 | #include <qcanvas.h> | ||
27 | #include <qmainwindow.h> | ||
28 | #include <qpixmap.h> | ||
29 | #include <qimage.h> | ||
30 | #include <qstack.h> | ||
31 | #include <qvector.h> | ||
32 | #include <qpe/process.h> | ||
33 | |||
34 | #define wPawn 'P' | ||
35 | #definewKnight 'N' | ||
36 | #define wBishop 'B' | ||
37 | #define wRook 'R' | ||
38 | #define wQueen 'Q' | ||
39 | #define wKing 'K' | ||
40 | #define bPawn 'p' | ||
41 | #define bKnight 'n' | ||
42 | #define bBishop 'b' | ||
43 | #define bRook 'r' | ||
44 | #define bQueen 'q' | ||
45 | #define bKing 'k' | ||
46 | #define NONE N | ||
47 | |||
48 | #define sideWhite 0 | ||
49 | #define sideBlack 1 | ||
50 | |||
51 | |||
52 | class Piece:public QCanvasRectangle { | ||
53 | public: | ||
54 | Piece(QCanvas *, int); | ||
55 | ~Piece() { | ||
56 | }; | ||
57 | |||
58 | char type; | ||
59 | |||
60 | protected: | ||
61 | void drawShape(QPainter &); | ||
62 | }; | ||
63 | |||
64 | |||
65 | class CraftyProcess : public Process { | ||
66 | public: | ||
67 | CraftyProcess(QObject *parent) : Process( parent ) { qDebug("CraftyProcess functions not implemented"); } | ||
68 | ~CraftyProcess() { } | ||
69 | bool start() { qDebug("CraftyProcess functions not implemented"); return FALSE; } | ||
70 | const char *readStdout() { qDebug("CraftyProcess functions not implemented"); return "Blah"; } | ||
71 | void writeToStdin(const char *) { qDebug("CraftyProcess functions not implemented"); } | ||
72 | }; | ||
73 | |||
74 | |||
75 | class BoardView:public QCanvasView { | ||
76 | Q_OBJECT public: | ||
77 | BoardView(QCanvas *, QWidget *, const char *); | ||
78 | ~BoardView() { | ||
79 | }; | ||
80 | |||
81 | protected: | ||
82 | void contentsMousePressEvent(QMouseEvent *); | ||
83 | |||
84 | signals: | ||
85 | void showMessage(const QString &); | ||
86 | |||
87 | public slots:void readStdout(); | ||
88 | void craftyDied() { | ||
89 | qFatal("Crafty died unexpectedly\n"); | ||
90 | }; | ||
91 | void newGame(); | ||
92 | void setTheme(QString); | ||
93 | void swapSides(); | ||
94 | void undo(); | ||
95 | void annotateGame(); | ||
96 | |||
97 | private: | ||
98 | CraftyProcess * crafty; | ||
99 | QList < Piece > list; | ||
100 | Piece *activePiece; | ||
101 | |||
102 | void revertLastMove(); | ||
103 | void emitErrorMessage(); | ||
104 | void drawBackgroundImage(QPoint activeSquare); | ||
105 | |||
106 | void buildImages(QImage); | ||
107 | |||
108 | char convertToFile(int); | ||
109 | int convertToRank(int); | ||
110 | int convertFromFile(char); | ||
111 | int convertFromRank(int); | ||
112 | |||
113 | void decodePosition(const QString & t); | ||
114 | |||
115 | Piece *findPiece(char f, int r); | ||
116 | Piece *newPiece(int, char, int); | ||
117 | void deletePiece(Piece *); | ||
118 | |||
119 | int pieceSize; | ||
120 | QPixmap bg; | ||
121 | QImage whiteSquare, blackSquare, activeWhiteSquare, activeBlackSquare; | ||
122 | |||
123 | bool humanSide; | ||
124 | bool activeSide; | ||
125 | bool playingGame; | ||
126 | }; | ||
127 | |||
128 | #endif | ||
diff --git a/noncore/games/chess/chess.pro b/noncore/games/chess/chess.pro new file mode 100644 index 0000000..f6650a0 --- a/dev/null +++ b/noncore/games/chess/chess.pro | |||
@@ -0,0 +1,14 @@ | |||
1 | SOURCES+= chess.cpp main.cpp | ||
2 | HEADERS+= chess.h | ||
3 | DESTDIR = ../bin | ||
4 | TARGET = chess | ||
5 | DEPENDPATH+= $(QPEDIR)/include | ||
6 | INTERFACES = mainwindow.ui | ||
7 | IMAGES= images/new.png images/repeat.png images/txt.png images/back.png | ||
8 | TEMPLATE=app | ||
9 | CONFIG+= qt warn_on release | ||
10 | INCLUDEPATH += $(QPEDIR)/include | ||
11 | LIBS+= -lqpe | ||
12 | DBFILE= chess.db | ||
13 | LANGUAGE= C++ | ||
14 | CPP_ALWAYS_CREATE_SOURCE= TRUE | ||
diff --git a/noncore/games/chess/main.cpp b/noncore/games/chess/main.cpp new file mode 100644 index 0000000..a56913f --- a/dev/null +++ b/noncore/games/chess/main.cpp | |||
@@ -0,0 +1,51 @@ | |||
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 | ** $Id$ | ||
20 | ** | ||
21 | **********************************************************************/ | ||
22 | #include <qpe/qpeapplication.h> | ||
23 | #include <qpe/qpetoolbar.h> | ||
24 | #include <qmainwindow.h> | ||
25 | #include <qcanvas.h> | ||
26 | #include "chess.h" | ||
27 | |||
28 | |||
29 | class CanvasMainWindow : public QMainWindow { | ||
30 | public: | ||
31 | CanvasMainWindow(QWidget* parent=0, const char* name=0, WFlags f=0) | ||
32 | : QMainWindow(parent,name,f), canvas(232, 258) { | ||
33 | view = new BoardView(&canvas, this, 0); | ||
34 | setToolBarsMovable( FALSE ); | ||
35 | QPEToolBar* toolbar = new QPEToolBar(this); | ||
36 | toolbar->setHorizontalStretchable( TRUE ); | ||
37 | } | ||
38 | |||
39 | private: | ||
40 | QCanvas canvas; | ||
41 | BoardView *view; | ||
42 | }; | ||
43 | |||
44 | |||
45 | int main( int argc, char **argv ) { | ||
46 | QPEApplication a(argc,argv); | ||
47 | CanvasMainWindow *mw = new CanvasMainWindow(); | ||
48 | a.showMainWidget( mw ); | ||
49 | return a.exec(); | ||
50 | } | ||
51 | |||
diff --git a/noncore/games/chess/mainwindow.ui b/noncore/games/chess/mainwindow.ui new file mode 100644 index 0000000..dc3ae0f --- a/dev/null +++ b/noncore/games/chess/mainwindow.ui | |||
@@ -0,0 +1,220 @@ | |||
1 | <!DOCTYPE UI><UI version="3.0" stdsetdef="1"> | ||
2 | <class>MainWindow</class> | ||
3 | <widget class="QMainWindow"> | ||
4 | <property name="name"> | ||
5 | <cstring>MainWindow</cstring> | ||
6 | </property> | ||
7 | <property name="geometry"> | ||
8 | <rect> | ||
9 | <x>0</x> | ||
10 | <y>0</y> | ||
11 | <width>256</width> | ||
12 | <height>338</height> | ||
13 | </rect> | ||
14 | </property> | ||
15 | <property name="caption"> | ||
16 | <string>Chess</string> | ||
17 | </property> | ||
18 | <widget class="QLabel"> | ||
19 | <property name="name"> | ||
20 | <cstring>TextLabel1</cstring> | ||
21 | </property> | ||
22 | <property name="geometry"> | ||
23 | <rect> | ||
24 | <x>10</x> | ||
25 | <y>236</y> | ||
26 | <width>221</width> | ||
27 | <height>31</height> | ||
28 | </rect> | ||
29 | </property> | ||
30 | <property name="text"> | ||
31 | <string>TextLabel1</string> | ||
32 | </property> | ||
33 | </widget> | ||
34 | <widget class="BoardView"> | ||
35 | <property name="name"> | ||
36 | <cstring>ChessBoard</cstring> | ||
37 | </property> | ||
38 | <property name="geometry"> | ||
39 | <rect> | ||
40 | <x>10</x> | ||
41 | <y>10</y> | ||
42 | <width>224</width> | ||
43 | <height>224</height> | ||
44 | </rect> | ||
45 | </property> | ||
46 | <property name="sizePolicy"> | ||
47 | <sizepolicy> | ||
48 | <hsizetype>1</hsizetype> | ||
49 | <vsizetype>1</vsizetype> | ||
50 | <horstretch>0</horstretch> | ||
51 | <verstretch>0</verstretch> | ||
52 | </sizepolicy> | ||
53 | </property> | ||
54 | <property name="minimumSize"> | ||
55 | <size> | ||
56 | <width>224</width> | ||
57 | <height>224</height> | ||
58 | </size> | ||
59 | </property> | ||
60 | </widget> | ||
61 | </widget> | ||
62 | <menubar> | ||
63 | <property name="name"> | ||
64 | <cstring>menubar</cstring> | ||
65 | </property> | ||
66 | <item text="Game" name="PopupMenu_2"> | ||
67 | <action name="newGame"/> | ||
68 | <action name="annotateGame"/> | ||
69 | </item> | ||
70 | <item text="Position" name="PopupMenu_3"> | ||
71 | <action name="swapSides"/> | ||
72 | <action name="undo"/> | ||
73 | </item> | ||
74 | </menubar> | ||
75 | <toolbars> | ||
76 | </toolbars> | ||
77 | <customwidgets> | ||
78 | <customwidget> | ||
79 | <class>BoardView</class> | ||
80 | <header location="global">/home/luke/depot/qpe/chess/chess.h</header> | ||
81 | <sizehint> | ||
82 | <width>-1</width> | ||
83 | <height>-1</height> | ||
84 | </sizehint> | ||
85 | <container>0</container> | ||
86 | <sizepolicy> | ||
87 | <hordata>5</hordata> | ||
88 | <verdata>5</verdata> | ||
89 | <horstretch>0</horstretch> | ||
90 | <verstretch>0</verstretch> | ||
91 | </sizepolicy> | ||
92 | <pixmap>image0</pixmap> | ||
93 | <signal>showMessage(const QString&)</signal> | ||
94 | <slot access="public" specifier="">newGame()</slot> | ||
95 | <slot access="public" specifier="">swapSides()</slot> | ||
96 | <slot access="public" specifier="">setTheme(QString)</slot> | ||
97 | <slot access="public" specifier="">undo()</slot> | ||
98 | <slot access="public" specifier="">annotateGame()</slot> | ||
99 | </customwidget> | ||
100 | </customwidgets> | ||
101 | <actions> | ||
102 | <actiongroup> | ||
103 | <property name="name"> | ||
104 | <cstring>gameActions</cstring> | ||
105 | </property> | ||
106 | <property name="text"> | ||
107 | <string>ActionGroup</string> | ||
108 | </property> | ||
109 | <property name="usesDropDown"> | ||
110 | <bool>false</bool> | ||
111 | </property> | ||
112 | <action> | ||
113 | <property name="name"> | ||
114 | <cstring>newGame</cstring> | ||
115 | </property> | ||
116 | <property name="iconSet"> | ||
117 | <iconset>new.png</iconset> | ||
118 | </property> | ||
119 | <property name="text"> | ||
120 | <string>New Game</string> | ||
121 | </property> | ||
122 | <property name="menuText"> | ||
123 | <string>New Game</string> | ||
124 | </property> | ||
125 | <property name="toolTip"> | ||
126 | <string>New Game</string> | ||
127 | </property> | ||
128 | </action> | ||
129 | <action> | ||
130 | <property name="name"> | ||
131 | <cstring>swapSides</cstring> | ||
132 | </property> | ||
133 | <property name="iconSet"> | ||
134 | <iconset>repeat.png</iconset> | ||
135 | </property> | ||
136 | <property name="text"> | ||
137 | <string>Swap sides</string> | ||
138 | </property> | ||
139 | <property name="toolTip"> | ||
140 | <string>Swap sides</string> | ||
141 | </property> | ||
142 | </action> | ||
143 | <action> | ||
144 | <property name="name"> | ||
145 | <cstring>annotateGame</cstring> | ||
146 | </property> | ||
147 | <property name="iconSet"> | ||
148 | <iconset>txt.png</iconset> | ||
149 | </property> | ||
150 | <property name="text"> | ||
151 | <string>Annotate game</string> | ||
152 | </property> | ||
153 | <property name="toolTip"> | ||
154 | <string>Annotate game</string> | ||
155 | </property> | ||
156 | </action> | ||
157 | <action> | ||
158 | <property name="name"> | ||
159 | <cstring>undo</cstring> | ||
160 | </property> | ||
161 | <property name="iconSet"> | ||
162 | <iconset>back.png</iconset> | ||
163 | </property> | ||
164 | <property name="text"> | ||
165 | <string>Undo move</string> | ||
166 | </property> | ||
167 | <property name="toolTip"> | ||
168 | <string>Undo move</string> | ||
169 | </property> | ||
170 | </action> | ||
171 | <action> | ||
172 | <property name="name"> | ||
173 | <cstring>saveGame</cstring> | ||
174 | </property> | ||
175 | <property name="text"> | ||
176 | <string>Action</string> | ||
177 | </property> | ||
178 | </action> | ||
179 | </actiongroup> | ||
180 | </actions> | ||
181 | <images> | ||
182 | <image name="image0"> | ||
183 | <data format="XPM.GZ" length="3456">789ce5d35d5313491406e07b7e458abea3b68e99cfccd4d65ee0079ac8a720a2d65ef474cf2424229004152dffbba7cf795941182a59bcd8aa6548524fbafb9d9ed3278fd63a47bb5b9db5472bb3b99d1fbb8e1bd96967cd5f9c9c5cbefffbaf6f2bab49dce1ff5eaf13affeb1b24aa6e33aa62b7f620fa7b01517ec423c850bb571b0c3f8bbe0a8db7591ae1fa9c3257e0aa7b0ac8f0ab6aeefc305bc073b783d38ee462ed6f5953a5ce20d38859f894b7629de820bb519c20ee3af829328764924be50275d7806a76a732c2ed9ba7e08176a33811d2cf548a3c4a59a97a9d3aedad4708af153b1655bf14bb880bfc00e3e0fcee2ac9be9f926629b65998eefc21e3e0acee3cce73affb33acfe037ff58e737629b97f026ece128b897e4be9788bfaa7b119cc319fc445cb12bf1215caa8d813d2cfd59243d5fe8faaeb82ab242d7d770097f803d2ce751a66554a6e28f70a636d24fa5633b191fc325fc1cf6f049b04d6d6435ef139cc16fc5ce5aabf3b7e11ade09ae525b573a7f5f5dc5f00bb1aff2ca8b07b0559b315c63fc20d86555ed32f15ced62f812ce61e95fe7d99a67610b3770ada65eb0e776f1bafe4c5cb36bf16bd8c245709dd7719d8b5371cddfc8b821d8aa290e6e78b4d1f9a5ba89e1c7e2a6b14d13bc37879b2bdf7f91b9fffadf65d8df90519123ffc08c9a1a1ad2a86d3ff767d0318d69421fe8843ed229a72c9d4167742ef79ed28ce69c7471f713b567d027beef675ea733bfd0257da5f5bb52da32e8313de18ca7f48c67add30657f539bde07df597c818d04bdae41a84593557654a5bb44d3bb44b7bbfeea53563c2ab467c1a61569f77123e5fd13e1d704a7533a535e3351dd21b3afa65dfeb9cf09677f86ec19a7679e64cea71f3daa788ebb45846cccf93dcaae1942bbb793be38e339ff2b34f28e5f7ab6f4e29e33a8c68f3f6dd5a320cdf29a7deb58c824aeeb31d434b64f48de1351b5736b6fd17d192e1a9321577d5cfe73e5c32c31ac79db16dfccf3e30f55219533e8b53634c73bd3bcc90e285332cf7f21177f51977d9f046775d2e9e6146fc8bbdabcab816c89872270f1e98e1f909c6b4c5cf7f71f5e2f7637e9fe9e742f5e8d3399feb3e0dcc9877744083f613693d174b23befbcc4ccc84b2f0fa1719d7d37c783d28a3b58affd18cef7faefc007d894af5</data> | ||
184 | </image> | ||
185 | </images> | ||
186 | <connections> | ||
187 | <connection> | ||
188 | <sender>newGame</sender> | ||
189 | <signal>activated()</signal> | ||
190 | <receiver>ChessBoard</receiver> | ||
191 | <slot>newGame()</slot> | ||
192 | </connection> | ||
193 | <connection> | ||
194 | <sender>swapSides</sender> | ||
195 | <signal>activated()</signal> | ||
196 | <receiver>ChessBoard</receiver> | ||
197 | <slot>swapSides()</slot> | ||
198 | </connection> | ||
199 | <connection> | ||
200 | <sender>annotateGame</sender> | ||
201 | <signal>activated()</signal> | ||
202 | <receiver>ChessBoard</receiver> | ||
203 | <slot>annotateGame()</slot> | ||
204 | </connection> | ||
205 | <connection> | ||
206 | <sender>undo</sender> | ||
207 | <signal>activated()</signal> | ||
208 | <receiver>ChessBoard</receiver> | ||
209 | <slot>undo()</slot> | ||
210 | </connection> | ||
211 | <connection> | ||
212 | <sender>ChessBoard</sender> | ||
213 | <signal>showMessage(const QString&)</signal> | ||
214 | <receiver>TextLabel1</receiver> | ||
215 | <slot>setText(const QString&)</slot> | ||
216 | </connection> | ||
217 | </connections> | ||
218 | <pixmapinproject/> | ||
219 | <layoutdefaults spacing="6" margin="11"/> | ||
220 | </UI> | ||
diff --git a/noncore/games/chess/pieces.png b/noncore/games/chess/pieces.png new file mode 100644 index 0000000..4baeb4a --- a/dev/null +++ b/noncore/games/chess/pieces.png | |||
Binary files differ | |||
diff --git a/noncore/games/chess/qpe-chess.control b/noncore/games/chess/qpe-chess.control new file mode 100644 index 0000000..2a7d2d2 --- a/dev/null +++ b/noncore/games/chess/qpe-chess.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/chess apps/Games/chess.desktop | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Luke Graham <luke@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: Crafty GUI | ||
9 | A GUI for the crafty chess engine | ||
diff --git a/noncore/games/chess/simple-l.png b/noncore/games/chess/simple-l.png new file mode 100644 index 0000000..908e2e1 --- a/dev/null +++ b/noncore/games/chess/simple-l.png | |||
Binary files differ | |||
diff --git a/noncore/games/fifteen/.cvsignore b/noncore/games/fifteen/.cvsignore new file mode 100644 index 0000000..6fe2396 --- a/dev/null +++ b/noncore/games/fifteen/.cvsignore | |||
@@ -0,0 +1,2 @@ | |||
1 | moc_* | ||
2 | Makefile | ||
diff --git a/noncore/games/fifteen/Makefile.in b/noncore/games/fifteen/Makefile.in new file mode 100644 index 0000000..23c7334 --- a/dev/null +++ b/noncore/games/fifteen/Makefile.in | |||
@@ -0,0 +1,118 @@ | |||
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 | |||
17 | DESTDIR = ../bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= fifteen | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =fifteen.h | ||
27 | SOURCES =fifteen.cpp \ | ||
28 | main.cpp | ||
29 | OBJECTS =fifteen.o \ | ||
30 | main.o | ||
31 | INTERFACES = | ||
32 | UICDECLS = | ||
33 | UICIMPLS = | ||
34 | SRCMOC =moc_fifteen.cpp | ||
35 | OBJMOC =moc_fifteen.o | ||
36 | |||
37 | |||
38 | ####### Implicit rules | ||
39 | |||
40 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
41 | |||
42 | .cpp.o: | ||
43 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
44 | |||
45 | .cxx.o: | ||
46 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
47 | |||
48 | .cc.o: | ||
49 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
50 | |||
51 | .C.o: | ||
52 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
53 | |||
54 | .c.o: | ||
55 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
56 | |||
57 | ####### Build rules | ||
58 | |||
59 | |||
60 | all: $(DESTDIR)$(TARGET) | ||
61 | |||
62 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
63 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
64 | |||
65 | moc: $(SRCMOC) | ||
66 | |||
67 | tmake: | ||
68 | tmake fifteen.pro | ||
69 | |||
70 | clean: | ||
71 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
72 | -rm -f *~ core | ||
73 | -rm -f allmoc.cpp | ||
74 | |||
75 | ####### Extension Modules | ||
76 | |||
77 | listpromodules: | ||
78 | @echo | ||
79 | |||
80 | listallmodules: | ||
81 | @echo | ||
82 | |||
83 | listaddonpromodules: | ||
84 | @echo | ||
85 | |||
86 | listaddonentmodules: | ||
87 | @echo | ||
88 | |||
89 | |||
90 | REQUIRES= | ||
91 | |||
92 | ####### Sub-libraries | ||
93 | |||
94 | |||
95 | ###### Combined headers | ||
96 | |||
97 | |||
98 | |||
99 | ####### Compile | ||
100 | |||
101 | fifteen.o: fifteen.cpp \ | ||
102 | fifteen.h \ | ||
103 | $(QPEDIR)/include/qpe/resource.h \ | ||
104 | $(QPEDIR)/include/qpe/config.h \ | ||
105 | $(QPEDIR)/include/qpe/qpetoolbar.h \ | ||
106 | $(QPEDIR)/include/qpe/qpemenubar.h | ||
107 | |||
108 | main.o: main.cpp \ | ||
109 | fifteen.h \ | ||
110 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
111 | |||
112 | moc_fifteen.o: moc_fifteen.cpp \ | ||
113 | fifteen.h | ||
114 | |||
115 | moc_fifteen.cpp: fifteen.h | ||
116 | $(MOC) fifteen.h -o moc_fifteen.cpp | ||
117 | |||
118 | |||
diff --git a/noncore/games/fifteen/fifteen.cpp b/noncore/games/fifteen/fifteen.cpp new file mode 100644 index 0000000..293cd65 --- a/dev/null +++ b/noncore/games/fifteen/fifteen.cpp | |||
@@ -0,0 +1,364 @@ | |||
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 "fifteen.h" | ||
22 | |||
23 | #include <qpe/resource.h> | ||
24 | #include <qpe/config.h> | ||
25 | |||
26 | #include <qvbox.h> | ||
27 | #include <qaction.h> | ||
28 | #include <qlayout.h> | ||
29 | #include <qpainter.h> | ||
30 | #include <qpopupmenu.h> | ||
31 | #include <qmessagebox.h> | ||
32 | #include <qpe/qpetoolbar.h> | ||
33 | #include <qpe/qpemenubar.h> | ||
34 | #include <qstringlist.h> | ||
35 | #include <qapplication.h> | ||
36 | |||
37 | #include <stdlib.h> | ||
38 | #include <time.h> | ||
39 | |||
40 | FifteenMainWindow::FifteenMainWindow(QWidget *parent, const char* name) | ||
41 | : QMainWindow( parent, name ) | ||
42 | { | ||
43 | // random seed | ||
44 | srand(time(0)); | ||
45 | |||
46 | setToolBarsMovable( FALSE ); | ||
47 | QVBox *vbox = new QVBox( this ); | ||
48 | PiecesTable *table = new PiecesTable( vbox ); | ||
49 | setCentralWidget(vbox); | ||
50 | |||
51 | QPEToolBar *toolbar = new QPEToolBar(this); | ||
52 | toolbar->setHorizontalStretchable( TRUE ); | ||
53 | addToolBar(toolbar); | ||
54 | |||
55 | QPEMenuBar *menubar = new QPEMenuBar( toolbar ); | ||
56 | menubar->setMargin(0); | ||
57 | |||
58 | QPopupMenu *game = new QPopupMenu( this ); | ||
59 | |||
60 | QWidget *spacer = new QWidget( toolbar ); | ||
61 | spacer->setBackgroundMode( PaletteButton ); | ||
62 | toolbar->setStretchableWidget( spacer ); | ||
63 | |||
64 | QAction *a = new QAction( tr( "Randomize" ), Resource::loadPixmap( "new" ), | ||
65 | QString::null, 0, this, 0 ); | ||
66 | connect( a, SIGNAL( activated() ), table, SLOT( slotRandomize() ) ); | ||
67 | a->addTo( game ); | ||
68 | a->addTo( toolbar ); | ||
69 | |||
70 | a = new QAction( tr( "Solve" ), Resource::loadPixmap( "repeat" ), | ||
71 | QString::null, 0, this, 0 ); | ||
72 | connect( a, SIGNAL( activated() ), table, SLOT( slotReset() ) ); | ||
73 | a->addTo( game ); | ||
74 | a->addTo( toolbar ); | ||
75 | |||
76 | menubar->insertItem( tr( "Game" ), game ); | ||
77 | } | ||
78 | |||
79 | PiecesTable::PiecesTable(QWidget* parent, const char* name ) | ||
80 | : QTableView(parent, name), _menu(0), _randomized(false) | ||
81 | { | ||
82 | // setup table view | ||
83 | setFrameStyle(StyledPanel | Sunken); | ||
84 | setBackgroundMode(NoBackground); | ||
85 | setMouseTracking(true); | ||
86 | |||
87 | setNumRows(4); | ||
88 | setNumCols(4); | ||
89 | |||
90 | // init arrays | ||
91 | initMap(); | ||
92 | readConfig(); | ||
93 | initColors(); | ||
94 | |||
95 | // set font | ||
96 | QFont f = font(); | ||
97 | f.setPixelSize(18); | ||
98 | f.setBold( TRUE ); | ||
99 | setFont(f); | ||
100 | } | ||
101 | |||
102 | PiecesTable::~PiecesTable() | ||
103 | { | ||
104 | writeConfig(); | ||
105 | } | ||
106 | |||
107 | void PiecesTable::writeConfig() | ||
108 | { | ||
109 | Config cfg("Fifteen"); | ||
110 | cfg.setGroup("Game"); | ||
111 | QStringList map; | ||
112 | for (unsigned int i = 0; i < 16; i++) | ||
113 | map.append( QString::number( _map[i] ) ); | ||
114 | cfg.writeEntry("Map", map, '-'); | ||
115 | cfg.writeEntry("Randomized", _randomized ); | ||
116 | } | ||
117 | |||
118 | void PiecesTable::readConfig() | ||
119 | { | ||
120 | Config cfg("Fifteen"); | ||
121 | cfg.setGroup("Game"); | ||
122 | QStringList map = cfg.readListEntry("Map", '-'); | ||
123 | _randomized = cfg.readBoolEntry( "Randomized", FALSE ); | ||
124 | unsigned int i = 0; | ||
125 | for ( QStringList::Iterator it = map.begin(); it != map.end(); ++it ) { | ||
126 | _map[i] = (*it).toInt(); | ||
127 | i++; | ||
128 | if ( i > 15 ) break; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | void PiecesTable::paintCell(QPainter *p, int row, int col) | ||
133 | { | ||
134 | int w = cellWidth(); | ||
135 | int h = cellHeight(); | ||
136 | int x2 = w - 1; | ||
137 | int y2 = h - 1; | ||
138 | |||
139 | int number = _map[col + row * numCols()] + 1; | ||
140 | |||
141 | // draw cell background | ||
142 | if(number == 16) | ||
143 | p->setBrush(colorGroup().background()); | ||
144 | else | ||
145 | p->setBrush(_colors[number-1]); | ||
146 | p->setPen(NoPen); | ||
147 | p->drawRect(0, 0, w, h); | ||
148 | |||
149 | // draw borders | ||
150 | if (height() > 40) { | ||
151 | p->setPen(colorGroup().text()); | ||
152 | if(col < numCols()-1) | ||
153 | p->drawLine(x2, 0, x2, y2); // right border line | ||
154 | |||
155 | if(row < numRows()-1) | ||
156 | p->drawLine(0, y2, x2, y2); // bottom boder line | ||
157 | } | ||
158 | |||
159 | // draw number | ||
160 | if (number == 16) return; | ||
161 | p->setPen(black); | ||
162 | p->drawText(0, 0, x2, y2, AlignHCenter | AlignVCenter, QString::number(number)); | ||
163 | } | ||
164 | |||
165 | void PiecesTable::resizeEvent(QResizeEvent *e) | ||
166 | { | ||
167 | QTableView::resizeEvent(e); | ||
168 | |||
169 | setCellWidth(contentsRect().width()/ numRows()); | ||
170 | setCellHeight(contentsRect().height() / numCols()); | ||
171 | } | ||
172 | |||
173 | void PiecesTable::initColors() | ||
174 | { | ||
175 | _colors.resize(numRows() * numCols()); | ||
176 | for (int r = 0; r < numRows(); r++) | ||
177 | for (int c = 0; c < numCols(); c++) | ||
178 | _colors[c + r *numCols()] = QColor(255 - 70 * c,255 - 70 * r, 150); | ||
179 | } | ||
180 | |||
181 | void PiecesTable::initMap() | ||
182 | { | ||
183 | _map.resize(16); | ||
184 | for (unsigned int i = 0; i < 16; i++) | ||
185 | _map[i] = i; | ||
186 | |||
187 | _randomized = false; | ||
188 | } | ||
189 | |||
190 | void PiecesTable::randomizeMap() | ||
191 | { | ||
192 | initMap(); | ||
193 | _randomized = true; | ||
194 | // find the free position | ||
195 | int pos = _map.find(15); | ||
196 | |||
197 | int move = 0; | ||
198 | while ( move < 333 ) { | ||
199 | |||
200 | int frow = pos / numCols(); | ||
201 | int fcol = pos - frow * numCols(); | ||
202 | |||
203 | // find click position | ||
204 | int row = rand()%4; | ||
205 | int col = rand()%4; | ||
206 | |||
207 | // sanity check | ||
208 | if ( row < 0 || row >= numRows() ) continue; | ||
209 | if ( col < 0 || col >= numCols() ) continue; | ||
210 | if ( row != frow && col != fcol ) continue; | ||
211 | |||
212 | move++; | ||
213 | |||
214 | // rows match -> shift pieces | ||
215 | if(row == frow) { | ||
216 | |||
217 | if (col < fcol) { | ||
218 | for(int c = fcol; c > col; c--) { | ||
219 | _map[c + row * numCols()] = _map[ c-1 + row *numCols()]; | ||
220 | } | ||
221 | } | ||
222 | else if (col > fcol) { | ||
223 | for(int c = fcol; c < col; c++) { | ||
224 | _map[c + row * numCols()] = _map[ c+1 + row *numCols()]; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | // cols match -> shift pieces | ||
229 | else if (col == fcol) { | ||
230 | |||
231 | if (row < frow) { | ||
232 | for(int r = frow; r > row; r--) { | ||
233 | _map[col + r * numCols()] = _map[ col + (r-1) *numCols()]; | ||
234 | } | ||
235 | } | ||
236 | else if (row > frow) { | ||
237 | for(int r = frow; r < row; r++) { | ||
238 | _map[col + r * numCols()] = _map[ col + (r+1) *numCols()]; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | // move free cell to click position | ||
243 | _map[pos=(col + row * numCols())] = 15; | ||
244 | repaint(); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | void PiecesTable::checkwin() | ||
249 | { | ||
250 | if(!_randomized) return; | ||
251 | |||
252 | int i; | ||
253 | for (i = 0; i < 16; i++) | ||
254 | if(i != _map[i]) | ||
255 | break; | ||
256 | |||
257 | if (i == 16) { | ||
258 | QMessageBox::information(this, tr("Fifteen Pieces"), | ||
259 | tr("Congratulations!\nYou win the game!")); | ||
260 | _randomized = FALSE; | ||
261 | } | ||
262 | |||
263 | } | ||
264 | |||
265 | void PiecesTable::slotRandomize() | ||
266 | { | ||
267 | randomizeMap(); | ||
268 | } | ||
269 | |||
270 | void PiecesTable::slotReset() | ||
271 | { | ||
272 | initMap(); | ||
273 | repaint(); | ||
274 | } | ||
275 | |||
276 | void PiecesTable::mousePressEvent(QMouseEvent* e) | ||
277 | { | ||
278 | QTableView::mousePressEvent(e); | ||
279 | |||
280 | if (e->button() == RightButton) { | ||
281 | |||
282 | // setup RMB pupup menu | ||
283 | if(!_menu) { | ||
284 | _menu = new QPopupMenu(this); | ||
285 | _menu->insertItem(tr("R&andomize Pieces"), mRandomize); | ||
286 | _menu->insertItem(tr("&Reset Pieces"), mReset); | ||
287 | _menu->adjustSize(); | ||
288 | } | ||
289 | |||
290 | // execute RMB popup and check result | ||
291 | switch(_menu->exec(mapToGlobal(e->pos()))) { | ||
292 | case mRandomize: | ||
293 | randomizeMap(); | ||
294 | break; | ||
295 | case mReset: | ||
296 | initMap(); | ||
297 | repaint(); | ||
298 | break; | ||
299 | default: | ||
300 | break; | ||
301 | } | ||
302 | } | ||
303 | else { | ||
304 | // GAME LOGIC | ||
305 | |||
306 | // find the free position | ||
307 | int pos = _map.find(15); | ||
308 | if(pos < 0) return; | ||
309 | |||
310 | int frow = pos / numCols(); | ||
311 | int fcol = pos - frow * numCols(); | ||
312 | |||
313 | // find click position | ||
314 | int row = findRow(e->y()); | ||
315 | int col = findCol(e->x()); | ||
316 | |||
317 | // sanity check | ||
318 | if (row < 0 || row >= numRows()) return; | ||
319 | if (col < 0 || col >= numCols()) return; | ||
320 | if ( row != frow && col != fcol ) return; | ||
321 | |||
322 | // valid move? | ||
323 | if(row != frow && col != fcol) return; | ||
324 | |||
325 | // rows match -> shift pieces | ||
326 | if(row == frow) { | ||
327 | |||
328 | if (col < fcol) { | ||
329 | for(int c = fcol; c > col; c--) { | ||
330 | _map[c + row * numCols()] = _map[ c-1 + row *numCols()]; | ||
331 | updateCell(row, c, false); | ||
332 | } | ||
333 | } | ||
334 | else if (col > fcol) { | ||
335 | for(int c = fcol; c < col; c++) { | ||
336 | _map[c + row * numCols()] = _map[ c+1 + row *numCols()]; | ||
337 | updateCell(row, c, false); | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | // cols match -> shift pieces | ||
342 | else if (col == fcol) { | ||
343 | |||
344 | if (row < frow) { | ||
345 | for(int r = frow; r > row; r--) { | ||
346 | _map[col + r * numCols()] = _map[ col + (r-1) *numCols()]; | ||
347 | updateCell(r, col, false); | ||
348 | } | ||
349 | } | ||
350 | else if (row > frow) { | ||
351 | for(int r = frow; r < row; r++) { | ||
352 | _map[col + r * numCols()] = _map[ col + (r+1) *numCols()]; | ||
353 | updateCell(r, col, false); | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | // move free cell to click position | ||
358 | _map[col + row * numCols()] = 15; | ||
359 | updateCell(row, col, false); | ||
360 | |||
361 | // check if the player wins with this move | ||
362 | checkwin(); | ||
363 | } | ||
364 | } | ||
diff --git a/noncore/games/fifteen/fifteen.h b/noncore/games/fifteen/fifteen.h new file mode 100644 index 0000000..703a8a7 --- a/dev/null +++ b/noncore/games/fifteen/fifteen.h | |||
@@ -0,0 +1,83 @@ | |||
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 | #ifndef __fifteenapplet_h__ | ||
22 | #define __fifteenapplet_h__ | ||
23 | |||
24 | #include <qmainwindow.h> | ||
25 | #include <qtableview.h> | ||
26 | #include <qarray.h> | ||
27 | |||
28 | class QPopupMenu; | ||
29 | |||
30 | class PiecesTable : public QTableView | ||
31 | { | ||
32 | Q_OBJECT | ||
33 | |||
34 | public: | ||
35 | PiecesTable(QWidget* parent = 0, const char* name = 0); | ||
36 | ~PiecesTable(); | ||
37 | |||
38 | protected slots: | ||
39 | void slotRandomize(); | ||
40 | void slotReset(); | ||
41 | |||
42 | protected: | ||
43 | void resizeEvent(QResizeEvent*); | ||
44 | void mousePressEvent(QMouseEvent*); | ||
45 | |||
46 | void paintCell(QPainter *, int row, int col); | ||
47 | |||
48 | void initMap(); | ||
49 | void initColors(); | ||
50 | void randomizeMap(); | ||
51 | void checkwin(); | ||
52 | void readConfig(); | ||
53 | void writeConfig(); | ||
54 | |||
55 | private: | ||
56 | QArray<int> _map; | ||
57 | QArray<QColor> _colors; | ||
58 | QPopupMenu *_menu; | ||
59 | bool _randomized; | ||
60 | |||
61 | enum MenuOp { mRandomize = 1, mReset = 2 }; | ||
62 | }; | ||
63 | |||
64 | class FifteenWidget : public QWidget | ||
65 | { | ||
66 | Q_OBJECT | ||
67 | |||
68 | public: | ||
69 | FifteenWidget(QWidget *parent = 0, const char *name = 0); | ||
70 | |||
71 | private: | ||
72 | PiecesTable *_table; | ||
73 | }; | ||
74 | |||
75 | class FifteenMainWindow : public QMainWindow | ||
76 | { | ||
77 | Q_OBJECT | ||
78 | |||
79 | public: | ||
80 | FifteenMainWindow(QWidget *parent=0, const char* name=0); | ||
81 | }; | ||
82 | |||
83 | #endif | ||
diff --git a/noncore/games/fifteen/fifteen.pro b/noncore/games/fifteen/fifteen.pro new file mode 100644 index 0000000..167f4f8 --- a/dev/null +++ b/noncore/games/fifteen/fifteen.pro | |||
@@ -0,0 +1,10 @@ | |||
1 | DESTDIR = ../bin | ||
2 | TEMPLATE= app | ||
3 | CONFIG = qt warn_on release | ||
4 | HEADERS = fifteen.h | ||
5 | SOURCES = fifteen.cpp \ | ||
6 | main.cpp | ||
7 | INCLUDEPATH += $(QPEDIR)/include | ||
8 | DEPENDPATH+= $(QPEDIR)/include | ||
9 | LIBS += -lqpe | ||
10 | TARGET = fifteen | ||
diff --git a/noncore/games/fifteen/main.cpp b/noncore/games/fifteen/main.cpp new file mode 100644 index 0000000..4838a36 --- a/dev/null +++ b/noncore/games/fifteen/main.cpp | |||
@@ -0,0 +1,33 @@ | |||
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 "fifteen.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | int main( int argc, char ** argv) | ||
26 | { | ||
27 | QPEApplication app( argc, argv ); | ||
28 | |||
29 | FifteenMainWindow mw; | ||
30 | mw.setCaption( FifteenMainWindow::tr("Fifteen Pieces") ); | ||
31 | app.showMainWidget( &mw ); | ||
32 | return app.exec(); | ||
33 | } | ||
diff --git a/noncore/games/fifteen/qpe-fifteen.control b/noncore/games/fifteen/qpe-fifteen.control new file mode 100644 index 0000000..d77eb32 --- a/dev/null +++ b/noncore/games/fifteen/qpe-fifteen.control | |||
@@ -0,0 +1,11 @@ | |||
1 | Files: bin/fifteen apps/Games/fifteen.desktop pics/Fifteen.png | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Arch: iPAQ | ||
7 | Version: $QPE_VERSION-4 | ||
8 | Depends: qpe-base ($QPE_VERSION) | ||
9 | Description: Fifteen pieces game | ||
10 | A game for the Qtopia environment | ||
11 | . | ||
diff --git a/noncore/games/go/.cvsignore b/noncore/games/go/.cvsignore new file mode 100644 index 0000000..6fe2396 --- a/dev/null +++ b/noncore/games/go/.cvsignore | |||
@@ -0,0 +1,2 @@ | |||
1 | moc_* | ||
2 | Makefile | ||
diff --git a/noncore/games/go/Makefile.in b/noncore/games/go/Makefile.in new file mode 100644 index 0000000..27304f1 --- a/dev/null +++ b/noncore/games/go/Makefile.in | |||
@@ -0,0 +1,158 @@ | |||
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 | |||
17 | DESTDIR = ../bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= go | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =amigo.h \ | ||
27 | go.h \ | ||
28 | goplayutils.h \ | ||
29 | gowidget.h | ||
30 | SOURCES =amigo.c \ | ||
31 | goplayer.c \ | ||
32 | goplayutils.c \ | ||
33 | killable.c \ | ||
34 | gowidget.cpp \ | ||
35 | main.cpp | ||
36 | OBJECTS =amigo.o \ | ||
37 | goplayer.o \ | ||
38 | goplayutils.o \ | ||
39 | killable.o \ | ||
40 | gowidget.o \ | ||
41 | main.o | ||
42 | INTERFACES = | ||
43 | UICDECLS = | ||
44 | UICIMPLS = | ||
45 | SRCMOC =moc_gowidget.cpp | ||
46 | OBJMOC =moc_gowidget.o | ||
47 | |||
48 | |||
49 | ####### Implicit rules | ||
50 | |||
51 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
52 | |||
53 | .cpp.o: | ||
54 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
55 | |||
56 | .cxx.o: | ||
57 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
58 | |||
59 | .cc.o: | ||
60 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
61 | |||
62 | .C.o: | ||
63 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
64 | |||
65 | .c.o: | ||
66 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
67 | |||
68 | ####### Build rules | ||
69 | |||
70 | |||
71 | all: $(DESTDIR)$(TARGET) | ||
72 | |||
73 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
74 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
75 | |||
76 | moc: $(SRCMOC) | ||
77 | |||
78 | tmake: | ||
79 | tmake go.pro | ||
80 | |||
81 | clean: | ||
82 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
83 | -rm -f *~ core | ||
84 | -rm -f allmoc.cpp | ||
85 | |||
86 | ####### Extension Modules | ||
87 | |||
88 | listpromodules: | ||
89 | @echo | ||
90 | |||
91 | listallmodules: | ||
92 | @echo | ||
93 | |||
94 | listaddonpromodules: | ||
95 | @echo | ||
96 | |||
97 | listaddonentmodules: | ||
98 | @echo | ||
99 | |||
100 | |||
101 | REQUIRES= | ||
102 | |||
103 | ####### Sub-libraries | ||
104 | |||
105 | |||
106 | ###### Combined headers | ||
107 | |||
108 | |||
109 | |||
110 | ####### Compile | ||
111 | |||
112 | amigo.o: amigo.c \ | ||
113 | go.h \ | ||
114 | goplayutils.h \ | ||
115 | amigo.h | ||
116 | |||
117 | goplayer.o: goplayer.c \ | ||
118 | go.h \ | ||
119 | goplayutils.h \ | ||
120 | amigo.h | ||
121 | |||
122 | goplayutils.o: goplayutils.c \ | ||
123 | goplayutils.h \ | ||
124 | amigo.h \ | ||
125 | go.h | ||
126 | |||
127 | killable.o: killable.c \ | ||
128 | go.h \ | ||
129 | goplayutils.h \ | ||
130 | amigo.h | ||
131 | |||
132 | gowidget.o: gowidget.cpp \ | ||
133 | gowidget.h \ | ||
134 | amigo.h \ | ||
135 | go.h \ | ||
136 | goplayutils.h \ | ||
137 | $(QPEDIR)/include/qpe/config.h \ | ||
138 | $(QPEDIR)/include/qpe/resource.h \ | ||
139 | $(QPEDIR)/include/qpe/qpetoolbar.h \ | ||
140 | $(QPEDIR)/include/qpe/qpemenubar.h | ||
141 | |||
142 | main.o: main.cpp \ | ||
143 | gowidget.h \ | ||
144 | amigo.h \ | ||
145 | go.h \ | ||
146 | goplayutils.h \ | ||
147 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
148 | |||
149 | moc_gowidget.o: moc_gowidget.cpp \ | ||
150 | gowidget.h \ | ||
151 | amigo.h \ | ||
152 | go.h \ | ||
153 | goplayutils.h | ||
154 | |||
155 | moc_gowidget.cpp: gowidget.h | ||
156 | $(MOC) gowidget.h -o moc_gowidget.cpp | ||
157 | |||
158 | |||
diff --git a/noncore/games/go/README b/noncore/games/go/README new file mode 100644 index 0000000..c6fa1f5 --- a/dev/null +++ b/noncore/games/go/README | |||
@@ -0,0 +1,3 @@ | |||
1 | This Go player For Qtopia is based on Xamigo, which in turn was | ||
2 | based on Amigo. The original README files are included as README.XAMIGO | ||
3 | and README.AMIGO. | ||
diff --git a/noncore/games/go/README.AMIGO b/noncore/games/go/README.AMIGO new file mode 100644 index 0000000..03978e7 --- a/dev/null +++ b/noncore/games/go/README.AMIGO | |||
@@ -0,0 +1,42 @@ | |||
1 | This is version 1.0 of AmiGo --- a Go board and player for the Amiga. | ||
2 | The Amiga interface and board manager were written by Todd R. Johnson. | ||
3 | The player is a C port of a Pascal player written by Stoney Ballard. | ||
4 | The interface allows you to play human vs. human, human vs. Amiga, or | ||
5 | Amiga vs. Amiga. | ||
6 | |||
7 | The board manager and player could both use some work. Currently, | ||
8 | you cannot save/load games, take back a move, or automatically score a | ||
9 | game. It is also limited to a 19 by 19 board. I'm releasing AmiGo | ||
10 | now because 1) I'm in the final phases of my dissertation and probably | ||
11 | won't have much time to do any further work on AmiGo, and 2) a lot of | ||
12 | people have been asking for an Amiga Go player. I am also releasing | ||
13 | all of the source code so that others can add to and modify AmiGo. | ||
14 | Note that all of my code in this release is public domain, while the | ||
15 | ported go player retains the original copyright. | ||
16 | |||
17 | If you distribute AmiGo, I urge you to include the source | ||
18 | code. If anyone makes changes, I would appreciate a copy. In fact, I | ||
19 | am willing to act as a clearinghouse for AmiGo changes. | ||
20 | |||
21 | Todd R. Johnson | ||
22 | tj@cis.ohio-state.edu | ||
23 | 8/8/89 | ||
24 | |||
25 | Here is the message attached to the original USENET posting of Stoney | ||
26 | Ballard's Pascal code. Note that the board manager mentioned here is | ||
27 | not included in this distribution. | ||
28 | |||
29 | This go board manager and rudimentary go player was written by | ||
30 | Stoney Ballard at Perq Systems in 1983-1984. It is written in | ||
31 | Perq Pascal and utilizes some Perq libraries for I/O. The code | ||
32 | is offered here if someone is interested to convert it to Unix. | ||
33 | |||
34 | The wonderful part about it is that a game is recorded as a tree | ||
35 | and can be played forward or backward, branching at any point | ||
36 | where there were alternate moves. | ||
37 | |||
38 | For some time, this program was also used to generate the go | ||
39 | boards displayed in the American Go Journal. For this it used | ||
40 | some large font digits which are now lost. | ||
41 | |||
42 | Fred Hansen | ||
diff --git a/noncore/games/go/README.XAMIGO b/noncore/games/go/README.XAMIGO new file mode 100644 index 0000000..219b25f --- a/dev/null +++ b/noncore/games/go/README.XAMIGO | |||
@@ -0,0 +1,26 @@ | |||
1 | |||
2 | Xamigo 1.1 | ||
3 | |||
4 | This is an alpha release of xamigo --- a port (read: quick hack) of the | ||
5 | Amiga Go program AmiGo. I don't have time to get it real nice now, | ||
6 | but will spend some more time on it when my thesis is out of the way. | ||
7 | Sadly this is the second time I've said that :-) | ||
8 | |||
9 | The `readme' from the original distribution is included as README.AMIGO | ||
10 | |||
11 | An Imakefile is included, so you should be able to type | ||
12 | xmkmf | ||
13 | make | ||
14 | to build xamigo. Let me know if you have problems with the Imakefile, | ||
15 | preferably with fixes :-) | ||
16 | |||
17 | You *have* to install the app-defaults file (Xamigo.ad) before you use | ||
18 | xamigo. This should either go in /usr/lib/X11/app-defaults, | ||
19 | or in your own app-defaults directory, as file Xamigo (ie lose the '.ad') | ||
20 | If you do the latter, you have to: | ||
21 | setenv XAPPLRESDIR <full path of your app-defaults directory> | ||
22 | |||
23 | Feel free to mail me any comments and suggestions for improvements. | ||
24 | |||
25 | Neil | ||
26 | neilb@scs.leeds.ac.uk | ||
diff --git a/noncore/games/go/amigo.c b/noncore/games/go/amigo.c new file mode 100644 index 0000000..cd61013 --- a/dev/null +++ b/noncore/games/go/amigo.c | |||
@@ -0,0 +1,656 @@ | |||
1 | /* Go started 4/17/88 by Todd R. Johnson */ | ||
2 | /* 8/8/89 cleaned up for first release */ | ||
3 | /* Public Domain */ | ||
4 | |||
5 | #include "go.h" | ||
6 | #include "goplayutils.h" | ||
7 | #include "amigo.h" | ||
8 | |||
9 | |||
10 | extern char*playReason; | ||
11 | extern shortplayLevel, showTrees; | ||
12 | |||
13 | struct bRec goboard[19][19]; /*-- The main go board --*/ | ||
14 | |||
15 | struct Group GroupList[MAXGROUPS]; /*-- The list of Groups --*/ | ||
16 | short DeletedGroups[4]; /*-- Codes of deleted groups--*/ | ||
17 | |||
18 | short GroupCount = 0; /*-- The total number of groups--*/ | ||
19 | short DeletedGroupCount; /*-- The total number of groups--*/ | ||
20 | /*-- deleted on a move --*/ | ||
21 | short ko, koX, koY; | ||
22 | short blackTerritory,whiteTerritory; | ||
23 | short blackPrisoners, whitePrisoners; | ||
24 | short showMoveReason= FALSE, | ||
25 | groupInfo= FALSE, | ||
26 | whitePassed= FALSE, | ||
27 | blackPassed= FALSE; | ||
28 | |||
29 | |||
30 | /* Arrays for use when checking around a point */ | ||
31 | short xVec[4] = {0, 1, 0, -1}; | ||
32 | short yVec[4] = {-1, 0, 1, 0}; | ||
33 | |||
34 | short | ||
35 | member(group, grouplist, cnt) | ||
36 | short group; | ||
37 | short grouplist[4]; | ||
38 | short cnt; | ||
39 | { | ||
40 | unsigned shorti; | ||
41 | |||
42 | |||
43 | for (i = 0; i < cnt; i++) | ||
44 | if (grouplist[i] == group) | ||
45 | return TRUE; | ||
46 | return FALSE; | ||
47 | } | ||
48 | |||
49 | /* Does a stone at x, y connect to any groups of color? */ | ||
50 | short | ||
51 | Connect( color, x, y, fGroups, fCnt, eGroups, eCnt) | ||
52 | enum bValcolor; | ||
53 | short x, y; | ||
54 | short fGroups[4], eGroups[4]; | ||
55 | short *fCnt, *eCnt; | ||
56 | { | ||
57 | unsigned shortpoint = 0; | ||
58 | short tx, ty, total = 0; | ||
59 | enum bValopcolor = WHITE; | ||
60 | |||
61 | |||
62 | *fCnt = 0; | ||
63 | *eCnt = 0; | ||
64 | if (color == WHITE) | ||
65 | opcolor = BLACK; | ||
66 | for (point = 0; point <= 3; point++ ) | ||
67 | { | ||
68 | tx = x + xVec[point]; | ||
69 | ty = y + yVec[point]; | ||
70 | if (!LegalPoint(tx,ty)) | ||
71 | continue; | ||
72 | if (goboard[tx][ty].Val == color) | ||
73 | { | ||
74 | total++; | ||
75 | if (!member(goboard[tx][ty].GroupNum, fGroups, *fCnt)) | ||
76 | fGroups[(*fCnt)++] = goboard[tx][ty].GroupNum; | ||
77 | } | ||
78 | else if (goboard[tx][ty].Val == opcolor) | ||
79 | { | ||
80 | total++; | ||
81 | if (!member(goboard[tx][ty].GroupNum, eGroups, *eCnt)) | ||
82 | eGroups[(*eCnt)++] = goboard[tx][ty].GroupNum; | ||
83 | } | ||
84 | } | ||
85 | return total; | ||
86 | } | ||
87 | |||
88 | /* Returns the maximum number of liberties for a given intersection */ | ||
89 | short | ||
90 | Maxlibs(x, y) | ||
91 | shortx, y; | ||
92 | { | ||
93 | shortcnt = 4; | ||
94 | |||
95 | |||
96 | if (x == 0 || x == 18) | ||
97 | cnt--; | ||
98 | if (y == 0 || y == 18) | ||
99 | cnt--; | ||
100 | return cnt; | ||
101 | } | ||
102 | |||
103 | DeleteGroupFromStone(x,y) | ||
104 | shortx,y; | ||
105 | { | ||
106 | if (goboard[x][y].Val != EMPTY) | ||
107 | GroupCapture(goboard[x][y].GroupNum); | ||
108 | } | ||
109 | |||
110 | /* Determine whether x, y is suicide for color */ | ||
111 | short | ||
112 | Suicide(color, x, y) | ||
113 | enum bValcolor; | ||
114 | short x, y; | ||
115 | { | ||
116 | enum bValopcolor = BLACK; | ||
117 | short friendlycnt, friendlygroups[4], | ||
118 | enemycnt, enemygroups[4], | ||
119 | total; | ||
120 | short maxlibs, i, libcnt = 0; | ||
121 | |||
122 | |||
123 | if (color == BLACK) | ||
124 | opcolor = WHITE; | ||
125 | maxlibs = Maxlibs( x, y); | ||
126 | total = Connect(color, x, y, friendlygroups, &friendlycnt, | ||
127 | enemygroups, &enemycnt); | ||
128 | |||
129 | if (total < maxlibs) | ||
130 | return FALSE; | ||
131 | |||
132 | /* Check for a capture */ | ||
133 | for (i = 0; i < enemycnt; i++) | ||
134 | if (GroupList[enemygroups[i]].liberties == 1) | ||
135 | return FALSE; | ||
136 | for (i = 0; i < friendlycnt; i++) | ||
137 | libcnt += (GroupList[friendlygroups[i]].liberties - 1); | ||
138 | if (libcnt != 0) | ||
139 | return FALSE; | ||
140 | return TRUE; | ||
141 | } | ||
142 | |||
143 | /* Returns the number of liberties for x, y */ | ||
144 | short | ||
145 | StoneLibs(x, y) | ||
146 | short x, y; | ||
147 | { | ||
148 | short cnt = 0, tx, ty; | ||
149 | unsigned shortpoint; | ||
150 | |||
151 | |||
152 | for (point = 0; point <= 3; point++) | ||
153 | { | ||
154 | tx = x + xVec[point]; | ||
155 | ty = y + yVec[point]; | ||
156 | if (LegalPoint(tx,ty) && goboard[tx][ty].Val == EMPTY) | ||
157 | cnt++; | ||
158 | } | ||
159 | return cnt; | ||
160 | } | ||
161 | |||
162 | void | ||
163 | EraseMarks() | ||
164 | { | ||
165 | register short i; | ||
166 | register struct bRec *gpt= &goboard[0][0]; | ||
167 | |||
168 | |||
169 | for (i=0; i<361; gpt++,i++) | ||
170 | gpt->marked = FALSE; | ||
171 | } | ||
172 | |||
173 | /* Place a stone of color at x, y */ | ||
174 | short | ||
175 | GoPlaceStone(color, x, y) | ||
176 | enum bValcolor; | ||
177 | short x, y; | ||
178 | { | ||
179 | short fgroups[4], egroups[4];/* group codes surrounding stone */ | ||
180 | shortfcnt, ecnt, i; | ||
181 | shortlowest = GroupCount + 1; | ||
182 | |||
183 | |||
184 | DeletedGroupCount = 0; | ||
185 | if (goboard[x][y].Val != EMPTY || Suicide(color,x,y)) | ||
186 | return FALSE; | ||
187 | |||
188 | if (ko && koX == x && koY == y) | ||
189 | return FALSE; | ||
190 | |||
191 | ko = FALSE; | ||
192 | placestone(color, x, y); | ||
193 | goboard[x][y].Val = color; | ||
194 | /* Does the new stone connect to any friendly stone(s)? */ | ||
195 | Connect(color, x, y, fgroups, &fcnt, egroups, &ecnt); | ||
196 | if (fcnt) | ||
197 | { | ||
198 | /* Find the connecting friendly group with the lowest code */ | ||
199 | for (i = 0; i < fcnt; i++) | ||
200 | if (fgroups[i] <= lowest) | ||
201 | lowest = fgroups[i]; | ||
202 | /*-- Renumber resulting group --*/ | ||
203 | /*-- Raise the stone count of the lowest by one to account --*/ | ||
204 | /*-- for new stone --*/ | ||
205 | goboard[x][y].GroupNum = lowest; | ||
206 | GroupList[lowest].count++; | ||
207 | for (i = 0; i < fcnt; i++) | ||
208 | if (fgroups[i] != lowest) | ||
209 | MergeGroups(lowest, fgroups[i]); | ||
210 | /* Fix the liberties of the resulting group */ | ||
211 | CountLiberties(lowest); | ||
212 | } | ||
213 | else | ||
214 | { | ||
215 | /* Isolated stone. Create new group. */ | ||
216 | GroupCount++; | ||
217 | lowest = GroupCount; | ||
218 | GroupList[lowest].color = color; | ||
219 | GroupList[lowest].count = 1; | ||
220 | GroupList[lowest].internal = 0; | ||
221 | GroupList[lowest].external = StoneLibs( x, y); | ||
222 | GroupList[lowest].liberties = GroupList[lowest].external; | ||
223 | GroupList[lowest].eyes = 0; | ||
224 | GroupList[lowest].alive = 0; | ||
225 | GroupList[lowest].territory = 0; | ||
226 | goboard[x][y].GroupNum = lowest; | ||
227 | } | ||
228 | /* Now fix the liberties of enemy groups adjacent to played stone */ | ||
229 | FixLibs(color, x, y, PLACED); /* Fix the liberties of opcolor */ | ||
230 | ReEvalGroups(color, x, y, lowest); | ||
231 | RelabelGroups(); | ||
232 | return TRUE; | ||
233 | } | ||
234 | |||
235 | /* Remove a stone from the board */ | ||
236 | void | ||
237 | GoRemoveStone(x, y) | ||
238 | shortx, y; | ||
239 | { | ||
240 | goboard[x][y].Val = EMPTY; | ||
241 | goboard[x][y].GroupNum = 0; | ||
242 | removestone( x, y); | ||
243 | } | ||
244 | |||
245 | /* Merges two groups -- Renumbers stones and deletes second group from | ||
246 | list. Fixes stone count of groups. This does not fix anything else. | ||
247 | FixLibs must be called to fix liberties, etc. */ | ||
248 | void | ||
249 | MergeGroups(g1, g2) | ||
250 | shortg1, g2; | ||
251 | { | ||
252 | shortx, y; | ||
253 | |||
254 | |||
255 | ForeachPoint(y,x) | ||
256 | if (goboard[x][y].GroupNum == g2) | ||
257 | goboard[x][y].GroupNum = g1; | ||
258 | GroupList[g1].count += GroupList[g2].count; | ||
259 | DeleteGroup( g2 ); /* Removes group from GroupList */ | ||
260 | } | ||
261 | |||
262 | /* Stores a group code to be deleted */ | ||
263 | void | ||
264 | DeleteGroup(code) | ||
265 | shortcode; | ||
266 | { | ||
267 | DeletedGroups[DeletedGroupCount++] = code; | ||
268 | } | ||
269 | |||
270 | /* Re-evaluate the groups given the last move. This assumes that the | ||
271 | last move has been merged into adjoining groups and all liberty counts | ||
272 | are correct. Handles capture. Checks for Ko. Keeps track of captured | ||
273 | stones. code is the group number of the stone just played. */ | ||
274 | void | ||
275 | ReEvalGroups(color, x, y, code) | ||
276 | enum bValcolor; | ||
277 | short x, y, code; | ||
278 | { | ||
279 | short fgroups[4], egroups[4], | ||
280 | fcnt, ecnt, i, killcnt = 0, count = 0; | ||
281 | enum bValopcolor = BLACK; | ||
282 | |||
283 | if (color == BLACK) | ||
284 | opcolor = WHITE; | ||
285 | /* Check for capture */ | ||
286 | Connect( color, x, y, fgroups, &fcnt, egroups, &ecnt); | ||
287 | if (ecnt) | ||
288 | { | ||
289 | /* See if any of the groups have no liberties */ | ||
290 | for (i = 0; i < ecnt; i++) | ||
291 | if (GroupList[egroups[i]].liberties == 0) | ||
292 | { | ||
293 | killcnt++; | ||
294 | count = GroupList[egroups[i]].count; | ||
295 | GroupCapture( egroups[i]); | ||
296 | } | ||
297 | } | ||
298 | /* Check for ko. koX and koY are set in GroupCapture above. */ | ||
299 | if (killcnt == 1 && count == 1 && GroupList[ code ].count == 1 | ||
300 | && GroupList[ code ].liberties == 1) | ||
301 | { | ||
302 | ko = TRUE; | ||
303 | } | ||
304 | if (killcnt) | ||
305 | intrPrisonerReport( blackPrisoners, whitePrisoners); | ||
306 | /* Set eye count for groups */ | ||
307 | CountEyes(); | ||
308 | } | ||
309 | |||
310 | /* Remove a captured group from the board and fix the liberties of any | ||
311 | adjacent groups. Fixes prisoner count. Sets KoX and KoY */ | ||
312 | /*-- update display of captured stones -neilb --*/ | ||
313 | void | ||
314 | GroupCapture(code) | ||
315 | shortcode; | ||
316 | { | ||
317 | shortx, y; | ||
318 | |||
319 | if (GroupList[code].color == BLACK) | ||
320 | blackPrisoners += GroupList[code].count; | ||
321 | else | ||
322 | whitePrisoners += GroupList[code].count; | ||
323 | intrPrisonerReport(blackPrisoners, whitePrisoners); | ||
324 | ForeachPoint(y,x) | ||
325 | if (goboard[x][y].GroupNum == code) | ||
326 | { | ||
327 | FixLibs(GroupList[code].color,x,y,REMOVED); | ||
328 | GoRemoveStone(x, y); | ||
329 | koX = x; | ||
330 | koY = y; | ||
331 | } | ||
332 | DeleteGroup( code); | ||
333 | } | ||
334 | |||
335 | /* Fix the liberties of groups adjacent to x, y. move indicates | ||
336 | whether a stone of color was placed or removed at x, y | ||
337 | This does not change liberty counts of friendly groups when a stone | ||
338 | is placed. Does not do captures. */ | ||
339 | void | ||
340 | FixLibs( color, x, y, move) | ||
341 | enumbVal color; | ||
342 | shortx, y, move; | ||
343 | { | ||
344 | shortfgroups[4], fcnt, egroups[4], ecnt, i; | ||
345 | enumbVal opcolor = BLACK; | ||
346 | |||
347 | if (color == BLACK) | ||
348 | opcolor = WHITE; | ||
349 | Connect( color, x, y, fgroups, &fcnt, egroups, &ecnt); | ||
350 | if (move == PLACED) | ||
351 | for (i = 0; i < ecnt; i++) | ||
352 | GroupList[egroups[i]].liberties--; | ||
353 | else /* Stone removed so increment opcolor */ | ||
354 | for (i = 0; i < ecnt; i++) | ||
355 | GroupList[egroups[i]].liberties++; | ||
356 | } | ||
357 | |||
358 | void | ||
359 | goSetHandicap(handicap) | ||
360 | int handicap; | ||
361 | { | ||
362 | if (handicap < 2) | ||
363 | return; | ||
364 | |||
365 | GoPlaceStone(BLACK,3,3); | ||
366 | GoPlaceStone(BLACK,15,15); | ||
367 | |||
368 | if (handicap >= 3) | ||
369 | GoPlaceStone(BLACK,15,3); | ||
370 | if (handicap >= 4) | ||
371 | GoPlaceStone(BLACK,3,15); | ||
372 | if (handicap == 5 || handicap == 7 || handicap == 9) | ||
373 | GoPlaceStone(BLACK,9,9); | ||
374 | if (handicap >= 6) | ||
375 | { | ||
376 | GoPlaceStone(BLACK,15,9); | ||
377 | GoPlaceStone(BLACK,3,9); | ||
378 | } | ||
379 | if (handicap >= 8) | ||
380 | { | ||
381 | GoPlaceStone(BLACK,9,15); | ||
382 | GoPlaceStone(BLACK,9,3); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | void | ||
387 | goRestart(handicap) | ||
388 | inthandicap; | ||
389 | { | ||
390 | register short i; | ||
391 | register struct bRec *gpt= &goboard[0][0]; | ||
392 | |||
393 | |||
394 | GroupCount = 0; | ||
395 | ko = FALSE; | ||
396 | blackPrisoners = whitePrisoners = 0; | ||
397 | intrPrisonerReport(0, 0); | ||
398 | for (i=0; i<361; gpt++,i++) | ||
399 | { | ||
400 | gpt->Val = EMPTY; | ||
401 | gpt->GroupNum = 0; | ||
402 | } | ||
403 | goSetHandicap(handicap); | ||
404 | } | ||
405 | |||
406 | |||
407 | /* if any groups have been deleted as a result of the last move, this | ||
408 | routine will delete the old group numbers from GroupList and | ||
409 | reassign group numbers. */ | ||
410 | void | ||
411 | RelabelGroups() | ||
412 | { | ||
413 | unsignedshort i, j, x, y; | ||
414 | |||
415 | for (i = 0; i < DeletedGroupCount; i++) | ||
416 | { | ||
417 | /* Relabel all higher groups */ | ||
418 | ForeachPoint(y,x) | ||
419 | if (goboard[x][y].GroupNum > DeletedGroups[i]) | ||
420 | goboard[x][y].GroupNum--; | ||
421 | /* Move the groups down */ | ||
422 | for (y = DeletedGroups[i]; y < GroupCount; y++) | ||
423 | GroupList[y] = GroupList[y+1]; | ||
424 | /* fix the group numbers stored in the deleted list */ | ||
425 | for (j = i+1; j < DeletedGroupCount; j++) | ||
426 | if (DeletedGroups[j] > DeletedGroups[i]) | ||
427 | DeletedGroups[j]--; | ||
428 | GroupCount--; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | /* Returns liberty count for x, y intersection. Sets marked to true | ||
433 | for each liberty */ | ||
434 | short | ||
435 | CountAndMarkLibs( x, y) | ||
436 | shortx, y; | ||
437 | { | ||
438 | shorttx,ty,i; | ||
439 | shortcnt = 0; | ||
440 | |||
441 | |||
442 | for (i=0;i<4;i++) | ||
443 | { | ||
444 | tx = x + xVec[i]; | ||
445 | ty = y + yVec[i]; | ||
446 | if (LegalPoint(tx,ty) && goboard[tx][ty].Val == EMPTY | ||
447 | && goboard[tx][ty].marked == FALSE) | ||
448 | { | ||
449 | cnt++; | ||
450 | goboard[tx][ty].marked = TRUE; | ||
451 | } | ||
452 | } | ||
453 | return cnt; | ||
454 | } | ||
455 | |||
456 | /* Determine the number of liberties for a group given the group code | ||
457 | num */ | ||
458 | void | ||
459 | CountLiberties( code) | ||
460 | shortcode; | ||
461 | { | ||
462 | shortx, y, libcnt = 0; | ||
463 | |||
464 | ForeachPoint(y,x) | ||
465 | if (goboard[x][y].GroupNum == code) | ||
466 | libcnt += CountAndMarkLibs( x, y); | ||
467 | EraseMarks(); | ||
468 | GroupList[code].liberties = libcnt; | ||
469 | } | ||
470 | |||
471 | void | ||
472 | CheckForEye( x, y, groups, cnt, recheck) | ||
473 | shortx, y, groups[4], cnt, *recheck; | ||
474 | { | ||
475 | shorti; | ||
476 | |||
477 | for (i = 0; i < (cnt-1); i++) | ||
478 | if (groups[i] != groups[i+1]) | ||
479 | { | ||
480 | /* Mark liberty for false eye check */ | ||
481 | goboard[x][y].marked = TRUE; | ||
482 | (*recheck)++; | ||
483 | return; | ||
484 | } | ||
485 | /* It is an eye */ | ||
486 | GroupList[groups[i]].eyes += 1; | ||
487 | } | ||
488 | |||
489 | /* Set the eye count for the groups */ | ||
490 | void CountEyes() | ||
491 | { | ||
492 | shorti, x, y, | ||
493 | wgroups[4], bgroups[4], wcnt, bcnt, max, cnt, recheck = 0, eye; | ||
494 | |||
495 | for (i = 1; i <= GroupCount; i++) | ||
496 | GroupList[i].eyes = 0; | ||
497 | |||
498 | ForeachPoint(y,x) | ||
499 | { | ||
500 | if (goboard[x][y].Val != EMPTY) | ||
501 | continue; | ||
502 | cnt = Connect(WHITE,x,y,wgroups,&wcnt,bgroups,&bcnt); | ||
503 | max = Maxlibs( x, y); | ||
504 | if (cnt == max && wcnt == 1 && bcnt == 0) | ||
505 | GroupList[wgroups[0]].eyes++; | ||
506 | else if (cnt == max && bcnt == 1 && wcnt == 0) | ||
507 | GroupList[bgroups[0]].eyes++; | ||
508 | else if (cnt == max && ( bcnt == 0 || wcnt == 0 )) | ||
509 | { | ||
510 | goboard[x][y].marked = TRUE; | ||
511 | recheck++; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /*-- Now recheck marked liberties to see if two or more one eye --*/ | ||
516 | /*-- groups contribute to a false eye */ | ||
517 | if (recheck == 0) | ||
518 | return; | ||
519 | |||
520 | ForeachPoint(y,x) | ||
521 | if (goboard[x][y].marked) | ||
522 | { | ||
523 | recheck--; | ||
524 | goboard[x][y].marked = FALSE; | ||
525 | Connect( WHITE, x, y, wgroups, &wcnt, bgroups, &bcnt); | ||
526 | /* If all the groups have at least one eye then all the | ||
527 | groups are safe from capture because of the common | ||
528 | liberty at x, y */ | ||
529 | eye = TRUE; | ||
530 | for (i = 0; i < wcnt; i++) | ||
531 | if (GroupList[wgroups[i]].eyes == 0) | ||
532 | eye = FALSE; | ||
533 | if (eye) | ||
534 | for (i = 0; i < wcnt; i++) | ||
535 | GroupList[wgroups[i]].eyes++; | ||
536 | for (i = 0; i < bcnt; i++) | ||
537 | if (GroupList[bgroups[i]].eyes == 0) | ||
538 | eye = FALSE; | ||
539 | if (eye) | ||
540 | for (i = 0; i < bcnt; i++) | ||
541 | GroupList[bgroups[i]].eyes++; | ||
542 | if (recheck == 0) | ||
543 | return; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | |||
548 | shortfoo[19][19]; | ||
549 | |||
550 | /*---------------------------------------------------------------- | ||
551 | -- CountUp() -- | ||
552 | -- Count up final scores at the end of the game. -- | ||
553 | ----------------------------------------------------------------*/ | ||
554 | CountUp( wtotal, btotal ) | ||
555 | int *wtotal, *btotal; | ||
556 | { | ||
557 | shortx,y; | ||
558 | shortCountFromPoint(); | ||
559 | shortvv; | ||
560 | charbuff[512]; | ||
561 | |||
562 | |||
563 | blackTerritory = whiteTerritory = 0; | ||
564 | ForeachPoint(y,x) | ||
565 | { | ||
566 | goboard[x][y].marked = FALSE; | ||
567 | foo[x][y] = CNT_UNDECIDED; | ||
568 | } | ||
569 | ForeachPoint(y,x) | ||
570 | if (goboard[x][y].Val==EMPTY && foo[x][y]==CNT_UNDECIDED) | ||
571 | { | ||
572 | FillPoints(x,y,CountFromPoint(x,y)); | ||
573 | } | ||
574 | |||
575 | *wtotal = whiteTerritory + blackPrisoners; | ||
576 | *btotal = blackTerritory + whitePrisoners; | ||
577 | /* | ||
578 | sprintf(buff,"White : %3d territory + %3d prisoners = %d\n\ | ||
579 | Black : %3d territory + %3d prisoners = %d\n\n%s.\n", | ||
580 | whiteTerritory,blackPrisoners,*wtotal, | ||
581 | blackTerritory,whitePrisoners,*btotal, | ||
582 | (*btotal>*wtotal?"Black wins":(*wtotal>*btotal?"White wins": | ||
583 | "A draw"))); | ||
584 | |||
585 | |||
586 | |||
587 | XtVaSetValues(message,XtNstring,buff,0); | ||
588 | printf( "CountUp() %s", buff ); | ||
589 | */ | ||
590 | } | ||
591 | |||
592 | FillPoints(x,y,val) | ||
593 | shortx,y,val; | ||
594 | { | ||
595 | inti; | ||
596 | shorttx,ty; | ||
597 | |||
598 | |||
599 | if ((foo[x][y] = val) == CNT_BLACK_TERR) | ||
600 | blackTerritory++; | ||
601 | else if (val == CNT_WHITE_TERR) | ||
602 | whiteTerritory++; | ||
603 | for (i=0;i<4;i++) | ||
604 | { | ||
605 | tx = x + xVec[i]; | ||
606 | ty = y + yVec[i]; | ||
607 | if (!LegalPoint(tx,ty)) | ||
608 | continue; | ||
609 | if (goboard[tx][ty].Val==EMPTY && foo[tx][ty]==CNT_UNDECIDED) | ||
610 | FillPoints(tx,ty,val); | ||
611 | } | ||
612 | } | ||
613 | |||
614 | short | ||
615 | CountFromPoint(x,y) | ||
616 | shortx,y; | ||
617 | { | ||
618 | inti; | ||
619 | shorttx,ty; | ||
620 | shortblkcnt=0,whtcnt=0; | ||
621 | shortbaz; | ||
622 | |||
623 | |||
624 | goboard[x][y].marked = TRUE; | ||
625 | for (i=0;i<4;i++) | ||
626 | { | ||
627 | tx = x + xVec[i]; | ||
628 | ty = y + yVec[i]; | ||
629 | if (!LegalPoint(tx,ty)) | ||
630 | continue; | ||
631 | if (goboard[tx][ty].Val == BLACK) | ||
632 | blkcnt++; | ||
633 | else if (goboard[tx][ty].Val == WHITE) | ||
634 | whtcnt++; | ||
635 | else | ||
636 | { | ||
637 | if (goboard[tx][ty].marked) | ||
638 | continue; | ||
639 | baz = CountFromPoint(tx,ty); | ||
640 | if (baz == CNT_NOONE) | ||
641 | return CNT_NOONE; | ||
642 | else if (baz == CNT_BLACK_TERR) | ||
643 | blkcnt++; | ||
644 | else if (baz == CNT_WHITE_TERR) | ||
645 | whtcnt++; | ||
646 | } | ||
647 | if (blkcnt && whtcnt) | ||
648 | return CNT_NOONE; | ||
649 | } | ||
650 | if (blkcnt && !whtcnt) | ||
651 | return CNT_BLACK_TERR; | ||
652 | else if (whtcnt && !blkcnt) | ||
653 | return CNT_WHITE_TERR; | ||
654 | else | ||
655 | return CNT_UNDECIDED; | ||
656 | } | ||
diff --git a/noncore/games/go/amigo.h b/noncore/games/go/amigo.h new file mode 100644 index 0000000..5150ac0 --- a/dev/null +++ b/noncore/games/go/amigo.h | |||
@@ -0,0 +1,146 @@ | |||
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 | === FILE amigo.h === | ||
23 | === === | ||
24 | === CONTENTS prototypes for the various AmiGo routines. === | ||
25 | === added by neilb === | ||
26 | === === | ||
27 | =========================================================================*/ | ||
28 | |||
29 | #ifndef __amigo_h | ||
30 | #define __amigo_h | ||
31 | |||
32 | #include "go.h" | ||
33 | #include "goplayutils.h" | ||
34 | |||
35 | #ifdef __STDC__ | ||
36 | #define PROTO(fp)fp | ||
37 | #else | ||
38 | #define PROTO(fp)() | ||
39 | #endif | ||
40 | |||
41 | |||
42 | #ifdef __cplusplus | ||
43 | extern "C" { | ||
44 | #endif | ||
45 | |||
46 | /* From goplayer.c */ | ||
47 | |||
48 | |||
49 | |||
50 | /* Procedures from amigo.c */ | ||
51 | |||
52 | shortConnect PROTO((enum bVal, short, short, short[4], short[4], short *, short * )); | ||
53 | shortMaxlibs PROTO((short, short)); | ||
54 | shortSuicide PROTO((enum bVal, short, short)); | ||
55 | shortStoneLibs PROTO((short, short)); | ||
56 | voidEraseMarks PROTO(()); | ||
57 | shortGoPlaceStone PROTO((enum bVal, short, short)); | ||
58 | voidGoRemoveStone PROTO((short, short)); | ||
59 | voidMergeGroups PROTO((short, short)); | ||
60 | voidDeleteGroup PROTO((short)); | ||
61 | voidReEvalGroups PROTO((enum bVal, short, short, short)); | ||
62 | voidGroupCapture PROTO((short)); | ||
63 | voidFixLibs PROTO((enum bVal, short, short, short)); | ||
64 | intCountUp PROTO((int*, int*)); | ||
65 | /*voidmain PROTO(());*/ | ||
66 | voidgoRestart PROTO((int)); | ||
67 | voidRelabelGroups PROTO(()); | ||
68 | shortCountAndMarkLibs PROTO((short, short)); | ||
69 | voidCountLiberties PROTO((short)); | ||
70 | voidCheckForEye PROTO((short, short, short[4], short, short *)); | ||
71 | voidCountEyes PROTO(()); | ||
72 | voidprintGroupReport PROTO((short, short)); | ||
73 | |||
74 | |||
75 | /* killable.c */ | ||
76 | |||
77 | inttryPlay PROTO(( short, short, short )); | ||
78 | intsSpanGroup PROTO(( short, short, sPointList * )); | ||
79 | intspanGroup PROTO(( short, short, pointList *)); | ||
80 | intpause PROTO(()); | ||
81 | |||
82 | intgenState PROTO(()); | ||
83 | intinitGPUtils PROTO(()); | ||
84 | intgenBord PROTO((enum bVal)); | ||
85 | |||
86 | shortgenMove PROTO(( enum bVal, short *, short * )); | ||
87 | shortcheckPos PROTO(( short, short, short )); | ||
88 | shorttakeCorner PROTO(( short *, short * )); | ||
89 | shortextend PROTO(( short *, short * )); | ||
90 | shortnoNbrs PROTO(( short, short )); | ||
91 | shortextend2 PROTO(( short *, short * )); | ||
92 | shortlookForSave PROTO(( short *, short * )); | ||
93 | shortlookForSaveN PROTO(( short *, short * )); | ||
94 | shortlookForKill PROTO(( short *, short * )); | ||
95 | shortdoubleAtari PROTO(( short *, short * )); | ||
96 | shortlookForAttack PROTO(( short *, short * )); | ||
97 | shortthreaten PROTO(( short *, short * )); | ||
98 | shortconnectCut PROTO(( short *, short * )); | ||
99 | shortheCanCut PROTO(( short, short )); | ||
100 | shortsafeMove PROTO(( short, short )); | ||
101 | shortextendWall PROTO(( short *, short * )); | ||
102 | shortfindAttack2 PROTO(( short *, short * )); | ||
103 | shortblockCut PROTO(( short *, short * )); | ||
104 | shortcutHim PROTO(( short *, short * )); | ||
105 | shortatariAnyway PROTO(( short *, short * )); | ||
106 | shortunderCut PROTO(( short *, short * )); | ||
107 | shortdropToEdge PROTO(( short *, short * )); | ||
108 | shortpushWall PROTO(( short *, short * )); | ||
109 | shortreduceHisLiberties PROTO(( short *, short * )); | ||
110 | shortdropToEdge2 PROTO(( short *, short * )); | ||
111 | |||
112 | |||
113 | /* goplayutils.c */ | ||
114 | |||
115 | shortsaveable PROTO((short, short, short *, short *)); | ||
116 | shortkillable PROTO((short, short, short *, short *)); | ||
117 | intinitBoolBoard PROTO((boolBoard)); | ||
118 | intintersectPlist PROTO((pointList *, pointList *, pointList *)); | ||
119 | intinitArray PROTO((intBoard)); | ||
120 | intinitState PROTO(()); | ||
121 | intcopyArray PROTO((intBoard, intBoard)); | ||
122 | intstake PROTO(()); | ||
123 | intspread PROTO(()); | ||
124 | intrespreicen PROTO(()); | ||
125 | inttryPlay PROTO((short, short, short)); | ||
126 | intsaveState PROTO(()); | ||
127 | intrestoreState PROTO(()); | ||
128 | shorttencen PROTO((short, short)); | ||
129 | intgenConnects PROTO(()); | ||
130 | intsortLibs PROTO(()); | ||
131 | |||
132 | |||
133 | /*-- from xinterface.c --*/ | ||
134 | voidremovestone PROTO((short, short)); | ||
135 | voidplacestone PROTO((enum bVal, short, short)); | ||
136 | |||
137 | voidintrMoveReport PROTO((enum bVal,char *,char *)); | ||
138 | voidintrPrisonerReport PROTO(( short, short )); | ||
139 | |||
140 | |||
141 | #ifdef __cplusplus | ||
142 | } | ||
143 | #endif | ||
144 | |||
145 | |||
146 | #endif | ||
diff --git a/noncore/games/go/go.h b/noncore/games/go/go.h new file mode 100644 index 0000000..9aa644b --- a/dev/null +++ b/noncore/games/go/go.h | |||
@@ -0,0 +1,81 @@ | |||
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 | /* AmiGo Include */ | ||
21 | /* MSG types for getinput() */ | ||
22 | |||
23 | #ifndef __go_h | ||
24 | #define __go_h | ||
25 | |||
26 | |||
27 | #define INTERSECTIONMSG 1/* User buttoned an intersection */ | ||
28 | #define QUITMSG 2 /* User buttoned QUIT icon */ | ||
29 | #define PLAYMSG 3 | ||
30 | #define RESTARTMSG 4 | ||
31 | #define PASSMSG 5 | ||
32 | |||
33 | #define TRUE 1 | ||
34 | #define FALSE 0 | ||
35 | |||
36 | #define MAXGROUPS 100 | ||
37 | |||
38 | #define PLACED 0 | ||
39 | #define REMOVED 1 | ||
40 | |||
41 | #define numPoints 19 | ||
42 | #define maxPoint numPoints - 1 | ||
43 | |||
44 | /*-- definitions used when counting up --*/ | ||
45 | |||
46 | #define CNT_UNDECIDED0 | ||
47 | #define CNT_BLACK_TERR1 | ||
48 | #define CNT_WHITE_TERR2 | ||
49 | #define CNT_NOONE3 | ||
50 | |||
51 | /*-- macro functions --*/ | ||
52 | |||
53 | #define LegalPoint(x,y) (x>=0 && x<=18 && y>=0 && y<=18) | ||
54 | #define ForeachPoint(a,b)for(a=0;a<19;a++) for (b=0;b<19;b++) | ||
55 | |||
56 | enum bVal {BLACK, WHITE, EMPTY}; | ||
57 | typedef enum bVal sType; | ||
58 | struct Group | ||
59 | { | ||
60 | enum bVal color;/* The color of the group */ | ||
61 | short code, /* The code used to mark stones in the group */ | ||
62 | count, /* The number of stones in the group */ | ||
63 | internal,/* The number of internal liberties */ | ||
64 | external,/* The number of external liberties */ | ||
65 | liberties,/* The total number of liberties */ | ||
66 | eyes, /* The number of eyes */ | ||
67 | alive, /* A judgement of how alive this group is */ | ||
68 | territory;/* The territory this group controls */ | ||
69 | }; | ||
70 | |||
71 | struct bRec | ||
72 | { | ||
73 | enum bVal Val;/* What is at this intersection */ | ||
74 | short xOfs, | ||
75 | yOfs; | ||
76 | short mNum; | ||
77 | short GroupNum;/* What group the stone belongs to */ | ||
78 | short marked;/* TRUE or FALSE */ | ||
79 | }; | ||
80 | |||
81 | #endif | ||
diff --git a/noncore/games/go/go.pro b/noncore/games/go/go.pro new file mode 100644 index 0000000..deb90c5 --- a/dev/null +++ b/noncore/games/go/go.pro | |||
@@ -0,0 +1,19 @@ | |||
1 | DESTDIR = ../bin | ||
2 | TEMPLATE= app | ||
3 | CONFIG = qt warn_on release | ||
4 | HEADERS = amigo.h \ | ||
5 | go.h \ | ||
6 | goplayutils.h \ | ||
7 | gowidget.h | ||
8 | SOURCES = amigo.c \ | ||
9 | goplayer.c \ | ||
10 | goplayutils.c \ | ||
11 | killable.c \ | ||
12 | gowidget.cpp \ | ||
13 | main.cpp | ||
14 | INCLUDEPATH += $(QPEDIR)/include | ||
15 | DEPENDPATH+= $(QPEDIR)/include | ||
16 | LIBS += -lqpe | ||
17 | TARGET = go | ||
18 | |||
19 | TRANSLATIONS = ../i18n/de/go.ts \ No newline at end of file | ||
diff --git a/noncore/games/go/goplayer.c b/noncore/games/go/goplayer.c new file mode 100644 index 0000000..88c0f61 --- a/dev/null +++ b/noncore/games/go/goplayer.c | |||
@@ -0,0 +1,1499 @@ | |||
1 | /* The go player */ | ||
2 | /* Ported from Pascal to C by Todd R. Johnson 4/17/88 */ | ||
3 | /* From the original pascal file: | ||
4 | Go Move Generator | ||
5 | Copyright (c) 1983 by Three Rivers Computer Corp. | ||
6 | |||
7 | Written: January 17, 1983 by Stoney Ballard | ||
8 | Edit History: | ||
9 | */ | ||
10 | |||
11 | #include "go.h" | ||
12 | #include "goplayutils.h" | ||
13 | #include "amigo.h" | ||
14 | |||
15 | #define BIGGEST 32767/* maximum value for short */ | ||
16 | |||
17 | /* From go.c */ | ||
18 | extern struct bRec goboard[19][19]; | ||
19 | extern short ko, koX, koY; | ||
20 | |||
21 | /* From goplayutils.c */ | ||
22 | extern intBoard bord; | ||
23 | extern intBoard ndbord; | ||
24 | extern intBoard claim; | ||
25 | extern intBoard legal; | ||
26 | extern intBoard connectMap; | ||
27 | extern intBoard threatBord; | ||
28 | extern short maxGroupID; | ||
29 | extern short treeLibLim; | ||
30 | extern short killFlag; | ||
31 | extern short depthLimit; | ||
32 | extern short showTrees; | ||
33 | extern short utilPlayLevel; | ||
34 | extern groupRec gList[maxGroup]; | ||
35 | extern short sGlist[maxGroup + 1]; | ||
36 | extern pointList pList; | ||
37 | extern pointList pList1; | ||
38 | extern pointList plist2; | ||
39 | extern pointList plist3; | ||
40 | extern intBoard groupIDs; | ||
41 | extern intBoard protPoints; | ||
42 | extern sType mySType; | ||
43 | |||
44 | |||
45 | short saveNLibs; | ||
46 | pointList dapList1, dapList2, dapList3; | ||
47 | char *playReason; | ||
48 | short maxPlayLevel = 7; | ||
49 | short playLevel = 7; | ||
50 | |||
51 | genBord(color) | ||
52 | enum bValcolor; | ||
53 | { | ||
54 | short x, y, nomoves = TRUE; | ||
55 | char mv[8]; | ||
56 | |||
57 | maxPlayLevel = 7; | ||
58 | utilPlayLevel = playLevel; | ||
59 | mySType = color; | ||
60 | if (playLevel < 2) | ||
61 | treeLibLim = 2; | ||
62 | else | ||
63 | treeLibLim = 3; | ||
64 | depthLimit = 100; | ||
65 | for (y = 0; y <= 18; y++) | ||
66 | for (x = 0; x <= 18; x++) | ||
67 | if (goboard[x][y].Val == color) | ||
68 | { | ||
69 | bord[x][y] = 1; | ||
70 | legal[x][y] = FALSE; | ||
71 | nomoves = FALSE; | ||
72 | } | ||
73 | else if (goboard[x][y].Val == EMPTY) | ||
74 | { | ||
75 | bord[x][y] = 0; | ||
76 | legal[x][y] = TRUE; | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | bord[x][y] = -1; | ||
81 | legal[x][y] = FALSE; | ||
82 | nomoves = FALSE; | ||
83 | } | ||
84 | if (ko) | ||
85 | { | ||
86 | legal[koX][koY] = FALSE; | ||
87 | } | ||
88 | |||
89 | if (! nomoves) | ||
90 | genState(); | ||
91 | else | ||
92 | initGPUtils(); | ||
93 | } | ||
94 | |||
95 | |||
96 | short getMove( x, y ) | ||
97 | short *x, *y; | ||
98 | { | ||
99 | if (takeCorner(x, y)) return TRUE; | ||
100 | if (lookForSave(x, y)) return TRUE; | ||
101 | if (lookForSaveN(x, y)) return TRUE; | ||
102 | if (extend(x, y)) return TRUE; | ||
103 | if (lookForKill(x, y)) return TRUE; | ||
104 | if (doubleAtari(x, y)) return TRUE; | ||
105 | if (lookForAttack(x, y)) return TRUE; | ||
106 | if (threaten(x, y)) return TRUE; | ||
107 | if (extend2(x, y)) return TRUE; | ||
108 | if (connectCut(x, y)) return TRUE; | ||
109 | if (blockCut(x, y)) return TRUE; | ||
110 | if (cutHim(x, y)) return TRUE; | ||
111 | if (extendWall(x, y)) return TRUE; | ||
112 | if (findAttack2(x, y)) return TRUE; | ||
113 | if (atariAnyway(x, y)) return TRUE; | ||
114 | if (underCut(x, y)) return TRUE; | ||
115 | if (dropToEdge(x, y)) return TRUE; | ||
116 | if (pushWall(x, y)) return TRUE; | ||
117 | if (reduceHisLiberties(x, y)) return TRUE; | ||
118 | if (dropToEdge2(x, y)) return TRUE; | ||
119 | return FALSE; | ||
120 | } | ||
121 | |||
122 | short genMove( color, x, y ) | ||
123 | enum bVal color; | ||
124 | short *x, *y; | ||
125 | { | ||
126 | if (playLevel > 2) | ||
127 | saveNLibs = TRUE; | ||
128 | else | ||
129 | saveNLibs = FALSE; | ||
130 | genBord(color); | ||
131 | if (getMove(x, y)) | ||
132 | return TRUE; | ||
133 | return FALSE; | ||
134 | } | ||
135 | |||
136 | short checkPos(x, y, field) | ||
137 | short x, y, field; | ||
138 | { | ||
139 | short ok; | ||
140 | ok = (((field == 0) && (claim[x][y] == 0)) || | ||
141 | ((field > 0) && | ||
142 | (claim[x][y] >= 0) && (claim[x][y] <= field)) || | ||
143 | ((field < 0) && | ||
144 | (claim[x][y] <= 0) && (claim[x][y] >= field))) && | ||
145 | (bord[x-1][y] == 0) && | ||
146 | (bord[x+1][y] == 0) && | ||
147 | (bord[x][y-1] == 0) && | ||
148 | (bord[x][y+1] == 0); | ||
149 | if (ok) return TRUE; else return FALSE; | ||
150 | } | ||
151 | |||
152 | short takeCorner( x, y ) | ||
153 | short *x, *y; | ||
154 | { | ||
155 | short field = -1, i; | ||
156 | i = 18 - 3; | ||
157 | playReason = "takeCorner"; | ||
158 | while (field != -4) | ||
159 | { | ||
160 | if (field == -1) field = 0; | ||
161 | else if (field == 0) field = 4; | ||
162 | else field = -4; | ||
163 | if (checkPos(2, 3, field)) { *x = 2; *y = 3; return TRUE; } | ||
164 | if (checkPos(3, 2, field)) { *x = 3; *y = 2; return TRUE; } | ||
165 | if (checkPos(2, i, field)) { *x = 2; *y = i; return TRUE; } | ||
166 | if (checkPos(3, i + 1, field)) { *x = 3; *y = i+1; return TRUE; } | ||
167 | if (checkPos(i, i + 1, field)) { *x = i; *y = i+1; return TRUE; } | ||
168 | if (checkPos(i + 1, i, field)) { *x = i+1; *y = i; return TRUE; } | ||
169 | if (checkPos(i, 2, field)) { *x = i; *y = 2; return TRUE; } | ||
170 | if (checkPos(i + 1, 3, field)) { *x = i+1; *y = 3; return TRUE; } | ||
171 | if (checkPos(2, 4, field)) { *x = 2; *y = 4; return TRUE; } | ||
172 | if (checkPos(4, 2, field)) { *x = 4; *y = 2; return TRUE; } | ||
173 | if (checkPos(2, i - 1, field)) { *x = 2; *y = i-1; return TRUE; } | ||
174 | if (checkPos(4, i + 1, field)) { *x = 4; *y = i+1; return TRUE; } | ||
175 | if (checkPos(i - 1, i + 1, field)) { *x = i-1; *y = i+1; return TRUE; } | ||
176 | if (checkPos(i + 1, i - 1, field)) { *x = i+1; *y = i-1; return TRUE; } | ||
177 | if (checkPos(i + 1, 4, field)) { *x = i+1; *y = 4; return TRUE; } | ||
178 | if (checkPos(i - 1, 2, field)) { *x = i-1; *y = 2; return TRUE; } | ||
179 | } | ||
180 | return FALSE; | ||
181 | } | ||
182 | |||
183 | printBoard(brd, name) | ||
184 | intBoard brd; | ||
185 | char *name; | ||
186 | { | ||
187 | short x, y; | ||
188 | printf( "%s\n", name ); | ||
189 | for (y = 0; y <= 18; y++) | ||
190 | { | ||
191 | for (x = 0; x <= 18; x++) | ||
192 | printf("%d ", brd[x][y]); | ||
193 | printf("\n"); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | short noNbrs( x, y ) | ||
198 | short x, y; | ||
199 | { | ||
200 | if (x > 0 && bord[x-1][y] != 0) return FALSE; | ||
201 | if (x < 18 && bord[x+1][y] != 0) return FALSE; | ||
202 | if (y > 0 && bord[x][y-1] != 0) return FALSE; | ||
203 | if (y < 18 && bord[x][y+1] != 0) return FALSE; | ||
204 | return TRUE; | ||
205 | } | ||
206 | |||
207 | short extend(x, y) | ||
208 | short *x, *y; | ||
209 | { | ||
210 | short i; | ||
211 | playReason = "extend"; | ||
212 | for (i = 2; i <= 18-2; i++) | ||
213 | if (claim[2][i] == 0 && noNbrs( 2, i )) | ||
214 | { | ||
215 | *x = 2; | ||
216 | *y = i; | ||
217 | return TRUE; | ||
218 | } | ||
219 | for (i = 2; i <= 18-2; i++) | ||
220 | if (claim[i][18-2] == 0 && noNbrs( 2, i )) | ||
221 | { | ||
222 | *x = i; | ||
223 | *y = 18-2; | ||
224 | return TRUE; | ||
225 | } | ||
226 | for (i = 18-2; i >= 2; i--) | ||
227 | if (claim[18-2][i] == 0 && noNbrs( 18-2, i )) | ||
228 | { | ||
229 | *x = 18-2; | ||
230 | *y = i; | ||
231 | return TRUE; | ||
232 | } | ||
233 | for (i = 18-2; i >= 2; i--) | ||
234 | if (claim[i][2] == 0 && noNbrs( i, 2 )) | ||
235 | { | ||
236 | *x = i; | ||
237 | *y = 2; | ||
238 | return TRUE; | ||
239 | } | ||
240 | return FALSE; | ||
241 | } | ||
242 | |||
243 | short extend2( x, y ) | ||
244 | short *x, *y; | ||
245 | { | ||
246 | short i, lowest = BIGGEST, value; | ||
247 | playReason = "extend2"; | ||
248 | for (i = 3; i <= 18-3; i++) | ||
249 | if (legal[2][i]) /* if there is nobody there */ | ||
250 | { | ||
251 | value = claim[2][i]; /* get influence */ | ||
252 | if ((value < 7) && /* a reasonable hole in my wall */ | ||
253 | (value > -5) && /* or a reasonable gap in his */ | ||
254 | (bord[2][i + 1] == 0) && /* not in contact with any stones */ | ||
255 | (bord[2][i - 1] == 0)) | ||
256 | if (value < lowest) | ||
257 | { | ||
258 | lowest = value; /* lowest gets the smallest value */ | ||
259 | *x = 2; /* that was seen along all the 3-lines */ | ||
260 | *y = i; /* x and y save that location */ | ||
261 | } | ||
262 | } | ||
263 | for (i = 3; i <= 18-3; i++) | ||
264 | if (legal[i][2]) | ||
265 | { | ||
266 | value = claim[i][2]; | ||
267 | if ((value < 7) && | ||
268 | (value > -5) && | ||
269 | (bord[i + 1][2] == 0) && | ||
270 | (bord[i - 1][2] == 0)) | ||
271 | if (value < lowest) | ||
272 | { | ||
273 | lowest = value; | ||
274 | *x = i; | ||
275 | *y = 2; | ||
276 | } | ||
277 | } | ||
278 | for (i = 18-3; i >= 3; i--) | ||
279 | if (legal[18 - 2][i]) | ||
280 | { | ||
281 | value = claim[18 - 2][i]; | ||
282 | if ((value < 7) && | ||
283 | (value > -5) && | ||
284 | (bord[18 - 2][i + 1] == 0) && | ||
285 | (bord[18 - 2][i - 1] == 0)) | ||
286 | if (value < lowest) | ||
287 | { | ||
288 | lowest = value; | ||
289 | *x = 18 - 2; | ||
290 | *y = i; | ||
291 | } | ||
292 | } | ||
293 | for (i = 3; i <= 18-3; i++) | ||
294 | if (legal[i][18 - 2]) | ||
295 | { | ||
296 | value = claim[i][18 - 2]; | ||
297 | if ((value < 7) && | ||
298 | (value > -5) && | ||
299 | (bord[i + 1][18 - 2] == 0) && | ||
300 | (bord[i - 1][18 - 2] == 0)) | ||
301 | if (value < lowest) | ||
302 | { | ||
303 | lowest = value; | ||
304 | *x = i; | ||
305 | *y = 18 - 2; | ||
306 | } | ||
307 | } | ||
308 | if (lowest == BIGGEST) return FALSE; | ||
309 | return TRUE; | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | check to see if I can save anything in atari | ||
314 | */ | ||
315 | short lookForSave(x, y) | ||
316 | short *x, *y; | ||
317 | { /* lookForSave */ | ||
318 | short i; | ||
319 | playReason = "lookForSave"; | ||
320 | for (i = 1; i <= maxGroupID; i++) /* scan the group list */ | ||
321 | if ((gList[i].libC == 1) && | ||
322 | (ndbord[gList[i].lx][gList[i].ly] == 1)) | ||
323 | if (saveable(gList[i].lx, gList[i].ly, x, y)) /* see if I can save it */ | ||
324 | return TRUE; | ||
325 | return FALSE; | ||
326 | } /* lookForSave */ | ||
327 | |||
328 | /* | ||
329 | check to see if I can save anything with n libs | ||
330 | */ | ||
331 | short lookForSaveN(x, y) | ||
332 | short *x, *y; | ||
333 | { /* lookForSaveN */ | ||
334 | short i; | ||
335 | if (saveNLibs) | ||
336 | { | ||
337 | playReason = "lookForSaveN"; | ||
338 | for (i = 1; i <= maxGroupID; i++) /* scan the group list */ | ||
339 | if ((gList[i].libC > 1) && | ||
340 | (gList[i].libC <= treeLibLim) && | ||
341 | (ndbord[gList[i].lx][gList[i].ly] == 1)) | ||
342 | { | ||
343 | if (killable(gList[i].lx, gList[i].ly, x, y)) | ||
344 | if (saveable(gList[i].lx, gList[i].ly, x, y)) /* see if I can save it */ | ||
345 | return TRUE; | ||
346 | } | ||
347 | } | ||
348 | return FALSE; | ||
349 | } /* lookForSaveN */ | ||
350 | |||
351 | |||
352 | /*---------------------------------------------------------------- | ||
353 | -- lookForKill() -- | ||
354 | -- check to see if I can kill anything. -- | ||
355 | ----------------------------------------------------------------*/ | ||
356 | short | ||
357 | lookForKill(x, y) | ||
358 | short*x, *y; | ||
359 | { | ||
360 | shorti; | ||
361 | charmv[8]; | ||
362 | |||
363 | playReason = "lookForKill"; | ||
364 | for (i = 1; i <= maxGroupID; i++) /* scan the group list */ | ||
365 | if ((gList[i].libC == 1) && | ||
366 | (ndbord[gList[i].lx][gList[i].ly] == -1)) | ||
367 | { /* we found a live enemy group with one liberty */ | ||
368 | /* find the liberty */ | ||
369 | spanGroup(gList[i].lx, gList[i].ly, &pList); | ||
370 | *x = pList.p[1].px; | ||
371 | *y = pList.p[1].py; | ||
372 | if (legal[*x][*y]) | ||
373 | { | ||
374 | return TRUE; | ||
375 | } | ||
376 | } | ||
377 | return FALSE; | ||
378 | } | ||
379 | |||
380 | short doubleAtari(x, y) | ||
381 | short *x, *y; | ||
382 | { /* doubleAtari */ | ||
383 | short i, j; | ||
384 | playReason = "doubleAtari"; | ||
385 | for (i = 1; i <= maxGroupID - 1; i++) | ||
386 | if ((gList[i].libC == 2) && | ||
387 | (ndbord[gList[i].lx][gList[i].ly] == -1)) /* found an atariable group of his */ | ||
388 | { | ||
389 | spanGroup(gList[i].lx, gList[i].ly, &dapList1); | ||
390 | for (j = i + 1; j <= maxGroupID; j++) | ||
391 | if ((gList[j].libC == 2) && | ||
392 | (ndbord[gList[j].lx][gList[j].ly] == -1)) | ||
393 | { | ||
394 | spanGroup(gList[j].lx, gList[j].ly, &dapList2); | ||
395 | intersectPlist(&dapList1, &dapList2, &dapList3); | ||
396 | if (dapList3.indx > 0) | ||
397 | if (legal[dapList3.p[1].px][dapList3.p[1].py]) | ||
398 | { | ||
399 | tryPlay(dapList3.p[1].px, dapList3.p[1].py, 1); | ||
400 | if (gList[groupIDs[dapList3.p[1].px][ | ||
401 | dapList3.p[1].py]].libC > 1) | ||
402 | { | ||
403 | *x = dapList3.p[1].px; | ||
404 | *y = dapList3.p[1].py; | ||
405 | restoreState(); | ||
406 | return TRUE; | ||
407 | } | ||
408 | restoreState(); | ||
409 | } | ||
410 | } | ||
411 | } | ||
412 | return FALSE; | ||
413 | } /* doubleAtari */ | ||
414 | |||
415 | short lookForAttack(x, y) | ||
416 | short *x, *y; | ||
417 | { /* lookForAttack */ | ||
418 | short tx, ty, i; | ||
419 | playReason = "lookForAttack"; | ||
420 | for (i = 1; i <= maxGroupID; i++) /* scan the group list */ | ||
421 | if ((! gList[i].isLive) && | ||
422 | (gList[i].libC > 1) && | ||
423 | (gList[i].libC <= (treeLibLim + 1)) && | ||
424 | (ndbord[gList[i].lx][gList[i].ly] == -1)) | ||
425 | { | ||
426 | if (killable(gList[i].lx, gList[i].ly, &tx, &ty)) /* can we kill it? */ | ||
427 | { | ||
428 | *x = tx; /* yep - do so */ | ||
429 | *y = ty; | ||
430 | return TRUE; | ||
431 | } | ||
432 | } | ||
433 | return FALSE; | ||
434 | } /* lookForAttack */ | ||
435 | |||
436 | /* | ||
437 | Plays a move that requires a response on the opponent's part | ||
438 | */ | ||
439 | short threaten(x, y) | ||
440 | short *x, *y; | ||
441 | { /* threaten */ | ||
442 | short i, j, gx, gy, tNum; | ||
443 | playReason = "threaten"; | ||
444 | initArray(threatBord); | ||
445 | for (i = 1; i <= maxGroupID; i++) | ||
446 | if ((! gList[i].isLive) && | ||
447 | (ndbord[gList[i].lx][gList[i].ly] == -1)) | ||
448 | { | ||
449 | spanGroup(gList[i].lx, gList[i].ly, &pList); | ||
450 | for (j = 1; j <= pList.indx; j++) | ||
451 | if (legal[pList.p[j].px][pList.p[j].py]) | ||
452 | { | ||
453 | tryPlay(pList.p[j].px, pList.p[j].py, 1); | ||
454 | if (gList[groupIDs[pList.p[j].px][pList.p[j].py]].libC > 1) | ||
455 | if (killable(gList[i].lx, gList[i].ly, &gx, &gy)) | ||
456 | threatBord[pList.p[j].px][pList.p[j].py] += 1; | ||
457 | restoreState(); | ||
458 | } | ||
459 | } | ||
460 | tNum = 0; | ||
461 | for (i = 0; i <= maxPoint; i++) | ||
462 | for (j = 0; j <= maxPoint; j++) | ||
463 | if ((threatBord[i][j] > tNum) && | ||
464 | ((threatBord[i][j] > 1) || | ||
465 | (connectMap[i][j] > 0))) | ||
466 | { | ||
467 | tNum = threatBord[i][j]; | ||
468 | *x = i; | ||
469 | *y = j; | ||
470 | } | ||
471 | if (tNum > 0) return TRUE; | ||
472 | else return FALSE; | ||
473 | } /* threaten */ | ||
474 | |||
475 | /* | ||
476 | connects against enemy cuts | ||
477 | */ | ||
478 | short connectCut(x, y) | ||
479 | short *x, *y; | ||
480 | { /* connectCut */ | ||
481 | short i, j, nap, gid, infl; | ||
482 | playReason = "connectCut"; | ||
483 | for (i = 0; i <= maxPoint; i++) | ||
484 | for (j = 0; j <= maxPoint; j++) | ||
485 | if (legal[i][j] && | ||
486 | (protPoints[i][j] == 0)) /* not a protected point */ | ||
487 | { | ||
488 | nap = 0; /* how many of my stones am I adjacent to? */ | ||
489 | if ((i > 0) && (bord[i - 1][j] == 1)) | ||
490 | { | ||
491 | nap = nap + 1; | ||
492 | pList.p[nap].px = i - 1; | ||
493 | pList.p[nap].py = j; | ||
494 | } | ||
495 | if ((j > 0) && (bord[i][j - 1] == 1)) | ||
496 | { | ||
497 | nap = nap + 1; | ||
498 | pList.p[nap].px = i; | ||
499 | pList.p[nap].py = j - 1; | ||
500 | } | ||
501 | if ((i < maxPoint) && (bord[i + 1][j] == 1)) | ||
502 | { | ||
503 | nap = nap + 1; | ||
504 | pList.p[nap].px = i + 1; | ||
505 | pList.p[nap].py = j; | ||
506 | } | ||
507 | if ((j < maxPoint) && (bord[i][j + 1] == 1)) | ||
508 | { | ||
509 | nap = nap + 1; | ||
510 | pList.p[nap].px = i; | ||
511 | pList.p[nap].py = j + 1; | ||
512 | } | ||
513 | if (nap == 1) /* possible knight's || 2-point extention */ | ||
514 | { | ||
515 | gid = groupIDs[pList.p[1].px][pList.p[1].py]; | ||
516 | if ((i > 0) && (i < maxPoint) && | ||
517 | (ndbord[i - 1][j] == 1) && | ||
518 | (ndbord[i + 1][j] == 0)) /* contact on left */ | ||
519 | { | ||
520 | if (((j > 0) && (ndbord[i][j - 1] == -1) && | ||
521 | (ndbord[i + 1][j - 1] == 1) && | ||
522 | (gid != groupIDs[i + 1][j - 1])) || | ||
523 | ((j < maxPoint) && (ndbord[i][j + 1] == -1) && | ||
524 | (ndbord[i + 1][j + 1] == 1) && | ||
525 | (gid != groupIDs[i + 1][j + 1])) || | ||
526 | ((((j > 0) && (ndbord[i][j - 1] == -1)) || | ||
527 | ((j < maxPoint) && (ndbord[i][j + 1] == -1))) && | ||
528 | (i < (maxPoint - 1)) && | ||
529 | (ndbord[i + 2][j] == 1) && | ||
530 | (gid != groupIDs[i + 2][j]))) | ||
531 | { | ||
532 | *x = i; | ||
533 | *y = j; | ||
534 | if (safeMove(*x, *y)) | ||
535 | return TRUE; | ||
536 | } | ||
537 | } | ||
538 | else if ((i < maxPoint) && (i > 0) && | ||
539 | (ndbord[i + 1][j] == 1) && | ||
540 | (ndbord[i - 1][j] == 0)) /* r */ | ||
541 | { | ||
542 | if (((j > 0) && (ndbord[i][j - 1] == -1) && | ||
543 | (ndbord[i - 1][j - 1] == 1) && | ||
544 | (gid != groupIDs[i - 1][j - 1])) || | ||
545 | ((j < maxPoint) && (ndbord[i][j + 1] == -1) && | ||
546 | (ndbord[i - 1][j + 1] == 1) && | ||
547 | (gid != groupIDs[i - 1][j + 1])) || | ||
548 | ((((j > 0) && (ndbord[i][j - 1] == -1)) || | ||
549 | ((j < maxPoint) && (ndbord[i][j + 1] == -1))) && | ||
550 | (i > 1) && | ||
551 | (ndbord[i - 2][j] == 1) && | ||
552 | (gid != groupIDs[i - 2][j]))) | ||
553 | { | ||
554 | *x = i; | ||
555 | *y = j; | ||
556 | if (safeMove(*x, *y)) | ||
557 | return TRUE; | ||
558 | } | ||
559 | } | ||
560 | else if ((j > 0) && (j < maxPoint) && | ||
561 | (ndbord[i][j - 1] == 1) && | ||
562 | (ndbord[i][j + 1] == 0)) /* top */ | ||
563 | { | ||
564 | if (((i > 0) && (ndbord[i - 1][j] == -1) && | ||
565 | (ndbord[i - 1][j + 1] == 1) && | ||
566 | (gid != groupIDs[i - 1][j + 1])) || | ||
567 | ((i < maxPoint) && (ndbord[i + 1][j] == -1) && | ||
568 | (ndbord[i + 1][j + 1] == 1) && | ||
569 | (gid != groupIDs[i + 1][j + 1])) || | ||
570 | ((((i > 0) && (ndbord[i - 1][j] == -1)) || | ||
571 | ((i < maxPoint) && (ndbord[i + 1][j] == -1))) && | ||
572 | (j < (maxPoint - 1)) && | ||
573 | (ndbord[i][j + 2] == 1) && | ||
574 | (gid != groupIDs[i][j + 2]))) | ||
575 | { | ||
576 | *x = i; | ||
577 | *y = j; | ||
578 | if (safeMove(*x, *y)) | ||
579 | return TRUE; | ||
580 | } | ||
581 | } | ||
582 | else if ((j > 0) && (j < maxPoint) && | ||
583 | (ndbord[i][j + 1] == 1) && | ||
584 | (ndbord[i][j - 1] == 0)) /* bottom */ | ||
585 | { | ||
586 | if (((i > 0) && (ndbord[i - 1][j] == -1) && | ||
587 | (ndbord[i - 1][j - 1] == 1) && | ||
588 | (gid != groupIDs[i - 1][j - 1])) || | ||
589 | ((i < maxPoint) && (ndbord[i + 1][j] == -1) && | ||
590 | (ndbord[i + 1][j - 1] == 1) && | ||
591 | (gid != groupIDs[i + 1][j - 1])) || | ||
592 | ((((i > 0) && (ndbord[i - 1][j] == -1)) || | ||
593 | ((i < maxPoint) && (ndbord[i + 1][j] == -1))) && | ||
594 | (j > 1) && | ||
595 | (ndbord[i][j - 2] == 1) && | ||
596 | (gid != groupIDs[i][j - 2]))) | ||
597 | { | ||
598 | *x = i; | ||
599 | *y = j; | ||
600 | if (safeMove(*x, *y)) | ||
601 | return TRUE; | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | else if (nap == 2) /* diagonal or 1-point extention */ | ||
606 | { | ||
607 | if (groupIDs[pList.p[1].px][pList.p[1].py] != | ||
608 | groupIDs[pList.p[2].px][pList.p[2].py]) | ||
609 | { | ||
610 | if ((pList.p[1].px != pList.p[2].px) && | ||
611 | (pList.p[1].py != pList.p[2].py)) /* diag */ | ||
612 | { | ||
613 | spanGroup(pList.p[1].px, | ||
614 | pList.p[1].py, &pList1); | ||
615 | spanGroup(pList.p[2].px, | ||
616 | pList.p[2].py, &plist2); | ||
617 | intersectPlist(&pList1, &plist2, &plist3); | ||
618 | if (plist3.indx == 1) | ||
619 | if ((i > 0) && (ndbord[i - 1][j] == -1) || | ||
620 | (i < maxPoint) && (ndbord[i + 1][j] == -1) || | ||
621 | (j > 0) && (ndbord[i][j - 1] == -1) || | ||
622 | (j < maxPoint) && (ndbord[i][j + 1] == -1)) | ||
623 | { /* must make direct connection */ | ||
624 | *x = i; | ||
625 | *y = j; | ||
626 | if (heCanCut(*x, *y)) | ||
627 | if (safeMove(*x, *y)) | ||
628 | return TRUE; | ||
629 | } | ||
630 | else if (heCanCut(i, j)) | ||
631 | { /* protect point if possible */ | ||
632 | infl = 1000; | ||
633 | if ((i > 0) && legal[i - 1][j] && | ||
634 | ((i == 1) || (ndbord[i - 2][j] == 0)) && | ||
635 | ((j == 0) || (ndbord[i - 1][j - 1] == 0)) && | ||
636 | ((j == maxPoint) || | ||
637 | (ndbord[i - 1][j + 1] == 0))) | ||
638 | if (safeMove(i - 1, j)) | ||
639 | if (claim[i - 1][j] < infl) | ||
640 | { | ||
641 | *x = i - 1; | ||
642 | *y = j; | ||
643 | infl = claim[i - 1][j]; | ||
644 | } | ||
645 | if ((j > 0) && legal[i][j - 1] && | ||
646 | ((j == 1) || (ndbord[i][j - 2] == 0)) && | ||
647 | ((i == 0) || (ndbord[i - 1][j - 1] == 0)) && | ||
648 | ((i == maxPoint) || | ||
649 | (ndbord[i + 1][j - 1] == 0))) | ||
650 | if (safeMove(i, j - 1)) | ||
651 | if (claim[i][j - 1] < infl) | ||
652 | { | ||
653 | *x = i; | ||
654 | *y = j - 1; | ||
655 | infl = claim[i][j - 1]; | ||
656 | } | ||
657 | if ((i < maxPoint) && legal[i + 1][j] && | ||
658 | ((i == (maxPoint - 1)) || | ||
659 | (ndbord[i + 2][j] == 0)) && | ||
660 | ((j == 0) || (ndbord[i + 1][j - 1] == 0)) && | ||
661 | ((j == maxPoint) || | ||
662 | (ndbord[i + 1][j + 1] == 0))) | ||
663 | if (safeMove(i + 1, j)) | ||
664 | if (claim[i + 1][j] < infl) | ||
665 | { | ||
666 | *x = i + 1; | ||
667 | *y = j; | ||
668 | infl = claim[i + 1][j]; | ||
669 | } | ||
670 | if ((j < maxPoint) && legal[i][j + 1] && | ||
671 | ((j == (maxPoint - 1)) || | ||
672 | (ndbord[i][j + 2] == 0)) && | ||
673 | ((i == 0) || (ndbord[i - 1][j + 1] == 0)) && | ||
674 | ((i == maxPoint) || | ||
675 | (ndbord[i + 1][j + 1] == 0))) | ||
676 | if (safeMove(i, j + 1)) | ||
677 | if (claim[i][j + 1] < infl) | ||
678 | { | ||
679 | *x = i; | ||
680 | *y = j + 1; | ||
681 | infl = claim[i][j + 1]; | ||
682 | } | ||
683 | if (infl < 1000) | ||
684 | return TRUE; | ||
685 | *x = i; /* direct connection */ | ||
686 | *y = j; | ||
687 | if (safeMove(*x, *y)) | ||
688 | return TRUE; | ||
689 | } | ||
690 | } | ||
691 | else /* 1-point extension, only protect if threatened */ | ||
692 | { | ||
693 | if ((i > 0) && (ndbord[i - 1][j] == -1) || | ||
694 | (j > 0) && (ndbord[i][j - 1] == -1) || | ||
695 | (i < maxPoint) && (ndbord[i + 1][j] == -1) || | ||
696 | (j < maxPoint) && (ndbord[i][j + 1] == -1)) | ||
697 | { | ||
698 | *x = i; | ||
699 | *y = j; | ||
700 | if (heCanCut(*x, *y)) | ||
701 | if (safeMove(*x, *y)) | ||
702 | return TRUE; | ||
703 | } | ||
704 | } | ||
705 | } | ||
706 | } | ||
707 | else if (nap == 3) /* unprotected, but me on 3 sides */ | ||
708 | { | ||
709 | if ((groupIDs[pList.p[1].px][pList.p[1].py] != | ||
710 | groupIDs[pList.p[2].px][pList.p[2].py]) || | ||
711 | (groupIDs[pList.p[1].px][pList.p[1].py] != | ||
712 | groupIDs[pList.p[3].px][pList.p[3].py]) || | ||
713 | (groupIDs[pList.p[3].px][pList.p[3].py] != | ||
714 | groupIDs[pList.p[2].px][pList.p[2].py])) | ||
715 | { | ||
716 | spanGroup(pList.p[1].px, pList.p[1].py, &pList1); | ||
717 | spanGroup(pList.p[2].px, pList.p[2].py, &plist2); | ||
718 | intersectPlist(&pList1, &plist2, &plist3); | ||
719 | spanGroup(pList.p[3].px, pList.p[3].py, &plist2); | ||
720 | intersectPlist(&plist2, &plist3, &pList1); | ||
721 | if (pList1.indx == 1) /* a common connect point */ | ||
722 | if (heCanCut(i, j)) | ||
723 | if (safeMove(i, j)) | ||
724 | { | ||
725 | *x = i; | ||
726 | *y = j; | ||
727 | return TRUE; | ||
728 | } | ||
729 | } | ||
730 | } | ||
731 | } | ||
732 | return FALSE; | ||
733 | } /* connectCut */ | ||
734 | |||
735 | short heCanCut(x, y) | ||
736 | short x, y; | ||
737 | { /* heCanCut */ | ||
738 | short gx, gy, result; | ||
739 | if (playLevel > 3) | ||
740 | { | ||
741 | tryPlay(x, y, -1); /* try his cut */ | ||
742 | result = ! killable(x, y, &gx, &gy); | ||
743 | restoreState(); | ||
744 | return result; | ||
745 | } | ||
746 | else | ||
747 | return FALSE; | ||
748 | } /* heCanCut */ | ||
749 | |||
750 | /* | ||
751 | Checks out a move. | ||
752 | If my stone is not killable then true. | ||
753 | */ | ||
754 | short safeMove(x, y) | ||
755 | short x, y; | ||
756 | { /* safeMove */ | ||
757 | short gbx, gby, result; | ||
758 | tryPlay(x, y, 1); /* try playing at point */ | ||
759 | if (killFlag) /* I shouldn't kill if lookForKill didn't */ | ||
760 | result = FALSE; | ||
761 | else if (gList[groupIDs[x][y]].libC < 2) | ||
762 | { /* if it is in atari or dead */ | ||
763 | result = FALSE; /* reject it */ | ||
764 | } | ||
765 | else if (gList[groupIDs[x][y]].libC <= treeLibLim) /* see if killable */ | ||
766 | if (playLevel > 0) | ||
767 | result = ! killable(x, y, &gbx, &gby); | ||
768 | else | ||
769 | result = TRUE; | ||
770 | else | ||
771 | result = TRUE; | ||
772 | restoreState(); | ||
773 | return result; | ||
774 | } /* safeMove */ | ||
775 | |||
776 | /* | ||
777 | Extends walls in a connected fashion. | ||
778 | Finds the lowest influence (mine) point that is connected to one | ||
779 | of my groups. | ||
780 | Only looks in the center of the board. | ||
781 | */ | ||
782 | short extendWall(x, y) | ||
783 | short *x, *y; | ||
784 | { /* extendWall */ | ||
785 | short infl, i, j; | ||
786 | playReason = "extendWall"; | ||
787 | *x = iNil; | ||
788 | *y = iNil; | ||
789 | infl = 11; | ||
790 | for (i = 2; i <= maxPoint - 2; i++) | ||
791 | for (j = 2; j <= maxPoint - 2; j++) | ||
792 | if (legal[i][j]) | ||
793 | if (connectMap[i][j] > 0) | ||
794 | if ((claim[i][j] < infl) && | ||
795 | (ndbord[i - 1][j] < 1) && | ||
796 | (ndbord[i + 1][j] < 1) && | ||
797 | (ndbord[i][j - 1] < 1) && | ||
798 | (ndbord[i][j + 1] < 1) && | ||
799 | ((claim[i - 1][j] < 0) || | ||
800 | (claim[i + 1][j] < 0) || | ||
801 | (claim[i][j - 1] < 0) || | ||
802 | (claim[i][j + 1] < 0))) | ||
803 | if (safeMove(i, j)) | ||
804 | { | ||
805 | infl = claim[i][j]; | ||
806 | *x = i; | ||
807 | *y = j; | ||
808 | } | ||
809 | if (*x != iNil) return TRUE; | ||
810 | return FALSE; | ||
811 | } /* extendWall */ | ||
812 | |||
813 | |||
814 | /* | ||
815 | check to see if I can attack one of his groups | ||
816 | uses limited depth search so that it can work on larger lib counts | ||
817 | */ | ||
818 | short findAttack2(x, y) | ||
819 | short *x, *y; | ||
820 | { /* findAttack2 */ | ||
821 | short tx, ty, i, otll; | ||
822 | if (playLevel < 7) | ||
823 | return FALSE; | ||
824 | playReason = "findAttack2"; | ||
825 | depthLimit = 8; | ||
826 | otll = treeLibLim; | ||
827 | for (i = 1; i <= maxGroupID; i++) /* scan the group list */ | ||
828 | if ((! gList[i].isLive) && | ||
829 | (ndbord[gList[i].lx][gList[i].ly] == -1) && | ||
830 | (gList[i].libC > 1)) | ||
831 | { | ||
832 | treeLibLim = 6; | ||
833 | if (killable(gList[i].lx, gList[i].ly, &tx, &ty)) /* can we kill it? */ | ||
834 | { | ||
835 | *x = tx; /* yep - do so */ | ||
836 | *y = ty; | ||
837 | return TRUE; | ||
838 | } | ||
839 | treeLibLim = otll; | ||
840 | } | ||
841 | depthLimit = 100; | ||
842 | return FALSE; | ||
843 | } /* findAttack2 */ | ||
844 | |||
845 | |||
846 | /* | ||
847 | blocks enemy cuts thru 1-point extensions | ||
848 | */ | ||
849 | short blockCut(x, y) | ||
850 | short *x, *y; | ||
851 | { /* blockCut */ | ||
852 | short i, j; | ||
853 | playReason = "blockCut"; | ||
854 | for (i = 0; i <= maxPoint; i++) | ||
855 | for (j = 0; j <= maxPoint; j++) | ||
856 | if (legal[i][j]) | ||
857 | { | ||
858 | if ((i > 0) && (j > 0) && (j < maxPoint)) | ||
859 | { | ||
860 | if ((ndbord[i - 1][j] == -1) && | ||
861 | (ndbord[i - 1][j - 1] == 1) && | ||
862 | (ndbord[i - 1][j + 1] == 1) && | ||
863 | (groupIDs[i - 1][j - 1] != groupIDs[i - 1][j + 1])) | ||
864 | { | ||
865 | *x = i; | ||
866 | *y = j; | ||
867 | if (heCanCut(*x, *y)) | ||
868 | if (safeMove(*x, *y)) | ||
869 | return TRUE; | ||
870 | } | ||
871 | } | ||
872 | if ((i < maxPoint) && (j > 0) && (j < maxPoint)) | ||
873 | { | ||
874 | if ((ndbord[i + 1][j] == -1) && | ||
875 | (ndbord[i + 1][j - 1] == 1) && | ||
876 | (ndbord[i + 1][j + 1] == 1) && | ||
877 | (groupIDs[i + 1][j - 1] != groupIDs[i + 1][j + 1])) | ||
878 | { | ||
879 | *x = i; | ||
880 | *y = j; | ||
881 | if (heCanCut(*x, *y)) | ||
882 | if (safeMove(*x, *y)) | ||
883 | return TRUE; | ||
884 | } | ||
885 | } | ||
886 | if ((j > 0) && (i > 0) && (i < maxPoint)) | ||
887 | { | ||
888 | if ((ndbord[i][j - 1] == -1) && | ||
889 | (ndbord[i - 1][j - 1] == 1) && | ||
890 | (ndbord[i + 1][j - 1] == 1) && | ||
891 | (groupIDs[i - 1][j - 1] != groupIDs[i + 1][j - 1])) | ||
892 | { | ||
893 | *x = i; | ||
894 | *y = j; | ||
895 | if (heCanCut(*x, *y)) | ||
896 | if (safeMove(*x, *y)) | ||
897 | return TRUE; | ||
898 | } | ||
899 | } | ||
900 | if ((j < maxPoint) && (i > 0) && (i < maxPoint)) | ||
901 | { | ||
902 | if ((ndbord[i][j + 1] == -1) && | ||
903 | (ndbord[i - 1][j + 1] == 1) && | ||
904 | (ndbord[i + 1][j + 1] == 1) && | ||
905 | (groupIDs[i - 1][j + 1] != groupIDs[i + 1][j + 1])) | ||
906 | { | ||
907 | *x = i; | ||
908 | *y = j; | ||
909 | if (heCanCut(*x, *y)) | ||
910 | if (safeMove(*x, *y)) | ||
911 | return TRUE; | ||
912 | } | ||
913 | } | ||
914 | } | ||
915 | return FALSE; | ||
916 | } /* blockCut */ | ||
917 | |||
918 | |||
919 | /* | ||
920 | cuts the enemy | ||
921 | */ | ||
922 | short cutHim(x, y) | ||
923 | short *x, *y; | ||
924 | { /* cutHim */ | ||
925 | short i, j, nap, gid; | ||
926 | playReason = "cutHim"; | ||
927 | for (i = 0; i <= maxPoint; i++) | ||
928 | for (j = 0; j <= maxPoint; j++) | ||
929 | if (legal[i][j]) | ||
930 | { | ||
931 | nap = 0; /* how many of his stones am I adjacent to? */ | ||
932 | if ((i > 0) && (ndbord[i - 1][j] == -1)) | ||
933 | { | ||
934 | nap = nap + 1; | ||
935 | pList.p[nap].px = i - 1; | ||
936 | pList.p[nap].py = j; | ||
937 | } | ||
938 | if ((j > 0) && (ndbord[i][j - 1] == -1)) | ||
939 | { | ||
940 | nap = nap + 1; | ||
941 | pList.p[nap].px = i; | ||
942 | pList.p[nap].py = j - 1; | ||
943 | } | ||
944 | if ((i < maxPoint) && (ndbord[i + 1][j] == -1)) | ||
945 | { | ||
946 | nap = nap + 1; | ||
947 | pList.p[nap].px = i + 1; | ||
948 | pList.p[nap].py = j; | ||
949 | } | ||
950 | if ((j < maxPoint) && (ndbord[i][j + 1] == -1)) | ||
951 | { | ||
952 | nap = nap + 1; | ||
953 | pList.p[nap].px = i; | ||
954 | pList.p[nap].py = j + 1; | ||
955 | } | ||
956 | if (nap == 1) /* possible knight's or 2-point extention */ | ||
957 | { | ||
958 | gid = groupIDs[pList.p[1].px][pList.p[1].py]; | ||
959 | if ((i > 0) && (i < maxPoint) && | ||
960 | (ndbord[i - 1][j] == -1) && | ||
961 | (connectMap[i][j] > 0)) /* contact on left */ | ||
962 | { | ||
963 | if (((j > 0) && | ||
964 | (ndbord[i + 1][j - 1] == -1) && | ||
965 | (gid != groupIDs[i + 1][j - 1])) || | ||
966 | ((j < maxPoint) && | ||
967 | (ndbord[i + 1][j + 1] == -1) && | ||
968 | (gid != groupIDs[i + 1][j + 1])) || | ||
969 | ((i < (maxPoint - 1)) && | ||
970 | (ndbord[i + 1][j] == 0) && | ||
971 | (ndbord[i + 2][j] == -1) && | ||
972 | (gid != groupIDs[i + 2][j]))) | ||
973 | { | ||
974 | *x = i; | ||
975 | *y = j; | ||
976 | if (safeMove(*x, *y)) | ||
977 | return TRUE; | ||
978 | } | ||
979 | } | ||
980 | else if ((i < maxPoint) && (i > 0) && | ||
981 | (ndbord[i + 1][j] == -1) && | ||
982 | (connectMap[i][j] > 0)) /* r */ | ||
983 | { | ||
984 | if (((j > 0) && | ||
985 | (ndbord[i - 1][j - 1] == -1) && | ||
986 | (gid != groupIDs[i - 1][j - 1])) || | ||
987 | ((j < maxPoint) && | ||
988 | (ndbord[i - 1][j + 1] == -1) && | ||
989 | (gid != groupIDs[i - 1][j + 1])) || | ||
990 | ((i > 1) && | ||
991 | (ndbord[i - 1][j] == 0) && | ||
992 | (ndbord[i - 2][j] == -1) && | ||
993 | (gid != groupIDs[i - 2][j]))) | ||
994 | { | ||
995 | *x = i; | ||
996 | *y = j; | ||
997 | if (safeMove(*x, *y)) | ||
998 | return TRUE; | ||
999 | } | ||
1000 | } | ||
1001 | else if ((j > 0) && (j < maxPoint) && | ||
1002 | (ndbord[i][j - 1] == -1) && | ||
1003 | (connectMap[i][j] > 0)) /* top */ | ||
1004 | { | ||
1005 | if (((i > 0) && | ||
1006 | (ndbord[i - 1][j + 1] == -1) && | ||
1007 | (gid != groupIDs[i - 1][j + 1])) || | ||
1008 | ((i < maxPoint) && | ||
1009 | (ndbord[i + 1][j + 1] == -1) && | ||
1010 | (gid != groupIDs[i + 1][j + 1])) || | ||
1011 | ((j < (maxPoint - 1)) && | ||
1012 | (ndbord[i][j + 1] == 0) && | ||
1013 | (ndbord[i][j + 2] == -1) && | ||
1014 | (gid != groupIDs[i][j + 2]))) | ||
1015 | { | ||
1016 | *x = i; | ||
1017 | *y = j; | ||
1018 | if (safeMove(*x, *y)) | ||
1019 | return TRUE; | ||
1020 | } | ||
1021 | } | ||
1022 | else if ((j > 0) && (j < maxPoint) && | ||
1023 | (ndbord[i][j + 1] == -1) && | ||
1024 | (connectMap[i][j] > 0)) /* bottom */ | ||
1025 | { | ||
1026 | if (((i > 0) && | ||
1027 | (ndbord[i - 1][j - 1] == -1) && | ||
1028 | (gid != groupIDs[i - 1][j - 1])) || | ||
1029 | ((i < maxPoint) && | ||
1030 | (ndbord[i + 1][j - 1] == -1) && | ||
1031 | (gid != groupIDs[i + 1][j - 1])) || | ||
1032 | ((j > 1) && | ||
1033 | (ndbord[i][j - 1] == 0) && | ||
1034 | (ndbord[i][j - 2] == -1) && | ||
1035 | (gid != groupIDs[i][j - 2]))) | ||
1036 | { | ||
1037 | *x = i; | ||
1038 | *y = j; | ||
1039 | if (safeMove(*x, *y)) | ||
1040 | return TRUE; | ||
1041 | } | ||
1042 | } | ||
1043 | } | ||
1044 | else if (nap == 2) /* diagonal or 1-point extention */ | ||
1045 | { | ||
1046 | if (groupIDs[pList.p[1].px][pList.p[1].py] != | ||
1047 | groupIDs[pList.p[2].px][pList.p[2].py]) | ||
1048 | { | ||
1049 | if ((pList.p[1].px != pList.p[2].px) && | ||
1050 | (pList.p[1].py != pList.p[2].py)) /* diag */ | ||
1051 | { | ||
1052 | spanGroup(pList.p[1].px, | ||
1053 | pList.p[1].py, &pList1); | ||
1054 | spanGroup(pList.p[2].px, | ||
1055 | pList.p[2].py, &plist2); | ||
1056 | intersectPlist(&pList1, &plist2, &plist3); | ||
1057 | if (plist3.indx == 1) | ||
1058 | { | ||
1059 | *x = i; | ||
1060 | *y = j; | ||
1061 | if (safeMove(*x, *y)) | ||
1062 | return TRUE; | ||
1063 | } | ||
1064 | } | ||
1065 | else /* 1-point extension, only cut if connected */ | ||
1066 | { | ||
1067 | if (connectMap[i][j] > 0) | ||
1068 | { | ||
1069 | *x = i; | ||
1070 | *y = j; | ||
1071 | if (safeMove(*x, *y)) | ||
1072 | return TRUE; | ||
1073 | } | ||
1074 | } | ||
1075 | } | ||
1076 | } | ||
1077 | else if (nap == 3) /* unprotected, but him on 3 sides */ | ||
1078 | { | ||
1079 | if ((groupIDs[pList.p[1].px][pList.p[1].py] != | ||
1080 | groupIDs[pList.p[2].px][pList.p[2].py]) || | ||
1081 | (groupIDs[pList.p[1].px][pList.p[1].py] != | ||
1082 | groupIDs[pList.p[3].px][pList.p[3].py]) || | ||
1083 | (groupIDs[pList.p[3].px][pList.p[3].py] != | ||
1084 | groupIDs[pList.p[2].px][pList.p[2].py])) | ||
1085 | { | ||
1086 | spanGroup(pList.p[1].px, pList.p[1].py, &pList1); | ||
1087 | spanGroup(pList.p[2].px, pList.p[2].py, &plist2); | ||
1088 | intersectPlist(&pList1, &plist2, &plist3); | ||
1089 | spanGroup(pList.p[3].px, pList.p[3].py, &plist2); | ||
1090 | intersectPlist(&plist2, &plist3, &pList1); | ||
1091 | if (pList1.indx == 1) /* a common connect point */ | ||
1092 | if (safeMove(i, j)) | ||
1093 | { | ||
1094 | *x = i; | ||
1095 | *y = j; | ||
1096 | return TRUE; | ||
1097 | } | ||
1098 | } | ||
1099 | } | ||
1100 | } | ||
1101 | return FALSE; | ||
1102 | } /* cutHim */ | ||
1103 | |||
1104 | |||
1105 | /* | ||
1106 | ataris a group just for the hell of it | ||
1107 | */ | ||
1108 | short atariAnyway(x, y) | ||
1109 | short *x, *y; | ||
1110 | { /* atariAnyway */ | ||
1111 | short i; | ||
1112 | playReason = "atariAnyway"; | ||
1113 | for (i = 1; i <= maxGroupID; i++) /* scan the group list */ | ||
1114 | if ((gList[i].libC == 2) && | ||
1115 | (ndbord[gList[i].lx][gList[i].ly] == -1)) | ||
1116 | { | ||
1117 | spanGroup(gList[i].lx, gList[i].ly, &pList); | ||
1118 | if (legal[pList.p[1].px][pList.p[1].py] && | ||
1119 | ((connectMap[pList.p[1].px][pList.p[1].py] > 0) || | ||
1120 | ((pList.p[1].px > 0) && | ||
1121 | (connectMap[pList.p[1].px - 1][pList.p[1].py] > 0)) || | ||
1122 | ((pList.p[1].px < maxPoint) && | ||
1123 | (connectMap[pList.p[1].px + 1][pList.p[1].py] > 0)) || | ||
1124 | ((pList.p[1].py > 0) && | ||
1125 | (connectMap[pList.p[1].px][pList.p[1].py - 1] > 0)) || | ||
1126 | ((pList.p[1].py < maxPoint) && | ||
1127 | (connectMap[pList.p[1].px][pList.p[1].py + 1] > 0)))) | ||
1128 | if (safeMove(pList.p[1].px, pList.p[1].py)) | ||
1129 | { | ||
1130 | *x = pList.p[1].px; | ||
1131 | *y = pList.p[1].py; | ||
1132 | return TRUE; | ||
1133 | } | ||
1134 | if (legal[pList.p[2].px][pList.p[2].py] && | ||
1135 | ((connectMap[pList.p[2].px][pList.p[2].py] > 0) || | ||
1136 | ((pList.p[2].px > 0) && | ||
1137 | (connectMap[pList.p[2].px - 1][pList.p[2].py] > 0)) || | ||
1138 | ((pList.p[2].px < maxPoint) && | ||
1139 | (connectMap[pList.p[2].px + 1][pList.p[2].py] > 0)) || | ||
1140 | ((pList.p[2].py > 0) && | ||
1141 | (connectMap[pList.p[2].px][pList.p[2].py - 1] > 0)) || | ||
1142 | ((pList.p[2].py < maxPoint) && | ||
1143 | (connectMap[pList.p[2].px][pList.p[2].py + 1] > 0)))) | ||
1144 | if (safeMove(pList.p[2].px, pList.p[2].py)) | ||
1145 | { | ||
1146 | *x = pList.p[2].px; | ||
1147 | *y = pList.p[2].py; | ||
1148 | return TRUE; | ||
1149 | } | ||
1150 | } | ||
1151 | return FALSE; | ||
1152 | } /* atariAnyway */ | ||
1153 | |||
1154 | |||
1155 | /* | ||
1156 | undercuts his groups | ||
1157 | */ | ||
1158 | short underCut(x, y) | ||
1159 | short *x, *y; | ||
1160 | { /* underCut */ | ||
1161 | short i, j; | ||
1162 | playReason = "underCut"; | ||
1163 | for (i = 1; i <= maxPoint - 1; i++) | ||
1164 | { | ||
1165 | if (legal[0][i]) | ||
1166 | { | ||
1167 | if (ndbord[1][i] == -1) | ||
1168 | if (safeMove(0, i)) | ||
1169 | { | ||
1170 | *x = 0; | ||
1171 | *y = i; | ||
1172 | return TRUE; | ||
1173 | } | ||
1174 | } | ||
1175 | if (legal[maxPoint][i]) | ||
1176 | { | ||
1177 | if (ndbord[maxPoint - 1][i] == -1) | ||
1178 | if (safeMove(maxPoint, i)) | ||
1179 | { | ||
1180 | *x = maxPoint; | ||
1181 | *y = i; | ||
1182 | return TRUE; | ||
1183 | } | ||
1184 | } | ||
1185 | if (legal[i][0]) | ||
1186 | { | ||
1187 | if (ndbord[i][1] == -1) | ||
1188 | if (safeMove(i, 0)) | ||
1189 | { | ||
1190 | *x = i; | ||
1191 | *y = 0; | ||
1192 | return TRUE; | ||
1193 | } | ||
1194 | } | ||
1195 | if (legal[i][maxPoint]) | ||
1196 | { | ||
1197 | if (ndbord[i][maxPoint - 1] == -1) | ||
1198 | if (safeMove(i, maxPoint)) | ||
1199 | { | ||
1200 | *x = i; | ||
1201 | *y = maxPoint; | ||
1202 | return TRUE; | ||
1203 | } | ||
1204 | } | ||
1205 | } | ||
1206 | return FALSE; | ||
1207 | } /* underCut */ | ||
1208 | |||
1209 | /* | ||
1210 | drops to the edge of the board if threatened | ||
1211 | */ | ||
1212 | short dropToEdge(x, y) | ||
1213 | short *x, *y; | ||
1214 | { /* dropToEdge */ | ||
1215 | short i; | ||
1216 | playReason = "dropToEdge"; | ||
1217 | for (i = 1; i <= maxPoint - 1; i++) | ||
1218 | { | ||
1219 | if (legal[1][i]) | ||
1220 | if ((ndbord[2][i] == 1) && | ||
1221 | (ndbord[0][i] == 0) && | ||
1222 | (ndbord[1][i - 1] < 1) && | ||
1223 | (ndbord[1][i + 1] < 1) && | ||
1224 | ((ndbord[2][i - 1] == -1) || | ||
1225 | (ndbord[2][i + 1] == -1) || | ||
1226 | (ndbord[1][i - 1] == -1) || | ||
1227 | (ndbord[1][i + 1] == -1))) | ||
1228 | { | ||
1229 | *x = 1; | ||
1230 | *y = i; | ||
1231 | if (safeMove(*x, *y)) | ||
1232 | return TRUE; | ||
1233 | } | ||
1234 | if (legal[maxPoint - 1][i]) | ||
1235 | if ((ndbord[maxPoint - 2][i] == 1) && | ||
1236 | (ndbord[maxPoint][i] == 0) && | ||
1237 | (ndbord[maxPoint - 1][i - 1] < 1) && | ||
1238 | (ndbord[maxPoint - 1][i + 1] < 1) && | ||
1239 | ((ndbord[maxPoint - 2][i - 1] == -1) || | ||
1240 | (ndbord[maxPoint - 2][i + 1] == -1) || | ||
1241 | (ndbord[maxPoint - 1][i - 1] == -1) || | ||
1242 | (ndbord[maxPoint - 1][i + 1] == -1))) | ||
1243 | { | ||
1244 | *x = maxPoint - 1; | ||
1245 | *y = i; | ||
1246 | if (safeMove(*x, *y)) | ||
1247 | return TRUE; | ||
1248 | } | ||
1249 | if (legal[i][1]) | ||
1250 | if ((ndbord[i][2] == 1) && | ||
1251 | (ndbord[i][0] == 0) && | ||
1252 | (ndbord[i - 1][1] < 1) && | ||
1253 | (ndbord[i + 1][1] < 1) && | ||
1254 | ((ndbord[i - 1][2] == -1) || | ||
1255 | (ndbord[i + 1][2] == -1) || | ||
1256 | (ndbord[i - 1][1] == -1) || | ||
1257 | (ndbord[i + 1][1] == -1))) | ||
1258 | { | ||
1259 | *x = i; | ||
1260 | *y = 1; | ||
1261 | if (safeMove(*x, *y)) | ||
1262 | return TRUE; | ||
1263 | } | ||
1264 | if (legal[i][maxPoint - 1]) | ||
1265 | if ((ndbord[i][maxPoint - 2] == 1) && | ||
1266 | (ndbord[i][maxPoint] == 0) && | ||
1267 | (ndbord[i - 1][maxPoint - 1] < 1) && | ||
1268 | (ndbord[i + 1][maxPoint - 1] < 1) && | ||
1269 | ((ndbord[i - 1][maxPoint - 2] == -1) || | ||
1270 | (ndbord[i + 1][maxPoint - 2] == -1) || | ||
1271 | (ndbord[i - 1][maxPoint - 1] == -1) || | ||
1272 | (ndbord[i + 1][maxPoint - 1] == -1))) | ||
1273 | { | ||
1274 | *x = i; | ||
1275 | *y = maxPoint - 1; | ||
1276 | if (safeMove(*x, *y)) | ||
1277 | return TRUE; | ||
1278 | } | ||
1279 | if (legal[0][i]) | ||
1280 | if ((ndbord[1][i] == 1) && | ||
1281 | (ndbord[0][i - 1] < 1) && | ||
1282 | (ndbord[0][i + 1] < 1) && | ||
1283 | (((ndbord[1][i - 1] == -1) && | ||
1284 | (ndbord[1][i + 1] == -1)) || | ||
1285 | (ndbord[0][i - 1] == -1) || | ||
1286 | (ndbord[0][i + 1] == -1))) | ||
1287 | { | ||
1288 | *x = 0; | ||
1289 | *y = i; | ||
1290 | if (safeMove(*x, *y)) | ||
1291 | return TRUE; | ||
1292 | } | ||
1293 | if (legal[maxPoint][i]) | ||
1294 | if ((ndbord[maxPoint - 1][i] == 1) && | ||
1295 | (ndbord[maxPoint][i - 1] < 1) && | ||
1296 | (ndbord[maxPoint][i + 1] < 1) && | ||
1297 | (((ndbord[maxPoint - 1][i - 1] == -1) && | ||
1298 | (ndbord[maxPoint - 1][i + 1] == -1)) || | ||
1299 | (ndbord[maxPoint][i - 1] == -1) || | ||
1300 | (ndbord[maxPoint][i + 1] == -1))) | ||
1301 | { | ||
1302 | *x = maxPoint; | ||
1303 | *y = i; | ||
1304 | if (safeMove(*x, *y)) | ||
1305 | return TRUE; | ||
1306 | } | ||
1307 | if (legal[i][0]) | ||
1308 | if ((ndbord[i][1] == 1) && | ||
1309 | (ndbord[i - 1][0] < 1) && | ||
1310 | (ndbord[i + 1][0] < 1) && | ||
1311 | (((ndbord[i - 1][1] == -1) && | ||
1312 | (ndbord[i + 1][1] == -1)) || | ||
1313 | (ndbord[i - 1][0] == -1) || | ||
1314 | (ndbord[i + 1][0] == -1))) | ||
1315 | { | ||
1316 | *x = i; | ||
1317 | *y = 0; | ||
1318 | if (safeMove(*x, *y)) | ||
1319 | return TRUE; | ||
1320 | } | ||
1321 | if (legal[i][maxPoint]) | ||
1322 | if ((ndbord[i][maxPoint - 1] == 1) && | ||
1323 | (ndbord[i - 1][maxPoint] < 1) && | ||
1324 | (ndbord[i + 1][maxPoint] < 1) && | ||
1325 | (((ndbord[i - 1][maxPoint - 1] == -1) && | ||
1326 | (ndbord[i + 1][maxPoint - 1] == -1)) || | ||
1327 | (ndbord[i - 1][maxPoint] == -1) || | ||
1328 | (ndbord[i + 1][maxPoint] == -1))) | ||
1329 | { | ||
1330 | *x = i; | ||
1331 | *y = maxPoint; | ||
1332 | if (safeMove(*x, *y)) | ||
1333 | return TRUE; | ||
1334 | } | ||
1335 | } | ||
1336 | return FALSE; | ||
1337 | } /* dropToEdge */ | ||
1338 | |||
1339 | /* | ||
1340 | Pushes walls in a tightly connected fashion. | ||
1341 | Finds the lowest influence (mine) point that is connected to one | ||
1342 | of my groups. | ||
1343 | */ | ||
1344 | short pushWall(x, y) | ||
1345 | short *x, *y; | ||
1346 | { /* pushWall */ | ||
1347 | short infl, i, j, na; | ||
1348 | playReason = "pushWall"; | ||
1349 | *x = iNil; | ||
1350 | *y = iNil; | ||
1351 | infl = 11; | ||
1352 | for (i = 0; i <= maxPoint; i++) | ||
1353 | for (j = 0; j <= maxPoint; j++) | ||
1354 | if (legal[i][j]) | ||
1355 | if (connectMap[i][j] > 0) | ||
1356 | if ((claim[i][j] < infl) && | ||
1357 | (((i > 0) && (ndbord[i - 1][j] == 1)) || | ||
1358 | ((i < maxPoint) && (ndbord[i + 1][j] == 1)) || | ||
1359 | ((j > 0) && (ndbord[i][j - 1] == 1)) || | ||
1360 | ((j < maxPoint) && (ndbord[i][j + 1] == 1)) || | ||
1361 | ((i > 0) && (j > 0) && (ndbord[i - 1][j - 1] == 1)) || | ||
1362 | ((i < maxPoint) && (j > 0) && (ndbord[i + 1][j - 1] == 1)) || | ||
1363 | ((i > 0) && (j < maxPoint) && (ndbord[i - 1][j + 1] == 1)) || | ||
1364 | ((i < maxPoint) && (j < maxPoint) && | ||
1365 | (ndbord[i + 1][j + 1] == 1))) && | ||
1366 | (((i > 0) && (claim[i - 1][j] < 0)) || | ||
1367 | ((i < maxPoint) && (claim[i + 1][j] < 0)) || | ||
1368 | ((j > 0) && (claim[i][j - 1] < 0)) || | ||
1369 | ((j < maxPoint) && (claim[i][j + 1] < 0)))) | ||
1370 | { | ||
1371 | na = 0; | ||
1372 | if ((i > 0) && (ndbord[i - 1][j] != 0)) | ||
1373 | na = na + 1; | ||
1374 | if ((i < maxPoint) && (ndbord[i + 1][j] != 0)) | ||
1375 | na = na + 1; | ||
1376 | if ((j > 0) && (ndbord[i][j - 1] != 0)) | ||
1377 | na = na + 1; | ||
1378 | if ((j < maxPoint) && (ndbord[i][j + 1] != 0)) | ||
1379 | na = na + 1; | ||
1380 | if (na < 3) | ||
1381 | if (safeMove(i, j)) | ||
1382 | { | ||
1383 | infl = claim[i][j]; | ||
1384 | *x = i; | ||
1385 | *y = j; | ||
1386 | } | ||
1387 | } | ||
1388 | if (*x != iNil) return TRUE; | ||
1389 | return FALSE; | ||
1390 | } /* pushWall */ | ||
1391 | |||
1392 | |||
1393 | /* | ||
1394 | reduces the liberty count of one of his groups | ||
1395 | */ | ||
1396 | short reduceHisLiberties(x, y) | ||
1397 | short *x, *y; | ||
1398 | { /* reduceHisLiberties */ | ||
1399 | short i, j; | ||
1400 | playReason = "reduceHisLiberties"; | ||
1401 | sortLibs(); | ||
1402 | for (i = 1; i <= maxGroupID; i++) | ||
1403 | if ((! gList[sGlist[i]].isLive) && | ||
1404 | (gList[sGlist[i]].libC > 2) && | ||
1405 | (ndbord[gList[sGlist[i]].lx][gList[sGlist[i]].ly] == -1)) | ||
1406 | { | ||
1407 | spanGroup(gList[sGlist[i]].lx, gList[sGlist[i]].ly, &pList); | ||
1408 | for (j = 1; j <= pList.indx; j++) | ||
1409 | if (legal[pList.p[j].px][pList.p[j].py] && | ||
1410 | (connectMap[pList.p[j].px][pList.p[j].py] > 0)) | ||
1411 | if (safeMove(pList.p[j].px, pList.p[j].py)) | ||
1412 | { | ||
1413 | *x = pList.p[j].px; | ||
1414 | *y = pList.p[j].py; | ||
1415 | return TRUE; | ||
1416 | } | ||
1417 | } | ||
1418 | return FALSE; | ||
1419 | } /* reduceHisLiberties */ | ||
1420 | |||
1421 | |||
1422 | /* | ||
1423 | connects a group to the edge | ||
1424 | */ | ||
1425 | short dropToEdge2(x, y) | ||
1426 | short *x, *y; | ||
1427 | { /* dropToEdge2 */ | ||
1428 | short i; | ||
1429 | playReason = "dropToEdge2"; | ||
1430 | for (i = 1; i <= maxPoint - 1; i++) | ||
1431 | { | ||
1432 | if (legal[i][0]) | ||
1433 | { | ||
1434 | if ((ndbord[i][1] == 1) && | ||
1435 | ((ndbord[i - 1][0] < 1) || | ||
1436 | (groupIDs[i - 1][0] != groupIDs[i][1])) && | ||
1437 | ((ndbord[i + 1][0] < 1) || | ||
1438 | (groupIDs[i + 1][0] != groupIDs[i][1])) && | ||
1439 | ((ndbord[i - 1][1] == -1) || | ||
1440 | (ndbord[i + 1][1] == -1))) | ||
1441 | { | ||
1442 | *x = i; | ||
1443 | *y = 0; | ||
1444 | if (safeMove(*x, *y)) | ||
1445 | return TRUE; | ||
1446 | } | ||
1447 | } | ||
1448 | if (legal[0][i]) | ||
1449 | { | ||
1450 | if ((ndbord[1][i] == 1) && | ||
1451 | ((ndbord[0][i - 1] < 1) || | ||
1452 | (groupIDs[0][i - 1] != groupIDs[1][i])) && | ||
1453 | ((ndbord[0][i + 1] < 1) || | ||
1454 | (groupIDs[0][i + 1] != groupIDs[1][i])) && | ||
1455 | ((ndbord[1][i - 1] == -1) || | ||
1456 | (ndbord[1][i + 1] == -1))) | ||
1457 | { | ||
1458 | *x = 0; | ||
1459 | *y = i; | ||
1460 | if (safeMove(*x, *y)) | ||
1461 | return TRUE; | ||
1462 | } | ||
1463 | } | ||
1464 | if (legal[i][maxPoint]) | ||
1465 | { | ||
1466 | if ((ndbord[i][maxPoint - 1] == 1) && | ||
1467 | ((ndbord[i - 1][maxPoint] < 1) || | ||
1468 | (groupIDs[i - 1][maxPoint] != groupIDs[i][maxPoint - 1])) && | ||
1469 | ((ndbord[i + 1][maxPoint] < 1) || | ||
1470 | (groupIDs[i + 1][maxPoint] != groupIDs[i][maxPoint - 1])) && | ||
1471 | ((ndbord[i - 1][maxPoint - 1] == -1) || | ||
1472 | (ndbord[i + 1][maxPoint - 1] == -1))) | ||
1473 | { | ||
1474 | *x = i; | ||
1475 | *y = maxPoint; | ||
1476 | if (safeMove(*x, *y)) | ||
1477 | return TRUE; | ||
1478 | } | ||
1479 | } | ||
1480 | if (legal[maxPoint][i]) | ||
1481 | { | ||
1482 | if ((ndbord[maxPoint - 1][i] == 1) && | ||
1483 | ((ndbord[maxPoint][i - 1] < 1) || | ||
1484 | (groupIDs[maxPoint][i - 1] != groupIDs[maxPoint - 1][i])) && | ||
1485 | ((ndbord[maxPoint][i + 1] < 1) || | ||
1486 | (groupIDs[maxPoint][i + 1] != groupIDs[maxPoint - 1][i])) && | ||
1487 | ((ndbord[maxPoint - 1][i - 1] == -1) || | ||
1488 | (ndbord[maxPoint - 1][i + 1] == -1))) | ||
1489 | { | ||
1490 | *x = maxPoint; | ||
1491 | *y = i; | ||
1492 | if (safeMove(*x, *y)) | ||
1493 | return TRUE; | ||
1494 | } | ||
1495 | } | ||
1496 | } | ||
1497 | return FALSE; | ||
1498 | } /* dropToEdge2 */ | ||
1499 | |||
diff --git a/noncore/games/go/goplayutils.c b/noncore/games/go/goplayutils.c new file mode 100644 index 0000000..9e2ce4c --- a/dev/null +++ b/noncore/games/go/goplayutils.c | |||
@@ -0,0 +1,1317 @@ | |||
1 | /* The go player utilities */ | ||
2 | /* Ported from Pascal to C by Todd R. Johnson */ | ||
3 | /* From the original Pascal file: | ||
4 | Copyright (c) 1983 by Three Rivers Computer Corp. | ||
5 | |||
6 | Written: January 17, 1983 by Stoney Ballard | ||
7 | */ | ||
8 | |||
9 | #include "goplayutils.h" | ||
10 | #include "amigo.h" | ||
11 | #include "go.h" | ||
12 | |||
13 | extern struct bRec goboard[19][19]; | ||
14 | |||
15 | intBoard claim, extra, bord, ndbord, sGroups, threatBord, | ||
16 | groupIDs, connectMap, protPoints; | ||
17 | boolBoard groupSeen, legal; | ||
18 | short maxGroupID; | ||
19 | pointList pList, pList1, plist2, plist3, pPlist; | ||
20 | intList nlcGroup, aList; | ||
21 | sgRec sList[401]; | ||
22 | groupRec gList[maxGroup]; | ||
23 | short killFlag, | ||
24 | numCapt, | ||
25 | utilPlayLevel, | ||
26 | treeLibLim; | ||
27 | sType mySType; | ||
28 | short showTrees; | ||
29 | short sGlist[maxGroup+1]; | ||
30 | short depthLimit; | ||
31 | intBoard markBoard; | ||
32 | short marker; | ||
33 | |||
34 | short adjInAtari, adj2Libs, | ||
35 | intersectNum, spanNum, libMark; | ||
36 | playRec playStack[1025]; | ||
37 | short playMark, | ||
38 | newGID, | ||
39 | tryLevel, | ||
40 | grpMark, | ||
41 | gMap[maxGroup]; | ||
42 | short dbStop, inGenState; | ||
43 | |||
44 | pause() | ||
45 | { /* pause */ | ||
46 | /* if (dbStop and ! inGenState) | ||
47 | { | ||
48 | while ! tabswitch do; | ||
49 | repeat | ||
50 | if (tabYellow) | ||
51 | dbStop = false; | ||
52 | until ! tabswitch; | ||
53 | } */ | ||
54 | } /* pause */ | ||
55 | |||
56 | sstone(w, x, y, numb) | ||
57 | short w, x, y, numb; | ||
58 | { /* sstone */ | ||
59 | if (w == 1) | ||
60 | placestone(mySType, x, y); | ||
61 | else if (mySType == WHITE) | ||
62 | placestone(BLACK, x, y); | ||
63 | else | ||
64 | placestone(WHITE, x, y); | ||
65 | } /* sstone */ | ||
66 | |||
67 | rstone(x, y) | ||
68 | short x, y; | ||
69 | { /* rstone */ | ||
70 | removestone(x, y); | ||
71 | } /* rstone */ | ||
72 | |||
73 | initBoolBoard(bb) | ||
74 | boolBoard bb; | ||
75 | { /* initBoolBoard */ | ||
76 | short i, j; | ||
77 | #ifdef DEBUG | ||
78 | printf( "initBoolBoard\n" ); | ||
79 | #endif | ||
80 | for (i = 0; i <= maxPoint; i++) | ||
81 | for (j = 0; j <= maxPoint; j++) | ||
82 | bb[i][j] = FALSE; | ||
83 | } /* initBoolBoard */ | ||
84 | |||
85 | sortLibs() | ||
86 | { /* sortLibs */ | ||
87 | short i, j, t; | ||
88 | #ifdef DEBUG | ||
89 | printf( "sortLibs\n" ); | ||
90 | #endif | ||
91 | for (i = 1; i <= maxGroupID; i++) | ||
92 | sGlist[i] = i; | ||
93 | for (i = 1; i < maxGroupID; i++) | ||
94 | for (j = i + 1; j <= maxGroupID; j++) | ||
95 | if (gList[sGlist[i]].libC > gList[sGlist[j]].libC) | ||
96 | { | ||
97 | t = sGlist[i]; | ||
98 | sGlist[i] = sGlist[j]; | ||
99 | sGlist[j] = t; | ||
100 | } | ||
101 | } /* sortLibs */ | ||
102 | |||
103 | spanGroupspan(x, y, libs, lookFor) | ||
104 | short x, y, lookFor; | ||
105 | pointList *libs; | ||
106 | { /* span */ | ||
107 | markBoard[x][y] = marker; | ||
108 | if (bord[x][y] == 0) | ||
109 | { | ||
110 | libs->indx = libs->indx + 1; | ||
111 | libs->p[libs->indx].px = x; | ||
112 | libs->p[libs->indx].py = y; | ||
113 | } | ||
114 | else if (bord[x][y] == lookFor) | ||
115 | { | ||
116 | groupSeen[x][y] = TRUE; | ||
117 | if ((x > 0) && (markBoard[x - 1][y] != marker)) | ||
118 | spanGroupspan(x - 1, y, libs, lookFor); | ||
119 | if ((y > 0) && (markBoard[x][y - 1] != marker)) | ||
120 | spanGroupspan(x, y - 1, libs, lookFor); | ||
121 | if ((x < maxPoint) && (markBoard[x + 1][y] != marker)) | ||
122 | spanGroupspan(x + 1, y, libs, lookFor); | ||
123 | if ((y < maxPoint) && (markBoard[x][y + 1] != marker)) | ||
124 | spanGroupspan(x, y + 1, libs, lookFor); | ||
125 | } | ||
126 | else if (gList[gMap[groupIDs[x][y]]].libC == 1) | ||
127 | adjInAtari = TRUE; | ||
128 | else if ((gList[gMap[groupIDs[x][y]]].libC == 2) && | ||
129 | (! gList[gMap[groupIDs[x][y]]].isLive)) | ||
130 | adj2Libs = TRUE; | ||
131 | } /* span */ | ||
132 | |||
133 | spanGroup(x, y, libs) | ||
134 | short x, y; | ||
135 | pointList *libs; | ||
136 | { /* spanGroup */ | ||
137 | short lookFor; | ||
138 | #ifdef DEBUG | ||
139 | printf( "spanGroup\n" ); | ||
140 | #endif | ||
141 | marker = marker + 1; | ||
142 | if (marker == 0) | ||
143 | { | ||
144 | initArray(markBoard); | ||
145 | marker = 1; | ||
146 | } | ||
147 | adjInAtari = FALSE; | ||
148 | adj2Libs = FALSE; | ||
149 | lookFor = bord[x][y]; | ||
150 | libs->indx = 0; | ||
151 | spanGroupspan(x, y, libs, lookFor); | ||
152 | } /* spanGroup */ | ||
153 | |||
154 | sSpanGroupspan(x, y, libs, lookFor) | ||
155 | short x, y, lookFor; | ||
156 | sPointList *libs; | ||
157 | { /* span */ | ||
158 | markBoard[x][y] = marker; | ||
159 | if (bord[x][y] == 0) | ||
160 | { | ||
161 | libs->indx += 1; | ||
162 | if (libs->indx <= maxSPoint) | ||
163 | { | ||
164 | libs->p[libs->indx].px = x; | ||
165 | libs->p[libs->indx].py = y; | ||
166 | } | ||
167 | } | ||
168 | else if (bord[x][y] == lookFor) | ||
169 | { | ||
170 | groupSeen[x][y] = TRUE; | ||
171 | if ((x > 0) && (markBoard[x - 1][y] != marker)) | ||
172 | sSpanGroupspan(x - 1, y, libs, lookFor); | ||
173 | if ((y > 0) && (markBoard[x][y - 1] != marker)) | ||
174 | sSpanGroupspan(x, y - 1, libs, lookFor); | ||
175 | if ((x < maxPoint) && (markBoard[x + 1][y] != marker)) | ||
176 | sSpanGroupspan(x + 1, y, libs, lookFor); | ||
177 | if ((y < maxPoint) && (markBoard[x][y + 1] != marker)) | ||
178 | sSpanGroupspan(x, y + 1, libs, lookFor); | ||
179 | } | ||
180 | else if (gList[gMap[groupIDs[x][y]]].libC == 1) | ||
181 | adjInAtari = TRUE; | ||
182 | else if ((gList[gMap[groupIDs[x][y]]].libC == 2) && | ||
183 | (! gList[gMap[groupIDs[x][y]]].isLive)) | ||
184 | adj2Libs = TRUE; | ||
185 | } /* span */ | ||
186 | |||
187 | sSpanGroup(x, y, libs) | ||
188 | short x, y; | ||
189 | sPointList *libs; | ||
190 | { /* sSpanGroup */ | ||
191 | short lookFor; | ||
192 | #ifdef DEBUG | ||
193 | printf( "sSpanGroup\n" ); | ||
194 | #endif | ||
195 | marker = marker + 1; | ||
196 | if (marker == 0) | ||
197 | { | ||
198 | initArray(markBoard); | ||
199 | marker = 1; | ||
200 | } | ||
201 | adjInAtari = FALSE; | ||
202 | adj2Libs = FALSE; | ||
203 | lookFor = bord[x][y]; | ||
204 | libs->indx = 0; | ||
205 | sSpanGroupspan(x, y, libs, lookFor); | ||
206 | } /* sSpanGroup */ | ||
207 | |||
208 | LAspan(x, y, me, him, iL) | ||
209 | short x, y, me, him; | ||
210 | intList *iL; | ||
211 | { /* span */ | ||
212 | #ifdef DEBUG | ||
213 | printf( "LAspan\n" ); | ||
214 | #endif | ||
215 | markBoard[x][y] = marker; | ||
216 | if (bord[x][y] == me) | ||
217 | { | ||
218 | if ((x > 0) && (markBoard[x - 1][y] != marker)) | ||
219 | LAspan(x - 1, y, me, him, iL); | ||
220 | if ((x < maxPoint) && (markBoard[x + 1][y] != marker)) | ||
221 | LAspan(x + 1, y, me, him, iL); | ||
222 | if ((y > 0) && (markBoard[x][y - 1] != marker)) | ||
223 | LAspan(x, y - 1, me, him, iL); | ||
224 | if ((y < maxPoint) && (markBoard[x][y + 1] != marker)) | ||
225 | LAspan(x, y + 1, me, him, iL); | ||
226 | } | ||
227 | else if (bord[x][y] == him) | ||
228 | if (gList[gMap[groupIDs[x][y]]].groupMark != grpMark) | ||
229 | { | ||
230 | gList[gMap[groupIDs[x][y]]].groupMark = grpMark; | ||
231 | iL->indx = iL->indx + 1; | ||
232 | iL->v[iL->indx] = gMap[groupIDs[x][y]]; | ||
233 | } | ||
234 | } /* span */ | ||
235 | |||
236 | listAdjacents(x, y, iL) | ||
237 | short x, y; | ||
238 | intList *iL; | ||
239 | { /* listAdjacents */ | ||
240 | short me, him; | ||
241 | #ifdef DEBUG | ||
242 | printf( "listAdjacents\n" ); | ||
243 | #endif | ||
244 | grpMark = grpMark + 1; | ||
245 | marker = marker + 1; | ||
246 | if (marker == 0) | ||
247 | { | ||
248 | initArray(markBoard); | ||
249 | marker = 1; | ||
250 | } | ||
251 | iL->indx = 0; | ||
252 | me = bord[x][y]; | ||
253 | him = -me; | ||
254 | LAspan(x, y, me , him, iL); | ||
255 | } /* listAdjacents */ | ||
256 | |||
257 | LDspan(x, y, me, diags) | ||
258 | short x, y, me; | ||
259 | sPointList *diags; | ||
260 | { /* span */ | ||
261 | #ifdef DEBUG | ||
262 | printf( "LDspan\n" ); | ||
263 | #endif | ||
264 | markBoard[x][y] = marker; | ||
265 | if ((x > 0) && (y > 0) && | ||
266 | (bord[x - 1][y - 1] == 0) && | ||
267 | (bord[x][y - 1] != me) && | ||
268 | (bord[x - 1][y] != me) && | ||
269 | (markBoard[x - 1][y - 1] != marker)) | ||
270 | { | ||
271 | markBoard[x - 1][y - 1] = marker; | ||
272 | diags->indx = diags->indx + 1; | ||
273 | if (diags->indx <= maxSPoint) | ||
274 | { | ||
275 | diags->p[diags->indx].px = x - 1; | ||
276 | diags->p[diags->indx].py = y - 1; | ||
277 | } | ||
278 | } | ||
279 | if ((x < maxPoint) && (y > 0) && | ||
280 | (bord[x + 1][y - 1] == 0) && | ||
281 | (bord[x][y - 1] != me) && | ||
282 | (bord[x + 1][y] != me) && | ||
283 | (markBoard[x + 1][y - 1] != marker)) | ||
284 | { | ||
285 | markBoard[x + 1][y - 1] = marker; | ||
286 | diags->indx = diags->indx + 1; | ||
287 | if (diags->indx <= maxSPoint) | ||
288 | { | ||
289 | diags->p[diags->indx].px = x + 1; | ||
290 | diags->p[diags->indx].py = y - 1; | ||
291 | } | ||
292 | } | ||
293 | if ((x > 0) && (y < maxPoint) && | ||
294 | (bord[x - 1][y + 1] == 0) && | ||
295 | (bord[x][y + 1] != me) && | ||
296 | (bord[x - 1][y] != me) && | ||
297 | (markBoard[x - 1][y + 1] != marker)) | ||
298 | { | ||
299 | markBoard[x - 1][y + 1] = marker; | ||
300 | diags->indx = diags->indx + 1; | ||
301 | if (diags->indx <= maxSPoint) | ||
302 | { | ||
303 | diags->p[diags->indx].px = x - 1; | ||
304 | diags->p[diags->indx].py = y + 1; | ||
305 | } | ||
306 | } | ||
307 | if ((x < maxPoint) && (y < maxPoint) && | ||
308 | (bord[x + 1][y + 1] == 0) && | ||
309 | (bord[x][y + 1] != me) && | ||
310 | (bord[x + 1][y] != me) && | ||
311 | (markBoard[x + 1][y + 1] != marker)) | ||
312 | { | ||
313 | markBoard[x + 1][y + 1] = marker; | ||
314 | diags->indx = diags->indx + 1; | ||
315 | if (diags->indx <= maxSPoint) | ||
316 | { | ||
317 | diags->p[diags->indx].px = x + 1; | ||
318 | diags->p[diags->indx].py = y + 1; | ||
319 | } | ||
320 | } | ||
321 | if ((x > 0) && (bord[x - 1][y] == me) && | ||
322 | (markBoard[x - 1][y] != marker)) | ||
323 | LDspan(x - 1, y, me, diags); | ||
324 | if ((x < maxPoint) && (bord[x + 1][y] == me) && | ||
325 | (markBoard[x + 1][y] != marker)) | ||
326 | LDspan(x + 1, y, me, diags); | ||
327 | if ((y > 0) && (bord[x][y - 1] == me) && | ||
328 | (markBoard[x][y - 1] != marker)) | ||
329 | LDspan(x, y - 1, me, diags); | ||
330 | if ((y < maxPoint) && (bord[x][y + 1] == me) && | ||
331 | (markBoard[x][y + 1] != marker)) | ||
332 | LDspan(x, y + 1, me , diags); | ||
333 | } /* span */ | ||
334 | |||
335 | listDiags(x, y, diags) | ||
336 | short x, y; | ||
337 | sPointList *diags; | ||
338 | { /* listDiags */ | ||
339 | short me; | ||
340 | #ifdef DEBUG | ||
341 | printf( "listDiags\n" ); | ||
342 | #endif | ||
343 | me = bord[x][y]; | ||
344 | diags->indx = 0; | ||
345 | marker = marker + 1; | ||
346 | if (marker == 0) | ||
347 | { | ||
348 | initArray(markBoard); | ||
349 | marker = 1; | ||
350 | } | ||
351 | LDspan(x, y, me, diags); | ||
352 | } /* listDiags */ | ||
353 | |||
354 | intersectPlist(p1, p2, pr) | ||
355 | pointList *p1, *p2, *pr; | ||
356 | { /* intersectPlist */ | ||
357 | short i, j, k; | ||
358 | #ifdef DEBUG | ||
359 | printf( "intersectPlist\n" ); | ||
360 | #endif | ||
361 | marker = marker + 1; | ||
362 | if (marker == 0) | ||
363 | { | ||
364 | initArray(markBoard); | ||
365 | marker = 1; | ||
366 | } | ||
367 | pr->indx = 0; | ||
368 | for (i = 1; i <= p1->indx; i++) | ||
369 | markBoard[p1->p[i].px][p1->p[i].py] = marker; | ||
370 | j = 0; | ||
371 | for (i = 1; i <= p2->indx; i++) | ||
372 | if (markBoard[p2->p[i].px][p2->p[i].py] == marker) | ||
373 | { | ||
374 | j = j + 1; | ||
375 | pr->p[j] = p2->p[i]; | ||
376 | } | ||
377 | pr->indx = j; | ||
378 | } /* intersectPlist */ | ||
379 | |||
380 | initArray(ary) | ||
381 | intBoard ary; | ||
382 | { /* initArray */ | ||
383 | short i, j; | ||
384 | for (i = 0; i <= maxPoint; i++) | ||
385 | for (j = 0; j <= maxPoint; j++) | ||
386 | ary[i][j] = 0; | ||
387 | } /* initArray */ | ||
388 | |||
389 | initState() | ||
390 | { /* initState */ | ||
391 | short i, j; | ||
392 | for (i = 0; i <= maxPoint; i++) | ||
393 | for (j = 0; j <= maxPoint; j++) | ||
394 | { | ||
395 | extra[i][j] = 0; | ||
396 | claim[i][j] = 0; | ||
397 | groupIDs[i][j] = 0; | ||
398 | connectMap[i][j] = 0; | ||
399 | protPoints[i][j] = 0; | ||
400 | } | ||
401 | } /* initState */ | ||
402 | |||
403 | copyArray( dest, src ) | ||
404 | intBoard dest, src; | ||
405 | { | ||
406 | short x, y; | ||
407 | for (y = 0; y <= maxPoint; y++) | ||
408 | for (x = 0; x <= maxPoint; x++) | ||
409 | dest[x][y] = src[x][y]; | ||
410 | } | ||
411 | |||
412 | /* | ||
413 | generates a one-point spread in the force field array (claim) | ||
414 | |||
415 | the spread from a single point after four calls is: | ||
416 | |||
417 | 1 | ||
418 | 2 2 2 | ||
419 | 2 4 6 4 2 | ||
420 | 2 4 8 10 8 4 2 | ||
421 | 1 2 6 10 62 10 6 2 1 | ||
422 | 2 4 8 10 8 4 2 | ||
423 | 2 4 6 4 2 | ||
424 | 2 2 2 | ||
425 | 1 | ||
426 | |||
427 | */ | ||
428 | stake() | ||
429 | { | ||
430 | short x, y; | ||
431 | initArray( extra ); | ||
432 | for (y = 0; y <= maxPoint; y++) | ||
433 | for (x = 0; x <= maxPoint; x++) | ||
434 | { | ||
435 | extra[x][y] = extra[x][y] + claim[x][y]; | ||
436 | if (claim[x][y] > 0) | ||
437 | { | ||
438 | if (x > 0) extra[x-1][y] += 1; | ||
439 | if (y > 0) extra[x][y-1] += 1; | ||
440 | if (x < maxPoint) extra[x+1][y] += 1; | ||
441 | if (y < maxPoint) extra[x][y+1] += 1; | ||
442 | } | ||
443 | else if (claim[x][y] < 0) | ||
444 | { | ||
445 | if (x > 0) extra[x-1][y] -= 1; | ||
446 | if (y > 0) extra[x][y-1] -= 1; | ||
447 | if (x < maxPoint) extra[x+1][y] -= 1; | ||
448 | if (y < maxPoint) extra[x][y+1] -= 1; | ||
449 | } | ||
450 | } | ||
451 | copyArray( claim, extra ); | ||
452 | } /* stake */ | ||
453 | |||
454 | /* | ||
455 | sets up claim from the current board position | ||
456 | */ | ||
457 | spread() | ||
458 | { | ||
459 | short x, y; | ||
460 | for (y = 0; y <= maxPoint; y++) | ||
461 | for (x = 0; x <= maxPoint; x++) | ||
462 | claim[x][y] = ndbord[x][y] * 50; | ||
463 | stake(); | ||
464 | stake(); | ||
465 | stake(); | ||
466 | stake(); | ||
467 | } /* spread */ | ||
468 | |||
469 | /* | ||
470 | gList is initialized with the size, loc, and libCount of each group | ||
471 | groupIDs contains the serial numbers of the groups. | ||
472 | */ | ||
473 | Resspan(x, y, gID, gSize, libCount, who) | ||
474 | short x, y, gID, *gSize, *libCount, who; | ||
475 | { /* span */ | ||
476 | if ((bord[x][y] == 0) && | ||
477 | (markBoard[x][y] != marker)) /* a liberty */ | ||
478 | { | ||
479 | markBoard[x][y] = marker; | ||
480 | *libCount = *libCount + 1; | ||
481 | } | ||
482 | else if ((bord[x][y] == who) && | ||
483 | (groupIDs[x][y] == 0)) | ||
484 | { | ||
485 | groupIDs[x][y] = gID; | ||
486 | *gSize = *gSize + 1; | ||
487 | if (x > 0) | ||
488 | Resspan(x - 1, y, gID, gSize, libCount, who); | ||
489 | if (x < maxPoint) | ||
490 | Resspan(x + 1, y, gID, gSize, libCount, who); | ||
491 | if (y > 0) | ||
492 | Resspan(x, y - 1, gID, gSize, libCount, who); | ||
493 | if (y < maxPoint) | ||
494 | Resspan(x, y + 1, gID, gSize, libCount, who); | ||
495 | } | ||
496 | } /* span */ | ||
497 | |||
498 | respreicen() | ||
499 | { /* respreicen */ | ||
500 | short i, j, gID, libCount, gSize, who; | ||
501 | gID = 0; | ||
502 | #ifdef DEBUG | ||
503 | printf( "respreicen\n" ); | ||
504 | #endif | ||
505 | for (i = 0; i <= maxPoint; i++) | ||
506 | for (j = 0; j <= maxPoint; j++) | ||
507 | groupIDs[i][j] = 0; | ||
508 | for (i = 0; i <= maxPoint; i++) | ||
509 | for (j = 0; j <= maxPoint; j++) | ||
510 | if ((bord[i][j] != 0) && /* a stone there */ | ||
511 | (groupIDs[i][j] == 0)) /* not seen yet */ | ||
512 | { | ||
513 | marker = marker + 1; | ||
514 | if (marker == 0) | ||
515 | { | ||
516 | initArray(markBoard); | ||
517 | marker = 1; | ||
518 | } | ||
519 | gID = gID + 1; | ||
520 | libCount = 0; | ||
521 | gSize = 0; | ||
522 | who = bord[i][j]; | ||
523 | Resspan(i, j, gID, &gSize, &libCount, who); /* span the group, collecting info */ | ||
524 | gList[gID].groupMark = 0; | ||
525 | gList[gID].atLevel = 0; | ||
526 | gList[gID].isLive = FALSE; /* we don't know yet */ | ||
527 | gList[gID].isDead = FALSE; | ||
528 | gList[gID].numEyes = -1; | ||
529 | gList[gID].size = gSize; | ||
530 | gList[gID].libC = libCount; | ||
531 | gList[gID].lx = i; | ||
532 | gList[gID].ly = j; | ||
533 | gMap[gID] = gID; /* set up identity map */ | ||
534 | } | ||
535 | maxGroupID = gID; | ||
536 | newGID = gID; | ||
537 | grpMark = 0; | ||
538 | } /* respreicen */ | ||
539 | |||
540 | /* | ||
541 | play z at [x, y]. | ||
542 | killFlag is set true if anything is killed. | ||
543 | */ | ||
544 | killGroup(x, y, me, him) | ||
545 | short x, y, me, him; | ||
546 | { /* killGroup */ | ||
547 | #ifdef DEBUG | ||
548 | printf( "killGroup\n" ); | ||
549 | #endif | ||
550 | playMark = playMark + 1; | ||
551 | /* record this kill */ | ||
552 | playStack[playMark].kind = rem; | ||
553 | playStack[playMark].uval.rem.who = him; | ||
554 | playStack[playMark].uval.rem.xl = x; | ||
555 | playStack[playMark].uval.rem.yl = y; | ||
556 | playStack[playMark].gID = groupIDs[x][y]; | ||
557 | playStack[playMark].uval.rem.sNumber = goboard[x][y].mNum; | ||
558 | if (showTrees) | ||
559 | rstone(x, y); | ||
560 | numCapt = numCapt + 1; | ||
561 | bord[x][y] = 0; | ||
562 | groupIDs[x][y] = 0; | ||
563 | if (x > 0) | ||
564 | { | ||
565 | if (bord[x - 1][y] == me) | ||
566 | { | ||
567 | nlcGroup.indx = nlcGroup.indx + 1; | ||
568 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]]; | ||
569 | } | ||
570 | else if (bord[x - 1][y] == him) | ||
571 | killGroup(x - 1, y, me , him); | ||
572 | } | ||
573 | if (x < maxPoint) | ||
574 | { | ||
575 | if (bord[x + 1][y] == me) | ||
576 | { | ||
577 | nlcGroup.indx = nlcGroup.indx + 1; | ||
578 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]]; | ||
579 | } | ||
580 | else if (bord[x + 1][y] == him) | ||
581 | killGroup(x + 1, y, me, him); | ||
582 | } | ||
583 | if (y > 0) | ||
584 | { | ||
585 | if (bord[x][y - 1] == me) | ||
586 | { | ||
587 | nlcGroup.indx = nlcGroup.indx + 1; | ||
588 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]]; | ||
589 | } | ||
590 | else if (bord[x][y - 1] == him) | ||
591 | killGroup(x, y - 1, me, him); | ||
592 | } | ||
593 | if (y < maxPoint) | ||
594 | { | ||
595 | if (bord[x][y + 1] == me) | ||
596 | { | ||
597 | nlcGroup.indx = nlcGroup.indx + 1; | ||
598 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]]; | ||
599 | } | ||
600 | else if (bord[x][y + 1] == him) | ||
601 | killGroup(x, y + 1, me, him); | ||
602 | } | ||
603 | } /* killGroup */ | ||
604 | |||
605 | mergeGroup(sGID, myGID) | ||
606 | short sGID, myGID; | ||
607 | { /* mergeGroup */ | ||
608 | short i; | ||
609 | #ifdef DEBUG | ||
610 | printf( "mergeGroup\n" ); | ||
611 | #endif | ||
612 | for (i = 1; i <= newGID; i++) | ||
613 | if (gMap[i] == sGID) | ||
614 | { | ||
615 | playMark = playMark + 1; | ||
616 | playStack[playMark].kind = reMap; | ||
617 | playStack[playMark].gID = i; | ||
618 | playStack[playMark].uval.reMap.oldGID = sGID; | ||
619 | gMap[i] = myGID; | ||
620 | } | ||
621 | } /* mergeGroup */ | ||
622 | |||
623 | tryPlay(x, y, z) | ||
624 | short x, y, z; | ||
625 | { /* plei */ | ||
626 | short i, me, him, myGID; | ||
627 | short isNew; | ||
628 | #ifdef DEBUG | ||
629 | printf( "tryPlay\n" ); | ||
630 | #endif | ||
631 | me = z; | ||
632 | him = -me; | ||
633 | killFlag = FALSE; /* set true if something is killed */ | ||
634 | numCapt = 0; | ||
635 | tryLevel = tryLevel + 1; | ||
636 | isNew = FALSE; | ||
637 | bord[x][y] = z; /* play the stone */ | ||
638 | if ((x > 0) && (bord[x - 1][y] == me)) /* connect to adjacent group */ | ||
639 | myGID = gMap[groupIDs[x - 1][y]]; | ||
640 | else if ((x < maxPoint) && (bord[x + 1][y] == me)) | ||
641 | myGID = gMap[groupIDs[x + 1][y]]; | ||
642 | else if ((y > 0) && (bord[x][y - 1] == me)) | ||
643 | myGID = gMap[groupIDs[x][y - 1]]; | ||
644 | else if ((y < maxPoint) && (bord[x][y + 1] == me)) | ||
645 | myGID = gMap[groupIDs[x][y + 1]]; | ||
646 | else /* nobody to connect to */ | ||
647 | { | ||
648 | newGID = newGID + 1; | ||
649 | isNew = TRUE; | ||
650 | myGID = newGID; | ||
651 | gList[myGID].groupMark = 0; | ||
652 | gList[myGID].atLevel = tryLevel; | ||
653 | gList[myGID].isLive = FALSE; | ||
654 | gList[myGID].numEyes = -1; | ||
655 | gList[myGID].size = -1; | ||
656 | gList[myGID].lx = x; | ||
657 | gList[myGID].ly = y; | ||
658 | gMap[myGID] = myGID; | ||
659 | } | ||
660 | groupIDs[x][y] = myGID; | ||
661 | playMark = playMark + 1; | ||
662 | /* record this move */ | ||
663 | playStack[playMark].kind = add; | ||
664 | playStack[playMark].uval.add.who = me; | ||
665 | playStack[playMark].uval.add.xl = x; | ||
666 | playStack[playMark].uval.add.yl = y; | ||
667 | playStack[playMark].gID = myGID; | ||
668 | playStack[playMark].uval.add.sNumber = 0; | ||
669 | if (isNew) | ||
670 | playStack[playMark].uval.add.nextGID = newGID - 1; | ||
671 | else | ||
672 | playStack[playMark].uval.add.nextGID = newGID; | ||
673 | if (showTrees) | ||
674 | sstone(me, x, y, 0); | ||
675 | /* merge adjacent groups */ | ||
676 | if ((x > 0) && (bord[x - 1][y] == me) && | ||
677 | (gMap[groupIDs[x - 1][y]] != myGID)) | ||
678 | mergeGroup(gMap[groupIDs[x - 1][y]], myGID); | ||
679 | if ((x < maxPoint) && (bord[x + 1][y] == me) && | ||
680 | (gMap[groupIDs[x + 1][y]] != myGID)) | ||
681 | mergeGroup(gMap[groupIDs[x + 1][y]], myGID); | ||
682 | if ((y > 0) && (bord[x][y - 1] == me) && | ||
683 | (gMap[groupIDs[x][y - 1]] != myGID)) | ||
684 | mergeGroup(gMap[groupIDs[x][y - 1]], myGID); | ||
685 | if ((y < maxPoint) && (bord[x][y + 1] == me) && | ||
686 | (gMap[groupIDs[x][y + 1]] != myGID)) | ||
687 | mergeGroup(gMap[groupIDs[x][y + 1]], myGID); | ||
688 | /* kill opposing groups, listing affected groups */ | ||
689 | nlcGroup.indx = 1; | ||
690 | nlcGroup.v[1] = myGID; /* init list to include me */ | ||
691 | if ((x > 0) && (bord[x - 1][y] == him) && | ||
692 | (gList[gMap[groupIDs[x - 1][y]]].libC == 1)) | ||
693 | { | ||
694 | killFlag = TRUE; | ||
695 | killGroup(x - 1, y, me, him); | ||
696 | } | ||
697 | if ((x < maxPoint) && (bord[x + 1][y] == him) && | ||
698 | (gList[gMap[groupIDs[x + 1][y]]].libC == 1)) | ||
699 | { | ||
700 | killFlag = TRUE; | ||
701 | killGroup(x + 1, y, me, him); | ||
702 | } | ||
703 | if ((y > 0) && (bord[x][y - 1] == him) && | ||
704 | (gList[gMap[groupIDs[x][y - 1]]].libC == 1)) | ||
705 | { | ||
706 | killFlag = TRUE; | ||
707 | killGroup(x, y - 1, me, him); | ||
708 | } | ||
709 | if ((y < maxPoint) && (bord[x][y + 1] == him) && | ||
710 | (gList[gMap[groupIDs[x][y + 1]]].libC == 1)) | ||
711 | { | ||
712 | killFlag = TRUE; | ||
713 | killGroup(x, y + 1, me, him); | ||
714 | } | ||
715 | /* list groups adjacent to me */ | ||
716 | if ((x > 0) && (bord[x - 1][y] == him)) | ||
717 | { | ||
718 | nlcGroup.indx = nlcGroup.indx + 1; | ||
719 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]]; | ||
720 | } | ||
721 | if ((x < maxPoint) && (bord[x + 1][y] == him)) | ||
722 | { | ||
723 | nlcGroup.indx = nlcGroup.indx + 1; | ||
724 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]]; | ||
725 | } | ||
726 | if ((y > 0) && (bord[x][y - 1] == him)) | ||
727 | { | ||
728 | nlcGroup.indx = nlcGroup.indx + 1; | ||
729 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]]; | ||
730 | } | ||
731 | if ((y < maxPoint) && (bord[x][y + 1] == him)) | ||
732 | { | ||
733 | nlcGroup.indx = nlcGroup.indx + 1; | ||
734 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]]; | ||
735 | } | ||
736 | /* fix liberty count for affected groups */ | ||
737 | grpMark = grpMark + 1; | ||
738 | for (i = 1; i <= nlcGroup.indx; i++) | ||
739 | if (gList[nlcGroup.v[i]].groupMark != grpMark) | ||
740 | { | ||
741 | if (gList[nlcGroup.v[i]].atLevel != tryLevel) | ||
742 | { | ||
743 | playMark = playMark + 1; | ||
744 | playStack[playMark].kind = chLib; | ||
745 | playStack[playMark].gID = nlcGroup.v[i]; | ||
746 | playStack[playMark].uval.chLib.oldLevel = | ||
747 | gList[nlcGroup.v[i]].atLevel; | ||
748 | playStack[playMark].uval.chLib.oldLC = | ||
749 | gList[nlcGroup.v[i]].libC; | ||
750 | } | ||
751 | gList[nlcGroup.v[i]].groupMark = grpMark; | ||
752 | gList[nlcGroup.v[i]].atLevel = tryLevel; | ||
753 | spanGroup(gList[nlcGroup.v[i]].lx, gList[nlcGroup.v[i]].ly, &pPlist); | ||
754 | gList[nlcGroup.v[i]].libC = pPlist.indx; | ||
755 | } | ||
756 | } /* plei */ | ||
757 | |||
758 | saveState() | ||
759 | { /* saveState */ | ||
760 | playMark = 0; | ||
761 | tryLevel = 0; | ||
762 | newGID = maxGroupID; | ||
763 | } /* saveState */ | ||
764 | |||
765 | /* | ||
766 | undoes a move sequence back to uMark | ||
767 | */ | ||
768 | undoTo(uMark) | ||
769 | short uMark; | ||
770 | { /* undoTo */ | ||
771 | short i, xl, yl; | ||
772 | #ifdef DEBUG | ||
773 | printf( "undoTo\n" ); | ||
774 | #endif | ||
775 | for (i = playMark; i >= uMark + 1; i--) | ||
776 | if (playStack[i].kind == rem) | ||
777 | { | ||
778 | xl = playStack[i].uval.rem.xl; | ||
779 | yl = playStack[i].uval.rem.yl; | ||
780 | bord[xl][yl] = playStack[i].uval.rem.who; | ||
781 | groupIDs[xl][yl] = playStack[i].gID; | ||
782 | if (showTrees) | ||
783 | sstone(playStack[i].uval.rem.who, xl, yl, | ||
784 | playStack[i].uval.rem.sNumber); | ||
785 | } | ||
786 | else if (playStack[i].kind == add) | ||
787 | { | ||
788 | xl = playStack[i].uval.add.xl; | ||
789 | yl = playStack[i].uval.add.yl; | ||
790 | bord[xl][yl] = 0; | ||
791 | groupIDs[xl][yl] = 0; | ||
792 | tryLevel = tryLevel - 1; | ||
793 | newGID = playStack[i].uval.add.nextGID; | ||
794 | if (showTrees) | ||
795 | rstone(xl, yl); | ||
796 | } | ||
797 | else if (playStack[i].kind == reMap) | ||
798 | gMap[playStack[i].gID] = playStack[i].uval.reMap.oldGID; | ||
799 | else /* change libs of group - gID is pre-mapped */ | ||
800 | { | ||
801 | gList[playStack[i].gID].libC = playStack[i].uval.chLib.oldLC; | ||
802 | gList[playStack[i].gID].atLevel = playStack[i].uval.chLib.oldLevel; | ||
803 | } | ||
804 | playMark = uMark; | ||
805 | } /* undoTo */ | ||
806 | |||
807 | /* | ||
808 | restores the state of the world after trying a move sequence | ||
809 | */ | ||
810 | restoreState() | ||
811 | { /* restoreState */ | ||
812 | #ifdef DEBUG | ||
813 | printf( "restoreState\n" ); | ||
814 | #endif | ||
815 | if (playMark > 0) | ||
816 | { | ||
817 | undoTo(0); | ||
818 | playMark = 0; | ||
819 | tryLevel = 0; | ||
820 | } | ||
821 | } /* restoreState */ | ||
822 | |||
823 | /* exception bpt; */ | ||
824 | |||
825 | |||
826 | /* | ||
827 | returns true if (the group (at gx, gy) is saveable. | ||
828 | if so, returns the point to play at in savex, savey | ||
829 | */ | ||
830 | short saveable(gx, gy, savex, savey) | ||
831 | short gx, gy, *savex, *savey; | ||
832 | { /* saveable */ | ||
833 | short me, him, gx1, gx2, i, j, smark, mark2, tl, result; | ||
834 | char sChar; | ||
835 | sPointList dList; | ||
836 | point tp; | ||
837 | short libList[maxSPoint+1]; | ||
838 | #ifdef DEBUG | ||
839 | printf( "saveable\n" ); | ||
840 | #endif | ||
841 | dbStop = TRUE; | ||
842 | me = bord[gx][gy]; | ||
843 | him = -me; | ||
844 | if (me == 1) | ||
845 | sChar = '|'; | ||
846 | else | ||
847 | sChar = '>'; | ||
848 | /* write(sChar); */ | ||
849 | spanGroup(gx, gy, &plist3); /* find my liberties */ | ||
850 | if (adjInAtari) /* one of my options is to kill */ | ||
851 | { | ||
852 | listAdjacents(gx, gy, &aList); | ||
853 | for (i = 1; i <= aList.indx; i++) | ||
854 | if (gList[aList.v[i]].libC == 1) | ||
855 | { | ||
856 | spanGroup(gList[aList.v[i]].lx, gList[aList.v[i]].ly, | ||
857 | &pList1); /* find it's liberty */ | ||
858 | plist3.indx = plist3.indx + 1; | ||
859 | plist3.p[plist3.indx].px = pList1.p[1].px; | ||
860 | plist3.p[plist3.indx].py = pList1.p[1].py; | ||
861 | } | ||
862 | } | ||
863 | for (i = 1; i <= maxSPoint; i++) | ||
864 | libList[i] = -1; | ||
865 | if ((utilPlayLevel > 4) && | ||
866 | (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* account for diags */ | ||
867 | { | ||
868 | listDiags(gx, gy, &dList); | ||
869 | j = 0; | ||
870 | i = plist3.indx; | ||
871 | while ((j < dList.indx) && | ||
872 | (i < maxSPoint)) | ||
873 | { | ||
874 | j = j + 1; | ||
875 | i = i + 1; | ||
876 | libList[i] = 100; | ||
877 | plist3.p[i].px = dList.p[j].px; | ||
878 | plist3.p[i].py = dList.p[j].py; | ||
879 | } | ||
880 | plist3.indx = i; | ||
881 | } | ||
882 | if (plist3.indx > 1) /* sort by decreasing lib count */ | ||
883 | { | ||
884 | for (i = 1; i <= plist3.indx; i++) | ||
885 | if (libList[i] != 100) | ||
886 | { | ||
887 | mark2 = playMark; | ||
888 | tryPlay(plist3.p[i].px, plist3.p[i].py, me); | ||
889 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; | ||
890 | if (libList[i] > treeLibLim) /* i'm safe */ | ||
891 | { | ||
892 | *savex = plist3.p[i].px; | ||
893 | *savey = plist3.p[i].py; | ||
894 | result = TRUE; | ||
895 | goto one; | ||
896 | } | ||
897 | undoTo(mark2); | ||
898 | } | ||
899 | for (i = 1; i <= plist3.indx - 1; i++) | ||
900 | for (j = i + 1; j <= plist3.indx; j++) | ||
901 | if (libList[i] < libList[j]) | ||
902 | { | ||
903 | tl = libList[i]; | ||
904 | libList[i] = libList[j]; | ||
905 | libList[j] = tl; | ||
906 | tp = plist3.p[i]; | ||
907 | plist3.p[i] = plist3.p[j]; | ||
908 | plist3.p[j] = tp; | ||
909 | } | ||
910 | } | ||
911 | for (i = 1; i <= plist3.indx; i++) | ||
912 | { | ||
913 | *savex = plist3.p[i].px; | ||
914 | *savey = plist3.p[i].py; | ||
915 | if (legal[*savex][*savey]) | ||
916 | { | ||
917 | smark = playMark; | ||
918 | tryPlay(*savex, *savey, me); | ||
919 | pause(); | ||
920 | if (gList[gMap[groupIDs[*savex][*savey]]].libC > 1) | ||
921 | if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) | ||
922 | { | ||
923 | restoreState(); | ||
924 | /* sClearChar(sChar, rXor); */ | ||
925 | return TRUE; | ||
926 | } | ||
927 | else if (gList[gMap[groupIDs[gx][gy]]].libC > 1) | ||
928 | if (! killable(gx, gy, &gx1, &gx2)) | ||
929 | { | ||
930 | restoreState(); | ||
931 | /* sClearChar(sChar, rXor); */ | ||
932 | return TRUE; | ||
933 | } | ||
934 | undoTo(smark); | ||
935 | } | ||
936 | } | ||
937 | result = FALSE; | ||
938 | one: | ||
939 | restoreState(); | ||
940 | /* sClearChar(sChar, rXor); */ | ||
941 | return result; | ||
942 | } /* saveable */ | ||
943 | |||
944 | /* | ||
945 | marks unsavable groups as dead | ||
946 | */ | ||
947 | markDead() | ||
948 | { /* markDead */ | ||
949 | short i, j, gx, gy, result; | ||
950 | #ifdef DEBUG | ||
951 | printf( "markDead\n" ); | ||
952 | #endif | ||
953 | for (i = 1; i <= maxGroupID; i++) | ||
954 | if (killable(gList[i].lx, gList[i].ly, &gx, &gy)) | ||
955 | result = ! saveable(gList[i].lx, gList[i].ly, &gx, &gy); | ||
956 | else | ||
957 | result = FALSE; | ||
958 | for (i = 0; i <= maxPoint; i++) | ||
959 | for (j = 0; j <= maxPoint; j++) | ||
960 | if (bord[i][j] == 0) | ||
961 | ndbord[i][j] = 0; | ||
962 | else if (gList[groupIDs[i][j]].isDead) | ||
963 | ndbord[i][j] = 0; | ||
964 | else | ||
965 | ndbord[i][j] = bord[i][j]; | ||
966 | } /* markDead */ | ||
967 | |||
968 | /* | ||
969 | marks groups with two eyes as live | ||
970 | */ | ||
971 | MLspan(x, y, saw1, sawm1, size, sMark) | ||
972 | short x, y, *saw1, *sawm1, *size, sMark; | ||
973 | { /* span */ | ||
974 | if (ndbord[x][y] == 1) | ||
975 | *saw1 = TRUE; | ||
976 | else if (ndbord[x][y] == -1) | ||
977 | *sawm1 = TRUE; | ||
978 | else if (sGroups[x][y] == 0) | ||
979 | { | ||
980 | sGroups[x][y] = sMark; | ||
981 | *size = *size + 1; | ||
982 | if (x > 0) | ||
983 | MLspan(x - 1, y, saw1, sawm1, size, sMark); | ||
984 | if (x < maxPoint) | ||
985 | MLspan(x + 1, y, saw1, sawm1, size, sMark); | ||
986 | if (y > 0) | ||
987 | MLspan(x, y - 1, saw1, sawm1, size, sMark); | ||
988 | if (y < maxPoint) | ||
989 | MLspan(x, y + 1, saw1, sawm1, size, sMark); | ||
990 | } | ||
991 | } /* span */ | ||
992 | |||
993 | short CLspan(x, y, numEyes, who) | ||
994 | short x, y, *numEyes, who; | ||
995 | { /* span */ | ||
996 | markBoard[x][y] = marker; | ||
997 | if (ndbord[x][y] == 0) | ||
998 | { | ||
999 | if ((sList[sGroups[x][y]].sm != marker) && | ||
1000 | (sList[sGroups[x][y]].w == who)) | ||
1001 | { | ||
1002 | sList[sGroups[x][y]].sm = marker; | ||
1003 | if (sList[sGroups[x][y]].s > 6) | ||
1004 | return TRUE; | ||
1005 | *numEyes = *numEyes + 1; | ||
1006 | if (*numEyes > 1) | ||
1007 | return TRUE; | ||
1008 | } | ||
1009 | } | ||
1010 | else if (bord[x][y] == who) | ||
1011 | { | ||
1012 | if ((x > 0) && | ||
1013 | (markBoard[x - 1][y] != marker)) | ||
1014 | if (CLspan(x - 1, y, numEyes, who)) return TRUE; | ||
1015 | if ((x < maxPoint) && | ||
1016 | (markBoard[x + 1][y] != marker)) | ||
1017 | if (CLspan(x + 1, y, numEyes, who)) return TRUE; | ||
1018 | if ((y > 0) && | ||
1019 | (markBoard[x][y - 1] != marker)) | ||
1020 | if (CLspan(x, y - 1, numEyes, who)) return TRUE; | ||
1021 | if ((y < maxPoint) && | ||
1022 | (markBoard[x][y + 1] != marker)) | ||
1023 | if (CLspan(x, y + 1, numEyes, who)) return TRUE; | ||
1024 | } | ||
1025 | return FALSE; | ||
1026 | } /* span */ | ||
1027 | |||
1028 | short checkLive(x, y) | ||
1029 | short x, y; | ||
1030 | { /* checkLive */ | ||
1031 | short numEyes, who; | ||
1032 | #ifdef DEBUG | ||
1033 | printf( "checkLive\n" ); | ||
1034 | #endif | ||
1035 | numEyes = 0; | ||
1036 | who = bord[x][y]; | ||
1037 | marker = marker + 1; | ||
1038 | return CLspan(x, y, &numEyes, who); | ||
1039 | } /* checkLive */ | ||
1040 | |||
1041 | markLive() | ||
1042 | { /* markLive */ | ||
1043 | short i, j, size, sMark = 0; | ||
1044 | short saw1, sawm1; | ||
1045 | #ifdef DEBUG | ||
1046 | printf( "markLive\n" ); | ||
1047 | #endif | ||
1048 | initArray(sGroups); | ||
1049 | for (i = 0; i <= maxPoint; i++) | ||
1050 | for (j = 0; j <= maxPoint; j++) | ||
1051 | if ((sGroups[i][j] == 0) && | ||
1052 | (ndbord[i][j] == 0)) | ||
1053 | { | ||
1054 | size = 0; | ||
1055 | sMark = sMark + 1; | ||
1056 | sawm1 = FALSE; | ||
1057 | saw1 = FALSE; | ||
1058 | MLspan(i, j, &saw1, &sawm1, &size, sMark); | ||
1059 | sList[sMark].s = size; | ||
1060 | sList[sMark].sm = 0; | ||
1061 | if (sawm1) | ||
1062 | if (saw1) | ||
1063 | sList[sMark].w = 0; | ||
1064 | else | ||
1065 | sList[sMark].w = -1; | ||
1066 | else if (saw1) | ||
1067 | sList[sMark].w = 1; | ||
1068 | else | ||
1069 | sList[sMark].w = 0; | ||
1070 | } | ||
1071 | for (i = 1; i <= maxGroupID; i++) | ||
1072 | if (! gList[i].isDead) | ||
1073 | gList[i].isLive = checkLive(gList[i].lx, gList[i].ly); | ||
1074 | } /* markLive */ | ||
1075 | |||
1076 | /* | ||
1077 | generates the connection map and the protected point map. | ||
1078 | */ | ||
1079 | genConnects() | ||
1080 | { /* genConnects */ | ||
1081 | short x, y, numStones; | ||
1082 | #ifdef DEBUG | ||
1083 | printf( "genConnects\n" ); | ||
1084 | #endif | ||
1085 | for (x = 0; x <= maxPoint; x++) | ||
1086 | for (y = 0; y <= maxPoint; y++) | ||
1087 | { | ||
1088 | connectMap[x][y] = 0; | ||
1089 | protPoints[x][y] = 0; | ||
1090 | } | ||
1091 | for (x = 0; x <= maxPoint; x++) | ||
1092 | for (y = 0; y <= maxPoint; y++) | ||
1093 | if (bord[x][y] == 1) /* map connections to this stone */ | ||
1094 | { | ||
1095 | if (x > 0) /* direct connection */ | ||
1096 | connectMap[x - 1][y] += 1; | ||
1097 | if (x < maxPoint) | ||
1098 | connectMap[x + 1][y] += 1; | ||
1099 | if (y > 0) | ||
1100 | connectMap[x][y - 1] += 1; | ||
1101 | if (y < maxPoint) | ||
1102 | connectMap[x][y + 1] += 1; | ||
1103 | if ((x > 0) && (y > 0) && /* diagonal connection */ | ||
1104 | (bord[x - 1][y] == 0) && (bord[x][y - 1] == 0)) | ||
1105 | connectMap[x - 1][y - 1] += 1; | ||
1106 | if ((x < maxPoint) && (y > 0) && | ||
1107 | (bord[x + 1][y] == 0) && (bord[x][y - 1] == 0)) | ||
1108 | connectMap[x + 1][y - 1] += 1; | ||
1109 | if ((x < maxPoint) && (y < maxPoint) && | ||
1110 | (bord[x + 1][y] == 0) && (bord[x][y + 1] == 0)) | ||
1111 | connectMap[x + 1][y + 1] += 1; | ||
1112 | if ((x > 0) && (y < maxPoint) && | ||
1113 | (bord[x - 1][y] == 0) && (bord[x][y + 1] == 0)) | ||
1114 | connectMap[x - 1][y + 1] += 1; | ||
1115 | if ((x > 1) && (claim[x - 1][y] > 3)) /* one point jump */ | ||
1116 | connectMap[x - 2][y] += 1; | ||
1117 | if ((x < (maxPoint - 1)) && (claim[x + 1][y] > 3)) | ||
1118 | connectMap[x + 2][y] += 1; | ||
1119 | if ((y > 1) && (claim[x][y - 1] > 3)) | ||
1120 | connectMap[x][y - 2] += 1; | ||
1121 | if ((y < (maxPoint - 1)) && (claim[x][y + 1] > 3)) | ||
1122 | connectMap[x][y + 2] += 1; | ||
1123 | if ((x > 1) && (y > 0) && /* knight's move */ | ||
1124 | (claim[x - 1][y] > 3) && (claim[x - 1][y - 1] > 3)) | ||
1125 | connectMap[x - 2][y - 1] += 1; | ||
1126 | if ((x > 0) && (y > 1) && | ||
1127 | (claim[x][y - 1] > 3) && (claim[x - 1][y - 1] > 3)) | ||
1128 | connectMap[x - 1][y - 2] += 1; | ||
1129 | if ((x < (maxPoint - 1)) && (y > 0) && | ||
1130 | (claim[x + 1][y] > 3) && (claim[x + 1][y - 1] > 3)) | ||
1131 | connectMap[x + 2][y - 1] += 1; | ||
1132 | if ((x < maxPoint) && (y > 1) && | ||
1133 | (claim[x][y - 1] > 3) && (claim[x + 1][y - 1] > 3)) | ||
1134 | connectMap[x + 1][y - 2] += 1; | ||
1135 | if ((x > 1) && (y < maxPoint) && | ||
1136 | (claim[x - 1][y] > 3) && (claim[x - 1][y + 1] > 3)) | ||
1137 | connectMap[x - 2][y + 1] += 1; | ||
1138 | if ((x > 0) && (y < (maxPoint - 1)) && | ||
1139 | (claim[x][y + 1] > 3) && (claim[x - 1][y + 1] > 3)) | ||
1140 | connectMap[x - 1][y + 2] += 1; | ||
1141 | if ((x < (maxPoint - 1)) && (y < maxPoint) && | ||
1142 | (claim[x + 1][y] > 3) && (claim[x + 1][y + 1] > 3)) | ||
1143 | connectMap[x + 2][y + 1] += 1; | ||
1144 | if ((x < maxPoint) && (y < (maxPoint - 1)) && | ||
1145 | (claim[x][y + 1] > 3) && (claim[x + 1][y + 1] > 3)) | ||
1146 | connectMap[x + 1][y + 2] += 1; | ||
1147 | } | ||
1148 | else if (bord[x][y] == 0) /* see if protected point */ | ||
1149 | { | ||
1150 | numStones = 0; | ||
1151 | if (x == 0) | ||
1152 | numStones = numStones + 1; | ||
1153 | if (y == 0) | ||
1154 | numStones = numStones + 1; | ||
1155 | if (x == maxPoint) | ||
1156 | numStones = numStones + 1; | ||
1157 | if (y == maxPoint) | ||
1158 | numStones = numStones + 1; | ||
1159 | if ((x > 0) && (bord[x - 1][y] == 1)) | ||
1160 | numStones = numStones + 1; | ||
1161 | if ((y > 0) && (bord[x][y - 1] == 1)) | ||
1162 | numStones = numStones + 1; | ||
1163 | if ((x < maxPoint) && (bord[x + 1][y] == 1)) | ||
1164 | numStones = numStones + 1; | ||
1165 | if ((y < maxPoint) && (bord[x][y + 1] == 1)) | ||
1166 | numStones = numStones + 1; | ||
1167 | if (numStones == 4) | ||
1168 | protPoints[x][y] = 1; | ||
1169 | else if (numStones == 3) | ||
1170 | { | ||
1171 | if ((x > 0) && | ||
1172 | ((bord[x - 1][y] == 0) || | ||
1173 | ((bord[x - 1][y] == -1) && | ||
1174 | (gList[groupIDs[x - 1][y]].libC == 1)))) | ||
1175 | protPoints[x][y] = 1; | ||
1176 | else if ((x < maxPoint) && | ||
1177 | ((bord[x + 1][y] == 0) || | ||
1178 | ((bord[x + 1][y] == -1) && | ||
1179 | (gList[groupIDs[x + 1][y]].libC == 1)))) | ||
1180 | protPoints[x][y] = 1; | ||
1181 | else if ((y > 0) && | ||
1182 | ((bord[x][y - 1] == 0) || | ||
1183 | ((bord[x][y - 1] == -1) && | ||
1184 | (gList[groupIDs[x][y - 1]].libC == 1)))) | ||
1185 | protPoints[x][y] = 1; | ||
1186 | else if ((y < maxPoint) && | ||
1187 | ((bord[x][y + 1] == 0) || | ||
1188 | ((bord[x][y + 1] == -1) && | ||
1189 | (gList[groupIDs[x][y + 1]].libC == 1)))) | ||
1190 | protPoints[x][y] = 1; | ||
1191 | } | ||
1192 | } | ||
1193 | for (x = 0; x <= maxPoint; x++) | ||
1194 | for (y = 0; y <= maxPoint; y++) | ||
1195 | if (bord[x][y] != 0) | ||
1196 | { | ||
1197 | connectMap[x][y] = 0; | ||
1198 | protPoints[x][y] = 0; | ||
1199 | } | ||
1200 | } /* genConnects */ | ||
1201 | |||
1202 | /* | ||
1203 | generates the whole state of the game. | ||
1204 | */ | ||
1205 | genState() | ||
1206 | { /* genState */ | ||
1207 | #ifdef DEBUG | ||
1208 | printf( "genState\n" ); | ||
1209 | #endif | ||
1210 | inGenState = TRUE; | ||
1211 | respreicen(); | ||
1212 | markDead(); | ||
1213 | markLive(); | ||
1214 | spread(); | ||
1215 | genConnects(); | ||
1216 | #ifdef DEBUG | ||
1217 | /* printBoard( claim, "claim" ); */ | ||
1218 | /* printBoard( bord, "bord" ); */ | ||
1219 | /* printBoard( ndbord, "ndbord" ); | ||
1220 | printBoard( sGroups, "sGroups" ); | ||
1221 | printBoard( groupIDs, "groupIDs" ); | ||
1222 | printBoard( connectMap, "connectMap" ); | ||
1223 | printBoard( protPoints, "protPoints" ); */ | ||
1224 | #endif | ||
1225 | inGenState = FALSE; | ||
1226 | } /* genState */ | ||
1227 | |||
1228 | /* | ||
1229 | generates a value for the [x, y] location that appears to get larger | ||
1230 | for points that are saddle points in the influence graph (klein) | ||
1231 | */ | ||
1232 | short tencen(x, y) | ||
1233 | short x, y; | ||
1234 | { /* tencen */ | ||
1235 | short a, b, c, d, w, z; | ||
1236 | #ifdef DEBUG | ||
1237 | printf( "tencen\n" ); | ||
1238 | #endif | ||
1239 | if (claim[x][y] > -1) /* if (he does not influence this area, return 50 */ | ||
1240 | { | ||
1241 | return 50; | ||
1242 | } | ||
1243 | w = claim[x][y]; /* w <= -1 */ | ||
1244 | a = iNil; | ||
1245 | if (x > 0) | ||
1246 | if (claim[x - 1][y] > -1) /* if (neighbor is not influenced by him */ | ||
1247 | a = claim[x - 1][y] - w; /* score is sum of his influence on central */ | ||
1248 | b = iNil; /* point and my influence on this neighbor */ | ||
1249 | if (y > 0) | ||
1250 | if (claim[x][y - 1] > -1) | ||
1251 | b = claim[x][y - 1] - w; | ||
1252 | c = iNil; | ||
1253 | if (x < maxPoint) | ||
1254 | if (claim[x + 1][y] > -1) | ||
1255 | c = claim[x + 1][y] - w; | ||
1256 | d = iNil; | ||
1257 | if (y < maxPoint) | ||
1258 | if (claim[x][y + 1] > -1) | ||
1259 | d = claim[x][y + 1] - w; | ||
1260 | z = a; /* z = max(a, b, c, d) */ | ||
1261 | if (z != iNil) | ||
1262 | { | ||
1263 | if ((b != iNil) && | ||
1264 | (b > z)) | ||
1265 | z = b; | ||
1266 | } | ||
1267 | else | ||
1268 | z = b; | ||
1269 | if (z != iNil) | ||
1270 | { | ||
1271 | if ((c != iNil) && | ||
1272 | (c > z)) | ||
1273 | z = c; | ||
1274 | } | ||
1275 | else | ||
1276 | z = c; | ||
1277 | if (z != iNil) | ||
1278 | { | ||
1279 | if ((d != iNil) && | ||
1280 | (d > z)) | ||
1281 | z = d; | ||
1282 | } | ||
1283 | else | ||
1284 | z = d; | ||
1285 | if ((z != iNil) && | ||
1286 | ((x == 0) || | ||
1287 | (y == 0) || | ||
1288 | (x == maxPoint) || | ||
1289 | (y == maxPoint))) | ||
1290 | z = z * 2; /* double z if (on the edge of the board ?? */ | ||
1291 | if (z != iNil) | ||
1292 | return z; | ||
1293 | else | ||
1294 | return 50; | ||
1295 | } /* tencen */ | ||
1296 | |||
1297 | initGPUtils() | ||
1298 | { /* initGPUtils */ | ||
1299 | #ifdef DEBUG | ||
1300 | printf( "initGPUtils\n" ); | ||
1301 | #endif | ||
1302 | initArray(markBoard); | ||
1303 | initState(); | ||
1304 | marker = 0; | ||
1305 | playMark = 0; | ||
1306 | gList[0].isLive = FALSE; | ||
1307 | gList[0].isDead = FALSE; | ||
1308 | gList[0].libC = 0; | ||
1309 | gList[0].size = 0; | ||
1310 | gList[0].numEyes = 0; | ||
1311 | gList[0].lx = -1; | ||
1312 | gList[0].ly = -1; | ||
1313 | gMap[0] = 0; | ||
1314 | dbStop = FALSE; | ||
1315 | inGenState = FALSE; | ||
1316 | } /* initGPUtils */ | ||
1317 | |||
diff --git a/noncore/games/go/goplayutils.h b/noncore/games/go/goplayutils.h new file mode 100644 index 0000000..11ab658 --- a/dev/null +++ b/noncore/games/go/goplayutils.h | |||
@@ -0,0 +1,85 @@ | |||
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 __goplayutils_h | ||
21 | #define __goplayutils_h | ||
22 | |||
23 | #define iNil 32767 /* a distinguished value like nil */ | ||
24 | #define maxGroup 512 | ||
25 | #define maxSPoint 16 | ||
26 | #define tryLimit 300 | ||
27 | |||
28 | typedef short intBoard[19][19]; /* these were -2 to maxPoint + 2 */ | ||
29 | |||
30 | typedef short boolBoard[19][19]; | ||
31 | |||
32 | typedef struct | ||
33 | { | ||
34 | short px, py; | ||
35 | } point; | ||
36 | |||
37 | typedef struct | ||
38 | { | ||
39 | point p[401]; | ||
40 | short indx; | ||
41 | } pointList; | ||
42 | |||
43 | typedef struct | ||
44 | { | ||
45 | point p[maxSPoint+1]; | ||
46 | short indx; | ||
47 | } sPointList; | ||
48 | |||
49 | typedef struct | ||
50 | { | ||
51 | short indx, | ||
52 | v[401]; | ||
53 | } intList; | ||
54 | |||
55 | typedef struct { short w, s, sm; } sgRec; | ||
56 | |||
57 | typedef struct | ||
58 | { | ||
59 | short groupMark, | ||
60 | atLevel, | ||
61 | isLive, | ||
62 | isDead, | ||
63 | libC, | ||
64 | numEyes, | ||
65 | size, | ||
66 | lx, ly; | ||
67 | } groupRec; | ||
68 | |||
69 | typedef enum {rem, add, chLib, reMap} playType; | ||
70 | |||
71 | typedef struct { short who, xl, yl, nextGID, sNumber; } remAddRec; | ||
72 | typedef struct { short oldLC, oldLevel; } chLibRec; | ||
73 | typedef struct { short oldGID; } reMapRec; | ||
74 | typedef struct | ||
75 | { | ||
76 | short gID; | ||
77 | playType kind; | ||
78 | union { | ||
79 | remAddRec rem, add; | ||
80 | chLibRec chLib; | ||
81 | reMapRec reMap; | ||
82 | } uval; | ||
83 | } playRec; | ||
84 | |||
85 | #endif | ||
diff --git a/noncore/games/go/gowidget.cpp b/noncore/games/go/gowidget.cpp new file mode 100644 index 0000000..fca9797 --- a/dev/null +++ b/noncore/games/go/gowidget.cpp | |||
@@ -0,0 +1,449 @@ | |||
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 "gowidget.h" | ||
22 | |||
23 | #include <qpe/config.h> | ||
24 | #include <qpe/resource.h> | ||
25 | |||
26 | #include <qpainter.h> | ||
27 | #include <qpixmap.h> | ||
28 | #include <qpe/qpetoolbar.h> | ||
29 | #include <qpe/qpemenubar.h> | ||
30 | #include <qpopupmenu.h> | ||
31 | #include <qaction.h> | ||
32 | #include <qapplication.h> //processEvents() | ||
33 | #include <qlabel.h> | ||
34 | |||
35 | //#include <stdio.h> | ||
36 | |||
37 | #include "amigo.h" | ||
38 | #include "goplayutils.h" | ||
39 | |||
40 | static const enum bVal computer_color = BLACK; | ||
41 | |||
42 | static int current_handicap = 1; | ||
43 | |||
44 | static QBrush *goBrush; | ||
45 | //static QImage *newBlackStone; | ||
46 | //static QImage *blackStone; | ||
47 | //static QImage *whiteStone; | ||
48 | static QPixmap *newBlackStone; | ||
49 | static QPixmap *blackStone; | ||
50 | static QPixmap *whiteStone; | ||
51 | |||
52 | GoMainWidget::GoMainWidget( QWidget *parent, const char* name) : | ||
53 | QMainWindow( parent, name ) | ||
54 | { | ||
55 | setToolBarsMovable( FALSE ); | ||
56 | GoWidget *go = new GoWidget(this); | ||
57 | |||
58 | setCentralWidget(go); | ||
59 | toolbar = new QPEToolBar(this); | ||
60 | toolbar->setHorizontalStretchable( TRUE ); | ||
61 | addToolBar(toolbar); | ||
62 | |||
63 | QPEMenuBar *mb = new QPEMenuBar( toolbar ); | ||
64 | mb->setMargin(0); | ||
65 | QPopupMenu *file = new QPopupMenu( this ); | ||
66 | |||
67 | QAction *a = new QAction( tr( "New Game" ), QString::null, 0, this, 0 ); | ||
68 | connect( a, SIGNAL( activated() ), go, SLOT( newGame() ) ); | ||
69 | a->addTo( file ); | ||
70 | |||
71 | a = new QAction( tr( "Pass" ), Resource::loadPixmap( "pass" ), QString::null, 0, this, 0 ); | ||
72 | connect( a, SIGNAL( activated() ), go, SLOT( pass() ) ); | ||
73 | a->addTo( file ); | ||
74 | a->addTo( toolbar ); | ||
75 | |||
76 | |||
77 | a = new QAction( tr( "Resign" ), Resource::loadPixmap( "reset" ), QString::null, 0, this, 0 ); | ||
78 | connect( a, SIGNAL( activated() ), go, SLOT( resign() ) ); | ||
79 | a->addTo( file ); | ||
80 | |||
81 | a = new QAction( tr( "Two player option" ), QString::null, 0, this, 0 ); | ||
82 | a->setToggleAction( TRUE ); | ||
83 | connect( a, SIGNAL( toggled(bool) ), go, SLOT( setTwoplayer(bool) ) ); | ||
84 | a->addTo( file ); | ||
85 | |||
86 | mb->insertItem( tr( "Game" ), file ); | ||
87 | |||
88 | QLabel *turnLabel = new QLabel( toolbar ); | ||
89 | turnLabel->setBackgroundMode( PaletteButton ); | ||
90 | connect( go, SIGNAL(showTurn(const QPixmap&)), | ||
91 | turnLabel, SLOT(setPixmap(const QPixmap&)) ); | ||
92 | |||
93 | |||
94 | QLabel * scoreLabel = new QLabel( toolbar ); | ||
95 | scoreLabel->setBackgroundMode( PaletteButton ); | ||
96 | connect( go, SIGNAL(showScore(const QString&)), | ||
97 | scoreLabel, SLOT(setText(const QString&)) ); | ||
98 | |||
99 | toolbar->setStretchableWidget( scoreLabel ); | ||
100 | |||
101 | go->readConfig(); | ||
102 | } | ||
103 | |||
104 | void GoMainWidget::resizeEvent( QResizeEvent * ) | ||
105 | { | ||
106 | //### this won't work because of the text label... | ||
107 | /* | ||
108 | if ( width() > height() ) | ||
109 | moveToolBar( toolbar, Left ); | ||
110 | else | ||
111 | moveToolBar( toolbar, Top ); | ||
112 | */ | ||
113 | } | ||
114 | |||
115 | GoWidget *GoWidget::self = 0; | ||
116 | |||
117 | GoWidget::GoWidget( QWidget *parent, const char* name) : | ||
118 | QWidget( parent, name ) | ||
119 | { | ||
120 | if ( self ) | ||
121 | fatal( "Only one Go widget allowed" ); | ||
122 | self = this; | ||
123 | twoplayer = FALSE; | ||
124 | |||
125 | |||
126 | d = bx = by = 1; | ||
127 | |||
128 | QPixmap pix = Resource::loadPixmap( "pine" ); | ||
129 | goBrush = new QBrush( black, pix ); | ||
130 | /* | ||
131 | QString fn = Resource::findPixmap("Go-black"); | ||
132 | blackStone = new QImage( fn ); | ||
133 | fn = Resource::findPixmap("Go-black-highlight"); | ||
134 | newBlackStone = new QImage( fn ); | ||
135 | fn = Resource::findPixmap("Go-white"); | ||
136 | whiteStone = new QImage( fn ); | ||
137 | */ | ||
138 | blackStone = new QPixmap(Resource::loadPixmap( "Go-black" )); | ||
139 | whiteStone = new QPixmap(Resource::loadPixmap( "Go-white" )); | ||
140 | newBlackStone = new QPixmap(Resource::loadPixmap( "Go-black-highlight" )); | ||
141 | |||
142 | init(); | ||
143 | } | ||
144 | |||
145 | GoWidget::~GoWidget() | ||
146 | { | ||
147 | writeConfig(); | ||
148 | } | ||
149 | |||
150 | void GoWidget::writeConfig() | ||
151 | { | ||
152 | Config cfg("Go"); | ||
153 | cfg.setGroup("Game"); | ||
154 | cfg.writeEntry("TwoPlayer", twoplayer); | ||
155 | cfg.writeEntry("CurrentPlayer", currentPlayer); | ||
156 | cfg.writeEntry("NPassed", nPassed); | ||
157 | QString b; | ||
158 | for (int i=0; i<19; i++) | ||
159 | for (int j=0; j<19; j++) | ||
160 | b += board[i][j] == BLACK ? 'B' : board[i][j] == WHITE ? 'W' : '.'; | ||
161 | cfg.writeEntry("Board", b); | ||
162 | cfg.writeEntry("LastX", lastX); | ||
163 | cfg.writeEntry("LastY", lastY); | ||
164 | extern int blackPrisoners, whitePrisoners; | ||
165 | cfg.writeEntry("BlackPrisoners", blackPrisoners); | ||
166 | cfg.writeEntry("WhitePrisoners", whitePrisoners); | ||
167 | } | ||
168 | |||
169 | void GoWidget::readConfig() | ||
170 | { | ||
171 | init(); | ||
172 | Config cfg("Go"); | ||
173 | cfg.setGroup("Game"); | ||
174 | twoplayer = cfg.readBoolEntry("TwoPlayer"); | ||
175 | currentPlayer = (bVal)cfg.readNumEntry("CurrentPlayer",1); | ||
176 | nPassed = cfg.readNumEntry("NPassed",0); | ||
177 | QString b = cfg.readEntry("Board"); | ||
178 | if ( b.length() == 19*19 ) | ||
179 | for (int i=0; i<19; i++) | ||
180 | for (int j=0; j<19; j++) { | ||
181 | QChar ch = b[j+19*i]; | ||
182 | if ( ch != '.' ) | ||
183 | GoPlaceStone( ch == 'B' ? BLACK : WHITE, i, j ); | ||
184 | } | ||
185 | lastX = cfg.readNumEntry("LastX"); | ||
186 | lastY = cfg.readNumEntry("LastY"); | ||
187 | extern int blackPrisoners, whitePrisoners; | ||
188 | blackPrisoners = cfg.readNumEntry("BlackPrisoners",0); | ||
189 | whitePrisoners = cfg.readNumEntry("WhitePrisoners",0); | ||
190 | reportPrisoners(blackPrisoners,whitePrisoners); | ||
191 | emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone ); | ||
192 | } | ||
193 | |||
194 | void GoWidget::resizeEvent( QResizeEvent * ) | ||
195 | { | ||
196 | d = QMIN(width(),height())/19; | ||
197 | // int r = (d/2-1); | ||
198 | bx = (width() - 18*d)/2 ; | ||
199 | by = (height() - 18*d)/2 ; | ||
200 | } | ||
201 | |||
202 | void GoWidget::init() | ||
203 | { | ||
204 | lastX = lastY = newX = newY = -1; | ||
205 | nPassed = 0; | ||
206 | for ( int i = 0; i < 19; i++ ) | ||
207 | for ( int j = 0; j < 19; j++ ) | ||
208 | board[i][j]=-1; | ||
209 | gameActive = TRUE; | ||
210 | goRestart(current_handicap); | ||
211 | |||
212 | if ( twoplayer ) { | ||
213 | currentPlayer = BLACK; | ||
214 | } else { | ||
215 | doComputerMove(); | ||
216 | currentPlayer = WHITE; | ||
217 | } | ||
218 | emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone ); | ||
219 | } | ||
220 | |||
221 | void GoWidget::paintEvent( QPaintEvent *e ) | ||
222 | { | ||
223 | int i,j; | ||
224 | |||
225 | int r = whiteStone->width()/2; | ||
226 | |||
227 | QPainter p(this); | ||
228 | p.fillRect( bx - d/2, by - d/2, 19*d, 19*d, *goBrush ); | ||
229 | |||
230 | int xMin = QMAX( x2board(e->rect().left()), 0 ); | ||
231 | int xMax = QMIN( x2board(e->rect().right()), 18 ); | ||
232 | int yMin = QMAX( y2board(e->rect().top()), 0 ); | ||
233 | int yMax = QMIN( y2board(e->rect().bottom()), 18 ); | ||
234 | |||
235 | QColor pine( 255, 186, 89 ); | ||
236 | p.setPen( pine.dark() ); | ||
237 | |||
238 | for ( i = xMin; i < xMax+1 ; i ++ ) { | ||
239 | p.drawLine( bx+i*d, by, bx+i*d, by+18*d ); | ||
240 | } | ||
241 | for ( j = yMin; j < yMax+1 ; j ++ ) { | ||
242 | p.drawLine( bx, by+j*d, bx+18*d, by+j*d); | ||
243 | } | ||
244 | |||
245 | // dots are at (3,3), (3,9), (3,15) and so on | ||
246 | p.setBrush( black ); | ||
247 | for ( i = 3; i < xMax+1; i+=6 ) | ||
248 | for ( j = 3; j < yMax+1; j+=6 ) | ||
249 | p.drawEllipse( bx+i*d-2, by+j*d-2, 5, 5 ); | ||
250 | |||
251 | |||
252 | for ( i = xMin; i < xMax+1; i++ ) | ||
253 | for ( j = yMin; j < yMax+1; j++ ) { | ||
254 | if ( board[i][j] == WHITE || | ||
255 | currentPlayer==WHITE && newX == i && newY == j ) | ||
256 | p.drawPixmap( bx+i*d - r, by+j*d - r, *whiteStone ); | ||
257 | else if ( i == lastX && j == lastY ) | ||
258 | p.drawPixmap( bx+i*d - r, by+j*d - r, *newBlackStone ); | ||
259 | else if ( board[i][j] == BLACK || | ||
260 | currentPlayer==BLACK && newX == i && newY == j) | ||
261 | p.drawPixmap( bx+i*d - r, by+j*d - r, *blackStone ); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | void GoWidget::doMove( int x, int y ) | ||
266 | { | ||
267 | |||
268 | if ( !GoPlaceStone( currentPlayer, x, y ) ) { | ||
269 | //printf( "Illegal move (%d,%d)\n", x, y ); | ||
270 | return; | ||
271 | } | ||
272 | //printf( "you do (%d,%d)\n", x, y ); | ||
273 | nPassed = 0; | ||
274 | if ( twoplayer ) | ||
275 | currentPlayer = (currentPlayer==WHITE) ? BLACK : WHITE; | ||
276 | else | ||
277 | doComputerMove(); | ||
278 | |||
279 | emit showTurn( currentPlayer == WHITE ? *whiteStone : *blackStone ); | ||
280 | |||
281 | } | ||
282 | |||
283 | void GoWidget::pass() | ||
284 | { | ||
285 | if ( !gameActive ) | ||
286 | return; | ||
287 | nPassed++; | ||
288 | if ( nPassed >= 2 ) | ||
289 | endGame(); | ||
290 | else if ( !twoplayer ) | ||
291 | doComputerMove(); | ||
292 | } | ||
293 | |||
294 | void GoWidget::resign() | ||
295 | { | ||
296 | if ( gameActive ) | ||
297 | endGame(); | ||
298 | } | ||
299 | |||
300 | |||
301 | void GoWidget::newGame() | ||
302 | { | ||
303 | init(); | ||
304 | update(); | ||
305 | } | ||
306 | |||
307 | |||
308 | void GoWidget::endGame() | ||
309 | { | ||
310 | gameActive = FALSE; | ||
311 | |||
312 | int w,b; | ||
313 | CountUp( &w, &b); | ||
314 | QString s = tr("White %1, Black %2. ").arg(w).arg(b); | ||
315 | if ( w > b ) | ||
316 | s += tr("White wins."); | ||
317 | else if ( w < b ) | ||
318 | s += tr("Black wins."); | ||
319 | else | ||
320 | s += tr("A draw."); | ||
321 | emit showScore( s ); | ||
322 | } | ||
323 | |||
324 | void GoWidget::doComputerMove() | ||
325 | { | ||
326 | int ox = lastX; | ||
327 | int oy = lastY; | ||
328 | lastX = lastY = -1; | ||
329 | emit showTurn( *blackStone ); | ||
330 | refresh( ox, oy); | ||
331 | qApp->processEvents(); | ||
332 | short int x,y; | ||
333 | if ( genMove( computer_color, &x, &y ) ) { | ||
334 | lastX = x; | ||
335 | lastY = y; | ||
336 | //printf( "I do (%d,%d)\n", x, y ); | ||
337 | GoPlaceStone(computer_color,x,y); | ||
338 | nPassed = 0; | ||
339 | } else { | ||
340 | emit showScore( tr("I pass") ); | ||
341 | nPassed++; | ||
342 | if ( nPassed >= 2 ) | ||
343 | endGame(); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | void GoWidget::mousePressEvent( QMouseEvent *me ) | ||
348 | { | ||
349 | if ( !gameActive ) | ||
350 | return; | ||
351 | int x = x2board(me->x()); | ||
352 | int y = y2board(me->y()); | ||
353 | showStone(x,y,currentPlayer); | ||
354 | } | ||
355 | |||
356 | void GoWidget::mouseMoveEvent( QMouseEvent *me ) | ||
357 | { | ||
358 | if ( !gameActive ) | ||
359 | return; | ||
360 | int x = x2board(me->x()); | ||
361 | int y = y2board(me->y()); | ||
362 | if ( x != newX || y != newY ) | ||
363 | showStone(x,y,currentPlayer); | ||
364 | } | ||
365 | |||
366 | void GoWidget::showStone( int x, int y, enum bVal c ) | ||
367 | { | ||
368 | |||
369 | if ( newX > -1 ) { | ||
370 | refresh( newX, newY ); | ||
371 | newY = newX = -1; | ||
372 | } | ||
373 | if ( x < 0 || x > 18 || y < 0 || y > 18 ) { | ||
374 | newX = newY = -1; | ||
375 | return; | ||
376 | } | ||
377 | if ( board[x][y] == -1 && !Suicide( c, x, y ) ) { | ||
378 | newX = x; | ||
379 | newY = y; | ||
380 | refresh(x,y); | ||
381 | } | ||
382 | |||
383 | } | ||
384 | |||
385 | void GoWidget::mouseReleaseEvent( QMouseEvent * ) | ||
386 | { | ||
387 | if ( gameActive && newX > -1 ) | ||
388 | doMove( newX, newY ); | ||
389 | newX = newY = -1; | ||
390 | } | ||
391 | |||
392 | void GoWidget::refresh( int x, int y ) | ||
393 | { | ||
394 | update( bx+d*x-d/2-1, by+d*y-d/2-1, d+2, d+2 ); | ||
395 | } | ||
396 | |||
397 | void GoWidget::removeStone(short x, short y) | ||
398 | { | ||
399 | board[x][y]=-1; | ||
400 | refresh( x, y ); | ||
401 | } | ||
402 | |||
403 | void GoWidget::placeStone (enum bVal c, short x, short y ) | ||
404 | { | ||
405 | board[x][y]=c; | ||
406 | refresh( x, y ); | ||
407 | } | ||
408 | |||
409 | void GoWidget::reportPrisoners( int blackcnt, int whitecnt ) | ||
410 | { | ||
411 | QString s = tr( "Prisoners: black %1, white %2" ).arg(blackcnt).arg(whitecnt); | ||
412 | emit showScore( s ); | ||
413 | } | ||
414 | |||
415 | void GoWidget::setTwoplayer( bool b ) | ||
416 | { | ||
417 | twoplayer = b; | ||
418 | } | ||
419 | |||
420 | void GoWidget::setHandicap( int h ) | ||
421 | { | ||
422 | current_handicap = h; | ||
423 | } | ||
424 | |||
425 | |||
426 | extern "C" { | ||
427 | |||
428 | voidremovestone(short x, short y) | ||
429 | { | ||
430 | GoWidget::self->removeStone(x,y); | ||
431 | } | ||
432 | |||
433 | voidplacestone (enum bVal c, short x, short y ) | ||
434 | { | ||
435 | GoWidget::self->placeStone(c,x,y); | ||
436 | } | ||
437 | |||
438 | voidintrMoveReport(enum bVal c ,char *coord ,char *reason ) | ||
439 | { | ||
440 | qDebug( "intrMoveReport colour %d, %s %s", c, coord, reason ); | ||
441 | } | ||
442 | |||
443 | voidintrPrisonerReport( short blackcnt, short whitecnt ) | ||
444 | { | ||
445 | GoWidget::self->reportPrisoners(blackcnt,whitecnt); | ||
446 | } | ||
447 | |||
448 | } | ||
449 | |||
diff --git a/noncore/games/go/gowidget.h b/noncore/games/go/gowidget.h new file mode 100644 index 0000000..94de2cc --- a/dev/null +++ b/noncore/games/go/gowidget.h | |||
@@ -0,0 +1,111 @@ | |||
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 | #ifndef GOWIDGET_H | ||
22 | #define GOWIDGET_H | ||
23 | |||
24 | #include <qmainwindow.h> | ||
25 | #include "amigo.h" | ||
26 | |||
27 | |||
28 | class QToolBar; | ||
29 | |||
30 | class GoMainWidget : public QMainWindow | ||
31 | { | ||
32 | Q_OBJECT | ||
33 | public: | ||
34 | GoMainWidget( QWidget *parent=0, const char* name=0); | ||
35 | protected: | ||
36 | void resizeEvent( QResizeEvent * ); | ||
37 | private: | ||
38 | QToolBar *toolbar; | ||
39 | |||
40 | }; | ||
41 | |||
42 | |||
43 | class QLabel; | ||
44 | class GoWidget : public QWidget | ||
45 | { | ||
46 | Q_OBJECT | ||
47 | public: | ||
48 | GoWidget( QWidget *parent=0, const char* name=0); | ||
49 | ~GoWidget(); | ||
50 | |||
51 | void doMove( int x, int y ); | ||
52 | void doComputerMove(); | ||
53 | |||
54 | void readConfig(); | ||
55 | void writeConfig(); | ||
56 | |||
57 | public slots: | ||
58 | void pass(); | ||
59 | void resign(); | ||
60 | void newGame(); | ||
61 | void setTwoplayer( bool ); | ||
62 | void setHandicap( int ); | ||
63 | signals: | ||
64 | void showScore( const QString& ); | ||
65 | void showTurn( const QPixmap& ); | ||
66 | |||
67 | protected: | ||
68 | void paintEvent( QPaintEvent * ); | ||
69 | void mousePressEvent( QMouseEvent * ); | ||
70 | void mouseMoveEvent( QMouseEvent * ); | ||
71 | void mouseReleaseEvent( QMouseEvent * ); | ||
72 | void resizeEvent( QResizeEvent * ); | ||
73 | private: | ||
74 | void init(); | ||
75 | void removeStone(short x, short y); | ||
76 | void placeStone (enum bVal c, short x, short y ); | ||
77 | |||
78 | void refresh( int x, int y ); | ||
79 | void showStone( int x, int y, enum bVal ); | ||
80 | void reportPrisoners(int,int); | ||
81 | |||
82 | inline int x2board( int x ) { return (x-bx+d/2)/d; } | ||
83 | inline int y2board( int y ) { return (y-by+d/2)/d; } | ||
84 | |||
85 | void endGame(); | ||
86 | |||
87 | bool twoplayer; | ||
88 | enum bVal currentPlayer; | ||
89 | bool gameActive; | ||
90 | int nPassed; | ||
91 | signed char board[19][19]; | ||
92 | |||
93 | int d; //distance between lines | ||
94 | int bx; //vertical baseline | ||
95 | int by; //horizontal baseline | ||
96 | |||
97 | int lastX,lastY; | ||
98 | int newX,newY; | ||
99 | |||
100 | static GoWidget *self; | ||
101 | |||
102 | friend void removestone(short x, short y); | ||
103 | friend voidintrPrisonerReport( short, short ); | ||
104 | friend void placestone(enum bVal c, short x, short y ); | ||
105 | }; | ||
106 | |||
107 | |||
108 | |||
109 | |||
110 | |||
111 | #endif | ||
diff --git a/noncore/games/go/killable.c b/noncore/games/go/killable.c new file mode 100644 index 0000000..3ed2d2e --- a/dev/null +++ b/noncore/games/go/killable.c | |||
@@ -0,0 +1,373 @@ | |||
1 | /* By Stoney Ballard */ | ||
2 | /* Ported from Pascal to C by Todd R. Johnson */ | ||
3 | |||
4 | #include "go.h" | ||
5 | #include "goplayutils.h" | ||
6 | #include "amigo.h" | ||
7 | |||
8 | extern intBoard bord, groupIDs; | ||
9 | extern boolBoard legal; | ||
10 | extern groupRec gList[maxGroup]; | ||
11 | extern short gMap[maxGroup], adjInAtari, adj2Libs, playMark, treeLibLim, | ||
12 | utilPlayLevel, killFlag, depthLimit, dbStop, showTrees; | ||
13 | extern pointList plist2; | ||
14 | |||
15 | /* | ||
16 | returns true if the group (at x, y) is killable. | ||
17 | if so, returns the point to play at in killx, killy. | ||
18 | */ | ||
19 | |||
20 | short me, him, depth, i, j, tryCount, tl, topMark, tkMark, mark2; | ||
21 | char sChar; | ||
22 | sPointList lList, dList; | ||
23 | point tp; | ||
24 | short libList[maxSPoint+1]; | ||
25 | short esc; | ||
26 | |||
27 | short mtNbrs(x, y) | ||
28 | short x, y; | ||
29 | { /* mtNbrs */ | ||
30 | short n = 0; | ||
31 | if ((x > 0) && (bord[x - 1][y] == 0)) | ||
32 | n = n + 1; | ||
33 | if ((x < maxPoint) && (bord[x + 1][y] == 0)) | ||
34 | n = n + 1; | ||
35 | if ((y > 0) && (bord[x][y - 1] == 0)) | ||
36 | n = n + 1; | ||
37 | if ((y < maxPoint) && (bord[x][y + 1] == 0)) | ||
38 | n = n + 1; | ||
39 | return n; | ||
40 | } /* mtNbrs */ | ||
41 | |||
42 | short killTree(tx, ty, gx, gy, escape, tkMark) | ||
43 | short tx, ty, gx, gy, *escape, tkMark; | ||
44 | { /* killTree */ | ||
45 | short curMark, mark2, mark3, i, j, k, tl, dStart, result; | ||
46 | sPointList lList1, lList2; | ||
47 | short libList[maxSPoint+1]; | ||
48 | point tp; | ||
49 | short esc = FALSE; | ||
50 | tryCount = tryCount + 1; | ||
51 | if (tryCount > tryLimit) | ||
52 | { | ||
53 | undoTo(tkMark); | ||
54 | /* for (i = 1; i <= depth - 1; i++) | ||
55 | { | ||
56 | sClearChar(sChar, rXor); | ||
57 | } */ | ||
58 | depth = 1; | ||
59 | return FALSE; | ||
60 | } | ||
61 | /* write(sChar); */ | ||
62 | depth = depth + 1; | ||
63 | curMark = playMark; | ||
64 | tryPlay(tx, ty, me); /* try my move */ | ||
65 | pause(); | ||
66 | if (gList[gMap[groupIDs[tx][ty]]].libC == 0) /* I'm dead */ | ||
67 | { | ||
68 | result = FALSE; | ||
69 | goto one; | ||
70 | } | ||
71 | else if (killFlag) /* I killed something of his */ | ||
72 | { | ||
73 | result = TRUE; | ||
74 | goto one; | ||
75 | } | ||
76 | else if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) /* safe */ | ||
77 | { | ||
78 | result = FALSE; | ||
79 | goto one; | ||
80 | } | ||
81 | else | ||
82 | { | ||
83 | sSpanGroup(gx, gy, &lList1); /* find his liberties */ | ||
84 | if (gList[gMap[groupIDs[tx][ty]]].libC == 1) /* he can kill me */ | ||
85 | { | ||
86 | if (lList1.indx < maxSPoint) /* add that option to his list */ | ||
87 | { | ||
88 | lList1.indx = lList1.indx + 1; | ||
89 | spanGroup(tx, ty, &plist2); /* find my liberty */ | ||
90 | lList1.p[lList1.indx].px = plist2.p[1].px; | ||
91 | lList1.p[lList1.indx].py = plist2.p[1].py; | ||
92 | } | ||
93 | else | ||
94 | { | ||
95 | result = FALSE; | ||
96 | goto one; | ||
97 | } | ||
98 | } | ||
99 | for (i = 1; i <= maxSPoint; i++) /* init liblist so diags can be marked */ | ||
100 | libList[i] = -1; | ||
101 | if ((utilPlayLevel > 4) && | ||
102 | (lList1.indx > 1) && | ||
103 | (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* try diags */ | ||
104 | { | ||
105 | listDiags(gx, gy, &dList); | ||
106 | j = 0; | ||
107 | i = lList1.indx; | ||
108 | while ((j < dList.indx) && | ||
109 | (i < maxSPoint)) | ||
110 | { | ||
111 | j = j + 1; | ||
112 | i = i + 1; | ||
113 | libList[i] = 0; /* mark this as a diag */ | ||
114 | lList1.p[i].px = dList.p[j].px; | ||
115 | lList1.p[i].py = dList.p[j].py; | ||
116 | } | ||
117 | lList1.indx = i; | ||
118 | } | ||
119 | if (lList1.indx > 1) /* sort by decreasing lib count */ | ||
120 | { | ||
121 | for (i = 1; i <= lList1.indx; i++) | ||
122 | if (libList[i] != 0) /* diags are tried last */ | ||
123 | { | ||
124 | mark2 = playMark; | ||
125 | tryPlay(lList1.p[i].px, lList1.p[i].py, him); | ||
126 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; | ||
127 | if ((libList[i] > treeLibLim) || | ||
128 | ((libList[i] > (depthLimit - depth)) && | ||
129 | (libList[i] > 2))) | ||
130 | { | ||
131 | *escape = TRUE; | ||
132 | result = FALSE; | ||
133 | goto one; | ||
134 | } | ||
135 | undoTo(mark2); | ||
136 | } | ||
137 | for (i = 1; i <= lList1.indx - 1; i++) | ||
138 | for (j = i + 1; j <= lList1.indx; j++) | ||
139 | if (libList[i] < libList[j]) | ||
140 | { | ||
141 | tl = libList[i]; | ||
142 | libList[i] = libList[j]; | ||
143 | libList[j] = tl; | ||
144 | tp = lList1.p[i]; | ||
145 | lList1.p[i] = lList1.p[j]; | ||
146 | lList1.p[j] = tp; | ||
147 | } | ||
148 | } | ||
149 | for (i = 1; i <= lList1.indx + 1; i++) /* try his responses */ | ||
150 | { | ||
151 | mark2 = playMark; | ||
152 | if (i <= lList1.indx) /* try his move */ | ||
153 | { | ||
154 | tryPlay(lList1.p[i].px, lList1.p[i].py, him); /* play his response */ | ||
155 | pause(); | ||
156 | if (gList[gMap[groupIDs[lList1.p[i].px] | ||
157 | [lList1.p[i].py]]].libC < 2) | ||
158 | goto two; /* a bogus move */ | ||
159 | } | ||
160 | else if (gList[gMap[groupIDs[gx][gy]]].libC <= 1) | ||
161 | { | ||
162 | result = TRUE; | ||
163 | goto one; | ||
164 | } | ||
165 | if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) | ||
166 | { | ||
167 | *escape = TRUE; | ||
168 | result = FALSE; | ||
169 | goto one; | ||
170 | } | ||
171 | if (gList[gMap[groupIDs[gx][gy]]].libC > 1) | ||
172 | { /* look at my responses */ | ||
173 | sSpanGroup(gx, gy, &lList2); /* list his liberties */ | ||
174 | dStart = lList2.indx + 1; | ||
175 | if (adjInAtari) /* he wins */ | ||
176 | { | ||
177 | result = FALSE; | ||
178 | goto one; | ||
179 | } | ||
180 | if ((lList2.indx > 2) && adj2Libs) /* he wins */ | ||
181 | { | ||
182 | result = FALSE; | ||
183 | goto one; | ||
184 | } | ||
185 | for (k = 1; k <= maxSPoint; k++) | ||
186 | libList[k] = -1; | ||
187 | if (utilPlayLevel > 4) /* account for diagonal moves */ | ||
188 | { | ||
189 | listDiags(gx, gy, &dList); | ||
190 | j = 0; | ||
191 | k = lList2.indx; | ||
192 | while ((j < dList.indx) && | ||
193 | (k < maxSPoint)) | ||
194 | { | ||
195 | j = j + 1; | ||
196 | k = k + 1; | ||
197 | libList[k] = 100; | ||
198 | lList2.p[k].px = dList.p[j].px; | ||
199 | lList2.p[k].py = dList.p[j].py; | ||
200 | } | ||
201 | lList2.indx = k; | ||
202 | } | ||
203 | if (lList2.indx > 1) /* sort by increasing lib count */ | ||
204 | { | ||
205 | for (k = 1; k <= lList2.indx; k++) | ||
206 | if (libList[k] != 100) /* diags go last */ | ||
207 | { | ||
208 | mark3 = playMark; | ||
209 | tryPlay(lList2.p[k].px, lList2.p[k].py, me); | ||
210 | libList[k] = gList[gMap[groupIDs[gx][gy]]].libC; | ||
211 | undoTo(mark3); | ||
212 | } | ||
213 | for (k = 1; k <= lList2.indx - 1; k++) | ||
214 | for (j = k + 1; j <= lList2.indx; j++) | ||
215 | if (libList[k] > libList[j]) | ||
216 | { | ||
217 | tl = libList[k]; | ||
218 | libList[k] = libList[j]; | ||
219 | libList[j] = tl; | ||
220 | tp = lList2.p[k]; | ||
221 | lList2.p[k] = lList2.p[j]; | ||
222 | lList2.p[j] = tp; | ||
223 | } | ||
224 | else if ((libList[k] == libList[j]) && | ||
225 | (libList[k] == 1)) | ||
226 | if (mtNbrs(lList2.p[k].px, lList2.p[k].py) < | ||
227 | mtNbrs(lList2.p[j].px, lList2.p[j].py)) | ||
228 | { | ||
229 | tl = libList[k]; | ||
230 | libList[k] = libList[j]; | ||
231 | libList[j] = tl; | ||
232 | tp = lList2.p[k]; | ||
233 | lList2.p[k] = lList2.p[j]; | ||
234 | lList2.p[j] = tp; | ||
235 | } | ||
236 | } | ||
237 | for (j = 1; j <= lList2.indx; j++) | ||
238 | { | ||
239 | if (killTree(lList2.p[j].px, lList2.p[j].py, gx, | ||
240 | gy, &esc, tkMark)) | ||
241 | goto two; /* this kills him */ | ||
242 | if (esc && (j >= dStart)) | ||
243 | { | ||
244 | result = FALSE; | ||
245 | goto one; /* don't bother with more diags if escapes */ | ||
246 | } | ||
247 | } | ||
248 | result = FALSE; /* none of my responses kills him */ | ||
249 | goto one; | ||
250 | } | ||
251 | two: | ||
252 | undoTo(mark2); | ||
253 | } | ||
254 | result = TRUE; /* none of his responses saves him */ | ||
255 | } | ||
256 | one: | ||
257 | undoTo(curMark); | ||
258 | /* sClearChar(sChar, rXor); */ | ||
259 | depth = depth - 1; | ||
260 | return result; | ||
261 | } /* killTree */ | ||
262 | |||
263 | short tKillTree(tx, ty, gx, gy) | ||
264 | short tx, ty, gx, gy; | ||
265 | { /* tKillTree */ | ||
266 | short tkMark, escape; | ||
267 | tryCount = 0; | ||
268 | tkMark = playMark; | ||
269 | return killTree(tx, ty, gx, gy, &escape, tkMark); | ||
270 | } /* tKillTree */ | ||
271 | |||
272 | short killable(gx, gy, killx, killy) | ||
273 | short gx, gy, *killx, *killy; | ||
274 | { /* killable */ | ||
275 | #ifdef DEBUG | ||
276 | printf( "killable\n" ); | ||
277 | showTrees = TRUE; | ||
278 | #endif | ||
279 | dbStop = TRUE; | ||
280 | him = bord[gx][gy]; /* find out who I am */ | ||
281 | me = -him; | ||
282 | /* if (me == 1) | ||
283 | sChar = '>'; | ||
284 | else | ||
285 | sChar = '|'; */ | ||
286 | /* write(sChar); */ | ||
287 | depth = 1; | ||
288 | topMark = playMark; | ||
289 | sSpanGroup(gx, gy, &lList); /* find his liberties */ | ||
290 | if (lList.indx == 1) | ||
291 | { | ||
292 | *killx = lList.p[1].px; | ||
293 | *killy = lList.p[1].py; | ||
294 | return TRUE; | ||
295 | } | ||
296 | else if (lList.indx > treeLibLim) | ||
297 | return FALSE; | ||
298 | else if (adjInAtari) | ||
299 | return FALSE; | ||
300 | else if ((lList.indx > 2) && adj2Libs) | ||
301 | return FALSE; | ||
302 | else | ||
303 | { | ||
304 | for (i = 1; i <= maxSPoint; i++) | ||
305 | libList[i] = -1; | ||
306 | if (utilPlayLevel > 4) /* account for diagonal moves */ | ||
307 | { | ||
308 | listDiags(gx, gy, &dList); | ||
309 | j = 0; | ||
310 | i = lList.indx; | ||
311 | while ((j < dList.indx) && | ||
312 | (i < maxSPoint)) | ||
313 | { | ||
314 | j = j + 1; | ||
315 | i = i + 1; | ||
316 | libList[i] = 100; | ||
317 | lList.p[i].px = dList.p[j].px; | ||
318 | lList.p[i].py = dList.p[j].py; | ||
319 | } | ||
320 | lList.indx = i; | ||
321 | } | ||
322 | if (lList.indx > 1) /* sort by increasing lib count */ | ||
323 | { | ||
324 | for (i = 1; i <= lList.indx; i++) | ||
325 | if (libList[i] != 100) /* diags go last */ | ||
326 | { | ||
327 | mark2 = playMark; | ||
328 | tryPlay(lList.p[i].px, lList.p[i].py, me); | ||
329 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; | ||
330 | undoTo(mark2); | ||
331 | } | ||
332 | for (i = 1; i <= lList.indx - 1; i++) | ||
333 | for (j = i + 1; j <= lList.indx; j++) | ||
334 | if (libList[i] > libList[j]) | ||
335 | { | ||
336 | tl = libList[i]; | ||
337 | libList[i] = libList[j]; | ||
338 | libList[j] = tl; | ||
339 | tp = lList.p[i]; | ||
340 | lList.p[i] = lList.p[j]; | ||
341 | lList.p[j] = tp; | ||
342 | } | ||
343 | else if ((libList[i] == libList[j]) && | ||
344 | (libList[i] == 1)) | ||
345 | if (mtNbrs(lList.p[i].px, lList.p[i].py) < | ||
346 | mtNbrs(lList.p[j].px, lList.p[j].py)) | ||
347 | { | ||
348 | tl = libList[i]; | ||
349 | libList[i] = libList[j]; | ||
350 | libList[j] = tl; | ||
351 | tp = lList.p[i]; | ||
352 | lList.p[i] = lList.p[j]; | ||
353 | lList.p[j] = tp; | ||
354 | } | ||
355 | } | ||
356 | for (i = 1; i <= lList.indx; i++) | ||
357 | { | ||
358 | if (legal[lList.p[i].px][lList.p[i].py]) | ||
359 | { | ||
360 | *killx = lList.p[i].px; | ||
361 | *killy = lList.p[i].py; | ||
362 | if (tKillTree(*killx, *killy, gx, gy)) | ||
363 | { | ||
364 | /* sClearChar(sChar, rXor); */ | ||
365 | return TRUE; | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | return FALSE; | ||
370 | } | ||
371 | /* sClearChar(sChar, rXor); */ | ||
372 | } /* killable */ | ||
373 | |||
diff --git a/noncore/games/go/main.cpp b/noncore/games/go/main.cpp new file mode 100644 index 0000000..c7e2669 --- a/dev/null +++ b/noncore/games/go/main.cpp | |||
@@ -0,0 +1,35 @@ | |||
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 "gowidget.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | #include <stdio.h> | ||
26 | |||
27 | int main( int argc, char ** argv) | ||
28 | { | ||
29 | QPEApplication app( argc, argv ); | ||
30 | |||
31 | GoMainWidget m; | ||
32 | m.setCaption( GoWidget::tr("Go") ); | ||
33 | app.showMainWidget( &m ); | ||
34 | return app.exec(); | ||
35 | } | ||
diff --git a/noncore/games/go/qpe-go.control b/noncore/games/go/qpe-go.control new file mode 100644 index 0000000..edc106b --- a/dev/null +++ b/noncore/games/go/qpe-go.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/go apps/Games/go.desktop | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: The game of Go | ||
9 | A game for the Qtopia environment. | ||
diff --git a/noncore/games/mindbreaker/.cvsignore b/noncore/games/mindbreaker/.cvsignore new file mode 100644 index 0000000..415ec09 --- a/dev/null +++ b/noncore/games/mindbreaker/.cvsignore | |||
@@ -0,0 +1,4 @@ | |||
1 | Makefile | ||
2 | moc_* | ||
3 | helpdialog.cpp | ||
4 | helpdialog.h | ||
diff --git a/noncore/games/mindbreaker/Makefile.in b/noncore/games/mindbreaker/Makefile.in new file mode 100644 index 0000000..88f6fb1 --- a/dev/null +++ b/noncore/games/mindbreaker/Makefile.in | |||
@@ -0,0 +1,117 @@ | |||
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 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= mindbreaker | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =mindbreaker.h | ||
27 | SOURCES =main.cpp \ | ||
28 | mindbreaker.cpp | ||
29 | OBJECTS =main.o \ | ||
30 | mindbreaker.o | ||
31 | INTERFACES = | ||
32 | UICDECLS = | ||
33 | UICIMPLS = | ||
34 | SRCMOC =moc_mindbreaker.cpp | ||
35 | OBJMOC =moc_mindbreaker.o | ||
36 | |||
37 | |||
38 | ####### Implicit rules | ||
39 | |||
40 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
41 | |||
42 | .cpp.o: | ||
43 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
44 | |||
45 | .cxx.o: | ||
46 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
47 | |||
48 | .cc.o: | ||
49 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
50 | |||
51 | .C.o: | ||
52 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
53 | |||
54 | .c.o: | ||
55 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
56 | |||
57 | ####### Build rules | ||
58 | |||
59 | |||
60 | all: $(DESTDIR)$(TARGET) | ||
61 | |||
62 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
63 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
64 | |||
65 | moc: $(SRCMOC) | ||
66 | |||
67 | tmake: | ||
68 | tmake mindbreaker.pro | ||
69 | |||
70 | clean: | ||
71 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
72 | -rm -f *~ core | ||
73 | -rm -f allmoc.cpp | ||
74 | |||
75 | ####### Extension Modules | ||
76 | |||
77 | listpromodules: | ||
78 | @echo | ||
79 | |||
80 | listallmodules: | ||
81 | @echo | ||
82 | |||
83 | listaddonpromodules: | ||
84 | @echo | ||
85 | |||
86 | listaddonentmodules: | ||
87 | @echo | ||
88 | |||
89 | |||
90 | REQUIRES= | ||
91 | |||
92 | ####### Sub-libraries | ||
93 | |||
94 | |||
95 | ###### Combined headers | ||
96 | |||
97 | |||
98 | |||
99 | ####### Compile | ||
100 | |||
101 | main.o: main.cpp \ | ||
102 | mindbreaker.h \ | ||
103 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
104 | |||
105 | mindbreaker.o: mindbreaker.cpp \ | ||
106 | mindbreaker.h \ | ||
107 | $(QPEDIR)/include/qpe/resource.h \ | ||
108 | $(QPEDIR)/include/qpe/config.h \ | ||
109 | $(QPEDIR)/include/qpe/qpetoolbar.h | ||
110 | |||
111 | moc_mindbreaker.o: moc_mindbreaker.cpp \ | ||
112 | mindbreaker.h | ||
113 | |||
114 | moc_mindbreaker.cpp: mindbreaker.h | ||
115 | $(MOC) mindbreaker.h -o moc_mindbreaker.cpp | ||
116 | |||
117 | |||
diff --git a/noncore/games/mindbreaker/main.cpp b/noncore/games/mindbreaker/main.cpp new file mode 100644 index 0000000..8ba0fde --- a/dev/null +++ b/noncore/games/mindbreaker/main.cpp | |||
@@ -0,0 +1,35 @@ | |||
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 "mindbreaker.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | int main( int argc, char **argv ) | ||
26 | { | ||
27 | QPEApplication a( argc, argv ); | ||
28 | |||
29 | MindBreaker w(0, "new window"); | ||
30 | w.setCaption("Mind Breaker"); | ||
31 | QPEApplication::setInputMethodHint( &w, QPEApplication::AlwaysOff ); | ||
32 | a.showMainWidget(&w); | ||
33 | |||
34 | return a.exec(); | ||
35 | } | ||
diff --git a/noncore/games/mindbreaker/mindbreaker.cpp b/noncore/games/mindbreaker/mindbreaker.cpp new file mode 100644 index 0000000..b0e4d88 --- a/dev/null +++ b/noncore/games/mindbreaker/mindbreaker.cpp | |||
@@ -0,0 +1,818 @@ | |||
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 "mindbreaker.h" | ||
22 | |||
23 | #include <qpe/resource.h> | ||
24 | #include <qpe/config.h> | ||
25 | |||
26 | #include <qpainter.h> | ||
27 | #include <qpixmap.h> | ||
28 | #include <qpe/qpetoolbar.h> | ||
29 | #include <qtoolbutton.h> | ||
30 | #include <qpushbutton.h> | ||
31 | #include <qmessagebox.h> | ||
32 | #include <qlabel.h> | ||
33 | #include <qstyle.h> | ||
34 | |||
35 | #include <stdlib.h> | ||
36 | #include <sys/time.h> | ||
37 | #include <unistd.h> | ||
38 | |||
39 | static int pegRTTI = 3393393; | ||
40 | |||
41 | /* helper class, */ | ||
42 | class Peg : public QCanvasRectangle | ||
43 | { | ||
44 | public: | ||
45 | Peg(QCanvas *canvas, int type, int go = -1, int pos = -1); | ||
46 | int rtti() const {return pegRTTI; } | ||
47 | void advance(int phase); | ||
48 | |||
49 | bool hit( const QPoint &) const; | ||
50 | |||
51 | /* a placed peg is one that has been set down on the board correctly and | ||
52 | should not be moved, only copied */ | ||
53 | bool placed() const; | ||
54 | void setPlaced(bool); | ||
55 | |||
56 | int pegGo() const; | ||
57 | int pegPos() const; | ||
58 | void setPegPos(int); | ||
59 | |||
60 | int type() const; | ||
61 | |||
62 | static void buildImages(); | ||
63 | static QImage imageForType(int t); | ||
64 | |||
65 | static int eggLevel; | ||
66 | |||
67 | protected: | ||
68 | void drawShape(QPainter &); | ||
69 | private: | ||
70 | static QVector<QImage> normalPegs; | ||
71 | static QVector<QImage> specialPegs; | ||
72 | |||
73 | bool isplaced; | ||
74 | int pegtype; | ||
75 | int peg_go; | ||
76 | int peg_pos; | ||
77 | |||
78 | int aniStep; | ||
79 | }; | ||
80 | |||
81 | int Peg::eggLevel = 0; | ||
82 | QVector<QImage> Peg::normalPegs; | ||
83 | QVector<QImage> Peg::specialPegs; | ||
84 | |||
85 | void Peg::buildImages() | ||
86 | { | ||
87 | |||
88 | QImage pegs = Resource::loadImage("mindbreaker/pegs"); | ||
89 | int x = 0; | ||
90 | int y = 0; | ||
91 | int i; | ||
92 | eggLevel = 0; | ||
93 | normalPegs.resize(10); | ||
94 | for (i = 0; i < 6; i++) { | ||
95 | normalPegs.insert(i, new QImage(pegs.copy(x, y, peg_size, peg_size))); | ||
96 | x += peg_size; | ||
97 | } | ||
98 | specialPegs.resize(5); | ||
99 | for (i = 0; i < 5; i++) { | ||
100 | specialPegs.insert(i, new QImage(pegs.copy(x,y,peg_size, peg_size))); | ||
101 | x += peg_size; | ||
102 | } | ||
103 | |||
104 | QImage image = Resource::loadImage("mindbreaker/mindbreaker"); | ||
105 | /* copy from master image to functional images */ | ||
106 | x = 0; | ||
107 | y = panel_height; | ||
108 | normalPegs.insert(8, | ||
109 | new QImage(image.copy(x, y, panel_width, panel_height))); | ||
110 | y += panel_height; | ||
111 | y += title_height; | ||
112 | normalPegs.insert(9, | ||
113 | new QImage(image.copy(x, y, title_width, title_height))); | ||
114 | y += title_height; | ||
115 | |||
116 | x = 6 * peg_size; | ||
117 | normalPegs.insert(6, | ||
118 | new QImage(image.copy(x, y, answerpeg_size, answerpeg_size))); | ||
119 | x += answerpeg_size; | ||
120 | normalPegs.insert(7, | ||
121 | new QImage(image.copy(x, y, answerpeg_size, answerpeg_size))); | ||
122 | } | ||
123 | |||
124 | QImage Peg::imageForType(int t) | ||
125 | { | ||
126 | if (eggLevel > t ) { | ||
127 | if( t < 5) { | ||
128 | return *specialPegs[t]; | ||
129 | } else { | ||
130 | return *normalPegs[rand() % 6]; | ||
131 | } | ||
132 | } | ||
133 | return *normalPegs[t]; | ||
134 | } | ||
135 | |||
136 | Peg::Peg(QCanvas *canvas , int t, int g = -1, int p = -1) | ||
137 | : QCanvasRectangle(canvas) | ||
138 | { | ||
139 | setSize(normalPegs[t]->width(), normalPegs[t]->height() ); | ||
140 | pegtype = t; | ||
141 | isplaced = FALSE; | ||
142 | peg_pos = p; | ||
143 | peg_go = g; | ||
144 | aniStep = rand() % 6; | ||
145 | setAnimated(TRUE); | ||
146 | } | ||
147 | |||
148 | void Peg::advance(int phase) { | ||
149 | if (phase == 0) | ||
150 | aniStep = (++aniStep) % 6; | ||
151 | else { | ||
152 | hide(); | ||
153 | show(); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | void Peg::drawShape(QPainter &p ) | ||
158 | { | ||
159 | if ((pegtype == 5) && eggLevel > 5) { | ||
160 | p.drawImage(x(), y(), *normalPegs[aniStep]); | ||
161 | } else | ||
162 | p.drawImage(x(), y(), imageForType(pegtype)); | ||
163 | } | ||
164 | |||
165 | bool Peg::hit( const QPoint &p ) const | ||
166 | { | ||
167 | int ix = p.x() - int(x()); | ||
168 | int iy = p.y() - int(y()); | ||
169 | if (!normalPegs[pegtype]->valid(ix, iy)) | ||
170 | return FALSE; | ||
171 | QRgb pixel = normalPegs[pegtype]->pixel(ix, iy); | ||
172 | return (qAlpha(pixel ) != 0); | ||
173 | } | ||
174 | |||
175 | inline bool Peg::placed() const | ||
176 | { | ||
177 | return isplaced; | ||
178 | } | ||
179 | |||
180 | inline int Peg::pegGo() const | ||
181 | { | ||
182 | return peg_go; | ||
183 | } | ||
184 | |||
185 | inline int Peg::pegPos() const | ||
186 | { | ||
187 | return peg_pos; | ||
188 | } | ||
189 | |||
190 | inline void Peg::setPegPos(int p) | ||
191 | { | ||
192 | peg_pos = p; | ||
193 | } | ||
194 | |||
195 | inline void Peg::setPlaced(bool p) | ||
196 | { | ||
197 | isplaced = p; | ||
198 | } | ||
199 | |||
200 | inline int Peg::type() const | ||
201 | { | ||
202 | return pegtype; | ||
203 | } | ||
204 | |||
205 | /* Load the main image, copy from it the pegs, the board, and the answer image | ||
206 | * and use these to create the tray, answer and board | ||
207 | */ | ||
208 | MindBreaker::MindBreaker( QWidget *parent=0, const char *name=0, int wFlags=0 ) | ||
209 | : QMainWindow(parent, name, wFlags), | ||
210 | canvas(board_height, board_width) | ||
211 | { | ||
212 | MindBreakerBoard *m = new MindBreakerBoard(canvas, this); | ||
213 | setCentralWidget(m); | ||
214 | |||
215 | setToolBarsMovable( FALSE ); | ||
216 | |||
217 | QPEToolBar *tb = new QPEToolBar(this); | ||
218 | tb->setHorizontalStretchable( TRUE ); | ||
219 | |||
220 | QPixmap newicon = Resource::loadPixmap("new"); | ||
221 | new QToolButton(newicon, tr("New Game"), 0, | ||
222 | m, SLOT(clear()), tb, "NewGame"); | ||
223 | |||
224 | score = new QToolButton(tb); | ||
225 | score->setText(""); | ||
226 | score->setMaximumHeight(20); | ||
227 | score->setUsesTextLabel(TRUE); | ||
228 | tb->setStretchableWidget(score); | ||
229 | |||
230 | connect(m, SIGNAL(scoreChanged(int, int)), this, SLOT(setScore(int, int))); | ||
231 | connect(score, SIGNAL(clicked()), m, SLOT(resetScore())); | ||
232 | |||
233 | int a, b; | ||
234 | m->getScore(&a, &b); | ||
235 | setScore(a,b); | ||
236 | } | ||
237 | |||
238 | void MindBreaker::setScore(int turns, int games) | ||
239 | { | ||
240 | double average; | ||
241 | double total_turns = turns; | ||
242 | double total_games = games; | ||
243 | |||
244 | if(total_games > 0) | ||
245 | average = total_turns / total_games; | ||
246 | else | ||
247 | average = 0.0; | ||
248 | |||
249 | score->setText(tr("win avg: %1 turns (%2 games)").arg(average).arg(games)); | ||
250 | } | ||
251 | |||
252 | |||
253 | MindBreakerBoard::MindBreakerBoard( QCanvas &c, QWidget *parent=0, | ||
254 | const char *name=0, int wFlags=0 ) | ||
255 | : QCanvasView(&c, parent, name, wFlags) | ||
256 | { | ||
257 | int i, x, y; | ||
258 | struct timeval tv; | ||
259 | |||
260 | current_go = 0; | ||
261 | gettimeofday(&tv, 0); | ||
262 | |||
263 | srand(tv.tv_usec); | ||
264 | |||
265 | canvas()->setAdvancePeriod(500); | ||
266 | |||
267 | QImage image = Resource::loadImage("mindbreaker/mindbreaker"); | ||
268 | |||
269 | /* copy from master image to functional images */ | ||
270 | x = 0; | ||
271 | y = 0; | ||
272 | panelImage = image.copy(x,y, panel_width, panel_height); | ||
273 | y += panel_height; | ||
274 | y += panel_height; | ||
275 | |||
276 | titleImage = image.copy(x, y, title_width, title_height); | ||
277 | |||
278 | Peg::buildImages(); // must be done BEFORE any pegs are made | ||
279 | |||
280 | current_highlight = new Peg(canvas(), 8); | ||
281 | current_highlight->setPlaced(TRUE); | ||
282 | current_highlight->setX(0); | ||
283 | current_highlight->setY(board_height - ((current_go + 1) * panel_height)); | ||
284 | current_highlight->setZ(0); | ||
285 | current_highlight->show(); | ||
286 | |||
287 | |||
288 | /* set up the game */ | ||
289 | Config c("MindBreaker", Config::User); | ||
290 | c.setGroup("Board"); | ||
291 | game_over = FALSE; | ||
292 | if (c.readNumEntry("Answer0") < 0) { | ||
293 | for (i = 0; i < 4; i++) { | ||
294 | answer[i] = rand() % 6; | ||
295 | current_guess[i] = 6; | ||
296 | } | ||
297 | total_turns = 0; | ||
298 | total_games = 0; | ||
299 | } else { | ||
300 | int j; | ||
301 | c.setGroup("Score"); | ||
302 | total_turns = c.readNumEntry("Turns"); | ||
303 | total_games = c.readNumEntry("Games"); | ||
304 | if(total_turns < 0) | ||
305 | total_turns = 0; | ||
306 | if(total_games < 0) | ||
307 | total_games = 0; | ||
308 | |||
309 | |||
310 | checkScores(); | ||
311 | c.setGroup("Board"); | ||
312 | for(i = 0; i < 4; i++) | ||
313 | answer[i] = c.readNumEntry(QString("Answer%1").arg(i)); | ||
314 | /* read, and parse past guesses */ | ||
315 | current_go = 0; | ||
316 | for(j=0; j < 9; j++) { | ||
317 | current_guess[0] = c.readNumEntry(QString("Go%1p0").arg(j)); | ||
318 | if (current_guess[0] < 0) | ||
319 | break; | ||
320 | placeGuessPeg(0, current_guess[0]); | ||
321 | current_guess[1] = c.readNumEntry(QString("Go%1p1").arg(j)); | ||
322 | placeGuessPeg(1, current_guess[1]); | ||
323 | current_guess[2] = c.readNumEntry(QString("Go%1p2").arg(j)); | ||
324 | placeGuessPeg(2, current_guess[2]); | ||
325 | current_guess[3] = c.readNumEntry(QString("Go%1p3").arg(j)); | ||
326 | placeGuessPeg(3, current_guess[3]); | ||
327 | checkGuess(); | ||
328 | } | ||
329 | for(i = 0; i < 4; i++) { | ||
330 | current_guess[i] = c.readNumEntry(QString("CurrentGo%1").arg(i)); | ||
331 | if (current_guess[i] != 6) | ||
332 | placeGuessPeg(i, current_guess[i]); | ||
333 | } | ||
334 | } | ||
335 | |||
336 | /* draw initial screen */ | ||
337 | drawBackground(); | ||
338 | canvas()->update(); | ||
339 | } | ||
340 | |||
341 | MindBreakerBoard::~MindBreakerBoard() | ||
342 | { | ||
343 | int i, j; | ||
344 | if (game_over) { | ||
345 | current_go = 0; | ||
346 | /* clear the answer, clear the guess */ | ||
347 | for (i = 0; i < 4; i++) { | ||
348 | answer[i] = rand() % 6; | ||
349 | current_guess[i] = 6; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | Config c("MindBreaker", Config::User); | ||
354 | c.setGroup("Board"); | ||
355 | c.clearGroup(); | ||
356 | /* write the board */ | ||
357 | for (i = 0; i < current_go; i++) { | ||
358 | for(j = 0; j < 4; j++) | ||
359 | c.writeEntry(tr("Go%1p%2").arg(i).arg(j), past_guesses[4*i+j]); | ||
360 | } | ||
361 | for(j = 0; j < 4; j++) | ||
362 | c.writeEntry(tr("CurrentGo%1").arg(j), current_guess[j]); | ||
363 | for(j = 0; j < 4; j++) | ||
364 | c.writeEntry(tr("Answer%1").arg(j), answer[j]); | ||
365 | |||
366 | c.setGroup("Score"); | ||
367 | /* write the score */ | ||
368 | |||
369 | c.writeEntry("Turns", total_turns); | ||
370 | c.writeEntry("Games", total_games); | ||
371 | } | ||
372 | |||
373 | void MindBreakerBoard::getScore(int *a, int *b) | ||
374 | { | ||
375 | *a = total_turns; | ||
376 | *b = total_games; | ||
377 | return; | ||
378 | } | ||
379 | |||
380 | void MindBreakerBoard::placeGuessPeg(int pos, int pegId) | ||
381 | { | ||
382 | int x = first_peg_x_diff + (pos * peg_spacing); | ||
383 | int y = board_height - ((current_go + 1) * panel_height) | ||
384 | + first_peg_y_diff; | ||
385 | |||
386 | Peg *peg = new Peg(canvas(), pegId, current_go, pos); | ||
387 | peg->setPegPos(pos); | ||
388 | peg->setPlaced(TRUE); | ||
389 | peg->setX(x); | ||
390 | peg->setY(y); | ||
391 | peg->setZ(2); | ||
392 | peg->show(); | ||
393 | } | ||
394 | |||
395 | void MindBreakerBoard::drawBackground() | ||
396 | { | ||
397 | int i, j, x, y, x_gap, y_gap; | ||
398 | QPixmap background = QPixmap(canvas()->width(), canvas()->height()); | ||
399 | |||
400 | QPainter painter(&background); | ||
401 | |||
402 | painter.fillRect(0, 0, canvas()->width(), canvas()->height(), QColor(0,0,0)); | ||
403 | /* very first thing is to draw the bins, as everything else needs | ||
404 | * to be drawn over them */ | ||
405 | |||
406 | QPen pen(QColor(85, 45, 27), 4); | ||
407 | painter.setPen(pen); | ||
408 | x_gap = canvas()->width() - (panel_width + (2 * bin_margin)); | ||
409 | //x_gap += peg_size >> 1; | ||
410 | if (x_gap < 1) | ||
411 | x_gap = 1; | ||
412 | |||
413 | y_gap = board_height / 6; | ||
414 | y_gap -= (2 * bin_margin); | ||
415 | //y_gap += peg_size >> 1; | ||
416 | if (y_gap < 1) | ||
417 | y_gap = 1; | ||
418 | x = panel_width + bin_margin - (peg_size >> 1); | ||
419 | y = bin_margin - (peg_size >> 1) + 2; | ||
420 | |||
421 | for (i = 0; i < 6; i++) { | ||
422 | for (j = 0; j < 10; j++) { | ||
423 | int rx = x + (rand() % x_gap); | ||
424 | int ry = y + (rand() % y_gap); | ||
425 | painter.drawImage(rx,ry, Peg::imageForType(i)); | ||
426 | } | ||
427 | y += board_height / 6; | ||
428 | } | ||
429 | /* now draw the surrounding boxes */ | ||
430 | x_gap = canvas()->width() - panel_width; | ||
431 | if (x_gap < 1) x_gap = 1; | ||
432 | y_gap = board_height / 6; | ||
433 | x = panel_width; | ||
434 | y = 1; | ||
435 | |||
436 | for (i = 0; i < 6; i++) { | ||
437 | painter.drawRect(x, y, x_gap, y_gap); | ||
438 | y += y_gap; | ||
439 | } | ||
440 | |||
441 | x = 0; | ||
442 | y = 0; | ||
443 | |||
444 | painter.drawImage(x,y, titleImage); | ||
445 | y = title_height; | ||
446 | /* now nine gues panels */ | ||
447 | for (i = 0; i < 9; i ++) { | ||
448 | painter.drawImage(x, y, panelImage); | ||
449 | y += panel_height; | ||
450 | } | ||
451 | |||
452 | painter.flush(); | ||
453 | canvas()->setBackgroundPixmap(background); | ||
454 | } | ||
455 | |||
456 | void MindBreakerBoard::checkGuess() | ||
457 | { | ||
458 | int i,j; | ||
459 | int num_white = 0; | ||
460 | int num_black = 0; | ||
461 | int copy_answer[4]; | ||
462 | int copy_guess[4]; | ||
463 | |||
464 | for(i = 0; i < 4; i++) { | ||
465 | copy_answer[i] = answer[i]; | ||
466 | copy_guess[i] = current_guess[i]; | ||
467 | if (current_guess[i] == 6) | ||
468 | return; | ||
469 | if (answer[i] == current_guess[i]) { | ||
470 | num_black++; | ||
471 | copy_answer[i] = 6; | ||
472 | copy_guess[i] = 7; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | /* now sure that user has completed a 'guess' */ | ||
477 | for (i = 0; i < 4; i++) { | ||
478 | if (copy_guess[i] == 7) | ||
479 | continue; // already marked for a black | ||
480 | for (j = 0; j < 4; j++) { | ||
481 | if(copy_guess[i] == copy_answer[j]) { | ||
482 | copy_answer[j] = 6; | ||
483 | num_white++; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | } | ||
488 | |||
489 | int x = answerpegx; | ||
490 | int y = (board_height - ((current_go + 1) * panel_height)) + answerpegy; | ||
491 | |||
492 | if (num_black == 4) | ||
493 | game_over = TRUE; | ||
494 | |||
495 | while(num_black > 0) { | ||
496 | Peg *p = new Peg(canvas(), 7); | ||
497 | p->setPlaced(TRUE); | ||
498 | p->setX(x); | ||
499 | p->setY(y); | ||
500 | p->setZ(1); | ||
501 | p->show(); | ||
502 | num_black--; | ||
503 | |||
504 | if (x == answerpegx) | ||
505 | x = answerpegx + answerpeg_diff; | ||
506 | else { | ||
507 | x = answerpegx; | ||
508 | y += answerpeg_diff; | ||
509 | } | ||
510 | } | ||
511 | while(num_white > 0){ | ||
512 | Peg *p = new Peg(canvas(), 6); | ||
513 | p->setPlaced(TRUE); | ||
514 | p->setX(x); | ||
515 | p->setY(y); | ||
516 | p->setZ(1); | ||
517 | p->show(); | ||
518 | num_white--; | ||
519 | |||
520 | if (x == answerpegx) | ||
521 | x = answerpegx + answerpeg_diff; | ||
522 | else { | ||
523 | x = answerpegx; | ||
524 | y += answerpeg_diff; | ||
525 | } | ||
526 | } | ||
527 | /* move to next go */ | ||
528 | for(i = 0; i < 4; i++) { | ||
529 | past_guesses[4*current_go+i] = current_guess[i]; | ||
530 | current_guess[i] = 6; | ||
531 | } | ||
532 | |||
533 | current_go++; | ||
534 | if((current_go > 8) || game_over) { | ||
535 | total_games++; | ||
536 | if(!game_over) | ||
537 | total_turns += 10; | ||
538 | else | ||
539 | total_turns += current_go; | ||
540 | |||
541 | emit scoreChanged(total_turns, total_games); | ||
542 | Peg *p = new Peg(canvas(), 9); | ||
543 | game_over = TRUE; | ||
544 | p->setPlaced(TRUE); | ||
545 | p->setX(0); | ||
546 | p->setY(0); | ||
547 | p->setZ(0); | ||
548 | p->show(); | ||
549 | |||
550 | for (i = 0; i < 4; i++) { | ||
551 | p = new Peg(canvas(), answer[i], -1); | ||
552 | p->setX(first_peg_x_diff + (i * peg_spacing)); | ||
553 | p->setY(5); | ||
554 | p->setZ(3); | ||
555 | p->show(); | ||
556 | } | ||
557 | } else { | ||
558 | current_highlight->setY(board_height - ((current_go + 1) * panel_height)); | ||
559 | } | ||
560 | canvas()->update(); | ||
561 | } | ||
562 | |||
563 | void MindBreakerBoard::clear() | ||
564 | { | ||
565 | if(!game_over) { | ||
566 | total_games++; | ||
567 | total_turns += 10; | ||
568 | emit scoreChanged(total_turns, total_games); | ||
569 | } | ||
570 | int i; | ||
571 | /* reset the game board */ | ||
572 | game_over = FALSE; | ||
573 | /* clear the answer, clear the guess */ | ||
574 | for (i = 0; i < 4; i++) { | ||
575 | answer[i] = rand() % 6; | ||
576 | current_guess[i] = 6; | ||
577 | } | ||
578 | current_go = 0; | ||
579 | |||
580 | QCanvasItemList list = canvas()->allItems(); | ||
581 | QCanvasItemList::Iterator it = list.begin(); | ||
582 | for (; it != list.end(); ++it) { | ||
583 | if (*it == current_highlight) | ||
584 | continue; | ||
585 | if (*it) | ||
586 | delete *it; | ||
587 | } | ||
588 | |||
589 | current_highlight->setY(board_height - ((current_go + 1) * panel_height)); | ||
590 | checkScores(); | ||
591 | drawBackground(); | ||
592 | canvas()->update(); | ||
593 | } | ||
594 | |||
595 | void MindBreakerBoard::resetScore() | ||
596 | { | ||
597 | /* are u sure */ | ||
598 | |||
599 | if (QMessageBox::information(this, tr( "Reset Statistics" ), | ||
600 | tr( "Reset the win ratio?" ), | ||
601 | tr( "OK" ), tr( "Cancel" ) ) == 0) { | ||
602 | total_turns = 0; | ||
603 | total_games = 0; | ||
604 | Peg::eggLevel = 0; | ||
605 | drawBackground(); | ||
606 | canvas()->update(); | ||
607 | emit scoreChanged(total_turns, total_games); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | /* EVENTS */ | ||
612 | |||
613 | void MindBreakerBoard::contentsMousePressEvent(QMouseEvent *e) | ||
614 | { | ||
615 | copy_press = FALSE; | ||
616 | null_press = FALSE; | ||
617 | /* ok, first work out if it is one of the bins that | ||
618 | got clicked */ | ||
619 | if (e->x() > panel_width) { | ||
620 | /* its a bin, but which bin */ | ||
621 | if(e->y() > board_height) | ||
622 | return; // missed everything | ||
623 | int bin = (e->y() + 2) / (board_height / 6); | ||
624 | |||
625 | /* make new peg... set it moving */ | ||
626 | moving_pos = e->pos(); | ||
627 | moving = new Peg(canvas(), bin, current_go); | ||
628 | moving->setX(e->x() - (peg_size >> 1)); | ||
629 | moving->setY(e->y() - (peg_size >> 1)); | ||
630 | moving->setZ(5); | ||
631 | moving->show(); | ||
632 | canvas()->update(); | ||
633 | return; | ||
634 | } | ||
635 | |||
636 | QCanvasItemList l = canvas()->collisions(e->pos()); | ||
637 | for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) { | ||
638 | if ( (*it)->rtti() == pegRTTI ) { | ||
639 | Peg *item = (Peg *)(*it); | ||
640 | if (!item->hit(e->pos())) | ||
641 | continue; | ||
642 | if (item->type() > 5) { | ||
643 | null_press = TRUE; | ||
644 | null_point = e->pos(); | ||
645 | continue; /* not a color peg */ | ||
646 | } | ||
647 | if (item->placed()) { | ||
648 | /* copy */ | ||
649 | if(item->pegGo() == -1) | ||
650 | return; | ||
651 | if(item->pegGo() == current_go) { | ||
652 | copy_press = TRUE; | ||
653 | copy_peg = item; | ||
654 | } | ||
655 | moving = new Peg(canvas(), | ||
656 | item->type(), current_go); | ||
657 | moving->setX(e->x() - (peg_size >> 1)); | ||
658 | moving->setY(e->y() - (peg_size >> 1)); | ||
659 | moving->setZ(5); | ||
660 | moving->show(); | ||
661 | moving_pos = QPoint(e->x(), e->y()); | ||
662 | canvas()->update(); | ||
663 | return; | ||
664 | } | ||
665 | moving = (Peg *)*it; | ||
666 | moving_pos = e->pos(); | ||
667 | canvas()->update(); | ||
668 | return; | ||
669 | } | ||
670 | } | ||
671 | null_press = TRUE; | ||
672 | null_point = e->pos(); | ||
673 | moving = 0; | ||
674 | } | ||
675 | |||
676 | void MindBreakerBoard::contentsMouseMoveEvent(QMouseEvent* e) | ||
677 | { | ||
678 | if (moving ) { | ||
679 | moving->moveBy(e->pos().x() - moving_pos.x(), | ||
680 | e->pos().y() - moving_pos.y()); | ||
681 | moving_pos = e->pos(); | ||
682 | canvas()->update(); | ||
683 | return; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | void MindBreakerBoard::contentsMouseReleaseEvent(QMouseEvent* e) | ||
688 | { | ||
689 | /* time to put down the peg */ | ||
690 | if(moving) { | ||
691 | if(copy_press) { | ||
692 | /* check if collided with original. if so, delete both */ | ||
693 | copy_press = FALSE; | ||
694 | QCanvasItemList l = canvas()->collisions(e->pos()); | ||
695 | for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) { | ||
696 | if (*it == copy_peg) | ||
697 | copy_press = TRUE; | ||
698 | } | ||
699 | if (copy_press) { | ||
700 | current_guess[copy_peg->pegPos()] = 6; | ||
701 | delete copy_peg; | ||
702 | delete moving; | ||
703 | copy_press = FALSE; | ||
704 | moving = 0; | ||
705 | copy_peg = 0; | ||
706 | canvas()->update(); | ||
707 | return; | ||
708 | } | ||
709 | } | ||
710 | |||
711 | /* first work out if in y */ | ||
712 | if (e->y() > (board_height - (current_go * panel_height))) { | ||
713 | delete moving; | ||
714 | moving = 0; | ||
715 | canvas()->update(); | ||
716 | return; | ||
717 | } | ||
718 | if (e->y() < (board_height - ((current_go + 1) * panel_height))) { | ||
719 | delete moving; | ||
720 | moving = 0; | ||
721 | canvas()->update(); | ||
722 | return; | ||
723 | } | ||
724 | /* ok, a valid go, but which peg */ | ||
725 | int x_bar = first_peg_x_diff - (peg_size >> 1); | ||
726 | x_bar += peg_spacing; | ||
727 | int pos = 0; | ||
728 | if (e->x() > x_bar) | ||
729 | pos = 1; | ||
730 | x_bar += peg_spacing; | ||
731 | if (e->x() > x_bar) | ||
732 | pos = 2; | ||
733 | x_bar += peg_spacing; | ||
734 | if (e->x() > x_bar) | ||
735 | pos = 3; | ||
736 | x_bar += peg_spacing; | ||
737 | |||
738 | if (e->x() > x_bar) { | ||
739 | /* invalid x */ | ||
740 | delete moving; | ||
741 | moving = 0; | ||
742 | canvas()->update(); | ||
743 | return; | ||
744 | } | ||
745 | |||
746 | int x = first_peg_x_diff + (pos * peg_spacing); | ||
747 | int y = board_height - ((current_go + 1) * panel_height) | ||
748 | + first_peg_y_diff; | ||
749 | moving->setPegPos(pos); | ||
750 | moving->setX(x); | ||
751 | moving->setY(y); | ||
752 | moving->setZ(2); | ||
753 | |||
754 | /* remove all other pegs from this position */ | ||
755 | QCanvasItemList l = canvas()->collisions(QPoint(x,y)); | ||
756 | for (QCanvasItemList::Iterator it=l.begin(); it !=l.end(); ++it) { | ||
757 | if ( (*it)->rtti() == pegRTTI ) { | ||
758 | Peg *item = (Peg *)(*it); | ||
759 | if ((item != moving) && (item != current_highlight)) | ||
760 | delete item; | ||
761 | } | ||
762 | } | ||
763 | current_guess[pos] = ((Peg *)moving)->type(); | ||
764 | |||
765 | ((Peg *)moving)->setPlaced(true); | ||
766 | canvas()->update(); | ||
767 | return; | ||
768 | } | ||
769 | moving = 0; | ||
770 | null_point -= e->pos(); | ||
771 | if(null_point.manhattanLength() < 6) { | ||
772 | if (game_over) | ||
773 | clear(); | ||
774 | else | ||
775 | checkGuess(); | ||
776 | } | ||
777 | } | ||
778 | |||
779 | void MindBreakerBoard::resizeEvent(QResizeEvent *e) | ||
780 | { | ||
781 | QSize s = e->size(); | ||
782 | int fw = style().defaultFrameWidth(); | ||
783 | s.setWidth(s.width() - fw); | ||
784 | s.setHeight(s.height() - fw); | ||
785 | |||
786 | /* min size is 200 x 260 */ | ||
787 | if (s.width() < board_width) | ||
788 | s.setWidth(board_width); | ||
789 | |||
790 | if (s.height() < board_height) | ||
791 | s.setHeight(board_height); | ||
792 | |||
793 | canvas()->resize(s.width() - fw, s.height() - fw); | ||
794 | drawBackground(); | ||
795 | } | ||
796 | |||
797 | |||
798 | /* Easter egg function... beat the clock */ | ||
799 | void MindBreakerBoard::checkScores() | ||
800 | { | ||
801 | double games = total_games; | ||
802 | double turns = total_turns; | ||
803 | double g = games / 10.0; | ||
804 | Peg::eggLevel = 0; | ||
805 | |||
806 | double break_even = 5.0; | ||
807 | if (g < 1.0) | ||
808 | return; | ||
809 | double avg = turns / games; | ||
810 | g--; | ||
811 | while (break_even >= 0.0) { | ||
812 | if (avg >= (break_even + g)) | ||
813 | return; | ||
814 | // score a peg. | ||
815 | break_even -= 1.0; | ||
816 | Peg::eggLevel = int(5.0 - break_even); | ||
817 | } | ||
818 | } | ||
diff --git a/noncore/games/mindbreaker/mindbreaker.h b/noncore/games/mindbreaker/mindbreaker.h new file mode 100644 index 0000000..fca649a --- a/dev/null +++ b/noncore/games/mindbreaker/mindbreaker.h | |||
@@ -0,0 +1,122 @@ | |||
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 | #ifndef MINDBREAKER_H | ||
22 | #define MINDBREAKER_H | ||
23 | |||
24 | #include <qwidget.h> | ||
25 | #include <qmainwindow.h> | ||
26 | #include <qimage.h> | ||
27 | #include <qvector.h> | ||
28 | #include <qcanvas.h> | ||
29 | #include <qlabel.h> | ||
30 | |||
31 | static const int panel_height = 26; | ||
32 | static const int panel_width = 180; | ||
33 | |||
34 | static const int title_height = 25; | ||
35 | static const int title_width = 180; | ||
36 | |||
37 | static const int bin_margin = 10; | ||
38 | static const int peg_size = 20; | ||
39 | static const int answerpeg_size = 13; | ||
40 | |||
41 | static const int first_peg_x_diff = 21; | ||
42 | static const int first_peg_y_diff = ((panel_height - peg_size) >> 1); | ||
43 | static const int peg_spacing = 30; | ||
44 | |||
45 | static const int answerpegx = 152; | ||
46 | static const int answerpegy = 2; | ||
47 | static const int answerpeg_diff = 9; | ||
48 | |||
49 | static const int board_height = (title_height + (panel_height * 9)); | ||
50 | static const int board_width = (panel_width + (bin_margin * 2) + peg_size); | ||
51 | |||
52 | class Peg; | ||
53 | class QToolButton; | ||
54 | |||
55 | class MindBreakerBoard : public QCanvasView // QWidget | ||
56 | { | ||
57 | Q_OBJECT | ||
58 | public: | ||
59 | MindBreakerBoard(QCanvas &c, QWidget *parent=0, const char *name=0, int wFlags=0 ); | ||
60 | ~MindBreakerBoard(); | ||
61 | |||
62 | void getScore(int *, int *); | ||
63 | signals: | ||
64 | void scoreChanged(int, int); | ||
65 | |||
66 | public slots: | ||
67 | void clear(); | ||
68 | void resetScore(); | ||
69 | |||
70 | protected: | ||
71 | void contentsMousePressEvent(QMouseEvent *); | ||
72 | void contentsMouseMoveEvent(QMouseEvent *); | ||
73 | void contentsMouseReleaseEvent(QMouseEvent *); | ||
74 | void resizeEvent(QResizeEvent *); | ||
75 | |||
76 | private: | ||
77 | void drawBackground(); | ||
78 | void checkGuess(); | ||
79 | void checkScores(); | ||
80 | void placeGuessPeg(int pos, int pegId); | ||
81 | |||
82 | QImage panelImage; | ||
83 | QImage titleImage; | ||
84 | |||
85 | Peg *moving; | ||
86 | Peg *current_highlight; | ||
87 | QPoint moving_pos; | ||
88 | |||
89 | // the game stuff | ||
90 | int answer[4]; | ||
91 | int current_guess[4]; | ||
92 | int past_guesses[4*9]; | ||
93 | int current_go; | ||
94 | |||
95 | int null_press; | ||
96 | QPoint null_point; | ||
97 | bool copy_press; | ||
98 | Peg *copy_peg; | ||
99 | bool game_over; | ||
100 | |||
101 | int total_turns; | ||
102 | int total_games; | ||
103 | }; | ||
104 | |||
105 | class MindBreaker : public QMainWindow // QWidget | ||
106 | { | ||
107 | Q_OBJECT | ||
108 | public: | ||
109 | MindBreaker(QWidget *parent=0, const char *name=0, int wFlags=0 ); | ||
110 | |||
111 | public slots: | ||
112 | void setScore(int, int); | ||
113 | |||
114 | private: | ||
115 | QCanvas canvas; | ||
116 | MindBreakerBoard *board; | ||
117 | QToolButton *score; | ||
118 | |||
119 | }; | ||
120 | |||
121 | |||
122 | #endif | ||
diff --git a/noncore/games/mindbreaker/mindbreaker.pro b/noncore/games/mindbreaker/mindbreaker.pro new file mode 100644 index 0000000..12944d1 --- a/dev/null +++ b/noncore/games/mindbreaker/mindbreaker.pro | |||
@@ -0,0 +1,12 @@ | |||
1 | TEMPLATE = app | ||
2 | CONFIG += qt warn_on release | ||
3 | DESTDIR = $(QPEDIR)/bin | ||
4 | HEADERS = mindbreaker.h | ||
5 | SOURCES = main.cpp \ | ||
6 | mindbreaker.cpp | ||
7 | TARGET = mindbreaker | ||
8 | INCLUDEPATH += $(QPEDIR)/include | ||
9 | DEPENDPATH += $(QPEDIR)/include | ||
10 | LIBS += -lqpe | ||
11 | |||
12 | TRANSLATIONS = ../i18n/de/mindbreaker.ts | ||
diff --git a/noncore/games/mindbreaker/qpe-mindbreaker.control b/noncore/games/mindbreaker/qpe-mindbreaker.control new file mode 100644 index 0000000..3bad93d --- a/dev/null +++ b/noncore/games/mindbreaker/qpe-mindbreaker.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/mindbreaker apps/Games/mindbreaker.desktop pics/mindbreaker | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: Game: crack the coloured code | ||
9 | A game for the Qtopia environment. | ||
diff --git a/noncore/games/minesweep/.cvsignore b/noncore/games/minesweep/.cvsignore new file mode 100644 index 0000000..6fe2396 --- a/dev/null +++ b/noncore/games/minesweep/.cvsignore | |||
@@ -0,0 +1,2 @@ | |||
1 | moc_* | ||
2 | Makefile | ||
diff --git a/noncore/games/minesweep/Makefile.in b/noncore/games/minesweep/Makefile.in new file mode 100644 index 0000000..9ed6234 --- a/dev/null +++ b/noncore/games/minesweep/Makefile.in | |||
@@ -0,0 +1,134 @@ | |||
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 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= minesweep | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =minefield.h \ | ||
27 | minesweep.h | ||
28 | SOURCES =main.cpp \ | ||
29 | minefield.cpp \ | ||
30 | minesweep.cpp | ||
31 | OBJECTS =main.o \ | ||
32 | minefield.o \ | ||
33 | minesweep.o | ||
34 | INTERFACES = | ||
35 | UICDECLS = | ||
36 | UICIMPLS = | ||
37 | SRCMOC =moc_minefield.cpp \ | ||
38 | moc_minesweep.cpp | ||
39 | OBJMOC =moc_minefield.o \ | ||
40 | moc_minesweep.o | ||
41 | |||
42 | |||
43 | ####### Implicit rules | ||
44 | |||
45 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
46 | |||
47 | .cpp.o: | ||
48 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
49 | |||
50 | .cxx.o: | ||
51 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
52 | |||
53 | .cc.o: | ||
54 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
55 | |||
56 | .C.o: | ||
57 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
58 | |||
59 | .c.o: | ||
60 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
61 | |||
62 | ####### Build rules | ||
63 | |||
64 | |||
65 | all: $(DESTDIR)$(TARGET) | ||
66 | |||
67 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
68 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
69 | |||
70 | moc: $(SRCMOC) | ||
71 | |||
72 | tmake: | ||
73 | tmake minesweep.pro | ||
74 | |||
75 | clean: | ||
76 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
77 | -rm -f *~ core | ||
78 | -rm -f allmoc.cpp | ||
79 | |||
80 | ####### Extension Modules | ||
81 | |||
82 | listpromodules: | ||
83 | @echo | ||
84 | |||
85 | listallmodules: | ||
86 | @echo | ||
87 | |||
88 | listaddonpromodules: | ||
89 | @echo | ||
90 | |||
91 | listaddonentmodules: | ||
92 | @echo | ||
93 | |||
94 | |||
95 | REQUIRES= | ||
96 | |||
97 | ####### Sub-libraries | ||
98 | |||
99 | |||
100 | ###### Combined headers | ||
101 | |||
102 | |||
103 | |||
104 | ####### Compile | ||
105 | |||
106 | main.o: main.cpp \ | ||
107 | minesweep.h \ | ||
108 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
109 | |||
110 | minefield.o: minefield.cpp \ | ||
111 | minefield.h \ | ||
112 | $(QPEDIR)/include/qpe/config.h | ||
113 | |||
114 | minesweep.o: minesweep.cpp \ | ||
115 | minesweep.h \ | ||
116 | minefield.h \ | ||
117 | $(QPEDIR)/include/qpe/resource.h \ | ||
118 | $(QPEDIR)/include/qpe/config.h \ | ||
119 | $(QPEDIR)/include/qpe/qpetoolbar.h \ | ||
120 | $(QPEDIR)/include/qpe/qpemenubar.h | ||
121 | |||
122 | moc_minefield.o: moc_minefield.cpp \ | ||
123 | minefield.h | ||
124 | |||
125 | moc_minesweep.o: moc_minesweep.cpp \ | ||
126 | minesweep.h | ||
127 | |||
128 | moc_minefield.cpp: minefield.h | ||
129 | $(MOC) minefield.h -o moc_minefield.cpp | ||
130 | |||
131 | moc_minesweep.cpp: minesweep.h | ||
132 | $(MOC) minesweep.h -o moc_minesweep.cpp | ||
133 | |||
134 | |||
diff --git a/noncore/games/minesweep/main.cpp b/noncore/games/minesweep/main.cpp new file mode 100644 index 0000000..83de9a3 --- a/dev/null +++ b/noncore/games/minesweep/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 "minesweep.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | int main( int argc, char** argv ) | ||
26 | { | ||
27 | QPEApplication a( argc, argv ); | ||
28 | |||
29 | MineSweep ms; | ||
30 | QPEApplication::setInputMethodHint( &ms, QPEApplication::AlwaysOff ); | ||
31 | a.showMainWidget( &ms ); | ||
32 | |||
33 | return a.exec(); | ||
34 | } | ||
diff --git a/noncore/games/minesweep/minefield.cpp b/noncore/games/minesweep/minefield.cpp new file mode 100644 index 0000000..be2f9a3 --- a/dev/null +++ b/noncore/games/minesweep/minefield.cpp | |||
@@ -0,0 +1,623 @@ | |||
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 | #include "minefield.h" | ||
21 | |||
22 | #include <qpe/config.h> | ||
23 | |||
24 | #include <qpainter.h> | ||
25 | #include <qdrawutil.h> | ||
26 | #include <qpixmap.h> | ||
27 | #include <qimage.h> | ||
28 | #include <qtimer.h> | ||
29 | |||
30 | #include <stdlib.h> | ||
31 | |||
32 | static const char *pix_flag[]={ | ||
33 | "13 13 3 1", | ||
34 | "# c #000000", | ||
35 | "x c #ff0000", | ||
36 | ". c None", | ||
37 | ".............", | ||
38 | ".............", | ||
39 | ".....#xxxxxx.", | ||
40 | ".....#xxxxxx.", | ||
41 | ".....#xxxxxx.", | ||
42 | ".....#xxxxxx.", | ||
43 | ".....#.......", | ||
44 | ".....#.......", | ||
45 | ".....#.......", | ||
46 | ".....#.......", | ||
47 | "...#####.....", | ||
48 | "..#######....", | ||
49 | "............."}; | ||
50 | |||
51 | static const char *pix_mine[]={ | ||
52 | "13 13 3 1", | ||
53 | "# c #000000", | ||
54 | ". c None", | ||
55 | "a c #ffffff", | ||
56 | "......#......", | ||
57 | "......#......", | ||
58 | "..#.#####.#..", | ||
59 | "...#######...", | ||
60 | "..##aa#####..", | ||
61 | "..##aa#####..", | ||
62 | "#############", | ||
63 | "..#########..", | ||
64 | "..#########..", | ||
65 | "...#######...", | ||
66 | "..#.#####.#..", | ||
67 | "......#......", | ||
68 | "......#......"}; | ||
69 | |||
70 | class Mine : public QTableItem | ||
71 | { | ||
72 | public: | ||
73 | enum MineState { | ||
74 | Hidden = 0, | ||
75 | Empty, | ||
76 | Mined, | ||
77 | Flagged, | ||
78 | #ifdef MARK_UNSURE | ||
79 | Unsure, | ||
80 | #endif | ||
81 | Exploded, | ||
82 | Wrong | ||
83 | }; | ||
84 | |||
85 | Mine( QTable* ); | ||
86 | void paint( QPainter * p, const QColorGroup & cg, const QRect & cr, bool selected ); | ||
87 | EditType editType() const { return Never; } | ||
88 | QSize sizeHint() const { return QSize( 12, 12 ); } | ||
89 | |||
90 | void activate( bool sure = TRUE ); | ||
91 | void setHint( int ); | ||
92 | |||
93 | void setState( MineState ); | ||
94 | MineState state() const { return st; } | ||
95 | |||
96 | bool isMined() const { return mined; } | ||
97 | void setMined( bool m ) { mined = m; } | ||
98 | |||
99 | static void paletteChange(); | ||
100 | |||
101 | private: | ||
102 | bool mined; | ||
103 | int hint; | ||
104 | |||
105 | MineState st; | ||
106 | |||
107 | static QPixmap* knownField; | ||
108 | static QPixmap* unknownField; | ||
109 | static QPixmap* flag_pix; | ||
110 | static QPixmap* mine_pix; | ||
111 | }; | ||
112 | |||
113 | QPixmap* Mine::knownField = 0; | ||
114 | QPixmap* Mine::unknownField = 0; | ||
115 | QPixmap* Mine::flag_pix = 0; | ||
116 | QPixmap* Mine::mine_pix = 0; | ||
117 | |||
118 | Mine::Mine( QTable *t ) | ||
119 | : QTableItem( t, Never, QString::null ) | ||
120 | { | ||
121 | mined = FALSE; | ||
122 | st = Hidden; | ||
123 | hint = 0; | ||
124 | } | ||
125 | |||
126 | void Mine::activate( bool sure ) | ||
127 | { | ||
128 | if ( !sure ) { | ||
129 | switch ( st ) { | ||
130 | case Hidden: | ||
131 | setState( Flagged ); | ||
132 | break; | ||
133 | case Flagged: | ||
134 | #ifdef MARK_UNSURE | ||
135 | setState( Unsure ); | ||
136 | break; | ||
137 | case Unsure: | ||
138 | #endif | ||
139 | setState( Hidden ); | ||
140 | default: | ||
141 | break; | ||
142 | } | ||
143 | } else if ( st == Flagged ) { | ||
144 | return; | ||
145 | } else { | ||
146 | if ( mined ) { | ||
147 | setState( Exploded ); | ||
148 | } else { | ||
149 | setState( Empty ); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | void Mine::setState( MineState s ) | ||
155 | { | ||
156 | st = s; | ||
157 | } | ||
158 | |||
159 | void Mine::setHint( int h ) | ||
160 | { | ||
161 | hint = h; | ||
162 | } | ||
163 | |||
164 | void Mine::paletteChange() | ||
165 | { | ||
166 | delete knownField; | ||
167 | knownField = 0; | ||
168 | delete unknownField; | ||
169 | unknownField = 0; | ||
170 | delete mine_pix; | ||
171 | mine_pix = 0; | ||
172 | delete flag_pix; | ||
173 | flag_pix = 0; | ||
174 | } | ||
175 | |||
176 | void Mine::paint( QPainter* p, const QColorGroup &cg, const QRect& cr, bool ) | ||
177 | { | ||
178 | if ( !knownField ) { | ||
179 | knownField = new QPixmap( cr.width(), cr.height() ); | ||
180 | QPainter pp( knownField ); | ||
181 | QBrush br( cg.button().dark(115) ); | ||
182 | qDrawWinButton( &pp, QRect(0,0,cr.width(), cr.height())/*cr*/, cg, TRUE, &br ); | ||
183 | } | ||
184 | |||
185 | const int pmmarg=cr.width()/5; | ||
186 | |||
187 | if ( !unknownField ) { | ||
188 | unknownField = new QPixmap( cr.width(), cr.height() ); | ||
189 | QPainter pp( unknownField ); | ||
190 | QBrush br( cg.button() ); | ||
191 | qDrawWinButton( &pp, QRect(0,0,cr.width(), cr.height())/*cr*/, cg, FALSE, &br ); | ||
192 | } | ||
193 | |||
194 | if ( !flag_pix ) { | ||
195 | flag_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 ); | ||
196 | flag_pix->convertFromImage( QImage(pix_flag).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) ); | ||
197 | } | ||
198 | |||
199 | if ( !mine_pix ) { | ||
200 | mine_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 ); | ||
201 | mine_pix->convertFromImage( QImage(pix_mine).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) ); | ||
202 | } | ||
203 | |||
204 | p->save(); | ||
205 | |||
206 | switch(st) { | ||
207 | case Hidden: | ||
208 | p->drawPixmap( 0, 0, *unknownField ); | ||
209 | break; | ||
210 | case Empty: | ||
211 | p->drawPixmap( 0, 0, *knownField ); | ||
212 | if ( hint > 0 ) { | ||
213 | switch( hint ) { | ||
214 | case 1: | ||
215 | p->setPen( blue ); | ||
216 | break; | ||
217 | case 2: | ||
218 | p->setPen( green ); | ||
219 | case 3: | ||
220 | p->setPen( red ); | ||
221 | break; | ||
222 | default: | ||
223 | p->setPen( darkMagenta ); | ||
224 | break; | ||
225 | } | ||
226 | p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, QString().setNum( hint ) ); | ||
227 | } | ||
228 | break; | ||
229 | case Mined: | ||
230 | p->drawPixmap( 0, 0, *knownField ); | ||
231 | p->drawPixmap( pmmarg, pmmarg, *mine_pix ); | ||
232 | break; | ||
233 | case Exploded: | ||
234 | p->drawPixmap( 0, 0, *knownField ); | ||
235 | p->drawPixmap( pmmarg, pmmarg, *mine_pix ); | ||
236 | p->setPen( red ); | ||
237 | p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "X" ); | ||
238 | break; | ||
239 | case Flagged: | ||
240 | p->drawPixmap( 0, 0, *unknownField ); | ||
241 | p->drawPixmap( pmmarg, pmmarg, *flag_pix ); | ||
242 | break; | ||
243 | #ifdef MARK_UNSURE | ||
244 | case Unsure: | ||
245 | p->drawPixmap( 0, 0, *unknownField ); | ||
246 | p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "?" ); | ||
247 | break; | ||
248 | #endif | ||
249 | case Wrong: | ||
250 | p->drawPixmap( 0, 0, *unknownField ); | ||
251 | p->drawPixmap( pmmarg, pmmarg, *flag_pix ); | ||
252 | p->setPen( red ); | ||
253 | p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "X" ); | ||
254 | break; | ||
255 | } | ||
256 | |||
257 | p->restore(); | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | MineField implementation | ||
262 | */ | ||
263 | |||
264 | MineField::MineField( QWidget* parent, const char* name ) | ||
265 | : QTable( parent, name ) | ||
266 | { | ||
267 | setState( GameOver ); | ||
268 | setShowGrid( FALSE ); | ||
269 | horizontalHeader()->hide(); | ||
270 | verticalHeader()->hide(); | ||
271 | setTopMargin( 0 ); | ||
272 | setLeftMargin( 0 ); | ||
273 | |||
274 | setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ) ); | ||
275 | |||
276 | setSelectionMode( QTable::NoSelection ); | ||
277 | setFocusPolicy( QWidget::NoFocus ); | ||
278 | |||
279 | setCurrentCell( -1, -1 ); | ||
280 | |||
281 | connect( this, SIGNAL( pressed( int, int, int, const QPoint& ) ), this, SLOT( cellPressed( int, int ) ) ); | ||
282 | connect( this, SIGNAL( clicked( int, int, int, const QPoint& ) ), this, SLOT( cellClicked( int, int ) ) ); | ||
283 | |||
284 | holdTimer = new QTimer( this ); | ||
285 | connect( holdTimer, SIGNAL( timeout() ), this, SLOT( held() ) ); | ||
286 | |||
287 | flagAction = NoAction; | ||
288 | ignoreClick = FALSE; | ||
289 | currRow = currCol = 0; | ||
290 | minecount=0; | ||
291 | mineguess=0; | ||
292 | nonminecount=0; | ||
293 | } | ||
294 | |||
295 | MineField::~MineField() | ||
296 | { | ||
297 | } | ||
298 | |||
299 | void MineField::setState( State st ) | ||
300 | { | ||
301 | stat = st; | ||
302 | } | ||
303 | |||
304 | |||
305 | void MineField::setup( int level ) | ||
306 | { | ||
307 | lev = level; | ||
308 | setState( Waiting ); | ||
309 | viewport()->setUpdatesEnabled( FALSE ); | ||
310 | |||
311 | int cellsize; | ||
312 | |||
313 | int x; | ||
314 | int y; | ||
315 | for ( x = 0; x < numCols(); x++ ) | ||
316 | for ( y = 0; y < numRows(); y++ ) | ||
317 | clearCell( y, x ); | ||
318 | |||
319 | switch( lev ) { | ||
320 | case 1: | ||
321 | setNumRows( 9 ); | ||
322 | setNumCols( 9 ); | ||
323 | minecount = 12; | ||
324 | cellsize = 21; | ||
325 | break; | ||
326 | case 2: | ||
327 | setNumRows( 16 ); | ||
328 | setNumCols( 16 ); | ||
329 | minecount = 45; | ||
330 | cellsize = 14; | ||
331 | break; | ||
332 | case 3: | ||
333 | setNumRows( 18 ); | ||
334 | setNumCols( 18 ); | ||
335 | minecount = 66 ; | ||
336 | cellsize = 12; | ||
337 | break; | ||
338 | } | ||
339 | nonminecount = numRows()*numCols() - minecount; | ||
340 | mineguess = minecount; | ||
341 | emit mineCount( mineguess ); | ||
342 | Mine::paletteChange(); | ||
343 | |||
344 | for ( y = 0; y < numRows(); y++ ) | ||
345 | setRowHeight( y, cellsize ); | ||
346 | for ( x = 0; x < numCols(); x++ ) | ||
347 | setColumnWidth( x, cellsize ); | ||
348 | for ( x = 0; x < numCols(); x++ ) | ||
349 | for ( y = 0; y < numRows(); y++ ) | ||
350 | setItem( y, x, new Mine( this ) ); | ||
351 | |||
352 | updateGeometry(); | ||
353 | viewport()->setUpdatesEnabled( TRUE ); | ||
354 | viewport()->repaint( TRUE ); | ||
355 | } | ||
356 | |||
357 | |||
358 | void MineField::placeMines() | ||
359 | { | ||
360 | int mines = minecount; | ||
361 | while ( mines ) { | ||
362 | int col = int((double(rand()) / double(RAND_MAX)) * numCols()); | ||
363 | int row = int((double(rand()) / double(RAND_MAX)) * numRows()); | ||
364 | |||
365 | Mine* mine = (Mine*)item( row, col ); | ||
366 | |||
367 | if ( mine && !mine->isMined() && mine->state() == Mine::Hidden ) { | ||
368 | mine->setMined( TRUE ); | ||
369 | mines--; | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | |||
374 | void MineField::paintFocus( QPainter*, const QRect& ) | ||
375 | { | ||
376 | } | ||
377 | |||
378 | void MineField::viewportMousePressEvent( QMouseEvent* e ) | ||
379 | { | ||
380 | QTable::viewportMousePressEvent( e ); | ||
381 | } | ||
382 | |||
383 | void MineField::viewportMouseReleaseEvent( QMouseEvent* e ) | ||
384 | { | ||
385 | QTable::viewportMouseReleaseEvent( e ); | ||
386 | if ( flagAction == FlagNext ) { | ||
387 | flagAction = NoAction; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | void MineField::keyPressEvent( QKeyEvent* e ) | ||
392 | { | ||
393 | #if defined(Q_WS_QWS) || defined(_WS_QWS_) | ||
394 | flagAction = ( e->key() == Key_Up ) ? FlagOn : NoAction; | ||
395 | #else | ||
396 | flagAction = ( ( e->state() & ShiftButton ) == ShiftButton ) ? FlagOn : NoAction; | ||
397 | #endif | ||
398 | } | ||
399 | |||
400 | void MineField::keyReleaseEvent( QKeyEvent* ) | ||
401 | { | ||
402 | flagAction = NoAction; | ||
403 | } | ||
404 | |||
405 | int MineField::getHint( int row, int col ) | ||
406 | { | ||
407 | int hint = 0; | ||
408 | for ( int c = col-1; c <= col+1; c++ ) | ||
409 | for ( int r = row-1; r <= row+1; r++ ) { | ||
410 | Mine* mine = (Mine*)item( r, c ); | ||
411 | if ( mine && mine->isMined() ) | ||
412 | hint++; | ||
413 | } | ||
414 | |||
415 | return hint; | ||
416 | } | ||
417 | |||
418 | void MineField::setHint( Mine* mine ) | ||
419 | { | ||
420 | if ( !mine ) | ||
421 | return; | ||
422 | |||
423 | int row = mine->row(); | ||
424 | int col = mine->col(); | ||
425 | int hint = getHint( row, col ); | ||
426 | |||
427 | if ( !hint ) { | ||
428 | for ( int c = col-1; c <= col+1; c++ ) | ||
429 | for ( int r = row-1; r <= row+1; r++ ) { | ||
430 | Mine* mine = (Mine*)item( r, c ); | ||
431 | if ( mine && mine->state() == Mine::Hidden ) { | ||
432 | mine->activate( TRUE ); | ||
433 | nonminecount--; | ||
434 | setHint( mine ); | ||
435 | updateCell( r, c ); | ||
436 | } | ||
437 | } | ||
438 | } | ||
439 | |||
440 | mine->setHint( hint ); | ||
441 | updateCell( row, col ); | ||
442 | } | ||
443 | |||
444 | /* | ||
445 | state == Waiting means no "hold" | ||
446 | |||
447 | |||
448 | */ | ||
449 | void MineField::cellPressed( int row, int col ) | ||
450 | { | ||
451 | if ( state() == GameOver ) | ||
452 | return; | ||
453 | currRow = row; | ||
454 | currCol = col; | ||
455 | if ( state() == Playing ) | ||
456 | holdTimer->start( 150, TRUE ); | ||
457 | } | ||
458 | |||
459 | void MineField::held() | ||
460 | { | ||
461 | flagAction = FlagNext; | ||
462 | updateMine( currRow, currCol ); | ||
463 | ignoreClick = TRUE; | ||
464 | } | ||
465 | |||
466 | /* | ||
467 | Only place mines after first click, since it is pointless to | ||
468 | kill the player before the game has started. | ||
469 | */ | ||
470 | |||
471 | void MineField::cellClicked( int row, int col ) | ||
472 | { | ||
473 | if ( state() == GameOver ) | ||
474 | return; | ||
475 | if ( state() == Waiting ) { | ||
476 | Mine* mine = (Mine*)item( row, col ); | ||
477 | if ( !mine ) | ||
478 | return; | ||
479 | mine->setState( Mine::Empty ); | ||
480 | nonminecount--; | ||
481 | placeMines(); | ||
482 | setState( Playing ); | ||
483 | emit gameStarted(); | ||
484 | updateMine( row, col ); | ||
485 | } else { // state() == Playing | ||
486 | holdTimer->stop(); | ||
487 | if ( ignoreClick ) | ||
488 | ignoreClick = FALSE; | ||
489 | else | ||
490 | updateMine( row, col ); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | void MineField::updateMine( int row, int col ) | ||
495 | { | ||
496 | Mine* mine = (Mine*)item( row, col ); | ||
497 | if ( !mine ) | ||
498 | return; | ||
499 | |||
500 | bool wasFlagged = mine->state() == Mine::Flagged; | ||
501 | bool wasEmpty = mine->state() == Mine::Empty; | ||
502 | |||
503 | mine->activate( flagAction == NoAction ); | ||
504 | |||
505 | if ( mine->state() == Mine::Exploded ) { | ||
506 | emit gameOver( FALSE ); | ||
507 | setState( GameOver ); | ||
508 | return; | ||
509 | } else if ( mine->state() == Mine::Empty ) { | ||
510 | setHint( mine ); | ||
511 | if ( !wasEmpty ) | ||
512 | nonminecount--; | ||
513 | } | ||
514 | |||
515 | if ( flagAction != NoAction ) { | ||
516 | if ( mine->state() == Mine::Flagged ) { | ||
517 | --mineguess; | ||
518 | emit mineCount( mineguess ); | ||
519 | if ( mine->isMined() ) | ||
520 | --minecount; | ||
521 | } else if ( wasFlagged ) { | ||
522 | ++mineguess; | ||
523 | emit mineCount( mineguess ); | ||
524 | if ( mine->isMined() ) | ||
525 | ++minecount; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | updateCell( row, col ); | ||
530 | |||
531 | if ( !minecount && !mineguess || !nonminecount ) { | ||
532 | emit gameOver( TRUE ); | ||
533 | setState( GameOver ); | ||
534 | } | ||
535 | } | ||
536 | |||
537 | void MineField::showMines() | ||
538 | { | ||
539 | for ( int c = 0; c < numCols(); c++ ) | ||
540 | for ( int r = 0; r < numRows(); r++ ) { | ||
541 | Mine* mine = (Mine*)item( r, c ); | ||
542 | if ( !mine ) | ||
543 | continue; | ||
544 | if ( mine->isMined() && mine->state() == Mine::Hidden ) | ||
545 | mine->setState( Mine::Mined ); | ||
546 | if ( !mine->isMined() && mine->state() == Mine::Flagged ) | ||
547 | mine->setState( Mine::Wrong ); | ||
548 | |||
549 | updateCell( r, c ); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | void MineField::paletteChange( const QPalette &o ) | ||
554 | { | ||
555 | Mine::paletteChange(); | ||
556 | QTable::paletteChange( o ); | ||
557 | } | ||
558 | |||
559 | void MineField::writeConfig(Config& cfg) const | ||
560 | { | ||
561 | cfg.setGroup("Field"); | ||
562 | cfg.writeEntry("Level",lev); | ||
563 | QString grid=""; | ||
564 | if ( stat == Playing ) { | ||
565 | for ( int x = 0; x < numCols(); x++ ) | ||
566 | for ( int y = 0; y < numRows(); y++ ) { | ||
567 | char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat | ||
568 | Mine* mine = (Mine*)item( y, x ); | ||
569 | int st = (int)mine->state(); if ( mine->isMined() ) st+=5; | ||
570 | grid += code + st; | ||
571 | } | ||
572 | } | ||
573 | cfg.writeEntry("Grid",grid); | ||
574 | } | ||
575 | |||
576 | void MineField::readConfig(Config& cfg) | ||
577 | { | ||
578 | cfg.setGroup("Field"); | ||
579 | lev = cfg.readNumEntry("Level",1); | ||
580 | setup(lev); | ||
581 | flagAction = NoAction; | ||
582 | ignoreClick = FALSE; | ||
583 | currRow = currCol = 0; | ||
584 | QString grid = cfg.readEntry("Grid"); | ||
585 | if ( !grid.isEmpty() ) { | ||
586 | int i=0; | ||
587 | minecount=0; | ||
588 | mineguess=0; | ||
589 | for ( int x = 0; x < numCols(); x++ ) { | ||
590 | for ( int y = 0; y < numRows(); y++ ) { | ||
591 | char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat | ||
592 | int st = (char)(QChar)grid[i++]-code; | ||
593 | Mine* mine = (Mine*)item( y, x ); | ||
594 | if ( st >= 5 ) { | ||
595 | st-=5; | ||
596 | mine->setMined(TRUE); | ||
597 | minecount++; | ||
598 | mineguess++; | ||
599 | } | ||
600 | mine->setState((Mine::MineState)st); | ||
601 | switch ( mine->state() ) { | ||
602 | case Mine::Flagged: | ||
603 | if (mine->isMined()) | ||
604 | minecount--; | ||
605 | mineguess--; | ||
606 | break; | ||
607 | case Mine::Empty: | ||
608 | --nonminecount; | ||
609 | } | ||
610 | } | ||
611 | } | ||
612 | for ( int x = 0; x < numCols(); x++ ) { | ||
613 | for ( int y = 0; y < numRows(); y++ ) { | ||
614 | Mine* mine = (Mine*)item( y, x ); | ||
615 | if ( mine->state() == Mine::Empty ) | ||
616 | mine->setHint(getHint(y,x)); | ||
617 | } | ||
618 | } | ||
619 | } | ||
620 | setState( Playing ); | ||
621 | emit mineCount( mineguess ); | ||
622 | } | ||
623 | |||
diff --git a/noncore/games/minesweep/minefield.h b/noncore/games/minesweep/minefield.h new file mode 100644 index 0000000..4ede435 --- a/dev/null +++ b/noncore/games/minesweep/minefield.h | |||
@@ -0,0 +1,87 @@ | |||
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 MINEFIELD_H | ||
21 | #define MINEFIELD_H | ||
22 | |||
23 | #include <qtable.h> | ||
24 | |||
25 | class Mine; | ||
26 | class Config; | ||
27 | |||
28 | class MineField : public QTable | ||
29 | { | ||
30 | Q_OBJECT | ||
31 | public: | ||
32 | MineField( QWidget* parent = 0, const char* name = 0 ); | ||
33 | ~MineField(); | ||
34 | |||
35 | enum State { Waiting, Playing, GameOver }; | ||
36 | |||
37 | State state() const { return stat; } | ||
38 | |||
39 | void readConfig(Config&); | ||
40 | void writeConfig(Config&) const; | ||
41 | |||
42 | int level() const { return lev; } | ||
43 | |||
44 | public slots: | ||
45 | void setup( int level ); | ||
46 | |||
47 | void showMines(); | ||
48 | |||
49 | signals: | ||
50 | void gameOver( bool won ); | ||
51 | void gameStarted(); | ||
52 | void mineCount( int ); | ||
53 | |||
54 | protected: | ||
55 | void paintFocus( QPainter*, const QRect& ); | ||
56 | void viewportMousePressEvent( QMouseEvent* ); | ||
57 | void viewportMouseReleaseEvent( QMouseEvent* ); | ||
58 | void keyPressEvent( QKeyEvent* ); | ||
59 | void keyReleaseEvent( QKeyEvent* ); | ||
60 | |||
61 | int getHint( int row, int col ); | ||
62 | void setHint( Mine* ); | ||
63 | void updateMine( int row, int col ); | ||
64 | void paletteChange( const QPalette & ); | ||
65 | |||
66 | protected slots: | ||
67 | void cellPressed( int row, int col ); | ||
68 | void cellClicked( int row, int col ); | ||
69 | void held(); | ||
70 | |||
71 | private: | ||
72 | State stat; | ||
73 | void MineField::setState( State st ); | ||
74 | void MineField::placeMines(); | ||
75 | enum FlagAction { NoAction, FlagOn, FlagNext }; | ||
76 | FlagAction flagAction; | ||
77 | bool ignoreClick; | ||
78 | int currRow; | ||
79 | int currCol; | ||
80 | int minecount; | ||
81 | int mineguess; | ||
82 | int nonminecount; | ||
83 | int lev; | ||
84 | QTimer *holdTimer; | ||
85 | }; | ||
86 | |||
87 | #endif // MINEFIELD_H | ||
diff --git a/noncore/games/minesweep/minesweep.cpp b/noncore/games/minesweep/minesweep.cpp new file mode 100644 index 0000000..6492462 --- a/dev/null +++ b/noncore/games/minesweep/minesweep.cpp | |||
@@ -0,0 +1,390 @@ | |||
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 "minesweep.h" | ||
22 | #include "minefield.h" | ||
23 | |||
24 | #include <qpe/resource.h> | ||
25 | #include <qpe/config.h> | ||
26 | |||
27 | #include <qpe/qpetoolbar.h> | ||
28 | #include <qpe/qpemenubar.h> | ||
29 | #include <qpopupmenu.h> | ||
30 | #include <qpushbutton.h> | ||
31 | #include <qlcdnumber.h> | ||
32 | #include <qmessagebox.h> | ||
33 | #include <qtimer.h> | ||
34 | #include <qpalette.h> | ||
35 | #include <qapplication.h> | ||
36 | #include <qlayout.h> | ||
37 | #include <qlabel.h> | ||
38 | |||
39 | #include <stdlib.h> | ||
40 | #include <time.h> | ||
41 | |||
42 | |||
43 | |||
44 | |||
45 | static const char *pix_new[]={ | ||
46 | "20 20 3 1", | ||
47 | " c None", | ||
48 | "# c #00FF00", | ||
49 | ". c #000000", | ||
50 | " ", | ||
51 | " ...... ", | ||
52 | " ..######.. ", | ||
53 | " .##########. ", | ||
54 | " .############. ", | ||
55 | " .##############. ", | ||
56 | " .##############. ", | ||
57 | " .################. ", | ||
58 | " .################. ", | ||
59 | " .################. ", | ||
60 | " .################. ", | ||
61 | " .################. ", | ||
62 | " .################. ", | ||
63 | " .##############. ", | ||
64 | " .##############. ", | ||
65 | " .############. ", | ||
66 | " .##########. ", | ||
67 | " ..######.. ", | ||
68 | " ...... ", | ||
69 | " "}; | ||
70 | |||
71 | |||
72 | /* XPM */ | ||
73 | static const char * happy_xpm[] = { | ||
74 | "20 20 3 1", | ||
75 | " c None", | ||
76 | ".c #ffff3f ", | ||
77 | "#c #000000", | ||
78 | " ", | ||
79 | " ###### ", | ||
80 | " ##......## ", | ||
81 | " #..........# ", | ||
82 | " #............# ", | ||
83 | " #..............# ", | ||
84 | " #..............# ", | ||
85 | " #....##....##....# ", | ||
86 | " #....##....##....# ", | ||
87 | " #................# ", | ||
88 | " #................# ", | ||
89 | " #................# ", | ||
90 | " #...#........#...# ", | ||
91 | " #.##........##.# ", | ||
92 | " #...########...# ", | ||
93 | " #...######...# ", | ||
94 | " #..........# ", | ||
95 | " ##......## ", | ||
96 | " ###### ", | ||
97 | " "}; | ||
98 | |||
99 | |||
100 | /* XPM */ | ||
101 | static const char * worried_xpm[] = { | ||
102 | "20 20 3 1", | ||
103 | " c None", | ||
104 | ".c #ffff3f", | ||
105 | "#c #000000", | ||
106 | " ", | ||
107 | " ###### ", | ||
108 | " ##......## ", | ||
109 | " #..........# ", | ||
110 | " #............# ", | ||
111 | " #..............# ", | ||
112 | " #..............# ", | ||
113 | " #....##....##....# ", | ||
114 | " #....##....##....# ", | ||
115 | " #................# ", | ||
116 | " #................# ", | ||
117 | " #................# ", | ||
118 | " #................# ", | ||
119 | " #....######....# ", | ||
120 | " #..............# ", | ||
121 | " #............# ", | ||
122 | " #..........# ", | ||
123 | " ##......## ", | ||
124 | " ###### ", | ||
125 | " "}; | ||
126 | |||
127 | |||
128 | /* XPM */ | ||
129 | static const char * dead_xpm[] = { | ||
130 | "20 20 3 1", | ||
131 | " c None", | ||
132 | ".c #ffff3f", | ||
133 | "#c #000000", | ||
134 | " ", | ||
135 | " ###### ", | ||
136 | " ##......## ", | ||
137 | " #..........# ", | ||
138 | " #............# ", | ||
139 | " #..............# ", | ||
140 | " #..#.#...#.#...# ", | ||
141 | " #....#.....#.....# ", | ||
142 | " #...#.#...#.#....# ", | ||
143 | " #................# ", | ||
144 | " #................# ", | ||
145 | " #................# ", | ||
146 | " #......####......# ", | ||
147 | " #....# #....# ", | ||
148 | " #...#......#...# ", | ||
149 | " #............# ", | ||
150 | " #..........# ", | ||
151 | " ##......## ", | ||
152 | " ###### ", | ||
153 | " "}; | ||
154 | |||
155 | |||
156 | class ResultIndicator : private QLabel | ||
157 | { | ||
158 | public: | ||
159 | static void showResult( QWidget *ref, bool won ); | ||
160 | private: | ||
161 | ResultIndicator( QWidget *parent, const char *name, WFlags f) | ||
162 | :QLabel( parent, name, f ) {} | ||
163 | |||
164 | void timerEvent( QTimerEvent *); | ||
165 | void center(); | ||
166 | bool twoStage; | ||
167 | int timerId; | ||
168 | }; | ||
169 | |||
170 | void ResultIndicator::showResult( QWidget *ref, bool won ) | ||
171 | { | ||
172 | ResultIndicator *r = new ResultIndicator( ref, 0, WStyle_Customize | WStyle_Tool | WType_TopLevel ); | ||
173 | |||
174 | r->setAlignment( AlignCenter ); | ||
175 | r->setFrameStyle( Sunken|StyledPanel ); | ||
176 | if ( won ) { | ||
177 | r->setText( MineSweep::tr("You won!") ); | ||
178 | r->center(); | ||
179 | r->show(); | ||
180 | r->twoStage = FALSE; | ||
181 | r->timerId = r->startTimer(1500); | ||
182 | } else { | ||
183 | QPalette p( red ); | ||
184 | r->setPalette( p ); | ||
185 | r->setText( MineSweep::tr("You exploded!") ); | ||
186 | r->resize( ref->size() ); | ||
187 | r->move( ref->mapToGlobal(QPoint(0,0)) ); | ||
188 | r->show(); | ||
189 | r->twoStage = TRUE; | ||
190 | r->timerId =r->startTimer(200); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | void ResultIndicator::center() | ||
195 | { | ||
196 | QWidget *w = parentWidget(); | ||
197 | |||
198 | QPoint pp = w->mapToGlobal( QPoint(0,0) ); | ||
199 | QSize s = sizeHint()*3; | ||
200 | pp = QPoint( pp.x() + w->width()/2 - s.width()/2, | ||
201 | pp.y() + w->height()/ 2 - s.height()/2 ); | ||
202 | |||
203 | setGeometry( QRect(pp, s) ); | ||
204 | |||
205 | } | ||
206 | |||
207 | void ResultIndicator::timerEvent( QTimerEvent *te ) | ||
208 | { | ||
209 | if ( te->timerId() != timerId ) | ||
210 | return; | ||
211 | killTimer( timerId ); | ||
212 | if ( twoStage ) { | ||
213 | center(); | ||
214 | twoStage = FALSE; | ||
215 | timerId = startTimer( 1000 ); | ||
216 | } else { | ||
217 | delete this; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | |||
222 | MineSweep::MineSweep( QWidget* parent, const char* name, WFlags f ) | ||
223 | : QMainWindow( parent, name, f ) | ||
224 | { | ||
225 | srand(::time(0)); | ||
226 | setCaption( tr("Mine Hunt") ); | ||
227 | setIcon( Resource::loadPixmap( "minesweep_icon" ) ); | ||
228 | |||
229 | QPEToolBar *menuToolBar = new QPEToolBar( this ); | ||
230 | QPEMenuBar *menuBar = new QPEMenuBar( menuToolBar ); | ||
231 | |||
232 | QPopupMenu *gameMenu = new QPopupMenu( this ); | ||
233 | gameMenu->insertItem( tr("Beginner"), this, SLOT( beginner() ) ); | ||
234 | gameMenu->insertItem( tr("Advanced"), this, SLOT( advanced() ) ); | ||
235 | gameMenu->insertItem( tr("Expert"), this, SLOT( expert() ) ); | ||
236 | |||
237 | menuBar->insertItem( tr("Game"), gameMenu ); | ||
238 | |||
239 | QPEToolBar *toolBar = new QPEToolBar( this ); | ||
240 | toolBar->setHorizontalStretchable( TRUE ); | ||
241 | |||
242 | guessLCD = new QLCDNumber( toolBar ); | ||
243 | toolBar->setStretchableWidget( guessLCD ); | ||
244 | |||
245 | QPalette lcdPal( red ); | ||
246 | lcdPal.setColor( QColorGroup::Background, QApplication::palette().active().background() ); | ||
247 | lcdPal.setColor( QColorGroup::Button, QApplication::palette().active().button() ); | ||
248 | |||
249 | // guessLCD->setPalette( lcdPal ); | ||
250 | guessLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
251 | guessLCD->setFrameStyle( QFrame::NoFrame ); | ||
252 | guessLCD->setNumDigits( 2 ); | ||
253 | guessLCD->setBackgroundMode( PaletteButton ); | ||
254 | newGameButton = new QPushButton( toolBar ); | ||
255 | newGameButton->setPixmap( QPixmap( pix_new ) ); | ||
256 | newGameButton->setFocusPolicy(QWidget::NoFocus); | ||
257 | connect( newGameButton, SIGNAL(clicked()), this, SLOT(newGame()) ); | ||
258 | |||
259 | timeLCD = new QLCDNumber( toolBar ); | ||
260 | // timeLCD->setPalette( lcdPal ); | ||
261 | timeLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
262 | timeLCD->setFrameStyle( QFrame::NoFrame ); | ||
263 | timeLCD->setNumDigits( 5 ); // "mm:ss" | ||
264 | timeLCD->setBackgroundMode( PaletteButton ); | ||
265 | |||
266 | setToolBarsMovable ( FALSE ); | ||
267 | |||
268 | addToolBar( menuToolBar ); | ||
269 | addToolBar( toolBar ); | ||
270 | |||
271 | QFrame *mainframe = new QFrame( this ); | ||
272 | mainframe->setFrameShape( QFrame::Box ); | ||
273 | mainframe->setFrameShadow( QFrame::Raised ); | ||
274 | mainframe->setMargin(5); | ||
275 | mainframe->setLineWidth(2); | ||
276 | QBoxLayout *box = new QVBoxLayout( mainframe ); | ||
277 | field = new MineField( mainframe ); | ||
278 | box->addWidget( field, 0, AlignCenter ); | ||
279 | QFont fnt = field->font(); | ||
280 | fnt.setBold( TRUE ); | ||
281 | field->setFont( QFont( fnt ) ); | ||
282 | field->setFocus(); | ||
283 | setCentralWidget( mainframe ); | ||
284 | |||
285 | connect( field, SIGNAL( gameOver( bool ) ), this, SLOT( gameOver( bool ) ) ); | ||
286 | connect( field, SIGNAL( mineCount( int ) ), this, SLOT( setCounter( int ) ) ); | ||
287 | connect( field, SIGNAL( gameStarted()), this, SLOT( startPlaying() ) ); | ||
288 | |||
289 | timer = new QTimer( this ); | ||
290 | |||
291 | connect( timer, SIGNAL( timeout() ), this, SLOT( updateTime() ) ); | ||
292 | |||
293 | readConfig(); | ||
294 | } | ||
295 | |||
296 | MineSweep::~MineSweep() | ||
297 | { | ||
298 | writeConfig(); | ||
299 | } | ||
300 | |||
301 | void MineSweep::gameOver( bool won ) | ||
302 | { | ||
303 | field->showMines(); | ||
304 | if ( won ) { | ||
305 | newGameButton->setPixmap( QPixmap( happy_xpm ) ); | ||
306 | } else { | ||
307 | newGameButton->setPixmap( QPixmap( dead_xpm ) ); | ||
308 | } | ||
309 | ResultIndicator::showResult( this, won ); | ||
310 | timer->stop(); | ||
311 | } | ||
312 | |||
313 | void MineSweep::newGame() | ||
314 | { | ||
315 | newGame(field->level()); | ||
316 | } | ||
317 | |||
318 | void MineSweep::newGame(int level) | ||
319 | { | ||
320 | timeLCD->display( "0:00" ); | ||
321 | field->setup( level ); | ||
322 | newGameButton->setPixmap( QPixmap( pix_new ) ); | ||
323 | timer->stop(); | ||
324 | } | ||
325 | |||
326 | void MineSweep::startPlaying() | ||
327 | { | ||
328 | newGameButton->setPixmap( QPixmap( worried_xpm ) ); | ||
329 | starttime = QDateTime::currentDateTime(); | ||
330 | timer->start( 1000 ); | ||
331 | } | ||
332 | |||
333 | void MineSweep::beginner() | ||
334 | { | ||
335 | newGame(1); | ||
336 | } | ||
337 | |||
338 | void MineSweep::advanced() | ||
339 | { | ||
340 | newGame(2); | ||
341 | } | ||
342 | |||
343 | void MineSweep::expert() | ||
344 | { | ||
345 | newGame(3); | ||
346 | } | ||
347 | |||
348 | void MineSweep::setCounter( int c ) | ||
349 | { | ||
350 | if ( !guessLCD ) | ||
351 | return; | ||
352 | |||
353 | guessLCD->display( c ); | ||
354 | } | ||
355 | |||
356 | void MineSweep::updateTime() | ||
357 | { | ||
358 | if ( !timeLCD ) | ||
359 | return; | ||
360 | |||
361 | int s = starttime.secsTo(QDateTime::currentDateTime()); | ||
362 | if ( s/60 > 99 ) | ||
363 | timeLCD->display( "-----" ); | ||
364 | else | ||
365 | timeLCD->display( QString().sprintf("%2d:%02d",s/60,s%60) ); | ||
366 | } | ||
367 | |||
368 | void MineSweep::writeConfig() const | ||
369 | { | ||
370 | Config cfg("MineSweep"); | ||
371 | cfg.setGroup("Panel"); | ||
372 | cfg.writeEntry("Time", | ||
373 | timer->isActive() ? starttime.secsTo(QDateTime::currentDateTime()) : -1); | ||
374 | field->writeConfig(cfg); | ||
375 | } | ||
376 | |||
377 | void MineSweep::readConfig() | ||
378 | { | ||
379 | Config cfg("MineSweep"); | ||
380 | field->readConfig(cfg); | ||
381 | cfg.setGroup("Panel"); | ||
382 | int s = cfg.readNumEntry("Time",-1); | ||
383 | if ( s<0 ) { | ||
384 | newGame(); | ||
385 | } else { | ||
386 | startPlaying(); | ||
387 | starttime = QDateTime::currentDateTime().addSecs(-s); | ||
388 | updateTime(); | ||
389 | } | ||
390 | } | ||
diff --git a/noncore/games/minesweep/minesweep.h b/noncore/games/minesweep/minesweep.h new file mode 100644 index 0000000..e860573 --- a/dev/null +++ b/noncore/games/minesweep/minesweep.h | |||
@@ -0,0 +1,67 @@ | |||
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 MINESWEEP_H | ||
21 | #define MINESWEEP_H | ||
22 | |||
23 | #include <qmainwindow.h> | ||
24 | #include <qdatetime.h> | ||
25 | |||
26 | class MineField; | ||
27 | class QLCDNumber; | ||
28 | class QPushButton; | ||
29 | |||
30 | class MineSweep : public QMainWindow | ||
31 | { | ||
32 | Q_OBJECT | ||
33 | public: | ||
34 | MineSweep( QWidget* parent = 0, const char* name = 0, WFlags f = 0 ); | ||
35 | ~MineSweep(); | ||
36 | |||
37 | public slots: | ||
38 | void gameOver( bool won ); | ||
39 | void newGame(); | ||
40 | |||
41 | protected slots: | ||
42 | void setCounter( int ); | ||
43 | void updateTime(); | ||
44 | |||
45 | void beginner(); | ||
46 | void advanced(); | ||
47 | void expert(); | ||
48 | |||
49 | private slots: | ||
50 | void startPlaying(); | ||
51 | |||
52 | private: | ||
53 | void readConfig(); | ||
54 | void writeConfig() const; | ||
55 | |||
56 | void newGame(int); | ||
57 | MineField* field; | ||
58 | QLCDNumber* guessLCD; | ||
59 | QLCDNumber* timeLCD; | ||
60 | QPushButton* newGameButton; | ||
61 | |||
62 | QDateTime starttime; | ||
63 | QTimer* timer; | ||
64 | }; | ||
65 | |||
66 | #endif // MINESWEEP_H | ||
67 | |||
diff --git a/noncore/games/minesweep/minesweep.pro b/noncore/games/minesweep/minesweep.pro new file mode 100644 index 0000000..87484bc --- a/dev/null +++ b/noncore/games/minesweep/minesweep.pro | |||
@@ -0,0 +1,14 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG = qt warn_on release | ||
3 | DESTDIR = $(QPEDIR)/bin | ||
4 | HEADERS = minefield.h \ | ||
5 | minesweep.h | ||
6 | SOURCES = main.cpp \ | ||
7 | minefield.cpp \ | ||
8 | minesweep.cpp | ||
9 | INCLUDEPATH += $(QPEDIR)/include | ||
10 | DEPENDPATH+= $(QPEDIR)/include | ||
11 | LIBS += -lqpe | ||
12 | INTERFACES= | ||
13 | |||
14 | TRANSLATIONS = ../i18n/de/minesweep.ts | ||
diff --git a/noncore/games/minesweep/qpe-minesweep.control b/noncore/games/minesweep/qpe-minesweep.control new file mode 100644 index 0000000..36bc221 --- a/dev/null +++ b/noncore/games/minesweep/qpe-minesweep.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/minesweep apps/Games/minesweep.desktop | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: Game: find the mines | ||
9 | A game for the Qtopia environment. | ||
diff --git a/noncore/games/parashoot/.cvsignore b/noncore/games/parashoot/.cvsignore new file mode 100644 index 0000000..edfa921 --- a/dev/null +++ b/noncore/games/parashoot/.cvsignore | |||
@@ -0,0 +1,3 @@ | |||
1 | moc_* | ||
2 | *.moc | ||
3 | Makefile | ||
diff --git a/noncore/games/parashoot/Makefile.in b/noncore/games/parashoot/Makefile.in new file mode 100644 index 0000000..ff7397e --- a/dev/null +++ b/noncore/games/parashoot/Makefile.in | |||
@@ -0,0 +1,203 @@ | |||
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 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= parashoot | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =interface.h \ | ||
27 | man.h \ | ||
28 | cannon.h \ | ||
29 | base.h \ | ||
30 | bullet.h \ | ||
31 | helicopter.h | ||
32 | SOURCES =main.cpp \ | ||
33 | interface.cpp \ | ||
34 | man.cpp \ | ||
35 | cannon.cpp \ | ||
36 | base.cpp \ | ||
37 | bullet.cpp \ | ||
38 | helicopter.cpp | ||
39 | OBJECTS =main.o \ | ||
40 | interface.o \ | ||
41 | man.o \ | ||
42 | cannon.o \ | ||
43 | base.o \ | ||
44 | bullet.o \ | ||
45 | helicopter.o | ||
46 | INTERFACES = | ||
47 | UICDECLS = | ||
48 | UICIMPLS = | ||
49 | SRCMOC =moc_interface.cpp \ | ||
50 | moc_cannon.cpp \ | ||
51 | moc_bullet.cpp | ||
52 | OBJMOC =moc_interface.o \ | ||
53 | moc_cannon.o \ | ||
54 | moc_bullet.o | ||
55 | |||
56 | |||
57 | ####### Implicit rules | ||
58 | |||
59 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
60 | |||
61 | .cpp.o: | ||
62 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
63 | |||
64 | .cxx.o: | ||
65 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
66 | |||
67 | .cc.o: | ||
68 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
69 | |||
70 | .C.o: | ||
71 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
72 | |||
73 | .c.o: | ||
74 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
75 | |||
76 | ####### Build rules | ||
77 | |||
78 | |||
79 | all: $(DESTDIR)$(TARGET) | ||
80 | |||
81 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
82 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
83 | |||
84 | moc: $(SRCMOC) | ||
85 | |||
86 | tmake: | ||
87 | tmake parashoot.pro | ||
88 | |||
89 | clean: | ||
90 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
91 | -rm -f *~ core | ||
92 | -rm -f allmoc.cpp | ||
93 | |||
94 | ####### Extension Modules | ||
95 | |||
96 | listpromodules: | ||
97 | @echo | ||
98 | |||
99 | listallmodules: | ||
100 | @echo | ||
101 | |||
102 | listaddonpromodules: | ||
103 | @echo | ||
104 | |||
105 | listaddonentmodules: | ||
106 | @echo | ||
107 | |||
108 | |||
109 | REQUIRES= | ||
110 | |||
111 | ####### Sub-libraries | ||
112 | |||
113 | |||
114 | ###### Combined headers | ||
115 | |||
116 | |||
117 | |||
118 | ####### Compile | ||
119 | |||
120 | main.o: main.cpp \ | ||
121 | interface.h \ | ||
122 | cannon.h \ | ||
123 | bullet.h \ | ||
124 | $(QPEDIR)/include/qpe/sound.h \ | ||
125 | base.h \ | ||
126 | helicopter.h \ | ||
127 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
128 | |||
129 | interface.o: interface.cpp \ | ||
130 | interface.h \ | ||
131 | cannon.h \ | ||
132 | bullet.h \ | ||
133 | $(QPEDIR)/include/qpe/sound.h \ | ||
134 | base.h \ | ||
135 | helicopter.h \ | ||
136 | man.h \ | ||
137 | $(QPEDIR)/include/qpe/resource.h \ | ||
138 | $(QPEDIR)/include/qpe/qpetoolbar.h | ||
139 | |||
140 | man.o: man.cpp \ | ||
141 | codes.h \ | ||
142 | man.h \ | ||
143 | $(QPEDIR)/include/qpe/sound.h \ | ||
144 | base.h \ | ||
145 | $(QPEDIR)/include/qpe/resource.h | ||
146 | |||
147 | cannon.o: cannon.cpp \ | ||
148 | $(QPEDIR)/include/qpe/resource.h \ | ||
149 | codes.h \ | ||
150 | cannon.h \ | ||
151 | bullet.h \ | ||
152 | $(QPEDIR)/include/qpe/sound.h | ||
153 | |||
154 | base.o: base.cpp \ | ||
155 | codes.h \ | ||
156 | base.h \ | ||
157 | $(QPEDIR)/include/qpe/sound.h \ | ||
158 | man.h \ | ||
159 | $(QPEDIR)/include/qpe/resource.h | ||
160 | |||
161 | bullet.o: bullet.cpp \ | ||
162 | codes.h \ | ||
163 | bullet.h \ | ||
164 | $(QPEDIR)/include/qpe/sound.h \ | ||
165 | man.h \ | ||
166 | helicopter.h \ | ||
167 | $(QPEDIR)/include/qpe/resource.h \ | ||
168 | $(QPEDIR)/include/qpe/qmath.h | ||
169 | |||
170 | helicopter.o: helicopter.cpp \ | ||
171 | helicopter.h \ | ||
172 | $(QPEDIR)/include/qpe/sound.h \ | ||
173 | man.h \ | ||
174 | codes.h \ | ||
175 | $(QPEDIR)/include/qpe/resource.h | ||
176 | |||
177 | moc_interface.o: moc_interface.cpp \ | ||
178 | interface.h \ | ||
179 | cannon.h \ | ||
180 | bullet.h \ | ||
181 | $(QPEDIR)/include/qpe/sound.h \ | ||
182 | base.h \ | ||
183 | helicopter.h | ||
184 | |||
185 | moc_cannon.o: moc_cannon.cpp \ | ||
186 | cannon.h \ | ||
187 | bullet.h \ | ||
188 | $(QPEDIR)/include/qpe/sound.h | ||
189 | |||
190 | moc_bullet.o: moc_bullet.cpp \ | ||
191 | bullet.h \ | ||
192 | $(QPEDIR)/include/qpe/sound.h | ||
193 | |||
194 | moc_interface.cpp: interface.h | ||
195 | $(MOC) interface.h -o moc_interface.cpp | ||
196 | |||
197 | moc_cannon.cpp: cannon.h | ||
198 | $(MOC) cannon.h -o moc_cannon.cpp | ||
199 | |||
200 | moc_bullet.cpp: bullet.h | ||
201 | $(MOC) bullet.h -o moc_bullet.cpp | ||
202 | |||
203 | |||
diff --git a/noncore/games/parashoot/base.cpp b/noncore/games/parashoot/base.cpp new file mode 100644 index 0000000..c03802f --- a/dev/null +++ b/noncore/games/parashoot/base.cpp | |||
@@ -0,0 +1,71 @@ | |||
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 | #include "codes.h" | ||
21 | #include "base.h" | ||
22 | #include "man.h" | ||
23 | |||
24 | #include <qpe/resource.h> | ||
25 | |||
26 | #include <qregexp.h> | ||
27 | |||
28 | int damage; | ||
29 | |||
30 | Base::Base(QCanvas* canvas) : | ||
31 | QCanvasSprite(0, canvas), | ||
32 | kaboom("landmine"), | ||
33 | ohdear("crmble01") | ||
34 | { | ||
35 | basearray = new QCanvasPixmapArray(); | ||
36 | QString b0 = Resource::findPixmap("parashoot/b0001"); | ||
37 | b0.replace(QRegExp("0001"),"%1"); | ||
38 | basearray->readPixmaps(b0, 4); | ||
39 | setSequence(basearray); | ||
40 | setFrame(0); | ||
41 | move(2, canvas->height()-50); | ||
42 | setZ(10); | ||
43 | show(); | ||
44 | damage = 0; | ||
45 | } | ||
46 | |||
47 | void Base::damageBase() | ||
48 | { | ||
49 | damage++; | ||
50 | |||
51 | switch(damage) { | ||
52 | case 1: setFrame(1); ohdear.play(); break; | ||
53 | case 2: setFrame(2); ohdear.play(); break; | ||
54 | case 3: setFrame(3); kaboom.play(); break; | ||
55 | } | ||
56 | show(); | ||
57 | } | ||
58 | |||
59 | bool Base::baseDestroyed() | ||
60 | { | ||
61 | return (damage >= 3); | ||
62 | } | ||
63 | |||
64 | Base::~Base() | ||
65 | { | ||
66 | } | ||
67 | |||
68 | int Base::rtti() const | ||
69 | { | ||
70 | return base_rtti; | ||
71 | } | ||
diff --git a/noncore/games/parashoot/base.h b/noncore/games/parashoot/base.h new file mode 100644 index 0000000..ee7f166 --- a/dev/null +++ b/noncore/games/parashoot/base.h | |||
@@ -0,0 +1,38 @@ | |||
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 <qpe/sound.h> | ||
22 | |||
23 | #include <qcanvas.h> | ||
24 | |||
25 | class Base : public QCanvasSprite | ||
26 | { | ||
27 | |||
28 | public: | ||
29 | Base(QCanvas*); | ||
30 | ~Base(); | ||
31 | void damageBase(); | ||
32 | int rtti() const; | ||
33 | static bool baseDestroyed(); | ||
34 | |||
35 | private: | ||
36 | QCanvasPixmapArray* basearray; | ||
37 | Sound kaboom, ohdear; | ||
38 | }; | ||
diff --git a/noncore/games/parashoot/bullet.cpp b/noncore/games/parashoot/bullet.cpp new file mode 100644 index 0000000..584f564 --- a/dev/null +++ b/noncore/games/parashoot/bullet.cpp | |||
@@ -0,0 +1,142 @@ | |||
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 "codes.h" | ||
22 | #include "bullet.h" | ||
23 | #include "man.h" | ||
24 | #include "helicopter.h" | ||
25 | |||
26 | #include <qpe/resource.h> | ||
27 | #include <qpe/qmath.h> | ||
28 | |||
29 | |||
30 | int limit; | ||
31 | int shotcount; | ||
32 | int nobullets; | ||
33 | |||
34 | Bullet::Bullet(QCanvas* canvas, double angle, int cannonx, int cannony) : | ||
35 | QCanvasSprite(0, canvas), | ||
36 | bang("collide01") | ||
37 | { | ||
38 | QCanvasPixmapArray* bulletarray = new QCanvasPixmapArray(Resource::findPixmap("parashoot/bullet")); | ||
39 | setSequence(bulletarray); | ||
40 | if (nobullets < limit) { | ||
41 | nobullets++; | ||
42 | move(cannonx, cannony); | ||
43 | dy = 0; | ||
44 | dx = 0; | ||
45 | show(); | ||
46 | setXY(angle); | ||
47 | setVelocity(-dx, -dy); | ||
48 | bang.play(); | ||
49 | } else | ||
50 | return; | ||
51 | } | ||
52 | |||
53 | void Bullet::setXY(double angle) | ||
54 | { | ||
55 | double ang = angle; | ||
56 | if ( (y() < 0) || (x() < 0) || (y() > canvas()->height()) || | ||
57 | (x() > canvas()->width()) ) | ||
58 | delete this; | ||
59 | else { | ||
60 | double radians = 0; | ||
61 | radians = ang * 3.14159265/180; | ||
62 | dx = (qCos(radians)) *7; | ||
63 | dy = (qSin(radians)) *7; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | void Bullet::setLimit(int amount) | ||
68 | { | ||
69 | limit = amount; | ||
70 | } | ||
71 | |||
72 | void Bullet::setNobullets(int amount) | ||
73 | { | ||
74 | nobullets = amount; | ||
75 | } | ||
76 | |||
77 | void Bullet::checkCollision() | ||
78 | { | ||
79 | QCanvasItem* item; | ||
80 | QCanvasItemList l=collisions(FALSE); | ||
81 | for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) { | ||
82 | item = *it; | ||
83 | if ( (item->rtti()== 1500) && (item->collidesWith(this)) ) { | ||
84 | Man* deadman = (Man*)item; | ||
85 | if (deadman->frame() != 5) return; | ||
86 | deadman->done(); | ||
87 | emit score(10); | ||
88 | setShotCount(shotcount+1); | ||
89 | setAnimated(false); | ||
90 | nobullets--; | ||
91 | delete this; | ||
92 | return; | ||
93 | } | ||
94 | else if ( (item->rtti()==1900) && (item->collidesWith(this)) ) { | ||
95 | Helicopter* deadchopper = (Helicopter*) item; | ||
96 | deadchopper->done(); | ||
97 | emit score(50); | ||
98 | setAnimated(false); | ||
99 | nobullets--; | ||
100 | delete this; | ||
101 | return; | ||
102 | } | ||
103 | } | ||
104 | //check shot is not out of bounds | ||
105 | if ( (y() < 0) || (x() < 0) || | ||
106 | (y() > canvas()->height()) || | ||
107 | ( x() > canvas()->width())) { | ||
108 | setAnimated(false); | ||
109 | nobullets--; | ||
110 | delete this; | ||
111 | return; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | void Bullet::advance(int phase) | ||
116 | { | ||
117 | QCanvasSprite::advance(phase); | ||
118 | |||
119 | if (phase == 0) | ||
120 | checkCollision(); | ||
121 | |||
122 | } | ||
123 | |||
124 | int Bullet::getShotCount() | ||
125 | { | ||
126 | return shotcount; | ||
127 | } | ||
128 | |||
129 | void Bullet::setShotCount(int amount) | ||
130 | { | ||
131 | shotcount = amount; | ||
132 | } | ||
133 | |||
134 | Bullet::~Bullet() | ||
135 | { | ||
136 | |||
137 | } | ||
138 | |||
139 | int Bullet::rtti() const | ||
140 | { | ||
141 | return bullet_rtti; | ||
142 | } | ||
diff --git a/noncore/games/parashoot/bullet.h b/noncore/games/parashoot/bullet.h new file mode 100644 index 0000000..7d15899 --- a/dev/null +++ b/noncore/games/parashoot/bullet.h | |||
@@ -0,0 +1,51 @@ | |||
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 <qpe/sound.h> | ||
22 | |||
23 | #include <qtimer.h> | ||
24 | #include <qcanvas.h> | ||
25 | |||
26 | #include <math.h> | ||
27 | |||
28 | class Bullet : public QObject, public QCanvasSprite | ||
29 | { | ||
30 | Q_OBJECT | ||
31 | public: | ||
32 | Bullet(QCanvas*, double angle, int cannonx, int cannony); | ||
33 | ~Bullet(); | ||
34 | void setXY(double angle); | ||
35 | void checkCollision(); | ||
36 | void advance(int phase); | ||
37 | int rtti() const; | ||
38 | static int getShotCount(); | ||
39 | static void setShotCount(int amount); | ||
40 | static void setLimit(int amount); | ||
41 | static void setNobullets(int amount); | ||
42 | |||
43 | signals: | ||
44 | void score(int); | ||
45 | |||
46 | private: | ||
47 | double dx; | ||
48 | double dy; | ||
49 | int damage; | ||
50 | Sound bang; | ||
51 | }; | ||
diff --git a/noncore/games/parashoot/cannon.cpp b/noncore/games/parashoot/cannon.cpp new file mode 100644 index 0000000..3c0a5fe --- a/dev/null +++ b/noncore/games/parashoot/cannon.cpp | |||
@@ -0,0 +1,140 @@ | |||
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 <qpe/resource.h> | ||
22 | |||
23 | #include <qregexp.h> | ||
24 | |||
25 | #include "codes.h" | ||
26 | #include "cannon.h" | ||
27 | |||
28 | Cannon::Cannon(QCanvas* canvas) : | ||
29 | QCanvasSprite(0, canvas) | ||
30 | { | ||
31 | shotsfired=0; | ||
32 | index = 8; | ||
33 | cannonx = 0; | ||
34 | cannony = 0; | ||
35 | cannonarray = new QCanvasPixmapArray(); | ||
36 | QString c0 = Resource::findPixmap("parashoot/can0001"); | ||
37 | c0.replace(QRegExp("0001"),"%1"); | ||
38 | cannonarray->readPixmaps(c0,17); | ||
39 | setSequence(cannonarray); | ||
40 | setFrame(index); | ||
41 | move(canvas->width()/2-20, canvas->height()-32); | ||
42 | // co ords for barrel of cannon when upright | ||
43 | barrelypos = canvas->height()-32; | ||
44 | barrelxpos = canvas->width()/2; | ||
45 | movedir = NoDir; | ||
46 | moveDelay = 0; | ||
47 | setAnimated(TRUE); | ||
48 | show(); | ||
49 | } | ||
50 | |||
51 | void Cannon::advance(int stage) | ||
52 | { | ||
53 | if ( stage == 1 && moveDelay-- == 0 ) { | ||
54 | if (movedir == Left) { | ||
55 | if (index > 0) { | ||
56 | setFrame(index-1); | ||
57 | index--; | ||
58 | } | ||
59 | } | ||
60 | if (movedir == Right) { | ||
61 | if (index < 16) { | ||
62 | setFrame(index+1); | ||
63 | index++; | ||
64 | } | ||
65 | } | ||
66 | moveDelay = 0; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | void Cannon::pointCannon(Direction dir) | ||
71 | { | ||
72 | movedir = dir; | ||
73 | moveDelay = 0; | ||
74 | advance(1); | ||
75 | moveDelay = 1; | ||
76 | } | ||
77 | |||
78 | void Cannon::setCoords() | ||
79 | { | ||
80 | switch(index) { | ||
81 | case 0: cannonx = barrelxpos-29; cannony = barrelypos-8; break; | ||
82 | case 1: cannonx = barrelxpos-27; cannony = barrelypos-8; break; | ||
83 | case 2: cannonx = barrelxpos-25; cannony = barrelypos-6; break; | ||
84 | case 3: cannonx = barrelxpos-23; cannony = barrelypos-4; break; | ||
85 | case 4: cannonx = barrelxpos-21; cannony = barrelypos-2; break; | ||
86 | case 5: cannonx = barrelxpos-19; cannony = barrelypos; break; | ||
87 | case 6: cannonx = barrelxpos-15; cannony = barrelypos; break; | ||
88 | case 7: cannonx = barrelxpos-10; cannony = barrelypos; break; | ||
89 | case 8: cannonx = barrelxpos; cannony = barrelypos; break; | ||
90 | case 9: cannonx = barrelxpos+2; cannony = barrelypos; break; | ||
91 | case 10: cannonx = barrelxpos+6; cannony = barrelypos; break; | ||
92 | case 11: cannonx = barrelxpos+8; cannony = barrelypos; break; | ||
93 | case 12: cannonx = barrelxpos+12; cannony = barrelypos-2; break; | ||
94 | case 13: cannonx = barrelxpos+18; cannony = barrelypos-4; break; | ||
95 | case 14: cannonx = barrelxpos+22; cannony = barrelypos-6; break; | ||
96 | case 15: cannonx = barrelxpos+26; cannony = barrelypos-8; break; | ||
97 | case 16: cannonx = barrelxpos+28; cannony = barrelypos-8; break; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | double Cannon::shootAngle() | ||
102 | { | ||
103 | switch(index) { | ||
104 | case 0: return 30.0; | ||
105 | case 1: return 37.5; | ||
106 | case 2: return 45.0; | ||
107 | case 3: return 52.5; | ||
108 | case 4: return 60.0; | ||
109 | case 5: return 67.5; | ||
110 | case 6: return 75.0; | ||
111 | case 7: return 82.5; | ||
112 | case 8: return 90.0; | ||
113 | case 9: return 97.5; | ||
114 | case 10: return 105.0; | ||
115 | case 11: return 112.5; | ||
116 | case 12: return 120.0; | ||
117 | case 13: return 127.5; | ||
118 | case 14: return 135.0; | ||
119 | case 15: return 142.5; | ||
120 | case 16: return 150.0; | ||
121 | } | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | void Cannon::shoot() | ||
126 | { | ||
127 | setCoords(); | ||
128 | Bullet* bullet = new Bullet(canvas(), shootAngle(), cannonx, cannony); | ||
129 | connect(bullet, SIGNAL(score(int)), this, SIGNAL(score(int))); | ||
130 | shotsfired++; | ||
131 | } | ||
132 | |||
133 | Cannon::~Cannon() | ||
134 | { | ||
135 | } | ||
136 | |||
137 | int Cannon::rtti() const | ||
138 | { | ||
139 | return cannon_rtti; | ||
140 | } | ||
diff --git a/noncore/games/parashoot/cannon.h b/noncore/games/parashoot/cannon.h new file mode 100644 index 0000000..44d0c65 --- a/dev/null +++ b/noncore/games/parashoot/cannon.h | |||
@@ -0,0 +1,58 @@ | |||
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 | #include <qcanvas.h> | ||
21 | |||
22 | #include "bullet.h" | ||
23 | |||
24 | class Cannon : public QObject, public QCanvasSprite | ||
25 | { | ||
26 | Q_OBJECT | ||
27 | |||
28 | public: | ||
29 | Cannon(QCanvas*); //create cannon | ||
30 | ~Cannon(); //destroy cannon | ||
31 | |||
32 | enum Direction{ Left, Right, NoDir }; | ||
33 | |||
34 | void pointCannon(Direction dir); | ||
35 | void setCoords(); | ||
36 | double shootAngle(); | ||
37 | void shoot(); | ||
38 | int rtti() const; | ||
39 | |||
40 | int shotsFired() { return shotsfired; }; | ||
41 | |||
42 | protected: | ||
43 | void advance(int stage); | ||
44 | |||
45 | signals: | ||
46 | void score(int); | ||
47 | |||
48 | private: | ||
49 | QCanvasPixmapArray* cannonarray; | ||
50 | int index; | ||
51 | int cannonx; | ||
52 | int cannony; | ||
53 | int barrelxpos; | ||
54 | int barrelypos; | ||
55 | int moveDelay; | ||
56 | Direction movedir; | ||
57 | int shotsfired; | ||
58 | }; | ||
diff --git a/noncore/games/parashoot/codes.h b/noncore/games/parashoot/codes.h new file mode 100644 index 0000000..68acb3f --- a/dev/null +++ b/noncore/games/parashoot/codes.h | |||
@@ -0,0 +1,25 @@ | |||
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 | const int man_rtti = 1500; | ||
22 | const int bullet_rtti = 1600; | ||
23 | const int cannon_rtti = 1700; | ||
24 | const int base_rtti = 1800; | ||
25 | const int helicopter_rtti = 1900; | ||
diff --git a/noncore/games/parashoot/helicopter.cpp b/noncore/games/parashoot/helicopter.cpp new file mode 100644 index 0000000..0923124 --- a/dev/null +++ b/noncore/games/parashoot/helicopter.cpp | |||
@@ -0,0 +1,114 @@ | |||
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 "helicopter.h" | ||
22 | #include "man.h" | ||
23 | #include "codes.h" | ||
24 | |||
25 | #include <qpe/resource.h> | ||
26 | |||
27 | #include <qregexp.h> | ||
28 | |||
29 | static QList<Helicopter> all; | ||
30 | |||
31 | Helicopter::Helicopter(QCanvas* canvas) : | ||
32 | QCanvasSprite(0, canvas), | ||
33 | chikachika("aland01") | ||
34 | { | ||
35 | all.append(this); | ||
36 | hits = 0; | ||
37 | QCanvasPixmapArray* helicopterarray = new QCanvasPixmapArray(); | ||
38 | QString h0 = Resource::findPixmap("parashoot/helicopter0001"); | ||
39 | h0.replace(QRegExp("0001"),"%1"); | ||
40 | helicopterarray->readPixmaps(h0,3 ); | ||
41 | setSequence(helicopterarray); | ||
42 | setAnimated(true); | ||
43 | move(canvas->width(), 5); | ||
44 | setVelocity(-2, 0); | ||
45 | chikachika.playLoop(); | ||
46 | show(); | ||
47 | } | ||
48 | |||
49 | Helicopter::~Helicopter() | ||
50 | { | ||
51 | all.remove(this); | ||
52 | } | ||
53 | |||
54 | int fr = 0; | ||
55 | |||
56 | void Helicopter::advance(int phase) | ||
57 | { | ||
58 | QCanvasSprite::advance(phase); | ||
59 | if (phase == 0) { | ||
60 | setFrame(fr%3); | ||
61 | fr++; | ||
62 | checkCollision(); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | void Helicopter::checkCollision() | ||
67 | { | ||
68 | if (x() == 6) { | ||
69 | setAnimated(false); //setVelocity(0, 0); | ||
70 | dropman(); | ||
71 | } | ||
72 | if (x() < 0) | ||
73 | done(); | ||
74 | } | ||
75 | |||
76 | void Helicopter::dropman() | ||
77 | { | ||
78 | (void)new Man(canvas(), 15, 25); | ||
79 | (void)new Man(canvas(), 35, 25); | ||
80 | takeOff(); | ||
81 | } | ||
82 | |||
83 | void Helicopter::done() | ||
84 | { | ||
85 | hits++; | ||
86 | if (hits >= 2) { | ||
87 | setAnimated(false); | ||
88 | delete this; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | void Helicopter::takeOff() | ||
93 | { | ||
94 | setVelocity(-1, 0); | ||
95 | } | ||
96 | |||
97 | int Helicopter::rtti() const | ||
98 | { | ||
99 | return helicopter_rtti; | ||
100 | } | ||
101 | |||
102 | void Helicopter::silenceAll() | ||
103 | { | ||
104 | for (Helicopter* h = all.first(); h; h = all.next()) | ||
105 | h->chikachika.stop(); | ||
106 | } | ||
107 | |||
108 | void Helicopter::deleteAll() | ||
109 | { | ||
110 | Helicopter* h; | ||
111 | while ((h = all.first())) | ||
112 | delete h; | ||
113 | } | ||
114 | |||
diff --git a/noncore/games/parashoot/helicopter.h b/noncore/games/parashoot/helicopter.h new file mode 100644 index 0000000..5cb92de --- a/dev/null +++ b/noncore/games/parashoot/helicopter.h | |||
@@ -0,0 +1,45 @@ | |||
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 <qpe/sound.h> | ||
22 | |||
23 | #include <qcanvas.h> | ||
24 | |||
25 | class Helicopter : public QCanvasSprite | ||
26 | { | ||
27 | |||
28 | public: | ||
29 | Helicopter(QCanvas*); | ||
30 | ~Helicopter(); | ||
31 | void advance(int phase); | ||
32 | void checkCollision(); | ||
33 | void dropman(); | ||
34 | void takeOff(); | ||
35 | void done(); | ||
36 | |||
37 | static void silenceAll(); | ||
38 | static void deleteAll(); | ||
39 | |||
40 | int rtti() const; | ||
41 | |||
42 | private: | ||
43 | int hits; | ||
44 | Sound chikachika; | ||
45 | }; | ||
diff --git a/noncore/games/parashoot/interface.cpp b/noncore/games/parashoot/interface.cpp new file mode 100644 index 0000000..84e5e60 --- a/dev/null +++ b/noncore/games/parashoot/interface.cpp | |||
@@ -0,0 +1,247 @@ | |||
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 "interface.h" | ||
22 | #include "man.h" | ||
23 | |||
24 | #include <qpe/resource.h> | ||
25 | |||
26 | #include <qlabel.h> | ||
27 | #include <qmessagebox.h> | ||
28 | #include <qapplication.h> | ||
29 | #include <qstyle.h> | ||
30 | #include <qpe/qpetoolbar.h> | ||
31 | #include <qtoolbutton.h> | ||
32 | |||
33 | ParaShoot::ParaShoot(QWidget* parent, const char* name, WFlags f) : | ||
34 | QMainWindow(parent,name,f), | ||
35 | canvas(232, 258), | ||
36 | fanfare("level_up"), | ||
37 | score(0) | ||
38 | { | ||
39 | canvas.setAdvancePeriod(80); | ||
40 | QPixmap bg = Resource::loadPixmap("parashoot/sky"); | ||
41 | canvas.setBackgroundPixmap(bg); | ||
42 | |||
43 | pb = new QCanvasView(&canvas, this); | ||
44 | pb->setFocus(); | ||
45 | |||
46 | setToolBarsMovable( FALSE ); | ||
47 | |||
48 | QPEToolBar* toolbar = new QPEToolBar(this); | ||
49 | toolbar->setHorizontalStretchable( TRUE ); | ||
50 | |||
51 | setCaption( tr("ParaShoot") ); | ||
52 | QPixmap newicon = Resource::loadPixmap("parashoot/manicon"); | ||
53 | setIcon(newicon); | ||
54 | new QToolButton(newicon, tr("New Game"), 0, | ||
55 | this, SLOT(newGame()), toolbar, "New Game"); | ||
56 | |||
57 | levelscore = new QLabel(toolbar); | ||
58 | levelscore->setBackgroundMode( PaletteButton ); | ||
59 | levelscore->setAlignment( AlignRight | AlignVCenter | ExpandTabs ); | ||
60 | toolbar->setStretchableWidget( levelscore ); | ||
61 | showScore(0,0); | ||
62 | |||
63 | setCentralWidget(pb); | ||
64 | |||
65 | autoDropTimer = new QTimer(this); | ||
66 | connect (autoDropTimer, SIGNAL(timeout()), this, SLOT(play()) ); | ||
67 | |||
68 | pauseTimer = new QTimer(this); | ||
69 | connect(pauseTimer, SIGNAL(timeout()), this, SLOT(wait()) ); | ||
70 | |||
71 | setFocusPolicy(StrongFocus); | ||
72 | |||
73 | newGame(); | ||
74 | } | ||
75 | |||
76 | |||
77 | void ParaShoot::resizeEvent(QResizeEvent *) | ||
78 | { | ||
79 | QSize s = centralWidget()->size(); | ||
80 | int fw = style().defaultFrameWidth(); | ||
81 | canvas.resize( s.width() - fw - 2, s.height() - fw - 2); | ||
82 | } | ||
83 | |||
84 | |||
85 | void ParaShoot::showScore( int score, int level ) | ||
86 | { | ||
87 | levelscore->setText(tr(" Level: %1 Score: %2 ").arg(score).arg(level) ); | ||
88 | } | ||
89 | |||
90 | |||
91 | void ParaShoot::newGame() | ||
92 | { | ||
93 | clear(); | ||
94 | if (pauseTimer->isActive()) | ||
95 | pauseTimer->stop(); | ||
96 | clear(); | ||
97 | Man::setManCount(0); | ||
98 | score = 0; | ||
99 | Bullet::setShotCount(0); | ||
100 | Bullet::setNobullets(0); | ||
101 | nomen = 2; | ||
102 | Bullet::setLimit(nomen); | ||
103 | level = 0; | ||
104 | updatespeed = 80; | ||
105 | showScore(0,0); | ||
106 | gamestopped = false; | ||
107 | Helicopter::deleteAll(); | ||
108 | waitover = true; | ||
109 | base = new Base(&canvas); | ||
110 | cannon = new Cannon(&canvas); | ||
111 | connect( cannon, SIGNAL(score(int)), this, SLOT(increaseScore(int))); | ||
112 | autoDropTimer->start(100); | ||
113 | } | ||
114 | |||
115 | |||
116 | void ParaShoot::clear() | ||
117 | { | ||
118 | autoDropTimer->stop(); | ||
119 | // QCanvasItem* item; | ||
120 | QCanvasItemList l = canvas.allItems(); | ||
121 | for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) { | ||
122 | delete *it; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | void ParaShoot::gameOver() | ||
127 | { | ||
128 | QCanvasItem* item; | ||
129 | QCanvasItemList l = canvas.allItems(); | ||
130 | for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) { | ||
131 | item = *it; | ||
132 | if ((item->rtti()==1500) || (item->rtti()==1600) || item->rtti()==1900) | ||
133 | item->setAnimated(false); | ||
134 | } | ||
135 | autoDropTimer->stop(); | ||
136 | Helicopter::silenceAll(); | ||
137 | |||
138 | int shots = Bullet::getShotCount(); | ||
139 | |||
140 | int shotsFired = cannon->shotsFired(); | ||
141 | if ( shotsFired == 0 ) | ||
142 | shotsFired = 1; | ||
143 | QCanvasText* gameover = new QCanvasText( | ||
144 | tr( " GAME OVER!\n" | ||
145 | " Your Score: %1\n" | ||
146 | " Parachuters Killed: %2\n" | ||
147 | " Accuracy: %3% " ).arg(score).arg(shots).arg(shots * 100 / shotsFired ), | ||
148 | &canvas); | ||
149 | gameover->setColor(red); | ||
150 | gameover->setFont( QFont("times", 18, QFont::Bold) ); | ||
151 | gameover->move(canvas.width()/2 -110, canvas.height()/2 -50); | ||
152 | gameover->setZ(500); | ||
153 | gameover->show(); | ||
154 | gamestopped = true; | ||
155 | waitover = false; | ||
156 | pauseTimer->start(3000); | ||
157 | } | ||
158 | |||
159 | void ParaShoot::wait() | ||
160 | { | ||
161 | waitover = true; | ||
162 | pauseTimer->stop(); | ||
163 | } | ||
164 | |||
165 | void ParaShoot::play() | ||
166 | { | ||
167 | if (Man::getManCount() < nomen ) { | ||
168 | new Man(&canvas); | ||
169 | } | ||
170 | if (Base::baseDestroyed()) { | ||
171 | gameOver(); | ||
172 | return; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | void ParaShoot::increaseScore(int x) | ||
177 | { | ||
178 | score += x; | ||
179 | if ( score / 150 != (score-x) / 150 ) | ||
180 | levelUp(); | ||
181 | showScore(level,score); | ||
182 | } | ||
183 | |||
184 | void ParaShoot::levelUp() | ||
185 | { | ||
186 | level++; | ||
187 | int stage = level % 3; | ||
188 | switch(stage) { | ||
189 | case 0: | ||
190 | nomen++; | ||
191 | Bullet::setLimit(nomen); | ||
192 | fanfare.play(); | ||
193 | break; | ||
194 | case 1: | ||
195 | new Helicopter(&canvas); | ||
196 | break; | ||
197 | case 2: | ||
198 | moveFaster(); | ||
199 | fanfare.play(); | ||
200 | break; | ||
201 | default: return; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | void ParaShoot::moveFaster() | ||
206 | { | ||
207 | if (updatespeed > 50) | ||
208 | updatespeed = updatespeed-5; | ||
209 | else | ||
210 | updatespeed = updatespeed-3; | ||
211 | canvas.setAdvancePeriod(updatespeed); | ||
212 | } | ||
213 | |||
214 | void ParaShoot::keyPressEvent(QKeyEvent* event) | ||
215 | { | ||
216 | if (gamestopped) { | ||
217 | if (waitover) | ||
218 | newGame(); | ||
219 | else | ||
220 | return; | ||
221 | } else { | ||
222 | switch(event->key()) { | ||
223 | case Key_Up: | ||
224 | case Key_F1: | ||
225 | case Key_F9: | ||
226 | case Key_Space: | ||
227 | cannon->shoot(); | ||
228 | break; | ||
229 | case Key_Left: | ||
230 | cannon->pointCannon(Cannon::Left); | ||
231 | lastcannonkey=Key_Left; | ||
232 | break; | ||
233 | case Key_Right: | ||
234 | cannon->pointCannon(Cannon::Right); | ||
235 | lastcannonkey=Key_Right; | ||
236 | break; | ||
237 | default: | ||
238 | return; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | void ParaShoot::keyReleaseEvent(QKeyEvent* event) | ||
244 | { | ||
245 | if ( lastcannonkey == event->key() ) | ||
246 | cannon->pointCannon(Cannon::NoDir); | ||
247 | } | ||
diff --git a/noncore/games/parashoot/interface.h b/noncore/games/parashoot/interface.h new file mode 100644 index 0000000..3f36d0b --- a/dev/null +++ b/noncore/games/parashoot/interface.h | |||
@@ -0,0 +1,79 @@ | |||
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 "cannon.h" | ||
22 | #include "base.h" | ||
23 | #include "helicopter.h" | ||
24 | |||
25 | #include <qpe/sound.h> | ||
26 | |||
27 | #include <qmainwindow.h> | ||
28 | #include <qtimer.h> | ||
29 | #include <qlabel.h> | ||
30 | |||
31 | class QCanvas; | ||
32 | class Helicopter; | ||
33 | |||
34 | //enum Direction{ | ||
35 | // left, right, up, down }; | ||
36 | |||
37 | class ParaShoot : public QMainWindow { | ||
38 | Q_OBJECT | ||
39 | |||
40 | public: | ||
41 | ParaShoot(QWidget* parent=0, const char* name=0, WFlags f=0); | ||
42 | |||
43 | void clear(); | ||
44 | void gameOver(); | ||
45 | int mancount; | ||
46 | void levelUp(); | ||
47 | void moveFaster(); | ||
48 | |||
49 | protected: | ||
50 | virtual void keyPressEvent(QKeyEvent*); | ||
51 | virtual void keyReleaseEvent(QKeyEvent*); | ||
52 | virtual void resizeEvent(QResizeEvent *e); | ||
53 | |||
54 | private slots: | ||
55 | void increaseScore(int); | ||
56 | void newGame(); | ||
57 | void play(); | ||
58 | void wait(); | ||
59 | |||
60 | private: | ||
61 | void showScore( int score, int level ); | ||
62 | QCanvasView* pb; | ||
63 | QCanvas canvas; | ||
64 | Cannon* cannon; | ||
65 | Base* base; | ||
66 | QCanvasText* gameover; | ||
67 | QLabel* levelscore; | ||
68 | int nomen; | ||
69 | int level; | ||
70 | int oldscore; | ||
71 | int updatespeed; | ||
72 | QTimer* autoDropTimer; | ||
73 | QTimer* pauseTimer; | ||
74 | bool gamestopped; | ||
75 | bool waitover; | ||
76 | Sound fanfare; | ||
77 | int score; | ||
78 | int lastcannonkey; | ||
79 | }; | ||
diff --git a/noncore/games/parashoot/main.cpp b/noncore/games/parashoot/main.cpp new file mode 100644 index 0000000..60eea18 --- a/dev/null +++ b/noncore/games/parashoot/main.cpp | |||
@@ -0,0 +1,36 @@ | |||
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 "interface.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | int main(int argc, char **argv) | ||
26 | { | ||
27 | QPEApplication app(argc,argv); | ||
28 | |||
29 | QPEApplication::grabKeyboard(); | ||
30 | |||
31 | ParaShoot m; | ||
32 | QPEApplication::setInputMethodHint( &m, QPEApplication::AlwaysOff ); | ||
33 | app.showMainWidget(&m); | ||
34 | |||
35 | return app.exec(); | ||
36 | } | ||
diff --git a/noncore/games/parashoot/man.cpp b/noncore/games/parashoot/man.cpp new file mode 100644 index 0000000..8435572 --- a/dev/null +++ b/noncore/games/parashoot/man.cpp | |||
@@ -0,0 +1,174 @@ | |||
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 "codes.h" | ||
22 | #include "man.h" | ||
23 | #include "base.h" | ||
24 | |||
25 | #include <qpe/resource.h> | ||
26 | |||
27 | #include <qregexp.h> | ||
28 | |||
29 | int mancount; | ||
30 | |||
31 | Man::Man(QCanvas* canvas) : | ||
32 | QCanvasSprite(0, canvas), | ||
33 | splat("lose") | ||
34 | { | ||
35 | manarray = new QCanvasPixmapArray(); | ||
36 | QString m0 = Resource::findPixmap("parashoot/man0001"); | ||
37 | m0.replace(QRegExp("0001"),"%1"); | ||
38 | manarray->readPixmaps(m0, 7); | ||
39 | setSequence(manarray); | ||
40 | setAnimated(true); | ||
41 | mancount++; | ||
42 | dead = false; | ||
43 | start(); | ||
44 | } | ||
45 | |||
46 | Man::Man(QCanvas* canvas, int x, int y) : | ||
47 | QCanvasSprite(0, canvas), | ||
48 | splat("bang") | ||
49 | { | ||
50 | manarray = new QCanvasPixmapArray(); | ||
51 | QString m0 = Resource::findPixmap("parashoot/man0001"); | ||
52 | m0.replace(QString("0001"),"%1"); | ||
53 | manarray->readPixmaps(m0, 7); | ||
54 | setSequence(manarray); | ||
55 | move(x, y); | ||
56 | setFrame(5); | ||
57 | setZ(300); | ||
58 | show(); | ||
59 | |||
60 | static bool first_time = TRUE; | ||
61 | if (first_time) { | ||
62 | first_time = FALSE; | ||
63 | QTime midnight(0, 0, 0); | ||
64 | srand(midnight.secsTo(QTime::currentTime()) ); | ||
65 | } | ||
66 | int yfallspeed = 0; | ||
67 | yfallspeed = (rand() % 3) + 1; | ||
68 | setVelocity(0, yfallspeed); | ||
69 | |||
70 | mancount++; | ||
71 | dead = false; | ||
72 | } | ||
73 | int f = 0; | ||
74 | |||
75 | void Man::advance(int phase) | ||
76 | { | ||
77 | QCanvasSprite::advance(phase); | ||
78 | if (phase == 0) { | ||
79 | checkCollision(); | ||
80 | if (dead) { | ||
81 | if (count < 10) { | ||
82 | setFrame(6); | ||
83 | setVelocity(0,0); | ||
84 | count++; | ||
85 | } else { | ||
86 | delete this; | ||
87 | return; | ||
88 | } | ||
89 | } | ||
90 | if (y() > canvas()->height()-43) { | ||
91 | setFrame(f%5); | ||
92 | f++; | ||
93 | move(x(), canvas()->height()-26); | ||
94 | setVelocity(-2, 0); | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | |||
99 | void Man::setInitialCoords() | ||
100 | { | ||
101 | static bool first_time = TRUE; | ||
102 | if (first_time) { | ||
103 | first_time = FALSE; | ||
104 | QTime midnight(0, 0, 0); | ||
105 | srand(midnight.secsTo(QTime::currentTime()) ); | ||
106 | } | ||
107 | dx = rand() % (canvas()->width()-16); | ||
108 | dy = -43; //height of a man off the screen | ||
109 | } | ||
110 | |||
111 | //check if man has reached the base | ||
112 | void Man::checkCollision() | ||
113 | { | ||
114 | if ( (x() < 23) && (y() == canvas()->height()-26)) { | ||
115 | QCanvasItem* item; | ||
116 | QCanvasItemList l=collisions(FALSE); | ||
117 | for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) { | ||
118 | item = *it; | ||
119 | if ( (item->rtti()== 1800) && (item->collidesWith(this)) ) { | ||
120 | Base* base = (Base*) item; | ||
121 | base->damageBase(); | ||
122 | start(); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | |||
128 | void Man::start() | ||
129 | { | ||
130 | setInitialCoords(); | ||
131 | move(dx, dy); | ||
132 | setFrame(5); | ||
133 | setZ(300); | ||
134 | show(); | ||
135 | |||
136 | static bool first_time = TRUE; | ||
137 | if (first_time) { | ||
138 | first_time = FALSE; | ||
139 | QTime midnight(0, 0, 0); | ||
140 | srand(midnight.secsTo(QTime::currentTime()) ); | ||
141 | } | ||
142 | int yfallspeed = 0; | ||
143 | yfallspeed = (rand() % 3) + 1; | ||
144 | setVelocity(0, yfallspeed); | ||
145 | } | ||
146 | |||
147 | void Man::done() | ||
148 | { | ||
149 | splat.play(); | ||
150 | count = 0; | ||
151 | dead = true; | ||
152 | setFrame(6); | ||
153 | } | ||
154 | |||
155 | int Man::getManCount() | ||
156 | { | ||
157 | return mancount; | ||
158 | } | ||
159 | |||
160 | void Man::setManCount(int count) | ||
161 | { | ||
162 | mancount = count; | ||
163 | } | ||
164 | |||
165 | |||
166 | int Man::rtti() const | ||
167 | { | ||
168 | return man_rtti; | ||
169 | } | ||
170 | |||
171 | Man::~Man() | ||
172 | { | ||
173 | mancount--; | ||
174 | } | ||
diff --git a/noncore/games/parashoot/man.h b/noncore/games/parashoot/man.h new file mode 100644 index 0000000..e48fc20 --- a/dev/null +++ b/noncore/games/parashoot/man.h | |||
@@ -0,0 +1,52 @@ | |||
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 <qpe/sound.h> | ||
22 | |||
23 | #include <qcanvas.h> | ||
24 | #include <qdatetime.h> | ||
25 | |||
26 | #include <stdlib.h> | ||
27 | |||
28 | class Man : public QCanvasSprite | ||
29 | { | ||
30 | |||
31 | public: | ||
32 | Man (QCanvas*); | ||
33 | Man (QCanvas*, int x, int y); | ||
34 | ~Man(); | ||
35 | void advance(int phase); | ||
36 | void setInitialCoords(); | ||
37 | void checkCollision(); | ||
38 | void start(); | ||
39 | void done(); | ||
40 | static int getManCount(); | ||
41 | static void setManCount(int count); | ||
42 | int rtti() const; | ||
43 | // int mancount; | ||
44 | |||
45 | private: | ||
46 | QCanvasPixmapArray* manarray; | ||
47 | int dx; | ||
48 | int dy; | ||
49 | bool dead; | ||
50 | int count; | ||
51 | Sound splat; | ||
52 | }; | ||
diff --git a/noncore/games/parashoot/parashoot.pro b/noncore/games/parashoot/parashoot.pro new file mode 100644 index 0000000..631560b --- a/dev/null +++ b/noncore/games/parashoot/parashoot.pro | |||
@@ -0,0 +1,11 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG += qt warn_on release | ||
3 | DESTDIR = $(QPEDIR)/bin | ||
4 | HEADERS = interface.h man.h cannon.h base.h bullet.h helicopter.h | ||
5 | SOURCES = main.cpp interface.cpp man.cpp cannon.cpp base.cpp bullet.cpp helicopter.cpp | ||
6 | TARGET = parashoot | ||
7 | INCLUDEPATH += $(QPEDIR)/include | ||
8 | DEPENDPATH+= $(QPEDIR)/include | ||
9 | LIBS += -lqpe | ||
10 | |||
11 | TRANSLATIONS = ../i18n/de/parashoot.ts | ||
diff --git a/noncore/games/parashoot/qpe-parashoot.control b/noncore/games/parashoot/qpe-parashoot.control new file mode 100644 index 0000000..82e9421 --- a/dev/null +++ b/noncore/games/parashoot/qpe-parashoot.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/parashoot apps/Games/parashoot.desktop pics/parashoot | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: Game: shoot the parachutists | ||
9 | A game for the Qtopia environment. | ||
diff --git a/noncore/games/qasteroids/.cvsignore b/noncore/games/qasteroids/.cvsignore new file mode 100644 index 0000000..c152c55 --- a/dev/null +++ b/noncore/games/qasteroids/.cvsignore | |||
@@ -0,0 +1,2 @@ | |||
1 | moc_*.cpp | ||
2 | Makefile | ||
diff --git a/noncore/games/qasteroids/Makefile.in b/noncore/games/qasteroids/Makefile.in new file mode 100644 index 0000000..7312743 --- a/dev/null +++ b/noncore/games/qasteroids/Makefile.in | |||
@@ -0,0 +1,155 @@ | |||
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 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= qasteroids | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =ledmeter.h \ | ||
27 | sprites.h \ | ||
28 | toplevel.h \ | ||
29 | view.h | ||
30 | SOURCES =ledmeter.cpp \ | ||
31 | toplevel.cpp \ | ||
32 | view.cpp \ | ||
33 | main.cpp | ||
34 | OBJECTS =ledmeter.o \ | ||
35 | toplevel.o \ | ||
36 | view.o \ | ||
37 | main.o | ||
38 | INTERFACES = | ||
39 | UICDECLS = | ||
40 | UICIMPLS = | ||
41 | SRCMOC =moc_ledmeter.cpp \ | ||
42 | moc_toplevel.cpp \ | ||
43 | moc_view.cpp | ||
44 | OBJMOC =moc_ledmeter.o \ | ||
45 | moc_toplevel.o \ | ||
46 | moc_view.o | ||
47 | |||
48 | |||
49 | ####### Implicit rules | ||
50 | |||
51 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
52 | |||
53 | .cpp.o: | ||
54 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
55 | |||
56 | .cxx.o: | ||
57 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
58 | |||
59 | .cc.o: | ||
60 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
61 | |||
62 | .C.o: | ||
63 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
64 | |||
65 | .c.o: | ||
66 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
67 | |||
68 | ####### Build rules | ||
69 | |||
70 | |||
71 | all: $(DESTDIR)$(TARGET) | ||
72 | |||
73 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
74 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
75 | |||
76 | moc: $(SRCMOC) | ||
77 | |||
78 | tmake: | ||
79 | tmake qasteroids.pro | ||
80 | |||
81 | clean: | ||
82 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
83 | -rm -f *~ core | ||
84 | -rm -f allmoc.cpp | ||
85 | |||
86 | ####### Extension Modules | ||
87 | |||
88 | listpromodules: | ||
89 | @echo | ||
90 | |||
91 | listallmodules: | ||
92 | @echo | ||
93 | |||
94 | listaddonpromodules: | ||
95 | @echo | ||
96 | |||
97 | listaddonentmodules: | ||
98 | @echo | ||
99 | |||
100 | |||
101 | REQUIRES= | ||
102 | |||
103 | ####### Sub-libraries | ||
104 | |||
105 | |||
106 | ###### Combined headers | ||
107 | |||
108 | |||
109 | |||
110 | ####### Compile | ||
111 | |||
112 | ledmeter.o: ledmeter.cpp \ | ||
113 | ledmeter.h | ||
114 | |||
115 | toplevel.o: toplevel.cpp \ | ||
116 | toplevel.h \ | ||
117 | view.h \ | ||
118 | sprites.h \ | ||
119 | ledmeter.h \ | ||
120 | $(QPEDIR)/include/qpe/qpeapplication.h \ | ||
121 | $(QPEDIR)/include/qpe/resource.h | ||
122 | |||
123 | view.o: view.cpp \ | ||
124 | view.h \ | ||
125 | sprites.h \ | ||
126 | $(QPEDIR)/include/qpe/resource.h | ||
127 | |||
128 | main.o: main.cpp \ | ||
129 | toplevel.h \ | ||
130 | view.h \ | ||
131 | sprites.h \ | ||
132 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
133 | |||
134 | moc_ledmeter.o: moc_ledmeter.cpp \ | ||
135 | ledmeter.h | ||
136 | |||
137 | moc_toplevel.o: moc_toplevel.cpp \ | ||
138 | toplevel.h \ | ||
139 | view.h \ | ||
140 | sprites.h | ||
141 | |||
142 | moc_view.o: moc_view.cpp \ | ||
143 | view.h \ | ||
144 | sprites.h | ||
145 | |||
146 | moc_ledmeter.cpp: ledmeter.h | ||
147 | $(MOC) ledmeter.h -o moc_ledmeter.cpp | ||
148 | |||
149 | moc_toplevel.cpp: toplevel.h | ||
150 | $(MOC) toplevel.h -o moc_toplevel.cpp | ||
151 | |||
152 | moc_view.cpp: view.h | ||
153 | $(MOC) view.h -o moc_view.cpp | ||
154 | |||
155 | |||
diff --git a/noncore/games/qasteroids/ledmeter.cpp b/noncore/games/qasteroids/ledmeter.cpp new file mode 100644 index 0000000..f4d4d1a --- a/dev/null +++ b/noncore/games/qasteroids/ledmeter.cpp | |||
@@ -0,0 +1,135 @@ | |||
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 | * KAsteroids - Copyright (c) Martin R. Jones 1997 | ||
21 | * | ||
22 | * Part of the KDE project | ||
23 | */ | ||
24 | |||
25 | #include <qpainter.h> | ||
26 | #include "ledmeter.h" | ||
27 | |||
28 | KALedMeter::KALedMeter( QWidget *parent ) : QFrame( parent ) | ||
29 | { | ||
30 | mCRanges.setAutoDelete( TRUE ); | ||
31 | mRange = 100; | ||
32 | mCount = 20; | ||
33 | mCurrentCount = 0; | ||
34 | mValue = 0; | ||
35 | setMinimumWidth( mCount * 2 + frameWidth() ); | ||
36 | } | ||
37 | |||
38 | void KALedMeter::setRange( int r ) | ||
39 | { | ||
40 | mRange = r; | ||
41 | if ( mRange < 1 ) | ||
42 | mRange = 1; | ||
43 | setValue( mValue ); | ||
44 | update(); | ||
45 | } | ||
46 | |||
47 | void KALedMeter::setCount( int c ) | ||
48 | { | ||
49 | mCount = c; | ||
50 | if ( mCount < 1 ) | ||
51 | mCount = 1; | ||
52 | setMinimumWidth( mCount * 2 + frameWidth() ); | ||
53 | calcColorRanges(); | ||
54 | setValue( mValue ); | ||
55 | update(); | ||
56 | } | ||
57 | |||
58 | void KALedMeter::setValue( int v ) | ||
59 | { | ||
60 | mValue = v; | ||
61 | if ( mValue > mRange ) | ||
62 | mValue = mRange; | ||
63 | else if ( mValue < 0 ) | ||
64 | mValue = 0; | ||
65 | int c = ( mValue + mRange / mCount - 1 ) * mCount / mRange; | ||
66 | if ( c != mCurrentCount ) | ||
67 | { | ||
68 | mCurrentCount = c; | ||
69 | update(); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | void KALedMeter::addColorRange( int pc, const QColor &c ) | ||
74 | { | ||
75 | ColorRange *cr = new ColorRange; | ||
76 | cr->mPc = pc; | ||
77 | cr->mColor = c; | ||
78 | mCRanges.append( cr ); | ||
79 | calcColorRanges(); | ||
80 | } | ||
81 | |||
82 | void KALedMeter::resizeEvent( QResizeEvent *e ) | ||
83 | { | ||
84 | QFrame::resizeEvent( e ); | ||
85 | int w = ( width() - frameWidth() - 2 ) / mCount * mCount; | ||
86 | w += frameWidth() + 2; | ||
87 | setFrameRect( QRect( 0, 0, w, height() ) ); | ||
88 | } | ||
89 | |||
90 | void KALedMeter::drawContents( QPainter *p ) | ||
91 | { | ||
92 | QRect b = contentsRect(); | ||
93 | |||
94 | unsigned cidx = 0; | ||
95 | int ncol = mCount; | ||
96 | QColor col = colorGroup().foreground(); | ||
97 | |||
98 | if ( !mCRanges.isEmpty() ) | ||
99 | { | ||
100 | col = mCRanges.at( cidx )->mColor; | ||
101 | ncol = mCRanges.at( cidx )->mValue; | ||
102 | } | ||
103 | p->setBrush( col ); | ||
104 | p->setPen( col ); | ||
105 | |||
106 | int lw = b.width() / mCount; | ||
107 | int lx = b.left() + 1; | ||
108 | for ( int i = 0; i < mCurrentCount; i++, lx += lw ) | ||
109 | { | ||
110 | if ( i > ncol ) | ||
111 | { | ||
112 | if ( ++cidx < mCRanges.count() ) | ||
113 | { | ||
114 | col = mCRanges.at( cidx )->mColor; | ||
115 | ncol = mCRanges.at( cidx )->mValue; | ||
116 | p->setBrush( col ); | ||
117 | p->setPen( col ); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | p->drawRect( lx, b.top() + 1, lw - 1, b.height() - 2 ); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | void KALedMeter::calcColorRanges() | ||
126 | { | ||
127 | int prev = 0; | ||
128 | ColorRange *cr; | ||
129 | for ( cr = mCRanges.first(); cr; cr = mCRanges.next() ) | ||
130 | { | ||
131 | cr->mValue = prev + cr->mPc * mCount / 100; | ||
132 | prev = cr->mValue; | ||
133 | } | ||
134 | } | ||
135 | |||
diff --git a/noncore/games/qasteroids/ledmeter.h b/noncore/games/qasteroids/ledmeter.h new file mode 100644 index 0000000..b2f06c1 --- a/dev/null +++ b/noncore/games/qasteroids/ledmeter.h | |||
@@ -0,0 +1,72 @@ | |||
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 | * KAsteroids - Copyright (c) Martin R. Jones 1997 | ||
21 | * | ||
22 | * Part of the KDE project | ||
23 | */ | ||
24 | |||
25 | #ifndef __LEDMETER_H__ | ||
26 | #define __LEDMETER_H__ | ||
27 | |||
28 | #include <qframe.h> | ||
29 | #include <qlist.h> | ||
30 | |||
31 | #define QPtrList QList | ||
32 | |||
33 | class KALedMeter : public QFrame | ||
34 | { | ||
35 | Q_OBJECT | ||
36 | public: | ||
37 | KALedMeter( QWidget *parent ); | ||
38 | |||
39 | int range() const { return mRange; } | ||
40 | void setRange( int r ); | ||
41 | |||
42 | int count() const { return mCount; } | ||
43 | void setCount( int c ); | ||
44 | |||
45 | int value () const { return mValue; } | ||
46 | |||
47 | void addColorRange( int pc, const QColor &c ); | ||
48 | |||
49 | public slots: | ||
50 | void setValue( int v ); | ||
51 | |||
52 | protected: | ||
53 | virtual void resizeEvent( QResizeEvent * ); | ||
54 | virtual void drawContents( QPainter * ); | ||
55 | void calcColorRanges(); | ||
56 | |||
57 | protected: | ||
58 | struct ColorRange | ||
59 | { | ||
60 | int mPc; | ||
61 | int mValue; | ||
62 | QColor mColor; | ||
63 | }; | ||
64 | |||
65 | int mRange; | ||
66 | int mCount; | ||
67 | int mCurrentCount; | ||
68 | int mValue; | ||
69 | QPtrList<ColorRange> mCRanges; | ||
70 | }; | ||
71 | |||
72 | #endif | ||
diff --git a/noncore/games/qasteroids/main.cpp b/noncore/games/qasteroids/main.cpp new file mode 100644 index 0000000..7d1682c --- a/dev/null +++ b/noncore/games/qasteroids/main.cpp | |||
@@ -0,0 +1,36 @@ | |||
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 "toplevel.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | int main( int argc, char *argv[] ) | ||
26 | { | ||
27 | QPEApplication app( argc, argv ); | ||
28 | |||
29 | QPEApplication::grabKeyboard(); | ||
30 | |||
31 | KAstTopLevel *mainWidget = new KAstTopLevel(); | ||
32 | app.showMainWidget( mainWidget ); | ||
33 | |||
34 | app.exec(); | ||
35 | } | ||
36 | |||
diff --git a/noncore/games/qasteroids/qasteroids.pro b/noncore/games/qasteroids/qasteroids.pro new file mode 100644 index 0000000..14a0901 --- a/dev/null +++ b/noncore/games/qasteroids/qasteroids.pro | |||
@@ -0,0 +1,11 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG += qt warn_on release | ||
3 | DESTDIR = $(QPEDIR)/bin | ||
4 | HEADERS = ledmeter.h sprites.h toplevel.h view.h | ||
5 | SOURCES = ledmeter.cpp toplevel.cpp view.cpp main.cpp | ||
6 | TARGET = qasteroids | ||
7 | INCLUDEPATH += $(QPEDIR)/include | ||
8 | DEPENDPATH+= $(QPEDIR)/include | ||
9 | LIBS += -lqpe | ||
10 | |||
11 | TRANSLATIONS = ../i18n/de/qasteroids.ts | ||
diff --git a/noncore/games/qasteroids/qpe-qasteroids.control b/noncore/games/qasteroids/qpe-qasteroids.control new file mode 100644 index 0000000..c1b328e --- a/dev/null +++ b/noncore/games/qasteroids/qpe-qasteroids.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/qasteroids apps/Games/qasteroids.desktop pics/qasteroids pics/Asteroids.png | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Martin Jones <mjones@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: Game: shoot the asteroids | ||
9 | A game for the Qtopia environment. | ||
diff --git a/noncore/games/qasteroids/sprites.h b/noncore/games/qasteroids/sprites.h new file mode 100644 index 0000000..0827821 --- a/dev/null +++ b/noncore/games/qasteroids/sprites.h | |||
@@ -0,0 +1,147 @@ | |||
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 | * KAsteroids - Copyright (c) Martin R. Jones 1997 | ||
21 | * | ||
22 | * Part of the KDE project | ||
23 | */ | ||
24 | |||
25 | #ifndef __SPRITES_H__ | ||
26 | #define __SPRITES_H__ | ||
27 | |||
28 | #include <qcanvas.h> | ||
29 | |||
30 | #define ID_ROCK_LARGE 1024 | ||
31 | #define ID_ROCK_MEDIUM 1025 | ||
32 | #define ID_ROCK_SMALL 1026 | ||
33 | |||
34 | #define ID_MISSILE 1030 | ||
35 | |||
36 | #define ID_BIT 1040 | ||
37 | #define ID_EXHAUST 1041 | ||
38 | |||
39 | #define ID_ENERGY_POWERUP 1310 | ||
40 | #define ID_TELEPORT_POWERUP 1311 | ||
41 | #define ID_BRAKE_POWERUP 1312 | ||
42 | #define ID_SHIELD_POWERUP 1313 | ||
43 | #define ID_SHOOT_POWERUP 1314 | ||
44 | |||
45 | #define ID_SHIP 1350 | ||
46 | #define ID_SHIELD 1351 | ||
47 | |||
48 | #define MAX_SHIELD_AGE 350 | ||
49 | #define MAX_POWERUP_AGE 500 | ||
50 | #define MAX_MISSILE_AGE 20 | ||
51 | |||
52 | class KMissile : public QCanvasSprite | ||
53 | { | ||
54 | public: | ||
55 | KMissile( QCanvasPixmapArray *s, QCanvas *c ) : QCanvasSprite( s, c ) | ||
56 | { myAge = 0; } | ||
57 | |||
58 | virtual int rtti() const { return ID_MISSILE; } | ||
59 | |||
60 | void growOlder() { myAge++; } | ||
61 | bool expired() { return myAge > MAX_MISSILE_AGE; } | ||
62 | |||
63 | private: | ||
64 | int myAge; | ||
65 | }; | ||
66 | |||
67 | class KBit : public QCanvasSprite | ||
68 | { | ||
69 | public: | ||
70 | KBit( QCanvasPixmapArray *s, QCanvas *c ) : QCanvasSprite( s, c ) | ||
71 | { death = 7; } | ||
72 | |||
73 | virtual int rtti() const { return ID_BIT; } | ||
74 | |||
75 | void setDeath( int d ) { death = d; } | ||
76 | void growOlder() { death--; } | ||
77 | bool expired() { return death <= 0; } | ||
78 | |||
79 | private: | ||
80 | int death; | ||
81 | }; | ||
82 | |||
83 | class KExhaust : public QCanvasSprite | ||
84 | { | ||
85 | public: | ||
86 | KExhaust( QCanvasPixmapArray *s, QCanvas *c ) : QCanvasSprite( s, c ) | ||
87 | { death = 1; } | ||
88 | |||
89 | virtual int rtti() const { return ID_EXHAUST; } | ||
90 | |||
91 | void setDeath( int d ) { death = d; } | ||
92 | void growOlder() { death--; } | ||
93 | bool expired() { return death <= 0; } | ||
94 | |||
95 | private: | ||
96 | int death; | ||
97 | }; | ||
98 | |||
99 | class KPowerup : public QCanvasSprite | ||
100 | { | ||
101 | public: | ||
102 | KPowerup( QCanvasPixmapArray *s, QCanvas *c, int t ) : QCanvasSprite( s, c ), | ||
103 | myAge( 0 ), type(t) { } | ||
104 | |||
105 | virtual int rtti() const { return type; } | ||
106 | |||
107 | void growOlder() { myAge++; } | ||
108 | bool expired() const { return myAge > MAX_POWERUP_AGE; } | ||
109 | |||
110 | protected: | ||
111 | int myAge; | ||
112 | int type; | ||
113 | }; | ||
114 | |||
115 | class KRock : public QCanvasSprite | ||
116 | { | ||
117 | public: | ||
118 | KRock (QCanvasPixmapArray *s, QCanvas *c, int t, int sk, int st) : QCanvasSprite( s, c ) | ||
119 | { type = t; skip = cskip = sk; step = st; } | ||
120 | |||
121 | void nextFrame() | ||
122 | { | ||
123 | if (cskip-- <= 0) { | ||
124 | setFrame( (frame()+step+frameCount())%frameCount() ); | ||
125 | cskip = QABS(skip); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | virtual int rtti() const { return type; } | ||
130 | |||
131 | private: | ||
132 | int type; | ||
133 | int skip; | ||
134 | int cskip; | ||
135 | int step; | ||
136 | }; | ||
137 | |||
138 | class KShield : public QCanvasSprite | ||
139 | { | ||
140 | public: | ||
141 | KShield( QCanvasPixmapArray *s, QCanvas *c ) | ||
142 | : QCanvasSprite( s, c ) {} | ||
143 | |||
144 | virtual int rtti() const { return ID_SHIELD; } | ||
145 | }; | ||
146 | |||
147 | #endif | ||
diff --git a/noncore/games/qasteroids/toplevel.cpp b/noncore/games/qasteroids/toplevel.cpp new file mode 100644 index 0000000..57242a0 --- a/dev/null +++ b/noncore/games/qasteroids/toplevel.cpp | |||
@@ -0,0 +1,514 @@ | |||
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 | * KAsteroids - Copyright (c) Martin R. Jones 1997 | ||
21 | * | ||
22 | * Part of the KDE project | ||
23 | */ | ||
24 | //--- toplevel.cpp --- | ||
25 | |||
26 | #include "toplevel.h" | ||
27 | #include "ledmeter.h" | ||
28 | |||
29 | #include <qpe/qpeapplication.h> | ||
30 | #include <qpe/resource.h> | ||
31 | |||
32 | #include <qaccel.h> | ||
33 | #include <qlabel.h> | ||
34 | #include <qlayout.h> | ||
35 | #include <qlcdnumber.h> | ||
36 | #include <qpushbutton.h> | ||
37 | |||
38 | |||
39 | #define SB_SCORE1 | ||
40 | #define SB_LEVEL2 | ||
41 | #define SB_SHIPS3 | ||
42 | |||
43 | struct SLevel | ||
44 | { | ||
45 | int nrocks; | ||
46 | double rockSpeed; | ||
47 | }; | ||
48 | |||
49 | #define MAX_LEVELS16 | ||
50 | |||
51 | SLevel levels[MAX_LEVELS] = | ||
52 | { | ||
53 | { 1, 0.4 }, | ||
54 | { 1, 0.6 }, | ||
55 | { 2, 0.5 }, | ||
56 | { 2, 0.7 }, | ||
57 | { 2, 0.8 }, | ||
58 | { 3, 0.6 }, | ||
59 | { 3, 0.7 }, | ||
60 | { 3, 0.8 }, | ||
61 | { 4, 0.6 }, | ||
62 | { 4, 0.7 }, | ||
63 | { 4, 0.8 }, | ||
64 | { 5, 0.7 }, | ||
65 | { 5, 0.8 }, | ||
66 | { 5, 0.9 }, | ||
67 | { 5, 1.0 } | ||
68 | }; | ||
69 | |||
70 | const char *soundEvents[] = | ||
71 | { | ||
72 | "ShipDestroyed", | ||
73 | "RockDestroyed", | ||
74 | 0 | ||
75 | }; | ||
76 | |||
77 | const char *soundDefaults[] = | ||
78 | { | ||
79 | "Explosion.wav", | ||
80 | "ploop.wav", | ||
81 | 0 | ||
82 | }; | ||
83 | |||
84 | |||
85 | KAstTopLevel::KAstTopLevel( QWidget *parent, const char *name ) | ||
86 | : QMainWindow( parent, name ) | ||
87 | { | ||
88 | setCaption( tr("Asteroids") ); | ||
89 | QWidget *border = new QWidget( this ); | ||
90 | border->setBackgroundColor( black ); | ||
91 | setCentralWidget( border ); | ||
92 | |||
93 | QVBoxLayout *borderLayout = new QVBoxLayout( border ); | ||
94 | |||
95 | QWidget *mainWin = new QWidget( border ); | ||
96 | borderLayout->addWidget( mainWin, 2, AlignHCenter ); | ||
97 | |||
98 | view = new KAsteroidsView( mainWin ); | ||
99 | connect( view, SIGNAL( shipKilled() ), SLOT( slotShipKilled() ) ); | ||
100 | connect( view, SIGNAL( rockHit(int) ), SLOT( slotRockHit(int) ) ); | ||
101 | connect( view, SIGNAL( rocksRemoved() ), SLOT( slotRocksRemoved() ) ); | ||
102 | connect( view, SIGNAL( updateVitals() ), SLOT( slotUpdateVitals() ) ); | ||
103 | |||
104 | QVBoxLayout *vb = new QVBoxLayout( mainWin ); | ||
105 | QHBoxLayout *hb = new QHBoxLayout; | ||
106 | QHBoxLayout *hbd = new QHBoxLayout; | ||
107 | vb->addLayout( hb ); | ||
108 | |||
109 | QFont labelFont( "helvetica", 12 ); | ||
110 | QColorGroup grp( darkGreen, black, QColor( 128, 128, 128 ), | ||
111 | QColor( 64, 64, 64 ), black, darkGreen, black ); | ||
112 | QPalette pal( grp, grp, grp ); | ||
113 | |||
114 | mainWin->setPalette( pal ); | ||
115 | |||
116 | QLabel *label; | ||
117 | label = new QLabel( tr("Score"), mainWin ); | ||
118 | label->setFont( labelFont ); | ||
119 | label->setPalette( pal ); | ||
120 | // label->setFixedWidth( label->sizeHint().width() ); | ||
121 | hb->addWidget( label ); | ||
122 | |||
123 | scoreLCD = new QLCDNumber( 5, mainWin ); | ||
124 | scoreLCD->setFrameStyle( QFrame::NoFrame ); | ||
125 | scoreLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
126 | scoreLCD->setFixedHeight( 16 ); | ||
127 | scoreLCD->setPalette( pal ); | ||
128 | hb->addWidget( scoreLCD ); | ||
129 | hb->addStretch( 1 ); | ||
130 | |||
131 | label = new QLabel( tr("Level"), mainWin ); | ||
132 | label->setFont( labelFont ); | ||
133 | label->setPalette( pal ); | ||
134 | // label->setFixedWidth( label->sizeHint().width() ); | ||
135 | hb->addWidget( label ); | ||
136 | |||
137 | levelLCD = new QLCDNumber( 2, mainWin ); | ||
138 | levelLCD->setFrameStyle( QFrame::NoFrame ); | ||
139 | levelLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
140 | levelLCD->setFixedHeight( 16 ); | ||
141 | levelLCD->setPalette( pal ); | ||
142 | hb->addWidget( levelLCD ); | ||
143 | hb->addStretch( 1 ); | ||
144 | |||
145 | label = new QLabel( tr("Ships"), mainWin ); | ||
146 | label->setFont( labelFont ); | ||
147 | // label->setFixedWidth( label->sizeHint().width() ); | ||
148 | label->setPalette( pal ); | ||
149 | hb->addWidget( label ); | ||
150 | |||
151 | shipsLCD = new QLCDNumber( 1, mainWin ); | ||
152 | shipsLCD->setFrameStyle( QFrame::NoFrame ); | ||
153 | shipsLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
154 | shipsLCD->setFixedHeight( 16 ); | ||
155 | shipsLCD->setPalette( pal ); | ||
156 | hb->addWidget( shipsLCD ); | ||
157 | |||
158 | // hb->addStrut( 14 ); | ||
159 | |||
160 | vb->addWidget( view, 10 ); | ||
161 | |||
162 | // -- bottom layout: | ||
163 | vb->addLayout( hbd ); | ||
164 | |||
165 | QFont smallFont( "helvetica", 12 ); | ||
166 | hbd->addSpacing( 5 ); | ||
167 | |||
168 | /* | ||
169 | label = new QLabel( tr( "T" ), mainWin ); | ||
170 | label->setFont( smallFont ); | ||
171 | label->setFixedWidth( label->sizeHint().width() ); | ||
172 | label->setPalette( pal ); | ||
173 | hbd->addWidget( label ); | ||
174 | |||
175 | teleportsLCD = new QLCDNumber( 1, mainWin ); | ||
176 | teleportsLCD->setFrameStyle( QFrame::NoFrame ); | ||
177 | teleportsLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
178 | teleportsLCD->setPalette( pal ); | ||
179 | teleportsLCD->setFixedHeight( 18 ); | ||
180 | hbd->addWidget( teleportsLCD ); | ||
181 | |||
182 | hbd->addSpacing( 10 ); | ||
183 | */ | ||
184 | label = new QLabel( mainWin ); | ||
185 | label->setPixmap( Resource::loadPixmap("qasteroids/powerups/brake.png") ); | ||
186 | label->setFixedWidth( 16 ); | ||
187 | label->setPalette( pal ); | ||
188 | hbd->addWidget( label ); | ||
189 | |||
190 | brakesLCD = new QLCDNumber( 1, mainWin ); | ||
191 | brakesLCD->setFrameStyle( QFrame::NoFrame ); | ||
192 | brakesLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
193 | brakesLCD->setPalette( pal ); | ||
194 | brakesLCD->setFixedHeight( 16 ); | ||
195 | hbd->addWidget( brakesLCD ); | ||
196 | |||
197 | hbd->addSpacing( 5 ); | ||
198 | |||
199 | label = new QLabel( mainWin ); | ||
200 | label->setPixmap( Resource::loadPixmap("qasteroids/powerups/shield.png") ); | ||
201 | label->setFixedWidth( 16 ); | ||
202 | label->setPalette( pal ); | ||
203 | hbd->addWidget( label ); | ||
204 | |||
205 | shieldLCD = new QLCDNumber( 1, mainWin ); | ||
206 | shieldLCD->setFrameStyle( QFrame::NoFrame ); | ||
207 | shieldLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
208 | shieldLCD->setPalette( pal ); | ||
209 | shieldLCD->setFixedHeight( 16 ); | ||
210 | hbd->addWidget( shieldLCD ); | ||
211 | |||
212 | hbd->addSpacing( 5 ); | ||
213 | |||
214 | label = new QLabel( mainWin ); | ||
215 | label->setPixmap( Resource::loadPixmap("qasteroids/powerups/shoot.png") ); | ||
216 | label->setFixedWidth( 16 ); | ||
217 | label->setPalette( pal ); | ||
218 | hbd->addWidget( label ); | ||
219 | |||
220 | shootLCD = new QLCDNumber( 1, mainWin ); | ||
221 | shootLCD->setFrameStyle( QFrame::NoFrame ); | ||
222 | shootLCD->setSegmentStyle( QLCDNumber::Flat ); | ||
223 | shootLCD->setPalette( pal ); | ||
224 | shootLCD->setFixedHeight( 16 ); | ||
225 | hbd->addWidget( shootLCD ); | ||
226 | |||
227 | hbd->addStretch( 1 ); | ||
228 | |||
229 | label = new QLabel( tr( "Fuel" ), mainWin ); | ||
230 | label->setFont( smallFont ); | ||
231 | label->setFixedWidth( label->sizeHint().width() + 5 ); | ||
232 | label->setPalette( pal ); | ||
233 | hbd->addWidget( label ); | ||
234 | |||
235 | powerMeter = new KALedMeter( mainWin ); | ||
236 | powerMeter->setFrameStyle( QFrame::Box | QFrame::Plain ); | ||
237 | powerMeter->setRange( MAX_POWER_LEVEL ); | ||
238 | powerMeter->addColorRange( 10, darkRed ); | ||
239 | powerMeter->addColorRange( 20, QColor(160, 96, 0) ); | ||
240 | powerMeter->addColorRange( 70, darkGreen ); | ||
241 | powerMeter->setCount( 15 ); | ||
242 | powerMeter->setPalette( pal ); | ||
243 | powerMeter->setFixedSize( 60, 12 ); | ||
244 | hbd->addWidget( powerMeter ); | ||
245 | |||
246 | shipsRemain = 3; | ||
247 | showHiscores = FALSE; | ||
248 | |||
249 | actions.insert( Qt::Key_Up, Thrust ); | ||
250 | actions.insert( Qt::Key_Left, RotateLeft ); | ||
251 | actions.insert( Qt::Key_Right, RotateRight ); | ||
252 | actions.insert( Qt::Key_Enter, Shoot ); | ||
253 | actions.insert( Qt::Key_Z, Teleport ); | ||
254 | actions.insert( Qt::Key_Down, Brake ); | ||
255 | actions.insert( Qt::Key_P, Pause ); | ||
256 | actions.insert( Key_F12, Launch ); | ||
257 | actions.insert( Key_F11, Shield ); | ||
258 | actions.insert( Key_F9, NewGame ); | ||
259 | |||
260 | // actions.insert( Qt::Key_S, Shield ); | ||
261 | // actions.insert( Qt::Key_X, Brake ); | ||
262 | // actions.insert( Qt::Key_L, Launch ); | ||
263 | actions.insert( Qt::Key_Space, Shoot ); | ||
264 | |||
265 | view->showText( tr( "Press Calendar to start playing" ), yellow ); | ||
266 | |||
267 | setFocusPolicy( StrongFocus ); | ||
268 | |||
269 | slotNewGame(); | ||
270 | } | ||
271 | |||
272 | KAstTopLevel::~KAstTopLevel() | ||
273 | { | ||
274 | } | ||
275 | |||
276 | void KAstTopLevel::playSound( const char * ) | ||
277 | { | ||
278 | } | ||
279 | |||
280 | void KAstTopLevel::keyPressEvent( QKeyEvent *event ) | ||
281 | { | ||
282 | if ( event->isAutoRepeat() || !actions.contains( event->key() ) ) | ||
283 | { | ||
284 | event->ignore(); | ||
285 | return; | ||
286 | } | ||
287 | |||
288 | Action a = actions[ event->key() ]; | ||
289 | |||
290 | switch ( a ) | ||
291 | { | ||
292 | case RotateLeft: | ||
293 | view->rotateLeft( TRUE ); | ||
294 | break; | ||
295 | |||
296 | case RotateRight: | ||
297 | view->rotateRight( TRUE ); | ||
298 | break; | ||
299 | |||
300 | case Thrust: | ||
301 | view->thrust( TRUE ); | ||
302 | break; | ||
303 | |||
304 | case Shoot: | ||
305 | view->shoot( TRUE ); | ||
306 | break; | ||
307 | |||
308 | case Shield: | ||
309 | view->setShield( TRUE ); | ||
310 | break; | ||
311 | |||
312 | case Teleport: | ||
313 | view->teleport( TRUE ); | ||
314 | break; | ||
315 | |||
316 | case Brake: | ||
317 | view->brake( TRUE ); | ||
318 | break; | ||
319 | |||
320 | default: | ||
321 | event->ignore(); | ||
322 | return; | ||
323 | } | ||
324 | event->accept(); | ||
325 | } | ||
326 | |||
327 | void KAstTopLevel::keyReleaseEvent( QKeyEvent *event ) | ||
328 | { | ||
329 | if ( event->isAutoRepeat() || !actions.contains( event->key() ) ) | ||
330 | { | ||
331 | event->ignore(); | ||
332 | return; | ||
333 | } | ||
334 | |||
335 | Action a = actions[ event->key() ]; | ||
336 | |||
337 | switch ( a ) | ||
338 | { | ||
339 | case RotateLeft: | ||
340 | view->rotateLeft( FALSE ); | ||
341 | break; | ||
342 | |||
343 | case RotateRight: | ||
344 | view->rotateRight( FALSE ); | ||
345 | break; | ||
346 | |||
347 | case Thrust: | ||
348 | view->thrust( FALSE ); | ||
349 | break; | ||
350 | |||
351 | case Shoot: | ||
352 | view->shoot( FALSE ); | ||
353 | break; | ||
354 | |||
355 | case Brake: | ||
356 | view->brake( FALSE ); | ||
357 | break; | ||
358 | |||
359 | case Shield: | ||
360 | view->setShield( FALSE ); | ||
361 | break; | ||
362 | |||
363 | case Teleport: | ||
364 | view->teleport( FALSE ); | ||
365 | break; | ||
366 | |||
367 | case Launch: | ||
368 | if ( waitShip ) | ||
369 | { | ||
370 | view->newShip(); | ||
371 | waitShip = FALSE; | ||
372 | view->hideText(); | ||
373 | } | ||
374 | else | ||
375 | { | ||
376 | event->ignore(); | ||
377 | return; | ||
378 | } | ||
379 | break; | ||
380 | |||
381 | case NewGame: | ||
382 | slotNewGame(); | ||
383 | break; | ||
384 | /* | ||
385 | case Pause: | ||
386 | { | ||
387 | view->pause( TRUE ); | ||
388 | QMessageBox::information( this, | ||
389 | tr("KAsteroids is paused"), | ||
390 | tr("Paused") ); | ||
391 | view->pause( FALSE ); | ||
392 | } | ||
393 | break; | ||
394 | */ | ||
395 | default: | ||
396 | event->ignore(); | ||
397 | return; | ||
398 | } | ||
399 | |||
400 | event->accept(); | ||
401 | } | ||
402 | |||
403 | void KAstTopLevel::showEvent( QShowEvent *e ) | ||
404 | { | ||
405 | QMainWindow::showEvent( e ); | ||
406 | view->pause( FALSE ); | ||
407 | setFocus(); | ||
408 | } | ||
409 | |||
410 | void KAstTopLevel::hideEvent( QHideEvent *e ) | ||
411 | { | ||
412 | QMainWindow::hideEvent( e ); | ||
413 | view->pause( TRUE ); | ||
414 | } | ||
415 | |||
416 | void KAstTopLevel::focusInEvent( QFocusEvent * ) | ||
417 | { | ||
418 | view->pause( FALSE ); | ||
419 | setFocus(); | ||
420 | } | ||
421 | |||
422 | void KAstTopLevel::focusOutEvent( QFocusEvent * ) | ||
423 | { | ||
424 | view->pause( TRUE ); | ||
425 | } | ||
426 | |||
427 | void KAstTopLevel::slotNewGame() | ||
428 | { | ||
429 | shipsRemain = 3; | ||
430 | score = 0; | ||
431 | scoreLCD->display( 0 ); | ||
432 | level = 0; | ||
433 | levelLCD->display( level+1 ); | ||
434 | shipsLCD->display( shipsRemain-1 ); | ||
435 | view->newGame(); | ||
436 | view->setRockSpeed( levels[0].rockSpeed ); | ||
437 | view->addRocks( levels[0].nrocks ); | ||
438 | view->newShip(); | ||
439 | waitShip = FALSE; | ||
440 | view->hideText(); | ||
441 | isPaused = FALSE; | ||
442 | } | ||
443 | |||
444 | void KAstTopLevel::slotShipKilled() | ||
445 | { | ||
446 | shipsRemain--; | ||
447 | shipsLCD->display( shipsRemain-1 ); | ||
448 | |||
449 | playSound( "ShipDestroyed" ); | ||
450 | |||
451 | if ( shipsRemain > 0 ) | ||
452 | { | ||
453 | waitShip = TRUE; | ||
454 | view->showText( tr( "Ship Destroyed.\nPress Launch/Home key."), yellow ); | ||
455 | } | ||
456 | else | ||
457 | { | ||
458 | view->endGame(); | ||
459 | doStats(); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | void KAstTopLevel::slotRockHit( int size ) | ||
464 | { | ||
465 | switch ( size ) | ||
466 | { | ||
467 | case 0: | ||
468 | score += 10; | ||
469 | break; | ||
470 | |||
471 | case 1: | ||
472 | score += 20; | ||
473 | break; | ||
474 | |||
475 | default: | ||
476 | score += 40; | ||
477 | } | ||
478 | |||
479 | playSound( "RockDestroyed" ); | ||
480 | |||
481 | scoreLCD->display( score ); | ||
482 | } | ||
483 | |||
484 | void KAstTopLevel::slotRocksRemoved() | ||
485 | { | ||
486 | level++; | ||
487 | |||
488 | if ( level >= MAX_LEVELS ) | ||
489 | level = MAX_LEVELS - 1; | ||
490 | |||
491 | view->setRockSpeed( levels[level-1].rockSpeed ); | ||
492 | view->addRocks( levels[level-1].nrocks ); | ||
493 | |||
494 | levelLCD->display( level+1 ); | ||
495 | } | ||
496 | |||
497 | void KAstTopLevel::doStats() | ||
498 | { | ||
499 | QString r( "0.00" ); | ||
500 | if ( view->shots() ) | ||
501 | r = QString::number( (double)view->hits() / view->shots() * 100.0, | ||
502 | 'g', 2 ); | ||
503 | |||
504 | view->showText( tr( "Game Over.\nPress Calendar for a new game." ), yellow, FALSE ); | ||
505 | } | ||
506 | |||
507 | void KAstTopLevel::slotUpdateVitals() | ||
508 | { | ||
509 | brakesLCD->display( view->brakeCount() ); | ||
510 | shieldLCD->display( view->shieldCount() ); | ||
511 | shootLCD->display( view->shootCount() ); | ||
512 | // teleportsLCD->display( view->teleportCount() ); | ||
513 | powerMeter->setValue( view->power() ); | ||
514 | } | ||
diff --git a/noncore/games/qasteroids/toplevel.h b/noncore/games/qasteroids/toplevel.h new file mode 100644 index 0000000..4e1ac9c --- a/dev/null +++ b/noncore/games/qasteroids/toplevel.h | |||
@@ -0,0 +1,99 @@ | |||
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 | * KAsteroids - Copyright (c) Martin R. Jones 1997 | ||
21 | * | ||
22 | * Part of the KDE project | ||
23 | */ | ||
24 | |||
25 | #ifndef __KAST_TOPLEVEL_H__ | ||
26 | #define __KAST_TOPLEVEL_H__ | ||
27 | |||
28 | #include <qmainwindow.h> | ||
29 | #include <qdict.h> | ||
30 | #include <qmap.h> | ||
31 | |||
32 | #include "view.h" | ||
33 | |||
34 | |||
35 | class KALedMeter; | ||
36 | class QLCDNumber; | ||
37 | |||
38 | class KAstTopLevel : public QMainWindow | ||
39 | { | ||
40 | Q_OBJECT | ||
41 | public: | ||
42 | KAstTopLevel( QWidget *parent=0, const char *name=0 ); | ||
43 | virtual ~KAstTopLevel(); | ||
44 | |||
45 | private: | ||
46 | void playSound( const char *snd ); | ||
47 | void readSoundMapping(); | ||
48 | void doStats(); | ||
49 | |||
50 | protected: | ||
51 | virtual void showEvent( QShowEvent * ); | ||
52 | virtual void hideEvent( QHideEvent * ); | ||
53 | virtual void keyPressEvent( QKeyEvent *event ); | ||
54 | virtual void keyReleaseEvent( QKeyEvent *event ); | ||
55 | virtual void focusInEvent( QFocusEvent *event ); | ||
56 | virtual void focusOutEvent( QFocusEvent *event ); | ||
57 | |||
58 | private slots: | ||
59 | void slotNewGame(); | ||
60 | |||
61 | void slotShipKilled(); | ||
62 | void slotRockHit( int size ); | ||
63 | void slotRocksRemoved(); | ||
64 | |||
65 | void slotUpdateVitals(); | ||
66 | |||
67 | private: | ||
68 | KAsteroidsView *view; | ||
69 | QLCDNumber *scoreLCD; | ||
70 | QLCDNumber *levelLCD; | ||
71 | QLCDNumber *shipsLCD; | ||
72 | |||
73 | QLCDNumber *teleportsLCD; | ||
74 | // QLCDNumber *bombsLCD; | ||
75 | QLCDNumber *brakesLCD; | ||
76 | QLCDNumber *shieldLCD; | ||
77 | QLCDNumber *shootLCD; | ||
78 | KALedMeter *powerMeter; | ||
79 | |||
80 | bool sound; | ||
81 | QDict<QString> soundDict; | ||
82 | |||
83 | // waiting for user to press Enter to launch a ship | ||
84 | bool waitShip; | ||
85 | bool isPaused; | ||
86 | |||
87 | int shipsRemain; | ||
88 | int score; | ||
89 | int level; | ||
90 | bool showHiscores; | ||
91 | |||
92 | enum Action { Launch, Thrust, RotateLeft, RotateRight, Shoot, Teleport, | ||
93 | Brake, Shield, Pause, NewGame }; | ||
94 | |||
95 | QMap<int,Action> actions; | ||
96 | }; | ||
97 | |||
98 | #endif | ||
99 | |||
diff --git a/noncore/games/qasteroids/view.cpp b/noncore/games/qasteroids/view.cpp new file mode 100644 index 0000000..ef08343 --- a/dev/null +++ b/noncore/games/qasteroids/view.cpp | |||
@@ -0,0 +1,884 @@ | |||
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 | * KAsteroids - Copyright (c) Martin R. Jones 1997 | ||
21 | * | ||
22 | * Part of the KDE project | ||
23 | */ | ||
24 | |||
25 | #include "view.h" | ||
26 | |||
27 | #include <qpe/resource.h> | ||
28 | |||
29 | #include <qapplication.h> | ||
30 | #include <qkeycode.h> | ||
31 | #include <qaccel.h> | ||
32 | |||
33 | #include <stdlib.h> | ||
34 | #include <math.h> | ||
35 | |||
36 | #define IMG_BACKGROUND "qasteroids/bg.png" | ||
37 | |||
38 | #define REFRESH_DELAY 33 | ||
39 | #define SHIP_SPEED 0.3 | ||
40 | #define MISSILE_SPEED 10.0 | ||
41 | #define SHIP_STEPS 64 | ||
42 | #define ROTATE_RATE 2 | ||
43 | #define SHIELD_ON_COST 1 | ||
44 | #define SHIELD_HIT_COST 30 | ||
45 | #define BRAKE_ON_COST 4 | ||
46 | |||
47 | #define MAX_ROCK_SPEED 2.5 | ||
48 | #define MAX_POWERUP_SPEED 1.5 | ||
49 | #define MAX_SHIP_SPEED 8 | ||
50 | #define MAX_BRAKES 5 | ||
51 | #define MAX_SHIELDS 5 | ||
52 | #define MAX_FIREPOWER 5 | ||
53 | |||
54 | #define TEXT_SPEED 4 | ||
55 | |||
56 | #define PI_X_2 6.283185307 | ||
57 | #ifndef M_PI | ||
58 | #define M_PI 3.141592654 | ||
59 | #endif | ||
60 | |||
61 | struct | ||
62 | { | ||
63 | int id; | ||
64 | const char *path; | ||
65 | int frames; | ||
66 | } | ||
67 | kas_animations [] = | ||
68 | { | ||
69 | // { ID_ROCK_LARGE, "rock1/rock1\%1.png", 32 }, | ||
70 | { ID_ROCK_MEDIUM, "rock2/rock2\%1.png", 32 }, | ||
71 | { ID_ROCK_SMALL, "rock3/rock3\%1.png", 32 }, | ||
72 | { ID_SHIP, "ship/ship\%1.png", 32 }, | ||
73 | { ID_MISSILE, "missile/missile.png", 1 }, | ||
74 | { ID_BIT, "bits/bits\%1.png", 16 }, | ||
75 | { ID_EXHAUST, "exhaust/exhaust.png", 1 }, | ||
76 | { ID_ENERGY_POWERUP, "powerups/energy.png", 1 }, | ||
77 | // { ID_TELEPORT_POWERUP, "powerups/teleport%1.png", 12 }, | ||
78 | { ID_BRAKE_POWERUP, "powerups/brake.png", 1 }, | ||
79 | { ID_SHIELD_POWERUP, "powerups/shield.png", 1 }, | ||
80 | { ID_SHOOT_POWERUP, "powerups/shoot.png", 1 }, | ||
81 | { ID_SHIELD, "shield/shield\%1.png", 6 }, | ||
82 | { 0, 0, 0 } | ||
83 | }; | ||
84 | |||
85 | |||
86 | |||
87 | KAsteroidsView::KAsteroidsView( QWidget *parent, const char *name ) | ||
88 | : QWidget( parent, name ), | ||
89 | field(200, 200), | ||
90 | view(&field,this) | ||
91 | { | ||
92 | view.setVScrollBarMode( QScrollView::AlwaysOff ); | ||
93 | view.setHScrollBarMode( QScrollView::AlwaysOff ); | ||
94 | rocks.setAutoDelete( TRUE ); | ||
95 | missiles.setAutoDelete( TRUE ); | ||
96 | bits.setAutoDelete( TRUE ); | ||
97 | powerups.setAutoDelete( TRUE ); | ||
98 | exhaust.setAutoDelete( TRUE ); | ||
99 | |||
100 | QPixmap pm( Resource::loadPixmap(IMG_BACKGROUND) ); | ||
101 | field.setBackgroundPixmap( pm ); | ||
102 | |||
103 | textSprite = new QCanvasText( &field ); | ||
104 | QFont font( "helvetica", 14 ); | ||
105 | textSprite->setFont( font ); | ||
106 | |||
107 | shield = 0; | ||
108 | shieldOn = FALSE; | ||
109 | refreshRate = REFRESH_DELAY; | ||
110 | |||
111 | readSprites(); | ||
112 | |||
113 | shieldTimer = new QTimer( this ); | ||
114 | connect( shieldTimer, SIGNAL(timeout()), this, SLOT(hideShield()) ); | ||
115 | mTimerId = -1; | ||
116 | |||
117 | shipPower = MAX_POWER_LEVEL; | ||
118 | vitalsChanged = TRUE; | ||
119 | can_destroy_powerups = FALSE; | ||
120 | |||
121 | mPaused = TRUE; | ||
122 | } | ||
123 | |||
124 | // - - - | ||
125 | |||
126 | KAsteroidsView::~KAsteroidsView() | ||
127 | { | ||
128 | } | ||
129 | |||
130 | // - - - | ||
131 | |||
132 | void KAsteroidsView::reset() | ||
133 | { | ||
134 | rocks.clear(); | ||
135 | missiles.clear(); | ||
136 | bits.clear(); | ||
137 | powerups.clear(); | ||
138 | exhaust.clear(); | ||
139 | |||
140 | shotsFired = 0; | ||
141 | shotsHit = 0; | ||
142 | |||
143 | rockSpeed = 1.0; | ||
144 | powerupSpeed = 1.0; | ||
145 | mFrameNum = 0; | ||
146 | mPaused = FALSE; | ||
147 | |||
148 | ship->hide(); | ||
149 | shield->hide(); | ||
150 | /* | ||
151 | if ( mTimerId >= 0 ) { | ||
152 | killTimer( mTimerId ); | ||
153 | mTimerId = -1; | ||
154 | } | ||
155 | */ | ||
156 | } | ||
157 | |||
158 | // - -- | ||
159 | |||
160 | void KAsteroidsView::newGame() | ||
161 | { | ||
162 | if ( shieldOn ) | ||
163 | { | ||
164 | shield->hide(); | ||
165 | shieldOn = FALSE; | ||
166 | } | ||
167 | reset(); | ||
168 | if ( mTimerId < 0 ) | ||
169 | mTimerId = startTimer( REFRESH_DELAY ); | ||
170 | emit updateVitals(); | ||
171 | } | ||
172 | |||
173 | // - - - | ||
174 | |||
175 | void KAsteroidsView::endGame() | ||
176 | { | ||
177 | } | ||
178 | |||
179 | void KAsteroidsView::pause( bool p ) | ||
180 | { | ||
181 | if ( !mPaused && p ) { | ||
182 | if ( mTimerId >= 0 ) { | ||
183 | killTimer( mTimerId ); | ||
184 | mTimerId = -1; | ||
185 | } | ||
186 | } else if ( mPaused && !p ) | ||
187 | mTimerId = startTimer( REFRESH_DELAY ); | ||
188 | mPaused = p; | ||
189 | } | ||
190 | |||
191 | // - - - | ||
192 | |||
193 | void KAsteroidsView::newShip() | ||
194 | { | ||
195 | ship->move( field.width()/2, field.height()/2, 0 ); | ||
196 | shield->move( field.width()/2, field.height()/2, 0 ); | ||
197 | ship->setVelocity( 0.0, 0.0 ); | ||
198 | shipDx = 0; | ||
199 | shipDy = 0; | ||
200 | shipAngle = 0; | ||
201 | rotateL = FALSE; | ||
202 | rotateR = FALSE; | ||
203 | thrustShip = FALSE; | ||
204 | shootShip = FALSE; | ||
205 | brakeShip = FALSE; | ||
206 | teleportShip = FALSE; | ||
207 | shieldOn = TRUE; | ||
208 | shootDelay = 0; | ||
209 | shipPower = MAX_POWER_LEVEL; | ||
210 | rotateRate = ROTATE_RATE; | ||
211 | rotateSlow = 0; | ||
212 | |||
213 | mBrakeCount = 0; | ||
214 | mTeleportCount = 0; | ||
215 | mShootCount = 0; | ||
216 | |||
217 | ship->show(); | ||
218 | shield->show(); | ||
219 | mShieldCount = 1; // just in case the ship appears on a rock. | ||
220 | shieldTimer->start( 1000, TRUE ); | ||
221 | } | ||
222 | |||
223 | void KAsteroidsView::setShield( bool s ) | ||
224 | { | ||
225 | if ( shieldTimer->isActive() && !s ) { | ||
226 | shieldTimer->stop(); | ||
227 | hideShield(); | ||
228 | } else { | ||
229 | shieldOn = s && mShieldCount; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | void KAsteroidsView::brake( bool b ) | ||
234 | { | ||
235 | if ( mBrakeCount ) | ||
236 | { | ||
237 | if ( brakeShip && !b ) | ||
238 | { | ||
239 | rotateL = FALSE; | ||
240 | rotateR = FALSE; | ||
241 | thrustShip = FALSE; | ||
242 | rotateRate = ROTATE_RATE; | ||
243 | } | ||
244 | |||
245 | brakeShip = b; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | // - - - | ||
250 | |||
251 | void KAsteroidsView::readSprites() | ||
252 | { | ||
253 | QString sprites_prefix = Resource::findPixmap( IMG_BACKGROUND ); | ||
254 | int sep = sprites_prefix.findRev( "/" ); | ||
255 | |||
256 | sprites_prefix.truncate( sep ); | ||
257 | |||
258 | int i = 0; | ||
259 | while ( kas_animations[i].id ) | ||
260 | { | ||
261 | animation.insert( kas_animations[i].id, | ||
262 | new QCanvasPixmapArray( sprites_prefix + "/" + kas_animations[i].path, | ||
263 | kas_animations[i].frames ) ); | ||
264 | i++; | ||
265 | } | ||
266 | |||
267 | ship = new QCanvasSprite( animation[ID_SHIP], &field ); | ||
268 | ship->hide(); | ||
269 | |||
270 | shield = new KShield( animation[ID_SHIELD], &field ); | ||
271 | shield->hide(); | ||
272 | } | ||
273 | |||
274 | // - - - | ||
275 | |||
276 | void KAsteroidsView::addRocks( int num ) | ||
277 | { | ||
278 | for ( int i = 0; i < num; i++ ) | ||
279 | { | ||
280 | KRock *rock = new KRock( animation[ID_ROCK_MEDIUM], &field, | ||
281 | ID_ROCK_MEDIUM, randInt(2), randInt(2) ? -1 : 1 ); | ||
282 | double dx = (2.0 - randDouble()*4.0) * rockSpeed; | ||
283 | double dy = (2.0 - randDouble()*4.0) * rockSpeed; | ||
284 | rock->setVelocity( dx, dy ); | ||
285 | rock->setFrame( randInt( rock->frameCount() ) ); | ||
286 | if ( dx > 0 ) | ||
287 | { | ||
288 | if ( dy > 0 ) | ||
289 | rock->move( 5, 5, 0 ); | ||
290 | else | ||
291 | rock->move( 5, field.height() - 25, 0 ); | ||
292 | } | ||
293 | else | ||
294 | { | ||
295 | if ( dy > 0 ) | ||
296 | rock->move( field.width() - 25, 5, 0 ); | ||
297 | else | ||
298 | rock->move( field.width() - 25, field.height() - 25, 0 ); | ||
299 | } | ||
300 | rock->show( ); | ||
301 | rocks.append( rock ); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | // - - - | ||
306 | |||
307 | void KAsteroidsView::showText( const QString &text, const QColor &color, bool scroll ) | ||
308 | { | ||
309 | textSprite->setTextFlags( AlignLeft | AlignVCenter ); | ||
310 | textSprite->setText( text ); | ||
311 | textSprite->setColor( color ); | ||
312 | |||
313 | if ( scroll ) { | ||
314 | textSprite->move( (field.width()-textSprite->boundingRect().width()) / 2, | ||
315 | -textSprite->boundingRect().height() ); | ||
316 | textDy = TEXT_SPEED; | ||
317 | } else { | ||
318 | textSprite->move( (field.width()-textSprite->boundingRect().width()) / 2, | ||
319 | (field.height()-textSprite->boundingRect().height()) / 2 ); | ||
320 | textDy = 0; | ||
321 | } | ||
322 | textSprite->show(); | ||
323 | } | ||
324 | |||
325 | // - - - | ||
326 | |||
327 | void KAsteroidsView::hideText() | ||
328 | { | ||
329 | textDy = -TEXT_SPEED; | ||
330 | } | ||
331 | |||
332 | // - - - | ||
333 | |||
334 | void KAsteroidsView::resizeEvent(QResizeEvent* event) | ||
335 | { | ||
336 | QWidget::resizeEvent(event); | ||
337 | field.resize(width()-4, height()-4); | ||
338 | view.resize(width(),height()); | ||
339 | } | ||
340 | |||
341 | // - - - | ||
342 | |||
343 | void KAsteroidsView::timerEvent( QTimerEvent * ) | ||
344 | { | ||
345 | field.advance(); | ||
346 | |||
347 | QCanvasSprite *rock; | ||
348 | |||
349 | // move rocks forward | ||
350 | for ( rock = rocks.first(); rock; rock = rocks.next() ) { | ||
351 | ((KRock *)rock)->nextFrame(); | ||
352 | wrapSprite( rock ); | ||
353 | } | ||
354 | |||
355 | wrapSprite( ship ); | ||
356 | |||
357 | // check for missile collision with rocks. | ||
358 | processMissiles(); | ||
359 | |||
360 | // these are generated when a ship explodes | ||
361 | for ( KBit *bit = bits.first(); bit; bit = bits.next() ) | ||
362 | { | ||
363 | if ( bit->expired() ) | ||
364 | { | ||
365 | bits.removeRef( bit ); | ||
366 | } | ||
367 | else | ||
368 | { | ||
369 | bit->growOlder(); | ||
370 | bit->setFrame( ( bit->frame()+1 ) % bit->frameCount() ); | ||
371 | } | ||
372 | } | ||
373 | |||
374 | for ( KExhaust *e = exhaust.first(); e; e = exhaust.next() ) | ||
375 | exhaust.removeRef( e ); | ||
376 | |||
377 | // move / rotate ship. | ||
378 | // check for collision with a rock. | ||
379 | processShip(); | ||
380 | |||
381 | // move powerups and check for collision with player and missiles | ||
382 | processPowerups(); | ||
383 | |||
384 | if ( textSprite->visible() ) | ||
385 | { | ||
386 | if ( textDy < 0 && | ||
387 | textSprite->boundingRect().y() <= -textSprite->boundingRect().height() ) { | ||
388 | textSprite->hide(); | ||
389 | } else { | ||
390 | textSprite->moveBy( 0, textDy ); | ||
391 | } | ||
392 | if ( textSprite->boundingRect().y() > (field.height()-textSprite->boundingRect().height())/2 ) | ||
393 | textDy = 0; | ||
394 | } | ||
395 | |||
396 | if ( vitalsChanged && !(mFrameNum % 10) ) { | ||
397 | emit updateVitals(); | ||
398 | vitalsChanged = FALSE; | ||
399 | } | ||
400 | |||
401 | mFrameNum++; | ||
402 | } | ||
403 | |||
404 | void KAsteroidsView::wrapSprite( QCanvasItem *s ) | ||
405 | { | ||
406 | int x = int(s->x() + s->boundingRect().width() / 2); | ||
407 | int y = int(s->y() + s->boundingRect().height() / 2); | ||
408 | |||
409 | if ( x > field.width() ) | ||
410 | s->move( s->x() - field.width(), s->y() ); | ||
411 | else if ( x < 0 ) | ||
412 | s->move( field.width() + s->x(), s->y() ); | ||
413 | |||
414 | if ( y > field.height() ) | ||
415 | s->move( s->x(), s->y() - field.height() ); | ||
416 | else if ( y < 0 ) | ||
417 | s->move( s->x(), field.height() + s->y() ); | ||
418 | } | ||
419 | |||
420 | // - - - | ||
421 | |||
422 | void KAsteroidsView::rockHit( QCanvasItem *hit ) | ||
423 | { | ||
424 | KPowerup *nPup = 0; | ||
425 | int rnd = static_cast<int>(randDouble()*30.0) % 30; | ||
426 | switch( rnd ) | ||
427 | { | ||
428 | case 4: | ||
429 | case 5: | ||
430 | nPup = new KPowerup( animation[ID_ENERGY_POWERUP], &field, | ||
431 | ID_ENERGY_POWERUP ); | ||
432 | break; | ||
433 | case 10: | ||
434 | // nPup = new KPowerup( animation[ID_TELEPORT_POWERUP], &field, | ||
435 | // ID_TELEPORT_POWERUP ); | ||
436 | break; | ||
437 | case 15: | ||
438 | nPup = new KPowerup( animation[ID_BRAKE_POWERUP], &field, | ||
439 | ID_BRAKE_POWERUP ); | ||
440 | break; | ||
441 | case 20: | ||
442 | nPup = new KPowerup( animation[ID_SHIELD_POWERUP], &field, | ||
443 | ID_SHIELD_POWERUP ); | ||
444 | break; | ||
445 | case 24: | ||
446 | case 25: | ||
447 | nPup = new KPowerup( animation[ID_SHOOT_POWERUP], &field, | ||
448 | ID_SHOOT_POWERUP ); | ||
449 | break; | ||
450 | } | ||
451 | if ( nPup ) | ||
452 | { | ||
453 | double r = 0.5 - randDouble(); | ||
454 | nPup->move( hit->x(), hit->y(), 0 ); | ||
455 | nPup->setVelocity( hit->xVelocity() + r, hit->yVelocity() + r ); | ||
456 | nPup->show( ); | ||
457 | powerups.append( nPup ); | ||
458 | } | ||
459 | |||
460 | if ( hit->rtti() == ID_ROCK_LARGE || hit->rtti() == ID_ROCK_MEDIUM ) | ||
461 | { | ||
462 | // break into smaller rocks | ||
463 | double addx[4] = { 1.0, 1.0, -1.0, -1.0 }; | ||
464 | double addy[4] = { -1.0, 1.0, -1.0, 1.0 }; | ||
465 | |||
466 | double dx = hit->xVelocity(); | ||
467 | double dy = hit->yVelocity(); | ||
468 | |||
469 | double maxRockSpeed = MAX_ROCK_SPEED * rockSpeed; | ||
470 | if ( dx > maxRockSpeed ) | ||
471 | dx = maxRockSpeed; | ||
472 | else if ( dx < -maxRockSpeed ) | ||
473 | dx = -maxRockSpeed; | ||
474 | if ( dy > maxRockSpeed ) | ||
475 | dy = maxRockSpeed; | ||
476 | else if ( dy < -maxRockSpeed ) | ||
477 | dy = -maxRockSpeed; | ||
478 | |||
479 | QCanvasSprite *nrock; | ||
480 | |||
481 | for ( int i = 0; i < 4; i++ ) | ||
482 | { | ||
483 | double r = rockSpeed/2 - randDouble()*rockSpeed; | ||
484 | if ( hit->rtti() == ID_ROCK_LARGE ) | ||
485 | { | ||
486 | nrock = new KRock( animation[ID_ROCK_MEDIUM], &field, | ||
487 | ID_ROCK_MEDIUM, randInt(2), randInt(2) ? -1 : 1 ); | ||
488 | emit rockHit( 0 ); | ||
489 | } | ||
490 | else | ||
491 | { | ||
492 | nrock = new KRock( animation[ID_ROCK_SMALL], &field, | ||
493 | ID_ROCK_SMALL, randInt(2), randInt(2) ? -1 : 1 ); | ||
494 | emit rockHit( 1 ); | ||
495 | } | ||
496 | |||
497 | nrock->move( hit->x(), hit->y(), 0 ); | ||
498 | nrock->setVelocity( dx+addx[i]*rockSpeed+r, dy+addy[i]*rockSpeed+r ); | ||
499 | nrock->setFrame( randInt( nrock->frameCount() ) ); | ||
500 | nrock->show( ); | ||
501 | rocks.append( nrock ); | ||
502 | } | ||
503 | } | ||
504 | else if ( hit->rtti() == ID_ROCK_SMALL ) | ||
505 | emit rockHit( 2 ); | ||
506 | rocks.removeRef( (QCanvasSprite *)hit ); | ||
507 | if ( rocks.count() == 0 ) | ||
508 | emit rocksRemoved(); | ||
509 | } | ||
510 | |||
511 | void KAsteroidsView::reducePower( int val ) | ||
512 | { | ||
513 | shipPower -= val; | ||
514 | if ( shipPower <= 0 ) | ||
515 | { | ||
516 | shipPower = 0; | ||
517 | thrustShip = FALSE; | ||
518 | if ( shieldOn ) | ||
519 | { | ||
520 | shieldOn = FALSE; | ||
521 | shield->hide(); | ||
522 | } | ||
523 | } | ||
524 | vitalsChanged = TRUE; | ||
525 | } | ||
526 | |||
527 | void KAsteroidsView::addExhaust( double x, double y, double dx, | ||
528 | double dy, int count ) | ||
529 | { | ||
530 | for ( int i = 0; i < count; i++ ) | ||
531 | { | ||
532 | KExhaust *e = new KExhaust( animation[ID_EXHAUST], &field ); | ||
533 | e->move( x + 2 - randDouble()*4, y + 2 - randDouble()*4 ); | ||
534 | e->setVelocity( dx, dy ); | ||
535 | e->show( ); | ||
536 | exhaust.append( e ); | ||
537 | } | ||
538 | } | ||
539 | |||
540 | void KAsteroidsView::processMissiles() | ||
541 | { | ||
542 | KMissile *missile; | ||
543 | |||
544 | // if a missile has hit a rock, remove missile and break rock into smaller | ||
545 | // rocks or remove completely. | ||
546 | QPtrListIterator<KMissile> it(missiles); | ||
547 | |||
548 | for ( ; it.current(); ++it ) | ||
549 | { | ||
550 | missile = it.current(); | ||
551 | missile->growOlder(); | ||
552 | |||
553 | if ( missile->expired() ) | ||
554 | { | ||
555 | missiles.removeRef( missile ); | ||
556 | continue; | ||
557 | } | ||
558 | |||
559 | wrapSprite( missile ); | ||
560 | |||
561 | QCanvasItemList hits = missile->collisions( TRUE ); | ||
562 | QCanvasItemList::Iterator hit; | ||
563 | for ( hit = hits.begin(); hit != hits.end(); ++hit ) | ||
564 | { | ||
565 | if ( (*hit)->rtti() >= ID_ROCK_LARGE && | ||
566 | (*hit)->rtti() <= ID_ROCK_SMALL ) | ||
567 | { | ||
568 | shotsHit++; | ||
569 | rockHit( *hit ); | ||
570 | missiles.removeRef( missile ); | ||
571 | break; | ||
572 | } | ||
573 | } | ||
574 | } | ||
575 | } | ||
576 | |||
577 | // - - - | ||
578 | |||
579 | void KAsteroidsView::processShip() | ||
580 | { | ||
581 | if ( ship->visible() ) | ||
582 | { | ||
583 | if ( shieldOn ) | ||
584 | { | ||
585 | shield->show(); | ||
586 | reducePower( SHIELD_ON_COST ); | ||
587 | static int sf = 0; | ||
588 | sf++; | ||
589 | |||
590 | if ( sf % 2 ) | ||
591 | shield->setFrame( (shield->frame()+1) % shield->frameCount() ); | ||
592 | shield->move( ship->x() - 5, ship->y() - 5 ); | ||
593 | |||
594 | QCanvasItemList hits = shield->collisions( TRUE ); | ||
595 | QCanvasItemList::Iterator it; | ||
596 | for ( it = hits.begin(); it != hits.end(); ++it ) | ||
597 | { | ||
598 | if ( (*it)->rtti() >= ID_ROCK_LARGE && | ||
599 | (*it)->rtti() <= ID_ROCK_SMALL ) | ||
600 | { | ||
601 | int factor; | ||
602 | switch ( (*it)->rtti() ) | ||
603 | { | ||
604 | case ID_ROCK_LARGE: | ||
605 | factor = 3; | ||
606 | break; | ||
607 | |||
608 | case ID_ROCK_MEDIUM: | ||
609 | factor = 2; | ||
610 | break; | ||
611 | |||
612 | default: | ||
613 | factor = 1; | ||
614 | } | ||
615 | |||
616 | if ( factor > mShieldCount ) | ||
617 | { | ||
618 | // shield not strong enough | ||
619 | shieldOn = FALSE; | ||
620 | break; | ||
621 | } | ||
622 | rockHit( *it ); | ||
623 | // the more shields we have the less costly | ||
624 | reducePower( factor * (SHIELD_HIT_COST - mShieldCount*2) ); | ||
625 | } | ||
626 | } | ||
627 | } | ||
628 | |||
629 | if ( !shieldOn ) | ||
630 | { | ||
631 | shield->hide(); | ||
632 | QCanvasItemList hits = ship->collisions( TRUE ); | ||
633 | QCanvasItemList::Iterator it; | ||
634 | for ( it = hits.begin(); it != hits.end(); ++it ) | ||
635 | { | ||
636 | if ( (*it)->rtti() >= ID_ROCK_LARGE && | ||
637 | (*it)->rtti() <= ID_ROCK_SMALL ) | ||
638 | { | ||
639 | KBit *bit; | ||
640 | for ( int i = 0; i < 8; i++ ) | ||
641 | { | ||
642 | bit = new KBit( animation[ID_BIT], &field ); | ||
643 | bit->move( ship->x() + 5 - randDouble() * 10, | ||
644 | ship->y() + 5 - randDouble() * 10, | ||
645 | randInt(bit->frameCount()) ); | ||
646 | bit->setVelocity( 1-randDouble()*2, | ||
647 | 1-randDouble()*2 ); | ||
648 | bit->setDeath( 60 + randInt(60) ); | ||
649 | bit->show( ); | ||
650 | bits.append( bit ); | ||
651 | } | ||
652 | ship->hide(); | ||
653 | shield->hide(); | ||
654 | emit shipKilled(); | ||
655 | break; | ||
656 | } | ||
657 | } | ||
658 | } | ||
659 | |||
660 | |||
661 | if ( rotateSlow ) | ||
662 | rotateSlow--; | ||
663 | |||
664 | if ( rotateL ) | ||
665 | { | ||
666 | shipAngle -= rotateSlow ? 1 : rotateRate; | ||
667 | if ( shipAngle < 0 ) | ||
668 | shipAngle += SHIP_STEPS; | ||
669 | } | ||
670 | |||
671 | if ( rotateR ) | ||
672 | { | ||
673 | shipAngle += rotateSlow ? 1 : rotateRate; | ||
674 | if ( shipAngle >= SHIP_STEPS ) | ||
675 | shipAngle -= SHIP_STEPS; | ||
676 | } | ||
677 | |||
678 | double angle = shipAngle * PI_X_2 / SHIP_STEPS; | ||
679 | double cosangle = cos( angle ); | ||
680 | double sinangle = sin( angle ); | ||
681 | |||
682 | if ( brakeShip ) | ||
683 | { | ||
684 | thrustShip = FALSE; | ||
685 | rotateL = FALSE; | ||
686 | rotateR = FALSE; | ||
687 | rotateRate = ROTATE_RATE; | ||
688 | if ( fabs(shipDx) < 2.5 && fabs(shipDy) < 2.5 ) | ||
689 | { | ||
690 | shipDx = 0.0; | ||
691 | shipDy = 0.0; | ||
692 | ship->setVelocity( shipDx, shipDy ); | ||
693 | brakeShip = FALSE; | ||
694 | } | ||
695 | else | ||
696 | { | ||
697 | double motionAngle = atan2( -shipDy, -shipDx ); | ||
698 | if ( angle > M_PI ) | ||
699 | angle -= PI_X_2; | ||
700 | double angleDiff = angle - motionAngle; | ||
701 | if ( angleDiff > M_PI ) | ||
702 | angleDiff = PI_X_2 - angleDiff; | ||
703 | else if ( angleDiff < -M_PI ) | ||
704 | angleDiff = PI_X_2 + angleDiff; | ||
705 | double fdiff = fabs( angleDiff ); | ||
706 | if ( fdiff > 0.08 ) | ||
707 | { | ||
708 | if ( angleDiff > 0 ) | ||
709 | rotateL = TRUE; | ||
710 | else if ( angleDiff < 0 ) | ||
711 | rotateR = TRUE; | ||
712 | if ( fdiff > 0.6 ) | ||
713 | rotateRate = mBrakeCount + 1; | ||
714 | else if ( fdiff > 0.4 ) | ||
715 | rotateRate = 2; | ||
716 | else | ||
717 | rotateRate = 1; | ||
718 | |||
719 | if ( rotateRate > 5 ) | ||
720 | rotateRate = 5; | ||
721 | } | ||
722 | else if ( fabs(shipDx) > 1 || fabs(shipDy) > 1 ) | ||
723 | { | ||
724 | thrustShip = TRUE; | ||
725 | // we'll make braking a bit faster | ||
726 | shipDx += cosangle/6 * (mBrakeCount - 1); | ||
727 | shipDy += sinangle/6 * (mBrakeCount - 1); | ||
728 | reducePower( BRAKE_ON_COST ); | ||
729 | addExhaust( ship->x() + 10 - cosangle*11, | ||
730 | ship->y() + 10 - sinangle*11, | ||
731 | shipDx-cosangle, shipDy-sinangle, | ||
732 | mBrakeCount+1 ); | ||
733 | } | ||
734 | } | ||
735 | } | ||
736 | |||
737 | if ( thrustShip ) | ||
738 | { | ||
739 | // The ship has a terminal velocity, but trying to go faster | ||
740 | // still uses fuel (can go faster diagonally - don't care). | ||
741 | double thrustx = cosangle/8; | ||
742 | double thrusty = sinangle/8; | ||
743 | if ( fabs(shipDx + thrustx) < MAX_SHIP_SPEED ) | ||
744 | shipDx += thrustx; | ||
745 | if ( fabs(shipDy + thrusty) < MAX_SHIP_SPEED ) | ||
746 | shipDy += thrusty; | ||
747 | ship->setVelocity( shipDx, shipDy ); | ||
748 | reducePower( 1 ); | ||
749 | addExhaust( ship->x() + 10 - cosangle*10, | ||
750 | ship->y() + 10 - sinangle*10, | ||
751 | shipDx-cosangle, shipDy-sinangle, 3 ); | ||
752 | } | ||
753 | |||
754 | ship->setFrame( shipAngle >> 1 ); | ||
755 | |||
756 | if ( shootShip ) | ||
757 | { | ||
758 | if ( !shootDelay && (int)missiles.count() < mShootCount + 2 ) | ||
759 | { | ||
760 | KMissile *missile = new KMissile( animation[ID_MISSILE], &field ); | ||
761 | missile->move( 11+ship->x()+cosangle*11, | ||
762 | 11+ship->y()+sinangle*11, 0 ); | ||
763 | missile->setVelocity( shipDx + cosangle*MISSILE_SPEED, | ||
764 | shipDy + sinangle*MISSILE_SPEED ); | ||
765 | missile->show( ); | ||
766 | missiles.append( missile ); | ||
767 | shotsFired++; | ||
768 | reducePower( 1 ); | ||
769 | |||
770 | shootDelay = 5; | ||
771 | } | ||
772 | |||
773 | if ( shootDelay ) | ||
774 | shootDelay--; | ||
775 | } | ||
776 | |||
777 | if ( teleportShip ) | ||
778 | { | ||
779 | int ra = rand() % 10; | ||
780 | if( ra == 0 ) | ||
781 | ra += rand() % 20; | ||
782 | int xra = ra * 60 + ( (rand() % 20) * (rand() % 20) ); | ||
783 | int yra = ra * 50 - ( (rand() % 20) * (rand() % 20) ); | ||
784 | ship->move( xra, yra ); | ||
785 | } | ||
786 | |||
787 | vitalsChanged = TRUE; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | // - - - | ||
792 | |||
793 | void KAsteroidsView::processPowerups() | ||
794 | { | ||
795 | if ( !powerups.isEmpty() ) | ||
796 | { | ||
797 | // if player gets the powerup remove it from the screen, if option | ||
798 | // "Can destroy powerups" is enabled and a missile hits the powerup | ||
799 | // destroy it | ||
800 | |||
801 | KPowerup *pup; | ||
802 | QPtrListIterator<KPowerup> it( powerups ); | ||
803 | |||
804 | for( ; it.current(); ++it ) | ||
805 | { | ||
806 | pup = it.current(); | ||
807 | pup->growOlder(); | ||
808 | |||
809 | if( pup->expired() ) | ||
810 | { | ||
811 | powerups.removeRef( pup ); | ||
812 | continue; | ||
813 | } | ||
814 | |||
815 | wrapSprite( pup ); | ||
816 | |||
817 | QCanvasItemList hits = pup->collisions( TRUE ); | ||
818 | QCanvasItemList::Iterator it; | ||
819 | for ( it = hits.begin(); it != hits.end(); ++it ) | ||
820 | { | ||
821 | if ( (*it) == ship ) | ||
822 | { | ||
823 | switch( pup->rtti() ) | ||
824 | { | ||
825 | case ID_ENERGY_POWERUP: | ||
826 | shipPower += 150; | ||
827 | if ( shipPower > MAX_POWER_LEVEL ) | ||
828 | shipPower = MAX_POWER_LEVEL; | ||
829 | break; | ||
830 | case ID_TELEPORT_POWERUP: | ||
831 | mTeleportCount++; | ||
832 | break; | ||
833 | case ID_BRAKE_POWERUP: | ||
834 | if ( mBrakeCount < MAX_BRAKES ) | ||
835 | mBrakeCount++; | ||
836 | break; | ||
837 | case ID_SHIELD_POWERUP: | ||
838 | if ( mShieldCount < MAX_SHIELDS ) | ||
839 | mShieldCount++; | ||
840 | break; | ||
841 | case ID_SHOOT_POWERUP: | ||
842 | if ( mShootCount < MAX_FIREPOWER ) | ||
843 | mShootCount++; | ||
844 | break; | ||
845 | } | ||
846 | |||
847 | powerups.removeRef( pup ); | ||
848 | vitalsChanged = TRUE; | ||
849 | } | ||
850 | else if ( (*it) == shield ) | ||
851 | { | ||
852 | powerups.removeRef( pup ); | ||
853 | } | ||
854 | else if ( (*it)->rtti() == ID_MISSILE ) | ||
855 | { | ||
856 | if ( can_destroy_powerups ) | ||
857 | { | ||
858 | powerups.removeRef( pup ); | ||
859 | } | ||
860 | } | ||
861 | } | ||
862 | } | ||
863 | } // -- if( powerups.isEmpty() ) | ||
864 | } | ||
865 | |||
866 | // - - - | ||
867 | |||
868 | void KAsteroidsView::hideShield() | ||
869 | { | ||
870 | shield->hide(); | ||
871 | mShieldCount = 0; | ||
872 | shieldOn = FALSE; | ||
873 | } | ||
874 | |||
875 | double KAsteroidsView::randDouble() | ||
876 | { | ||
877 | int v = rand(); | ||
878 | return (double)v / (double)RAND_MAX; | ||
879 | } | ||
880 | |||
881 | int KAsteroidsView::randInt( int range ) | ||
882 | { | ||
883 | return rand() % range; | ||
884 | } | ||
diff --git a/noncore/games/qasteroids/view.h b/noncore/games/qasteroids/view.h new file mode 100644 index 0000000..0a7902b --- a/dev/null +++ b/noncore/games/qasteroids/view.h | |||
@@ -0,0 +1,156 @@ | |||
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 | * KAsteroids - Copyright (c) Martin R. Jones 1997 | ||
21 | * | ||
22 | * Part of the KDE project | ||
23 | */ | ||
24 | |||
25 | #ifndef __AST_VIEW_H__ | ||
26 | #define __AST_VIEW_H__ | ||
27 | |||
28 | #include <qwidget.h> | ||
29 | #include <qlist.h> | ||
30 | #include <qintdict.h> | ||
31 | #include <qtimer.h> | ||
32 | #include <qcanvas.h> | ||
33 | #include "sprites.h" | ||
34 | |||
35 | #define QPtrList QList | ||
36 | #define QPtrListIterator QListIterator | ||
37 | |||
38 | #define MAX_POWER_LEVEL 1000 | ||
39 | |||
40 | class KAsteroidsView : public QWidget | ||
41 | { | ||
42 | Q_OBJECT | ||
43 | public: | ||
44 | KAsteroidsView( QWidget *parent = 0, const char *name = 0 ); | ||
45 | virtual ~KAsteroidsView(); | ||
46 | |||
47 | int refreshRate; | ||
48 | |||
49 | void reset(); | ||
50 | void setRockSpeed( double rs ) { rockSpeed = rs; } | ||
51 | void addRocks( int num ); | ||
52 | void newGame(); | ||
53 | void endGame(); | ||
54 | void newShip(); | ||
55 | |||
56 | void rotateLeft( bool r ) { rotateL = r; rotateSlow = 5; } | ||
57 | void rotateRight( bool r ) { rotateR = r; rotateSlow = 5; } | ||
58 | void thrust( bool t ) { thrustShip = t && shipPower > 0; } | ||
59 | void shoot( bool s ) { shootShip = s; shootDelay = 0; } | ||
60 | void setShield( bool s ); | ||
61 | void teleport( bool te) { teleportShip = te && mTeleportCount; } | ||
62 | void brake( bool b ); | ||
63 | void pause( bool p); | ||
64 | |||
65 | void showText( const QString &text, const QColor &color, bool scroll=TRUE ); | ||
66 | void hideText(); | ||
67 | |||
68 | int shots() const { return shotsFired; } | ||
69 | int hits() const { return shotsHit; } | ||
70 | int power() const { return shipPower; } | ||
71 | |||
72 | int teleportCount() const { return mTeleportCount; } | ||
73 | int brakeCount() const { return mBrakeCount; } | ||
74 | int shieldCount() const { return mShieldCount; } | ||
75 | int shootCount() const { return mShootCount; } | ||
76 | |||
77 | signals: | ||
78 | void shipKilled(); | ||
79 | void rockHit( int size ); | ||
80 | void rocksRemoved(); | ||
81 | void updateVitals(); | ||
82 | |||
83 | private slots: | ||
84 | void hideShield(); | ||
85 | |||
86 | protected: | ||
87 | void readSprites(); | ||
88 | void wrapSprite( QCanvasItem * ); | ||
89 | void rockHit( QCanvasItem * ); | ||
90 | void reducePower( int val ); | ||
91 | void addExhaust( double x, double y, double dx, double dy, int count ); | ||
92 | void processMissiles(); | ||
93 | void processShip(); | ||
94 | void processPowerups(); | ||
95 | void processShield(); | ||
96 | double randDouble(); | ||
97 | int randInt( int range ); | ||
98 | |||
99 | virtual void resizeEvent( QResizeEvent *event ); | ||
100 | virtual void timerEvent( QTimerEvent * ); | ||
101 | |||
102 | private: | ||
103 | QCanvas field; | ||
104 | QCanvasView view; | ||
105 | QIntDict<QCanvasPixmapArray> animation; | ||
106 | QPtrList<QCanvasSprite> rocks; | ||
107 | QPtrList<KMissile> missiles; | ||
108 | QPtrList<KBit> bits; | ||
109 | QPtrList<KExhaust> exhaust; | ||
110 | QPtrList<KPowerup> powerups; | ||
111 | KShield *shield; | ||
112 | QCanvasSprite *ship; | ||
113 | QCanvasText *textSprite; | ||
114 | |||
115 | bool rotateL; | ||
116 | bool rotateR; | ||
117 | bool thrustShip; | ||
118 | bool shootShip; | ||
119 | bool teleportShip; | ||
120 | bool brakeShip; | ||
121 | bool pauseShip; | ||
122 | bool shieldOn; | ||
123 | |||
124 | bool vitalsChanged; | ||
125 | |||
126 | int shipAngle; | ||
127 | int rotateSlow; | ||
128 | int rotateRate; | ||
129 | int shipPower; | ||
130 | |||
131 | int shotsFired; | ||
132 | int shotsHit; | ||
133 | int shootDelay; | ||
134 | |||
135 | int mBrakeCount; | ||
136 | int mShieldCount; | ||
137 | int mTeleportCount; | ||
138 | int mShootCount; | ||
139 | |||
140 | double shipDx; | ||
141 | double shipDy; | ||
142 | |||
143 | int textDy; | ||
144 | int mFrameNum; | ||
145 | bool mPaused; | ||
146 | int mTimerId; | ||
147 | |||
148 | double rockSpeed; | ||
149 | double powerupSpeed; | ||
150 | |||
151 | bool can_destroy_powerups; | ||
152 | |||
153 | QTimer *shieldTimer; | ||
154 | }; | ||
155 | |||
156 | #endif | ||
diff --git a/noncore/games/snake/.cvsignore b/noncore/games/snake/.cvsignore new file mode 100644 index 0000000..edfa921 --- a/dev/null +++ b/noncore/games/snake/.cvsignore | |||
@@ -0,0 +1,3 @@ | |||
1 | moc_* | ||
2 | *.moc | ||
3 | Makefile | ||
diff --git a/noncore/games/snake/Makefile.in b/noncore/games/snake/Makefile.in new file mode 100644 index 0000000..8179b6f --- a/dev/null +++ b/noncore/games/snake/Makefile.in | |||
@@ -0,0 +1,159 @@ | |||
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 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= snake | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =snake.h \ | ||
27 | target.h \ | ||
28 | obstacle.h \ | ||
29 | interface.h \ | ||
30 | codes.h | ||
31 | SOURCES =snake.cpp \ | ||
32 | target.cpp \ | ||
33 | obstacle.cpp \ | ||
34 | interface.cpp \ | ||
35 | main.cpp | ||
36 | OBJECTS =snake.o \ | ||
37 | target.o \ | ||
38 | obstacle.o \ | ||
39 | interface.o \ | ||
40 | main.o | ||
41 | INTERFACES = | ||
42 | UICDECLS = | ||
43 | UICIMPLS = | ||
44 | SRCMOC =moc_snake.cpp \ | ||
45 | moc_interface.cpp | ||
46 | OBJMOC =moc_snake.o \ | ||
47 | moc_interface.o | ||
48 | |||
49 | |||
50 | ####### Implicit rules | ||
51 | |||
52 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
53 | |||
54 | .cpp.o: | ||
55 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
56 | |||
57 | .cxx.o: | ||
58 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
59 | |||
60 | .cc.o: | ||
61 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
62 | |||
63 | .C.o: | ||
64 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
65 | |||
66 | .c.o: | ||
67 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
68 | |||
69 | ####### Build rules | ||
70 | |||
71 | |||
72 | all: $(DESTDIR)$(TARGET) | ||
73 | |||
74 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
75 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
76 | |||
77 | moc: $(SRCMOC) | ||
78 | |||
79 | tmake: | ||
80 | tmake snake.pro | ||
81 | |||
82 | clean: | ||
83 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
84 | -rm -f *~ core | ||
85 | -rm -f allmoc.cpp | ||
86 | |||
87 | ####### Extension Modules | ||
88 | |||
89 | listpromodules: | ||
90 | @echo | ||
91 | |||
92 | listallmodules: | ||
93 | @echo | ||
94 | |||
95 | listaddonpromodules: | ||
96 | @echo | ||
97 | |||
98 | listaddonentmodules: | ||
99 | @echo | ||
100 | |||
101 | |||
102 | REQUIRES= | ||
103 | |||
104 | ####### Sub-libraries | ||
105 | |||
106 | |||
107 | ###### Combined headers | ||
108 | |||
109 | |||
110 | |||
111 | ####### Compile | ||
112 | |||
113 | snake.o: snake.cpp \ | ||
114 | snake.h \ | ||
115 | target.h \ | ||
116 | codes.h \ | ||
117 | $(QPEDIR)/include/qpe/resource.h | ||
118 | |||
119 | target.o: target.cpp \ | ||
120 | target.h \ | ||
121 | codes.h \ | ||
122 | $(QPEDIR)/include/qpe/resource.h | ||
123 | |||
124 | obstacle.o: obstacle.cpp \ | ||
125 | obstacle.h \ | ||
126 | codes.h \ | ||
127 | $(QPEDIR)/include/qpe/resource.h | ||
128 | |||
129 | interface.o: interface.cpp \ | ||
130 | interface.h \ | ||
131 | snake.h \ | ||
132 | target.h \ | ||
133 | obstacle.h \ | ||
134 | $(QPEDIR)/include/qpe/resource.h \ | ||
135 | $(QPEDIR)/include/qpe/qpetoolbar.h | ||
136 | |||
137 | main.o: main.cpp \ | ||
138 | interface.h \ | ||
139 | snake.h \ | ||
140 | target.h \ | ||
141 | obstacle.h \ | ||
142 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
143 | |||
144 | moc_snake.o: moc_snake.cpp \ | ||
145 | snake.h | ||
146 | |||
147 | moc_interface.o: moc_interface.cpp \ | ||
148 | interface.h \ | ||
149 | snake.h \ | ||
150 | target.h \ | ||
151 | obstacle.h | ||
152 | |||
153 | moc_snake.cpp: snake.h | ||
154 | $(MOC) snake.h -o moc_snake.cpp | ||
155 | |||
156 | moc_interface.cpp: interface.h | ||
157 | $(MOC) interface.h -o moc_interface.cpp | ||
158 | |||
159 | |||
diff --git a/noncore/games/snake/codes.h b/noncore/games/snake/codes.h new file mode 100644 index 0000000..3b5e4d0 --- a/dev/null +++ b/noncore/games/snake/codes.h | |||
@@ -0,0 +1,20 @@ | |||
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 | **********************************************************************/const int target_rtti = 1500; | ||
20 | const int obstacle_rtti = 1600; | ||
diff --git a/noncore/games/snake/interface.cpp b/noncore/games/snake/interface.cpp new file mode 100644 index 0000000..c9b4931 --- a/dev/null +++ b/noncore/games/snake/interface.cpp | |||
@@ -0,0 +1,224 @@ | |||
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 "interface.h" | ||
22 | |||
23 | #include <qpe/resource.h> | ||
24 | |||
25 | #include <qpe/qpetoolbar.h> | ||
26 | #include <qtoolbutton.h> | ||
27 | #include <qstyle.h> | ||
28 | #include <qapplication.h> | ||
29 | #include <qmessagebox.h> | ||
30 | |||
31 | SnakeGame::SnakeGame(QWidget* parent, const char* name, WFlags f) : | ||
32 | QMainWindow(parent,name,f), | ||
33 | canvas(232, 258) | ||
34 | { | ||
35 | setCaption( tr("Snake") ); | ||
36 | QPixmap bg = Resource::loadPixmap("grass"); | ||
37 | canvas.setBackgroundPixmap(bg); | ||
38 | canvas.setUpdatePeriod(100); | ||
39 | snake = 0; | ||
40 | |||
41 | cv = new QCanvasView(&canvas, this); | ||
42 | |||
43 | pauseTimer = new QTimer(this); | ||
44 | connect(pauseTimer, SIGNAL(timeout()), this, SLOT(wait()) ); | ||
45 | |||
46 | setToolBarsMovable( FALSE ); | ||
47 | |||
48 | QPEToolBar* toolbar = new QPEToolBar( this); | ||
49 | toolbar->setHorizontalStretchable( TRUE ); | ||
50 | |||
51 | QPixmap newicon = Resource::loadPixmap("ksnake"); | ||
52 | setIcon(newicon); | ||
53 | (void)new QToolButton(newicon, tr("New Game"), 0, | ||
54 | this, SLOT(newGame()), toolbar, "New Game"); | ||
55 | |||
56 | scorelabel = new QLabel(toolbar); | ||
57 | showScore(0); | ||
58 | scorelabel->setBackgroundMode( PaletteButton ); | ||
59 | scorelabel->setAlignment( AlignRight | AlignVCenter | ExpandTabs ); | ||
60 | toolbar->setStretchableWidget( scorelabel ); | ||
61 | |||
62 | setFocusPolicy(StrongFocus); | ||
63 | |||
64 | setCentralWidget(cv); | ||
65 | |||
66 | welcomescreen(); | ||
67 | gamestopped = true; | ||
68 | waitover = true; | ||
69 | } | ||
70 | |||
71 | SnakeGame::~SnakeGame() | ||
72 | { | ||
73 | delete snake; | ||
74 | } | ||
75 | |||
76 | void SnakeGame::resizeEvent(QResizeEvent *) | ||
77 | { | ||
78 | QSize s = centralWidget()->size(); | ||
79 | int fw = style().defaultFrameWidth(); | ||
80 | canvas.resize( s.width() - fw - 2, s.height() - fw - 2); | ||
81 | } | ||
82 | |||
83 | void SnakeGame::welcomescreen() | ||
84 | { | ||
85 | QCanvasText* title = new QCanvasText(tr("SNAKE!"), &canvas); | ||
86 | title->setColor(yellow); | ||
87 | title->setFont( QFont("times", 18, QFont::Bold) ); | ||
88 | int w = title->boundingRect().width(); | ||
89 | title->move(canvas.width()/2 -w/2, canvas.height()/2-110); | ||
90 | title->show(); | ||
91 | QCanvasPixmapArray* titlearray = new QCanvasPixmapArray(Resource::findPixmap("title")); | ||
92 | QCanvasSprite* titlepic = new QCanvasSprite(titlearray, &canvas); | ||
93 | titlepic->move(canvas.width()/2 - 33, canvas.height()/2-85); | ||
94 | titlepic->show(); | ||
95 | QCanvasText* instr = new QCanvasText(tr("Use the arrow keys to guide the\n" | ||
96 | "snake to eat the mouse. You must not\n" | ||
97 | "crash into the walls, edges or its tail."), | ||
98 | &canvas); | ||
99 | w = instr->boundingRect().width(); | ||
100 | instr->move(canvas.width()/2-w/2, canvas.height()/2-20); | ||
101 | instr->setColor(white); | ||
102 | instr->show(); | ||
103 | QCanvasText* cont = new QCanvasText(tr("Press Any Key To Start"), &canvas); | ||
104 | w = cont->boundingRect().width(); | ||
105 | cont->move(canvas.width()/2-w/2, canvas.height()/2+80); | ||
106 | cont->setColor(yellow); | ||
107 | cont->show(); | ||
108 | |||
109 | } | ||
110 | |||
111 | void SnakeGame::newGame() | ||
112 | { | ||
113 | clear(); | ||
114 | snake = new Snake(&canvas); | ||
115 | connect(snake, SIGNAL(dead()), this, SLOT(gameOver()) ); | ||
116 | connect(snake, SIGNAL(targethit()), this, SLOT(levelUp()) ); | ||
117 | connect(snake, SIGNAL(scorechanged()), this, SLOT(scoreInc()) ); | ||
118 | connect(this, SIGNAL(moveFaster()), snake, SLOT(increaseSpeed()) ); | ||
119 | last = 0; | ||
120 | targetamount = 1; | ||
121 | notargets = 1; | ||
122 | level = 1; | ||
123 | stage = 1; | ||
124 | showScore(0); | ||
125 | gamestopped = false; | ||
126 | waitover = true; | ||
127 | int x = canvas.width()/2 - 70; | ||
128 | x = x - x % 16; | ||
129 | int y = canvas.height()-50; | ||
130 | y = y - y % 16; | ||
131 | (void)new Obstacle(&canvas, x, 32); | ||
132 | (void)new Obstacle(&canvas, x, y); | ||
133 | createTargets(); | ||
134 | } | ||
135 | |||
136 | |||
137 | void SnakeGame::showScore(int score) | ||
138 | { | ||
139 | scorelabel->setText(tr(" Score : %1 ").arg(score) ); | ||
140 | } | ||
141 | |||
142 | |||
143 | void SnakeGame::scoreInc() | ||
144 | { | ||
145 | showScore( snake->getScore() ); | ||
146 | } | ||
147 | |||
148 | void SnakeGame::levelUp() | ||
149 | { | ||
150 | notargets--; | ||
151 | if (notargets == 0) { | ||
152 | stage++; | ||
153 | if (stage == 3) { | ||
154 | level++; | ||
155 | emit moveFaster(); | ||
156 | targetamount++; | ||
157 | stage = 0; | ||
158 | } | ||
159 | createTargets(); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | void SnakeGame::createTargets() | ||
164 | { | ||
165 | for (int i = 0; i < targetamount; i++) | ||
166 | (void)new Target(&canvas); | ||
167 | notargets = targetamount; | ||
168 | } | ||
169 | |||
170 | void SnakeGame::clear() | ||
171 | { | ||
172 | delete snake; | ||
173 | snake = 0; | ||
174 | QCanvasItemList l = canvas.allItems(); | ||
175 | for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) { | ||
176 | delete *it; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | void SnakeGame::gameOver() | ||
181 | { | ||
182 | int score = snake->getScore(); | ||
183 | QString scoreoutput=""; | ||
184 | scoreoutput.setNum(score); | ||
185 | QCanvasText* gameover = new QCanvasText(tr("GAME OVER!\n Your Score: %1").arg( scoreoutput), &canvas); | ||
186 | |||
187 | gameover->setZ(100); | ||
188 | gameover->setColor(yellow); | ||
189 | gameover->setFont( QFont("times", 18, QFont::Bold) ); | ||
190 | int w = gameover->boundingRect().width(); | ||
191 | gameover->move(canvas.width()/2 -w/2, canvas.height()/2 -50); | ||
192 | gameover->show(); | ||
193 | gamestopped = true; | ||
194 | waitover = false; | ||
195 | pauseTimer->start(2500); | ||
196 | } | ||
197 | |||
198 | void SnakeGame::wait() | ||
199 | { | ||
200 | waitover = true; | ||
201 | pauseTimer->stop(); | ||
202 | QCanvasText* cont = new QCanvasText(tr("Press Any Key to Begin a New Game."), | ||
203 | &canvas); | ||
204 | cont->setZ(100); | ||
205 | cont->setColor(white); | ||
206 | int w = cont->boundingRect().width(); | ||
207 | cont->move(canvas.width()/2 -w/2, canvas.height()/2); | ||
208 | cont->show(); | ||
209 | } | ||
210 | |||
211 | void SnakeGame::keyPressEvent(QKeyEvent* event) | ||
212 | { | ||
213 | if (gamestopped) { | ||
214 | if (waitover) | ||
215 | newGame(); | ||
216 | else | ||
217 | return; | ||
218 | } | ||
219 | else { | ||
220 | int newkey = event->key(); | ||
221 | snake->go(newkey); | ||
222 | } | ||
223 | } | ||
224 | |||
diff --git a/noncore/games/snake/interface.h b/noncore/games/snake/interface.h new file mode 100644 index 0000000..30c7f84 --- a/dev/null +++ b/noncore/games/snake/interface.h | |||
@@ -0,0 +1,69 @@ | |||
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 | #include <qmainwindow.h> | ||
21 | #include <qcanvas.h> | ||
22 | #include <qlabel.h> | ||
23 | |||
24 | #include "snake.h" | ||
25 | #include "target.h" | ||
26 | #include "obstacle.h" | ||
27 | |||
28 | // class QCanvas; | ||
29 | |||
30 | class SnakeGame : public QMainWindow { | ||
31 | Q_OBJECT | ||
32 | |||
33 | public: | ||
34 | SnakeGame(QWidget* parent=0, const char* name=0, WFlags f=0); | ||
35 | ~SnakeGame(); | ||
36 | |||
37 | void clear(); | ||
38 | void createTargets(); | ||
39 | void welcomescreen(); | ||
40 | |||
41 | protected: | ||
42 | virtual void keyPressEvent(QKeyEvent*); | ||
43 | virtual void resizeEvent(QResizeEvent *e); | ||
44 | |||
45 | signals: | ||
46 | void moveFaster(); | ||
47 | |||
48 | private slots: | ||
49 | void newGame(); | ||
50 | void gameOver(); | ||
51 | void wait(); | ||
52 | void levelUp(); | ||
53 | void scoreInc(); | ||
54 | |||
55 | private: | ||
56 | void showScore(int); | ||
57 | QCanvasView* cv; | ||
58 | QLabel* scorelabel; | ||
59 | QCanvas canvas; | ||
60 | QTimer* pauseTimer; | ||
61 | Snake* snake; | ||
62 | int last; | ||
63 | int level; | ||
64 | int stage; | ||
65 | int targetamount; | ||
66 | int notargets; | ||
67 | bool waitover; | ||
68 | bool gamestopped; | ||
69 | }; | ||
diff --git a/noncore/games/snake/main.cpp b/noncore/games/snake/main.cpp new file mode 100644 index 0000000..90a93b7 --- a/dev/null +++ b/noncore/games/snake/main.cpp | |||
@@ -0,0 +1,35 @@ | |||
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 "interface.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | |||
26 | int main(int argc, char **argv) | ||
27 | { | ||
28 | QPEApplication app(argc,argv); | ||
29 | |||
30 | SnakeGame* m = new SnakeGame; | ||
31 | QPEApplication::setInputMethodHint( m, QPEApplication::AlwaysOff ); | ||
32 | app.showMainWidget(m); | ||
33 | |||
34 | return app.exec(); | ||
35 | } | ||
diff --git a/noncore/games/snake/obstacle.cpp b/noncore/games/snake/obstacle.cpp new file mode 100644 index 0000000..2d07fe7 --- a/dev/null +++ b/noncore/games/snake/obstacle.cpp | |||
@@ -0,0 +1,51 @@ | |||
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 "obstacle.h" | ||
22 | #include "codes.h" | ||
23 | |||
24 | #include <qpe/resource.h> | ||
25 | |||
26 | Obstacle::Obstacle(QCanvas* canvas, int x, int y) | ||
27 | : QCanvasSprite(0, canvas) | ||
28 | { | ||
29 | newObstacle(x, y); | ||
30 | } | ||
31 | |||
32 | void Obstacle::newObstacle(int x, int y) | ||
33 | { | ||
34 | QCanvasPixmapArray* obstaclearray = new QCanvasPixmapArray(Resource::findPixmap("snake/wall.png")); | ||
35 | |||
36 | setSequence(obstaclearray); | ||
37 | |||
38 | move(x, y); | ||
39 | |||
40 | show(); | ||
41 | canvas()->update(); | ||
42 | } | ||
43 | |||
44 | int Obstacle::rtti() const | ||
45 | { | ||
46 | return obstacle_rtti; | ||
47 | } | ||
48 | |||
49 | Obstacle::~Obstacle() | ||
50 | { | ||
51 | } | ||
diff --git a/noncore/games/snake/obstacle.h b/noncore/games/snake/obstacle.h new file mode 100644 index 0000000..838917f --- a/dev/null +++ b/noncore/games/snake/obstacle.h | |||
@@ -0,0 +1,30 @@ | |||
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 | #include <qcanvas.h> | ||
21 | |||
22 | class Obstacle : public QCanvasSprite | ||
23 | { | ||
24 | |||
25 | public: | ||
26 | Obstacle(QCanvas*, int x, int y); | ||
27 | ~Obstacle(); | ||
28 | void newObstacle(int x, int y); | ||
29 | int rtti() const; | ||
30 | }; | ||
diff --git a/noncore/games/snake/qpe-snake.control b/noncore/games/snake/qpe-snake.control new file mode 100644 index 0000000..489e642 --- a/dev/null +++ b/noncore/games/snake/qpe-snake.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/snake apps/Games/snake.desktop pics/snake | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: Game: control the snake | ||
9 | A game for the Qtopia environment. | ||
diff --git a/noncore/games/snake/snake.cpp b/noncore/games/snake/snake.cpp new file mode 100644 index 0000000..9f19841 --- a/dev/null +++ b/noncore/games/snake/snake.cpp | |||
@@ -0,0 +1,246 @@ | |||
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 "snake.h" | ||
22 | #include "target.h" | ||
23 | #include "codes.h" | ||
24 | |||
25 | #include <qpe/resource.h> | ||
26 | |||
27 | #include <qregexp.h> | ||
28 | |||
29 | static int Piecekey[4][4] = { {6, 0, 4, 3 }, {0, 6, 2, 1 }, { 1, 3, 5, 0 }, {2, 4, 0, 5 } }; | ||
30 | |||
31 | Snake::Snake(QCanvas* c) | ||
32 | { | ||
33 | canvas = c; | ||
34 | score = 0; | ||
35 | snakelist.setAutoDelete(true); | ||
36 | autoMoveTimer = new QTimer(this); | ||
37 | connect( autoMoveTimer, SIGNAL(timeout()), this, SLOT(moveSnake()) ); | ||
38 | createSnake(); | ||
39 | } | ||
40 | |||
41 | void Snake::createSnake() | ||
42 | { | ||
43 | snakeparts = new QCanvasPixmapArray(); | ||
44 | QString s0 = Resource::findPixmap("snake/s0001"); | ||
45 | s0.replace(QRegExp("0001"),"%1"); | ||
46 | snakeparts->readPixmaps(s0, 15); | ||
47 | |||
48 | grow = 0; | ||
49 | last = Key_Right; | ||
50 | |||
51 | QCanvasSprite* head = new QCanvasSprite(snakeparts, canvas ); | ||
52 | head->setFrame(7); | ||
53 | snakelist.insert(0, head); | ||
54 | head->show(); | ||
55 | head->move(34, 16); | ||
56 | |||
57 | QCanvasSprite* body = new QCanvasSprite(snakeparts, canvas ); | ||
58 | body->setFrame(6); | ||
59 | snakelist.append( body ); | ||
60 | body->show(); | ||
61 | body->move(18, 16); | ||
62 | |||
63 | QCanvasSprite* end = new QCanvasSprite(snakeparts, canvas ); | ||
64 | end->setFrame(11); | ||
65 | snakelist.append( end ); | ||
66 | end->show(); | ||
67 | end->move(2, 16); | ||
68 | |||
69 | currentdir = right; | ||
70 | speed = 250; | ||
71 | autoMoveTimer->start(speed); | ||
72 | moveSnake(); | ||
73 | } | ||
74 | |||
75 | void Snake::increaseSpeed() | ||
76 | { | ||
77 | if (speed > 150) | ||
78 | speed = speed - 5; | ||
79 | autoMoveTimer->start(speed); | ||
80 | } | ||
81 | |||
82 | void Snake::go(int newkey) | ||
83 | { | ||
84 | // check key is a direction | ||
85 | if (!( (newkey == Key_Up) || (newkey == Key_Left) || | ||
86 | (newkey == Key_Right) || (newkey == Key_Down) )) | ||
87 | return; | ||
88 | // check move is possible | ||
89 | if ( ((currentdir == left) && ((newkey == Key_Right) || (newkey == Key_Left)) ) || | ||
90 | ((currentdir == right) && ((newkey == Key_Left) || (newkey == Key_Right)) ) || | ||
91 | ((currentdir == up) && ((newkey == Key_Down) || (newkey == Key_Up)) ) || | ||
92 | ((currentdir == down) && ((newkey == Key_Up) || (newkey == Key_Down)) ) ) | ||
93 | return; | ||
94 | else { | ||
95 | Snake::changeHead(newkey); | ||
96 | Snake::moveSnake(); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | void Snake::move(Direction dir) | ||
101 | { | ||
102 | autoMoveTimer->start(speed); | ||
103 | int x = 0; | ||
104 | int y = 0; | ||
105 | newdir = dir; | ||
106 | switch (dir) { | ||
107 | case right: x = 16; break; | ||
108 | case left: x = -16; break; | ||
109 | case down: y = 16; break; | ||
110 | case up: y = -16; break; | ||
111 | } | ||
112 | int index = lookUpPiece(currentdir, newdir); | ||
113 | QCanvasSprite* sprite = new QCanvasSprite(snakeparts, canvas ); | ||
114 | sprite->setFrame(index); | ||
115 | snakelist.insert(1, sprite); | ||
116 | sprite->move(snakelist.first()->x(), snakelist.first()->y() ); | ||
117 | |||
118 | snakelist.first()->moveBy(x, y); | ||
119 | if (grow <= 0) | ||
120 | changeTail(); | ||
121 | else | ||
122 | grow--; | ||
123 | sprite->show(); | ||
124 | |||
125 | currentdir = dir; | ||
126 | } | ||
127 | |||
128 | void Snake::changeTail() | ||
129 | { | ||
130 | snakelist.removeLast(); | ||
131 | |||
132 | double lastx = snakelist.last()->x(); | ||
133 | double prevx = snakelist.prev()->x(); | ||
134 | int index = 0; | ||
135 | |||
136 | if ( prevx == lastx ) { //vertical | ||
137 | if ( snakelist.prev()->y() > snakelist.last()->y() ) | ||
138 | index = 13; | ||
139 | else | ||
140 | index = 14; | ||
141 | } else { //horizontal | ||
142 | if (snakelist.prev()->x() > snakelist.last()->x() ) | ||
143 | index = 11; | ||
144 | else | ||
145 | index = 12; | ||
146 | } | ||
147 | |||
148 | snakelist.last()->setFrame(index); | ||
149 | } | ||
150 | |||
151 | void Snake::changeHead(int lastkey) | ||
152 | { | ||
153 | int index = 0; | ||
154 | last = lastkey; | ||
155 | |||
156 | switch (last) | ||
157 | { | ||
158 | case Key_Up: index = 10; break; | ||
159 | case Key_Left: index = 8; break; | ||
160 | case Key_Right: index = 7; break; | ||
161 | case Key_Down: index = 9; break; | ||
162 | } | ||
163 | |||
164 | if (index) { | ||
165 | snakelist.first()->setFrame(index); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | // returns an integer corresponding to a particular type of snake piece | ||
170 | int Snake::lookUpPiece(Direction currentdir, Direction newdir) | ||
171 | { | ||
172 | return Piecekey[currentdir][newdir]; | ||
173 | } | ||
174 | |||
175 | void Snake::extendSnake() | ||
176 | { | ||
177 | grow++; | ||
178 | } | ||
179 | |||
180 | void Snake::moveSnake() | ||
181 | { | ||
182 | switch (last) | ||
183 | { | ||
184 | case Key_Up: move(up); break; | ||
185 | case Key_Left: move(left); break; | ||
186 | case Key_Right: move(right); break; | ||
187 | case Key_Down: move(down); break; | ||
188 | } | ||
189 | detectCrash(); | ||
190 | } | ||
191 | |||
192 | void Snake::detectCrash() | ||
193 | { | ||
194 | QCanvasSprite* head = snakelist.first(); | ||
195 | QCanvasItem* item; | ||
196 | QCanvasItemList l=head->collisions(FALSE); | ||
197 | for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) { | ||
198 | item = *it; | ||
199 | // check if snake hit target | ||
200 | if ( (item->rtti()== 1500 ) && (item->collidesWith(head)) ) { | ||
201 | Target* target = (Target*) item; | ||
202 | target->done(); | ||
203 | emit targethit(); | ||
204 | extendSnake(); | ||
205 | setScore(5); | ||
206 | return; | ||
207 | } | ||
208 | // check if snake hit obstacles | ||
209 | if ( (item->rtti()==1600) && (item->collidesWith(head)) ) { | ||
210 | emit dead(); | ||
211 | autoMoveTimer->stop(); | ||
212 | return; | ||
213 | } | ||
214 | } | ||
215 | //check if snake hit itself | ||
216 | for (uint i = 3; i < snakelist.count(); i++) { | ||
217 | if (head->collidesWith(snakelist.at(i)) ) { | ||
218 | emit dead(); | ||
219 | autoMoveTimer->stop(); | ||
220 | return; | ||
221 | } | ||
222 | } | ||
223 | //check if snake hit edge | ||
224 | if ( (head->x() > canvas->width()-5) || (head->y() > canvas->height()-10) | ||
225 | || (head->x() <2) || (head->y() <-5) ) { | ||
226 | emit dead(); | ||
227 | autoMoveTimer->stop(); | ||
228 | return; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | void Snake::setScore(int amount) | ||
233 | { | ||
234 | score = score + amount; | ||
235 | emit scorechanged(); | ||
236 | } | ||
237 | |||
238 | int Snake::getScore() | ||
239 | { | ||
240 | return score; | ||
241 | } | ||
242 | |||
243 | Snake::~Snake() | ||
244 | { | ||
245 | autoMoveTimer->stop(); | ||
246 | } | ||
diff --git a/noncore/games/snake/snake.h b/noncore/games/snake/snake.h new file mode 100644 index 0000000..5725343 --- a/dev/null +++ b/noncore/games/snake/snake.h | |||
@@ -0,0 +1,64 @@ | |||
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 | #include <qcanvas.h> | ||
21 | #include <qtimer.h> | ||
22 | |||
23 | class Snake : public QObject | ||
24 | { | ||
25 | Q_OBJECT | ||
26 | |||
27 | public: | ||
28 | enum Direction{ left, right, up, down}; | ||
29 | |||
30 | Snake(QCanvas*); | ||
31 | ~Snake(); | ||
32 | void go(int newkey); | ||
33 | void move(Direction dir); | ||
34 | void changeHead(int last); | ||
35 | void changeTail(); | ||
36 | void detectCrash(); | ||
37 | void createSnake(); | ||
38 | void extendSnake(); | ||
39 | int lookUpPiece(Direction currentdir, Direction newdir); | ||
40 | void setScore(int amount); | ||
41 | int getScore(); | ||
42 | |||
43 | signals: | ||
44 | void dead(); | ||
45 | void targethit(); | ||
46 | void scorechanged(); | ||
47 | |||
48 | private slots: | ||
49 | void moveSnake(); | ||
50 | void increaseSpeed(); | ||
51 | |||
52 | private: | ||
53 | QCanvasPixmapArray* snakeparts; | ||
54 | QList<QCanvasSprite>snakelist; | ||
55 | QTimer* autoMoveTimer; | ||
56 | QCanvas* canvas; | ||
57 | int grow; | ||
58 | int last; | ||
59 | int speed; | ||
60 | int score; | ||
61 | Direction currentdir; | ||
62 | Direction newdir; | ||
63 | }; | ||
64 | |||
diff --git a/noncore/games/snake/snake.pro b/noncore/games/snake/snake.pro new file mode 100644 index 0000000..6dacdbd --- a/dev/null +++ b/noncore/games/snake/snake.pro | |||
@@ -0,0 +1,11 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG += qt warn_on release | ||
3 | DESTDIR = $(QPEDIR)/bin | ||
4 | HEADERS = snake.h target.h obstacle.h interface.h codes.h | ||
5 | SOURCES = snake.cpp target.cpp obstacle.cpp interface.cpp main.cpp | ||
6 | TARGET = snake | ||
7 | INCLUDEPATH += $(QPEDIR)/include | ||
8 | DEPENDPATH+= $(QPEDIR)/include | ||
9 | LIBS += -lqpe | ||
10 | |||
11 | TRANSLATIONS = ../i18n/de/snake.ts | ||
diff --git a/noncore/games/snake/target.cpp b/noncore/games/snake/target.cpp new file mode 100644 index 0000000..a09af69 --- a/dev/null +++ b/noncore/games/snake/target.cpp | |||
@@ -0,0 +1,77 @@ | |||
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 "target.h" | ||
22 | #include "codes.h" | ||
23 | |||
24 | #include <qpe/resource.h> | ||
25 | |||
26 | #include <stdlib.h> | ||
27 | |||
28 | Target::Target(QCanvas* canvas) | ||
29 | : QCanvasSprite(0, canvas) | ||
30 | { | ||
31 | mouse = new QCanvasPixmapArray(Resource::findPixmap("snake/mouse")); | ||
32 | setSequence(mouse); | ||
33 | newTarget(); | ||
34 | } | ||
35 | |||
36 | void Target::newTarget() | ||
37 | { | ||
38 | static bool first_time = TRUE; | ||
39 | if (first_time) { | ||
40 | first_time = FALSE; | ||
41 | QTime midnight(0, 0, 0); | ||
42 | srand(midnight.secsTo(QTime::currentTime()) ); | ||
43 | } | ||
44 | do { | ||
45 | int x = rand() % (canvas()->width()-10); | ||
46 | x = x - (x % 16) + 2; | ||
47 | int y = rand() % (canvas()->height()-10); | ||
48 | y = y - (y % 16) + 2; | ||
49 | move(x, y); | ||
50 | } while (onTop()); | ||
51 | show(); | ||
52 | } | ||
53 | |||
54 | bool Target::onTop() | ||
55 | { | ||
56 | QCanvasItem* item; | ||
57 | QCanvasItemList l= canvas()->allItems(); //collisions(FALSE); | ||
58 | for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) { | ||
59 | item = *it; | ||
60 | if (item != this && item->collidesWith(this)) return true; | ||
61 | } | ||
62 | return false; | ||
63 | } | ||
64 | |||
65 | void Target::done() | ||
66 | { | ||
67 | delete this; | ||
68 | } | ||
69 | |||
70 | int Target::rtti() const | ||
71 | { | ||
72 | return target_rtti; | ||
73 | } | ||
74 | |||
75 | Target::~Target() | ||
76 | { | ||
77 | } | ||
diff --git a/noncore/games/snake/target.h b/noncore/games/snake/target.h new file mode 100644 index 0000000..a6da37c --- a/dev/null +++ b/noncore/games/snake/target.h | |||
@@ -0,0 +1,37 @@ | |||
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 | #include <qcanvas.h> | ||
21 | #include <qdatetime.h> | ||
22 | |||
23 | class Target : public QCanvasSprite | ||
24 | { | ||
25 | |||
26 | public: | ||
27 | Target(QCanvas*); | ||
28 | ~Target(); | ||
29 | void newTarget(); | ||
30 | void done(); | ||
31 | void createMouse(); | ||
32 | bool onTop(); | ||
33 | int rtti() const; | ||
34 | |||
35 | private: | ||
36 | QCanvasPixmapArray* mouse; | ||
37 | }; | ||
diff --git a/noncore/games/solitaire/.cvsignore b/noncore/games/solitaire/.cvsignore new file mode 100644 index 0000000..edfa921 --- a/dev/null +++ b/noncore/games/solitaire/.cvsignore | |||
@@ -0,0 +1,3 @@ | |||
1 | moc_* | ||
2 | *.moc | ||
3 | Makefile | ||
diff --git a/noncore/games/solitaire/Makefile.in b/noncore/games/solitaire/Makefile.in new file mode 100644 index 0000000..3c50345 --- a/dev/null +++ b/noncore/games/solitaire/Makefile.in | |||
@@ -0,0 +1,235 @@ | |||
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 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= patience | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =canvascard.h \ | ||
27 | canvasshapes.h \ | ||
28 | cardgame.h \ | ||
29 | cardgamelayout.h \ | ||
30 | cardpile.h \ | ||
31 | card.h \ | ||
32 | carddeck.h \ | ||
33 | canvascardgame.h \ | ||
34 | freecellcardgame.h \ | ||
35 | patiencecardgame.h \ | ||
36 | canvascardwindow.h | ||
37 | SOURCES =canvascard.cpp \ | ||
38 | canvasshapes.cpp \ | ||
39 | cardgame.cpp \ | ||
40 | cardgamelayout.cpp \ | ||
41 | cardpile.cpp \ | ||
42 | card.cpp \ | ||
43 | carddeck.cpp \ | ||
44 | canvascardgame.cpp \ | ||
45 | freecellcardgame.cpp \ | ||
46 | patiencecardgame.cpp \ | ||
47 | canvascardwindow.cpp \ | ||
48 | main.cpp | ||
49 | OBJECTS =canvascard.o \ | ||
50 | canvasshapes.o \ | ||
51 | cardgame.o \ | ||
52 | cardgamelayout.o \ | ||
53 | cardpile.o \ | ||
54 | card.o \ | ||
55 | carddeck.o \ | ||
56 | canvascardgame.o \ | ||
57 | freecellcardgame.o \ | ||
58 | patiencecardgame.o \ | ||
59 | canvascardwindow.o \ | ||
60 | main.o | ||
61 | INTERFACES = | ||
62 | UICDECLS = | ||
63 | UICIMPLS = | ||
64 | SRCMOC =moc_canvascardwindow.cpp | ||
65 | OBJMOC =moc_canvascardwindow.o | ||
66 | |||
67 | |||
68 | ####### Implicit rules | ||
69 | |||
70 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
71 | |||
72 | .cpp.o: | ||
73 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
74 | |||
75 | .cxx.o: | ||
76 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
77 | |||
78 | .cc.o: | ||
79 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
80 | |||
81 | .C.o: | ||
82 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
83 | |||
84 | .c.o: | ||
85 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
86 | |||
87 | ####### Build rules | ||
88 | |||
89 | |||
90 | all: $(DESTDIR)$(TARGET) | ||
91 | |||
92 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
93 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
94 | |||
95 | moc: $(SRCMOC) | ||
96 | |||
97 | tmake: | ||
98 | tmake solitaire.pro | ||
99 | |||
100 | clean: | ||
101 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
102 | -rm -f *~ core | ||
103 | -rm -f allmoc.cpp | ||
104 | |||
105 | ####### Extension Modules | ||
106 | |||
107 | listpromodules: | ||
108 | @echo | ||
109 | |||
110 | listallmodules: | ||
111 | @echo | ||
112 | |||
113 | listaddonpromodules: | ||
114 | @echo | ||
115 | |||
116 | listaddonentmodules: | ||
117 | @echo | ||
118 | |||
119 | |||
120 | REQUIRES=patience | ||
121 | |||
122 | ####### Sub-libraries | ||
123 | |||
124 | |||
125 | ###### Combined headers | ||
126 | |||
127 | |||
128 | |||
129 | ####### Compile | ||
130 | |||
131 | canvascard.o: canvascard.cpp \ | ||
132 | cardgame.h \ | ||
133 | card.h \ | ||
134 | cardpile.h \ | ||
135 | carddeck.h \ | ||
136 | cardgamelayout.h \ | ||
137 | canvascard.h \ | ||
138 | $(QPEDIR)/include/qpe/resource.h | ||
139 | |||
140 | canvasshapes.o: canvasshapes.cpp \ | ||
141 | canvasshapes.h | ||
142 | |||
143 | cardgame.o: cardgame.cpp \ | ||
144 | cardgame.h \ | ||
145 | card.h \ | ||
146 | cardpile.h \ | ||
147 | carddeck.h \ | ||
148 | cardgamelayout.h | ||
149 | |||
150 | cardgamelayout.o: cardgamelayout.cpp \ | ||
151 | cardgamelayout.h \ | ||
152 | cardpile.h | ||
153 | |||
154 | cardpile.o: cardpile.cpp \ | ||
155 | cardpile.h \ | ||
156 | card.h \ | ||
157 | $(QPEDIR)/include/qpe/config.h | ||
158 | |||
159 | card.o: card.cpp \ | ||
160 | card.h \ | ||
161 | $(QPEDIR)/include/qpe/config.h | ||
162 | |||
163 | carddeck.o: carddeck.cpp \ | ||
164 | card.h \ | ||
165 | carddeck.h | ||
166 | |||
167 | canvascardgame.o: canvascardgame.cpp \ | ||
168 | cardgame.h \ | ||
169 | card.h \ | ||
170 | cardpile.h \ | ||
171 | carddeck.h \ | ||
172 | cardgamelayout.h \ | ||
173 | canvasshapes.h \ | ||
174 | canvascard.h \ | ||
175 | canvascardgame.h \ | ||
176 | $(QPEDIR)/include/qpe/resource.h \ | ||
177 | $(QPEDIR)/include/qpe/config.h \ | ||
178 | $(QPEDIR)/include/qpe/qpemenubar.h | ||
179 | |||
180 | freecellcardgame.o: freecellcardgame.cpp \ | ||
181 | freecellcardgame.h \ | ||
182 | patiencecardgame.h \ | ||
183 | canvascardgame.h \ | ||
184 | cardgame.h \ | ||
185 | card.h \ | ||
186 | cardpile.h \ | ||
187 | carddeck.h \ | ||
188 | cardgamelayout.h \ | ||
189 | canvasshapes.h \ | ||
190 | canvascard.h \ | ||
191 | $(QPEDIR)/include/qpe/resource.h \ | ||
192 | $(QPEDIR)/include/qpe/config.h \ | ||
193 | $(QPEDIR)/include/qpe/qpemenubar.h | ||
194 | |||
195 | patiencecardgame.o: patiencecardgame.cpp \ | ||
196 | patiencecardgame.h \ | ||
197 | canvascardgame.h \ | ||
198 | cardgame.h \ | ||
199 | card.h \ | ||
200 | cardpile.h \ | ||
201 | carddeck.h \ | ||
202 | cardgamelayout.h \ | ||
203 | canvasshapes.h \ | ||
204 | canvascard.h \ | ||
205 | $(QPEDIR)/include/qpe/resource.h \ | ||
206 | $(QPEDIR)/include/qpe/config.h \ | ||
207 | $(QPEDIR)/include/qpe/qpemenubar.h | ||
208 | |||
209 | canvascardwindow.o: canvascardwindow.cpp \ | ||
210 | canvascardwindow.h \ | ||
211 | patiencecardgame.h \ | ||
212 | canvascardgame.h \ | ||
213 | cardgame.h \ | ||
214 | card.h \ | ||
215 | cardpile.h \ | ||
216 | carddeck.h \ | ||
217 | cardgamelayout.h \ | ||
218 | canvasshapes.h \ | ||
219 | canvascard.h \ | ||
220 | $(QPEDIR)/include/qpe/resource.h \ | ||
221 | $(QPEDIR)/include/qpe/config.h \ | ||
222 | $(QPEDIR)/include/qpe/qpemenubar.h \ | ||
223 | freecellcardgame.h | ||
224 | |||
225 | main.o: main.cpp \ | ||
226 | canvascardwindow.h \ | ||
227 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
228 | |||
229 | moc_canvascardwindow.o: moc_canvascardwindow.cpp \ | ||
230 | canvascardwindow.h | ||
231 | |||
232 | moc_canvascardwindow.cpp: canvascardwindow.h | ||
233 | $(MOC) canvascardwindow.h -o moc_canvascardwindow.cpp | ||
234 | |||
235 | |||
diff --git a/noncore/games/solitaire/canvascard.cpp b/noncore/games/solitaire/canvascard.cpp new file mode 100644 index 0000000..ae3c859 --- a/dev/null +++ b/noncore/games/solitaire/canvascard.cpp | |||
@@ -0,0 +1,282 @@ | |||
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 "cardgame.h" | ||
22 | #include "canvascard.h" | ||
23 | |||
24 | #include <qpe/resource.h> | ||
25 | |||
26 | #include <qpainter.h> | ||
27 | #include <qimage.h> | ||
28 | #include <qpaintdevice.h> | ||
29 | #include <qbitmap.h> | ||
30 | |||
31 | #include <math.h> | ||
32 | |||
33 | #if defined( QT_QWS_CASSIOPEIA ) | ||
34 | #define SLOW_HARDWARE | ||
35 | #endif | ||
36 | |||
37 | // Seems to be fast enough to me even without Transformations in the library | ||
38 | //#if defined( QT_NO_TRANSFORMATIONS ) && defined( QT_QWS_IPAQ ) | ||
39 | //#define SLOW_HARDWARE | ||
40 | //#endif | ||
41 | |||
42 | |||
43 | QBitmap *Create180RotatedBitmap(QBitmap *srcBitmap) | ||
44 | { | ||
45 | #ifdef QT_NO_TRANSFORMATIONS | ||
46 | int w = srcBitmap->width(); | ||
47 | int h = srcBitmap->height(); | ||
48 | QBitmap *dstBitmap = new QBitmap( w, h ); | ||
49 | // ### this is very poorly implemented and probably could be much faster | ||
50 | for (int i = 0; i < w; i++) | ||
51 | for (int j = 0; j < h; j++) | ||
52 | bitBlt( dstBitmap, i, j, srcBitmap, w - i - 1, h - j - 1, 1, 1 ); | ||
53 | return dstBitmap; | ||
54 | #else | ||
55 | QWMatrix m; | ||
56 | m.rotate( 180.0 ); | ||
57 | return new QBitmap( srcBitmap->xForm( m ) ); | ||
58 | #endif | ||
59 | } | ||
60 | |||
61 | |||
62 | QPixmap *CreateScaledPixmap(QPixmap *srcPixmap, double scaleX, double scaleY) | ||
63 | { | ||
64 | #ifdef QT_NO_TRANSFORMATIONS | ||
65 | int w = srcPixmap->width(); | ||
66 | int h = srcPixmap->height(); | ||
67 | int newW = (int)(w * scaleX); | ||
68 | int newH = (int)(h * scaleY); | ||
69 | QPixmap *dstPixmap = new QPixmap( newW, newH ); | ||
70 | // ### this is very poorly implemented and probably could be much faster | ||
71 | for (int i = 0; i < newW; i++) { | ||
72 | int srcX = w * i / newW; | ||
73 | if (newH == h) { | ||
74 | // Optimise for scaleing in the X-axis only | ||
75 | bitBlt( dstPixmap, i, 0, srcPixmap, srcX, 0, 1, h ); | ||
76 | } else { | ||
77 | for (int j = 0; j < newH; j++) { | ||
78 | int srcY = h * j / newH; | ||
79 | bitBlt( dstPixmap, i, j, srcPixmap, srcX, srcY, 1, 1 ); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | return dstPixmap; | ||
84 | #else | ||
85 | QWMatrix s; | ||
86 | s.scale( scaleX, scaleY ); | ||
87 | return new QPixmap( srcPixmap->xForm( s ) ); | ||
88 | #endif | ||
89 | } | ||
90 | |||
91 | |||
92 | // Initialise static member variables to NULL | ||
93 | QPixmap *CanvasCard::cardsFaces = NULL; | ||
94 | QPixmap *CanvasCard::cardsBacks = NULL; | ||
95 | QBitmap *CanvasCard::cardsChars = NULL; | ||
96 | QBitmap *CanvasCard::cardsSuits = NULL; | ||
97 | QBitmap *CanvasCard::cardsCharsUpsideDown = NULL; | ||
98 | QBitmap *CanvasCard::cardsSuitsUpsideDown = NULL; | ||
99 | |||
100 | |||
101 | CanvasCard::CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas ) : | ||
102 | Card(v, s, f), QCanvasRectangle( 0, 0, 1, 1, canvas ), cardBack(1), scaleX(1.0), scaleY(1.0) | ||
103 | { | ||
104 | if ( !cardsFaces ) { | ||
105 | cardsFaces = new QPixmap( Resource::loadPixmap( "cards/card_face" ) ); | ||
106 | cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) ); | ||
107 | cardsChars = new QBitmap( Resource::loadBitmap( "cards/card_chars" ) ); | ||
108 | cardsSuits = new QBitmap( Resource::loadBitmap( "cards/card_suits" ) ); | ||
109 | cardsCharsUpsideDown = Create180RotatedBitmap( cardsChars ); | ||
110 | cardsSuitsUpsideDown = Create180RotatedBitmap( cardsSuits ); | ||
111 | } | ||
112 | xOff = cardsFaces->width() / 2; | ||
113 | yOff = cardsFaces->height() / 2; | ||
114 | setSize( cardsFaces->width(), cardsFaces->height() ); | ||
115 | setPen( NoPen ); | ||
116 | flipping = FALSE; | ||
117 | } | ||
118 | |||
119 | |||
120 | void CanvasCard::setCardBack(int b) | ||
121 | { | ||
122 | if ( cardBack != b ) { | ||
123 | |||
124 | cardBack = b; | ||
125 | |||
126 | if ( cardsBacks ) | ||
127 | delete cardsBacks; | ||
128 | |||
129 | switch (cardBack) { | ||
130 | case 0: | ||
131 | cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0001" ) ); break; | ||
132 | case 1: | ||
133 | cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0002" ) ); break; | ||
134 | case 2: | ||
135 | cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0003" ) ); break; | ||
136 | case 3: | ||
137 | cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0004" ) ); break; | ||
138 | case 4: | ||
139 | cardsBacks = new QPixmap( Resource::loadPixmap( "cards/card_back0005" ) ); break; | ||
140 | } | ||
141 | |||
142 | if ( !isFacing() ) | ||
143 | redraw(); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | |||
148 | void CanvasCard::draw(QPainter &painter) | ||
149 | { | ||
150 | int ix = (int)x(), iy = (int)y(); | ||
151 | |||
152 | QPainter *p = &painter; | ||
153 | QPixmap *unscaledCard = NULL; | ||
154 | |||
155 | if ((scaleX <= 0.98) || (scaleY <= 0.98)) | ||
156 | { | ||
157 | p = new QPainter(); | ||
158 | unscaledCard = new QPixmap( cardsFaces->width(), cardsFaces->height() ); | ||
159 | p->begin(unscaledCard); | ||
160 | ix = 0; | ||
161 | iy = 0; | ||
162 | } | ||
163 | |||
164 | if ( isFacing() ) { | ||
165 | |||
166 | /* | ||
167 | // Now add the joker and card backs to the list of pixmaps | ||
168 | QPixmap *CardsBack = new QPixmap( Resource::loadPixmap( "cards/card_joker.png" ) ); | ||
169 | QPoint *newBackHotspot = new QPoint( 0, 0 ); | ||
170 | pixmaps->append((const QPixmap *)CardsBack); | ||
171 | hotspots->append((const QPoint *)newBackHotspot); | ||
172 | */ | ||
173 | |||
174 | int w = cardsFaces->width(), h = cardsFaces->height(); | ||
175 | |||
176 | //p->setBrush( NoBrush ); | ||
177 | p->setBrush( QColor( 0xFF, 0xFF, 0xFF ) ); | ||
178 | |||
179 | if ( isRed() == TRUE ) | ||
180 | p->setPen( QColor( 0xFF, 0, 0 ) ); | ||
181 | else | ||
182 | p->setPen( QColor( 0, 0, 0 ) ); | ||
183 | |||
184 | p->drawPixmap( ix + 0, iy + 0, *cardsFaces ); | ||
185 | p->drawPixmap( ix + 4, iy + 4, *cardsChars, 7*(getValue()-1), 0, 7, 7 ); | ||
186 | p->drawPixmap( ix + 12, iy + 4, *cardsSuits, 7*(getSuit()-1), 0, 7, 8 ); | ||
187 | p->drawPixmap( ix + w-4-7, iy + h-4-7, *cardsCharsUpsideDown, 7*(12-getValue()+1), 0, 7, 7 ); | ||
188 | p->drawPixmap( ix + w-12-7, iy + h-5-7, *cardsSuitsUpsideDown, 7*(3-getSuit()+1), 0, 7, 8 ); | ||
189 | |||
190 | } else { | ||
191 | |||
192 | p->drawPixmap( ix, iy, *cardsBacks ); | ||
193 | |||
194 | } | ||
195 | |||
196 | if (p != &painter) | ||
197 | { | ||
198 | p->end(); | ||
199 | QPixmap *scaledCard = CreateScaledPixmap( unscaledCard, scaleX, scaleY ); | ||
200 | int xoff = scaledCard->width() / 2; | ||
201 | int yoff = scaledCard->height() / 2; | ||
202 | painter.drawPixmap( (int)x() + xOff - xoff, (int)y() + yOff - yoff, *scaledCard ); | ||
203 | delete p; | ||
204 | delete unscaledCard; | ||
205 | delete scaledCard; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | |||
210 | static const double flipLift = 1.5; | ||
211 | |||
212 | |||
213 | void CanvasCard::flipTo(int x2, int y2, int steps) | ||
214 | { | ||
215 | flipSteps = steps; | ||
216 | |||
217 | #ifdef SLOW_HARDWARE | ||
218 | move(x2,y2); | ||
219 | Card::flipTo(x2,y2,steps); | ||
220 | #else | ||
221 | int x1 = (int)x(); | ||
222 | int y1 = (int)y(); | ||
223 | double dx = x2 - x1; | ||
224 | double dy = y2 - y1; | ||
225 | |||
226 | flipping = TRUE; | ||
227 | destX = x2; | ||
228 | destY = y2; | ||
229 | animSteps = flipSteps; | ||
230 | setVelocity(dx/animSteps, dy/animSteps-flipLift); | ||
231 | setAnimated(TRUE); | ||
232 | #endif | ||
233 | } | ||
234 | |||
235 | |||
236 | void CanvasCard::advance(int stage) | ||
237 | { | ||
238 | if ( stage==1 ) { | ||
239 | if ( animSteps-- <= 0 ) { | ||
240 | scaleX = 1.0; | ||
241 | scaleY = 1.0; | ||
242 | flipping = FALSE; | ||
243 | setVelocity(0,0); | ||
244 | setAnimated(FALSE); | ||
245 | move(destX,destY); // exact | ||
246 | } else { | ||
247 | if ( flipping ) { | ||
248 | if ( animSteps > flipSteps / 2 ) { | ||
249 | // animSteps = flipSteps .. flipSteps/2 (flip up) -> 1..0 | ||
250 | scaleX = ((double)animSteps/flipSteps-0.5)*2; | ||
251 | } else { | ||
252 | // animSteps = flipSteps/2 .. 0 (flip down) -> 0..1 | ||
253 | scaleX = 1-((double)animSteps/flipSteps)*2; | ||
254 | } | ||
255 | if ( animSteps == flipSteps / 2-1 ) { | ||
256 | setYVelocity(yVelocity()+flipLift*2); | ||
257 | setFace( !isFacing() ); | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | QCanvasRectangle::advance(stage); | ||
263 | } | ||
264 | |||
265 | |||
266 | void CanvasCard::animatedMove(int x2, int y2, int steps) | ||
267 | { | ||
268 | destX = x2; | ||
269 | destY = y2; | ||
270 | |||
271 | double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1; | ||
272 | |||
273 | // Ensure a good speed | ||
274 | while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 ) | ||
275 | steps--; | ||
276 | |||
277 | setAnimated(TRUE); | ||
278 | setVelocity(dx/steps, dy/steps); | ||
279 | |||
280 | animSteps = steps; | ||
281 | } | ||
282 | |||
diff --git a/noncore/games/solitaire/canvascard.h b/noncore/games/solitaire/canvascard.h new file mode 100644 index 0000000..cd9691f --- a/dev/null +++ b/noncore/games/solitaire/canvascard.h | |||
@@ -0,0 +1,82 @@ | |||
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 CANVAS_CARD_H | ||
21 | #define CANVAS_CARD_H | ||
22 | |||
23 | |||
24 | #include <qpainter.h> | ||
25 | #include <qbitmap.h> | ||
26 | #include <qpixmap.h> | ||
27 | #include <qpoint.h> | ||
28 | #include <qcanvas.h> | ||
29 | #include "cardgame.h" | ||
30 | |||
31 | |||
32 | // ### Just made the number up, is that what you do??? | ||
33 | static const int canvasCardId = 2434321; | ||
34 | |||
35 | |||
36 | class CanvasCard : public Card, public QCanvasRectangle | ||
37 | { | ||
38 | public: | ||
39 | CanvasCard( eValue v, eSuit s, bool f, QCanvas *canvas ); | ||
40 | virtual ~CanvasCard() { canvas()->removeItem(this); } | ||
41 | |||
42 | int rtti () const { return canvasCardId; } | ||
43 | void move(QPoint p) { QCanvasItem::move( p.x(), p.y() ); } | ||
44 | void move(int x, int y) { QCanvasItem::move( x, y ); } | ||
45 | void animatedMove(int x, int y, int steps = 10); | ||
46 | void animatedMove() { animatedMove(savedX, savedY); } | ||
47 | void savePos(void) { savedX = (int)x(); savedY = (int)y(); } | ||
48 | void moveToPile(int p) { Q_UNUSED(p); } | ||
49 | void setCardBack(int b); | ||
50 | |||
51 | /*virtual*/ void flipTo(int x, int y, int steps = 8); | ||
52 | /*virtual*/ void setPos( int x, int y, int z ) { setX( x ); setY( y ); setZ( z ); } | ||
53 | /*virtual*/ void showCard(void) { show(); } | ||
54 | /*virtual*/ void redraw(void) { hide(); show(); } | ||
55 | /*virtual*/ void draw(QPainter &p); | ||
56 | |||
57 | void advance(int stage); | ||
58 | |||
59 | protected: | ||
60 | /*virtual*/ void flip(void) { redraw(); } | ||
61 | |||
62 | private: | ||
63 | int destX, destY; | ||
64 | int animSteps; | ||
65 | int flipSteps; | ||
66 | bool flipping; | ||
67 | int savedX, savedY; | ||
68 | int cardBack; | ||
69 | int oldCardBack; | ||
70 | double scaleX, scaleY; | ||
71 | int xOff, yOff; | ||
72 | static QPixmap *cardsFaces; | ||
73 | static QPixmap *cardsBacks; | ||
74 | static QBitmap *cardsChars; | ||
75 | static QBitmap *cardsSuits; | ||
76 | static QBitmap *cardsCharsUpsideDown; | ||
77 | static QBitmap *cardsSuitsUpsideDown; | ||
78 | }; | ||
79 | |||
80 | |||
81 | #endif | ||
82 | |||
diff --git a/noncore/games/solitaire/canvascardgame.cpp b/noncore/games/solitaire/canvascardgame.cpp new file mode 100644 index 0000000..32635a0 --- a/dev/null +++ b/noncore/games/solitaire/canvascardgame.cpp | |||
@@ -0,0 +1,380 @@ | |||
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 "cardgame.h" | ||
22 | #include "canvasshapes.h" | ||
23 | #include "canvascard.h" | ||
24 | #include "canvascardgame.h" | ||
25 | |||
26 | #include <qpe/resource.h> | ||
27 | #include <qpe/config.h> | ||
28 | |||
29 | #include <qmainwindow.h> | ||
30 | #include <qpe/qpemenubar.h> | ||
31 | #include <qpainter.h> | ||
32 | |||
33 | #include <stdlib.h> | ||
34 | #include <limits.h> | ||
35 | #include <time.h> | ||
36 | #include <math.h> | ||
37 | |||
38 | |||
39 | extern int highestZ; | ||
40 | |||
41 | |||
42 | class CanvasCardPile : public QCanvasRectangle | ||
43 | { | ||
44 | public: | ||
45 | CanvasCardPile( CanvasCardGame *ccg, QCanvas *canvas ) : QCanvasRectangle( canvas ), parent( ccg ) { | ||
46 | pile = new QPixmap( 0, 0 ); | ||
47 | pileHeight = 0; | ||
48 | firstCard = NULL; | ||
49 | } | ||
50 | |||
51 | void addCard( CanvasCard *card ); | ||
52 | void advance(int stage); | ||
53 | void animatedMove() { animatedMove(savedX, savedY); } | ||
54 | void savePos(void) { savedX = (int)x(); savedY = (int)y(); } | ||
55 | void animatedMove(int x2, int y2, int steps = 7 ); | ||
56 | |||
57 | protected: | ||
58 | virtual void draw( QPainter& p ); | ||
59 | |||
60 | private: | ||
61 | CanvasCardGame *parent; | ||
62 | QPixmap *pile; | ||
63 | QImage tempImage32; | ||
64 | CanvasCard *firstCard; | ||
65 | int pileHeight; | ||
66 | int destX, destY; | ||
67 | int savedX, savedY; | ||
68 | int animSteps; | ||
69 | }; | ||
70 | |||
71 | |||
72 | void CanvasCardPile::addCard( CanvasCard *card ) | ||
73 | { | ||
74 | if ( !firstCard ) | ||
75 | firstCard = card; | ||
76 | |||
77 | int height = 36 + pileHeight * 13; | ||
78 | setSize( 23, height ); | ||
79 | pile->resize( 23, height ); | ||
80 | QPainter p( pile ); | ||
81 | p.translate( -card->x(), -card->y() + pileHeight * 13 ); | ||
82 | card->draw( p ); | ||
83 | pileHeight++; | ||
84 | |||
85 | QImage tempImage; | ||
86 | tempImage = *pile; | ||
87 | tempImage32 = tempImage.convertDepth( 32 ); | ||
88 | tempImage32.setAlphaBuffer( TRUE ); | ||
89 | for ( int i = 0; i < tempImage32.width(); i++ ) | ||
90 | for ( int j = 0; j < tempImage32.height(); j++ ) { | ||
91 | QRgb col = tempImage32.pixel( i, j ); | ||
92 | int a = 255-j*220/tempImage32.height(); | ||
93 | QRgb alpha = qRgba( qRed( col ), qGreen( col ), qBlue( col ), a ); | ||
94 | tempImage32.setPixel( i, j, alpha ); | ||
95 | } | ||
96 | |||
97 | QRgb alpha = qRgba( 0, 0, 0, 0 ); | ||
98 | tempImage32.setPixel( 1, 0, alpha ); | ||
99 | tempImage32.setPixel( 0, 0, alpha ); | ||
100 | tempImage32.setPixel( 0, 1, alpha ); | ||
101 | |||
102 | tempImage32.setPixel( 21, 0, alpha ); | ||
103 | tempImage32.setPixel( 22, 0, alpha ); | ||
104 | tempImage32.setPixel( 22, 1, alpha ); | ||
105 | height--; | ||
106 | tempImage32.setPixel( 1, height, alpha ); | ||
107 | tempImage32.setPixel( 0, height - 1, alpha ); | ||
108 | tempImage32.setPixel( 0, height, alpha ); | ||
109 | |||
110 | tempImage32.setPixel( 21, height, alpha ); | ||
111 | tempImage32.setPixel( 22, height, alpha ); | ||
112 | tempImage32.setPixel( 22, height - 1, alpha ); | ||
113 | } | ||
114 | |||
115 | |||
116 | void CanvasCardPile::advance(int stage) | ||
117 | { | ||
118 | if ( stage==1 ) { | ||
119 | if ( animSteps-- <= 0 ) { | ||
120 | CanvasCard *item = firstCard; | ||
121 | while (item) { | ||
122 | item->show(); | ||
123 | item = (CanvasCard *)item->getCardPile()->cardInfront(item); | ||
124 | } | ||
125 | setVelocity(0,0); | ||
126 | setAnimated(FALSE); | ||
127 | parent->cancelMoving(); | ||
128 | hide(); | ||
129 | move(destX,destY); // exact | ||
130 | } | ||
131 | } | ||
132 | QCanvasRectangle::advance(stage); | ||
133 | } | ||
134 | |||
135 | |||
136 | void CanvasCardPile::animatedMove(int x2, int y2, int steps = 7 ) | ||
137 | { | ||
138 | destX = x2; | ||
139 | destY = y2; | ||
140 | |||
141 | double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1; | ||
142 | |||
143 | // Ensure a good speed | ||
144 | while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 ) | ||
145 | steps--; | ||
146 | |||
147 | setAnimated(TRUE); | ||
148 | setVelocity(dx/steps, dy/steps); | ||
149 | |||
150 | animSteps = steps; | ||
151 | } | ||
152 | |||
153 | |||
154 | void CanvasCardPile::draw( QPainter& p ) | ||
155 | { | ||
156 | int ix = (int)x(), iy = (int)y(); | ||
157 | p.drawImage( ix, iy, tempImage32 ); | ||
158 | } | ||
159 | |||
160 | |||
161 | CanvasCardGame::~CanvasCardGame() { | ||
162 | // the deletion stuff should be fixed now and only deletes | ||
163 | // items created by this CardGame. I haven't verified there are zero | ||
164 | // memory leaks yet | ||
165 | if ( alphaCardPile ) | ||
166 | delete alphaCardPile; | ||
167 | } | ||
168 | |||
169 | |||
170 | void CanvasCardGame::gameWon() { | ||
171 | |||
172 | srand(time(NULL)); | ||
173 | |||
174 | QCanvasItemList list = canvas()->allItems(); | ||
175 | QCanvasItemList::Iterator it = list.begin(); | ||
176 | |||
177 | for (; it != list.end(); ++it) { | ||
178 | if ( (*it)->rtti() == canvasCardId ) { | ||
179 | // disperse the cards everywhere | ||
180 | int x = 300 - rand() % 1000; | ||
181 | int y = 300 + rand() % 200; | ||
182 | ((CanvasCard *)*it)->animatedMove( x, y, 50 ); | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | |||
188 | void CanvasCardGame::contentsMousePressEvent(QMouseEvent *e) { | ||
189 | |||
190 | if ( moving ) | ||
191 | return; | ||
192 | |||
193 | QCanvasItemList l = canvas()->collisions( e->pos() ); | ||
194 | |||
195 | for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { | ||
196 | |||
197 | if ( (*it)->rtti() == canvasCardId ) { | ||
198 | |||
199 | moving = (CanvasCard *)*it; | ||
200 | |||
201 | if ( moving->animated() ) | ||
202 | return; | ||
203 | |||
204 | cardXOff = (int)(e->pos().x() - moving->x()); | ||
205 | cardYOff = (int)(e->pos().y() - moving->y()); | ||
206 | |||
207 | if ( !mousePressCard( moving, e->pos() ) ) { | ||
208 | CanvasCard *card = moving; | ||
209 | |||
210 | if ( alphaCardPile ) | ||
211 | delete alphaCardPile; | ||
212 | |||
213 | alphaCardPile = new CanvasCardPile( this, canvas() ); | ||
214 | alphaCardPile->move( card->x(), card->y() ); | ||
215 | alphaCardPile->savePos(); | ||
216 | alphaCardPile->show(); | ||
217 | |||
218 | while (card) { | ||
219 | alphaCardPile->addCard( card ); | ||
220 | card->hide(); | ||
221 | card = (CanvasCard *)card->getCardPile()->cardInfront(card); | ||
222 | } | ||
223 | |||
224 | alphaCardPile->setZ( INT_MAX ); | ||
225 | |||
226 | moved = TRUE; | ||
227 | } else { | ||
228 | if ( alphaCardPile ) | ||
229 | alphaCardPile->hide(); | ||
230 | } | ||
231 | return; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | mousePress( e->pos() ); | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | // | ||
240 | // Should have some intelligent way to make double clicking on a | ||
241 | // card send it to the most appropriate pile | ||
242 | // | ||
243 | void CanvasCardGame::contentsMouseDoubleClickEvent(QMouseEvent *e) { | ||
244 | QCanvasItemList l = canvas()->collisions( e->pos() ); | ||
245 | for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { | ||
246 | if ( (*it)->rtti() == canvasCardId ) { | ||
247 | CanvasCard *card = (CanvasCard *)*it; | ||
248 | |||
249 | if ( card->animated() ) | ||
250 | return; | ||
251 | |||
252 | if ( card->getCardPile()->isAllowedToBeMoved(card) ) { | ||
253 | if (card->getCardPile()->cardInfront(card) == NULL) { | ||
254 | CardPile *pile = first(); | ||
255 | if (pile && pile->isAllowedOnTop(card)) { | ||
256 | // move card to this pile | ||
257 | return; | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | */ | ||
265 | |||
266 | void CanvasCardGame::contentsMouseMoveEvent(QMouseEvent *e) { | ||
267 | |||
268 | QPoint p = e->pos(); | ||
269 | |||
270 | if ( moving ) { | ||
271 | |||
272 | moved = TRUE; | ||
273 | |||
274 | if (moving->isFacing() != TRUE) | ||
275 | return; | ||
276 | |||
277 | int tx = (int)p.x() - cardXOff; | ||
278 | int ty = (int)p.y() - cardYOff; | ||
279 | |||
280 | if (snapOn == TRUE) { | ||
281 | CardPile *pile = closestPile( tx, ty, 50 ); | ||
282 | if ( pile && pile->isAllowedOnTop( moving ) ) { | ||
283 | QPoint p = pile->getHypertheticalNextCardPos(); | ||
284 | if ( alphaCardPile ) | ||
285 | alphaCardPile->move( p.x(), p.y() ); | ||
286 | return; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | if ( alphaCardPile ) | ||
291 | alphaCardPile->move( tx, ty ); | ||
292 | } | ||
293 | |||
294 | } | ||
295 | |||
296 | |||
297 | void CanvasCardGame::contentsMouseReleaseEvent(QMouseEvent *e) | ||
298 | { | ||
299 | QPoint p = e->pos(); | ||
300 | |||
301 | Q_UNUSED(p); | ||
302 | |||
303 | if ( moving ) { | ||
304 | |||
305 | CanvasCard *item = moving; | ||
306 | |||
307 | if ( item->animated() ) | ||
308 | return; | ||
309 | |||
310 | if ( alphaCardPile ) | ||
311 | if ( moved ) { | ||
312 | |||
313 | CardPile *pile = closestPile((int)alphaCardPile->x(), (int)alphaCardPile->y(), 30); | ||
314 | |||
315 | if (pile && pile->isAllowedOnTop(item)) { | ||
316 | CardPile *oldPile = item->getCardPile(); | ||
317 | Card *c = NULL; | ||
318 | if ( oldPile != pile) { | ||
319 | while ( item ) { | ||
320 | item->show(); | ||
321 | if ( oldPile ) { | ||
322 | c = oldPile->cardInfront(item); | ||
323 | oldPile->removeCard(item); | ||
324 | } | ||
325 | pile->addCardToTop(item); | ||
326 | item->setCardPile(pile); | ||
327 | //item->move( pile->getCardPos(item) ); | ||
328 | QPoint p = pile->getCardPos(item); | ||
329 | item->setPos( p.x(), p.y(), highestZ ); | ||
330 | highestZ++; | ||
331 | |||
332 | if (item->getValue() == king && haveWeWon()) { | ||
333 | alphaCardPile->hide(); | ||
334 | gameWon(); | ||
335 | moving = NULL; | ||
336 | return; | ||
337 | } | ||
338 | |||
339 | if (oldPile) { | ||
340 | item = (CanvasCard *)c; | ||
341 | } else { | ||
342 | item = NULL; | ||
343 | } | ||
344 | } | ||
345 | alphaCardPile->hide(); | ||
346 | moving = NULL; | ||
347 | return; | ||
348 | } | ||
349 | } | ||
350 | |||
351 | alphaCardPile->animatedMove(); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | moved = FALSE; | ||
356 | } | ||
357 | |||
358 | |||
359 | void CanvasCardGame::readPile( Config& cfg, CardPile *pile, QString name, int& highestZ ) | ||
360 | { | ||
361 | cfg.setGroup( name ); | ||
362 | int numberOfCards = cfg.readNumEntry("NumberOfCards", 0); | ||
363 | Card *card = NULL; | ||
364 | for ( int i = 0; i < numberOfCards; i++ ) { | ||
365 | QString cardStr; | ||
366 | cardStr.sprintf( "%i", i ); | ||
367 | int val = cfg.readNumEntry( "Card" + cardStr ); | ||
368 | bool facing = cfg.readBoolEntry( "CardFacing" + cardStr ); | ||
369 | card = cards[ val ]; | ||
370 | card->setFace(facing); | ||
371 | pile->addCardToTop(card); | ||
372 | card->setCardPile(pile); | ||
373 | QPoint p = pile->getCardPos( card ); | ||
374 | card->setPos( p.x(), p.y(), highestZ ); | ||
375 | card->showCard(); | ||
376 | highestZ++; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | |||
diff --git a/noncore/games/solitaire/canvascardgame.h b/noncore/games/solitaire/canvascardgame.h new file mode 100644 index 0000000..4d32014 --- a/dev/null +++ b/noncore/games/solitaire/canvascardgame.h | |||
@@ -0,0 +1,95 @@ | |||
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 CANVAS_CARD_GAME_H | ||
21 | #define CANVAS_CARD_GAME_H | ||
22 | |||
23 | #include "cardgame.h" | ||
24 | #include "canvasshapes.h" | ||
25 | #include "canvascard.h" | ||
26 | |||
27 | #include <qpe/resource.h> | ||
28 | #include <qpe/config.h> | ||
29 | |||
30 | #include <qmainwindow.h> | ||
31 | #include <qpe/qpemenubar.h> | ||
32 | #include <qpainter.h> | ||
33 | |||
34 | #include <stdlib.h> | ||
35 | #include <time.h> | ||
36 | |||
37 | |||
38 | class CanvasCardPile; | ||
39 | |||
40 | |||
41 | class CanvasCardGame : public QCanvasView, public CardGame | ||
42 | { | ||
43 | public: | ||
44 | CanvasCardGame(QCanvas &c, bool snap, QWidget *parent = 0, const char *name = 0, WFlags f = 0) : | ||
45 | QCanvasView( &c, parent, name, f ), | ||
46 | moved(FALSE), | ||
47 | moving(NULL), | ||
48 | alphaCardPile( NULL ), | ||
49 | cardXOff(0), cardYOff(0), | ||
50 | snapOn(snap), | ||
51 | numberToDraw(1) { } | ||
52 | |||
53 | virtual ~CanvasCardGame(); | ||
54 | |||
55 | virtual Card *newCard( eValue v, eSuit s, bool f ) { | ||
56 | return new CanvasCard( v, s, f, canvas() ); | ||
57 | } | ||
58 | |||
59 | virtual void readConfig( Config& cfg ) { Q_UNUSED( cfg ); } | ||
60 | virtual void writeConfig( Config& cfg ) { Q_UNUSED( cfg ); } | ||
61 | |||
62 | virtual void gameWon(); | ||
63 | virtual bool haveWeWon() { return FALSE; } | ||
64 | |||
65 | virtual bool mousePressCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); return FALSE; } | ||
66 | virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } | ||
67 | |||
68 | void cancelMoving() { moving = NULL; } | ||
69 | void toggleSnap() { snapOn = (snapOn == TRUE) ? FALSE : TRUE; } | ||
70 | void toggleCardsDrawn() { numberToDraw = (numberToDraw == 1) ? 3 : 1; } | ||
71 | int cardsDrawn() { return numberToDraw; } | ||
72 | void setNumberToDraw(int numToDraw) { this->numberToDraw = numToDraw; } | ||
73 | |||
74 | void readPile( Config& cfg, CardPile *pile, QString name, int& highestZ ); | ||
75 | |||
76 | protected: | ||
77 | void contentsMousePressEvent(QMouseEvent *e); | ||
78 | void contentsMouseReleaseEvent(QMouseEvent *e); | ||
79 | void contentsMouseMoveEvent(QMouseEvent *e); | ||
80 | |||
81 | protected: | ||
82 | // Mouse event state variables | ||
83 | bool moved; | ||
84 | CanvasCard *moving; | ||
85 | CanvasCardPile *alphaCardPile; | ||
86 | int cardXOff, cardYOff; | ||
87 | |||
88 | private: | ||
89 | bool snapOn; | ||
90 | int numberToDraw; | ||
91 | }; | ||
92 | |||
93 | |||
94 | #endif | ||
95 | |||
diff --git a/noncore/games/solitaire/canvascardwindow.cpp b/noncore/games/solitaire/canvascardwindow.cpp new file mode 100644 index 0000000..4c365a5 --- a/dev/null +++ b/noncore/games/solitaire/canvascardwindow.cpp | |||
@@ -0,0 +1,227 @@ | |||
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 "canvascardwindow.h" | ||
22 | #include "patiencecardgame.h" | ||
23 | #include "freecellcardgame.h" | ||
24 | |||
25 | #include <qpe/resource.h> | ||
26 | |||
27 | #include <qmainwindow.h> | ||
28 | #include <qpopupmenu.h> | ||
29 | #include <qstyle.h> | ||
30 | |||
31 | |||
32 | CanvasCardWindow::CanvasCardWindow(QWidget* parent, const char* name, WFlags f) : | ||
33 | QMainWindow(parent, name, f), canvas(230, 260), snapOn(TRUE), cardBack(4), gameType(0), | ||
34 | cardGame(NULL) | ||
35 | { | ||
36 | setIcon( Resource::loadPixmap( "cards" ) ); | ||
37 | |||
38 | // Create Playing Area for Games | ||
39 | if ( QPixmap::defaultDepth() < 12 ) { | ||
40 | // canvas.setBackgroundColor(QColor(0x51, 0x74, 0x6B)); | ||
41 | //canvas.setBackgroundColor(QColor(0x20, 0xb0, 0x50)); | ||
42 | canvas.setBackgroundColor(QColor(0x08, 0x98, 0x2D)); | ||
43 | } else { | ||
44 | QPixmap bg; | ||
45 | bg.convertFromImage( Resource::loadImage( "table_pattern" ), ThresholdDither ); | ||
46 | canvas.setBackgroundPixmap(bg); | ||
47 | } | ||
48 | |||
49 | #if defined( QT_QWS_CASSIOPEIA ) | ||
50 | canvas.setAdvancePeriod(70); | ||
51 | #else | ||
52 | canvas.setAdvancePeriod(30); | ||
53 | #endif | ||
54 | |||
55 | |||
56 | #ifdef _PATIENCE_USE_ACCELS_ | ||
57 | QPEMenuBar* menu = menuBar(); | ||
58 | |||
59 | QPopupMenu* file = new QPopupMenu; | ||
60 | file->insertItem(tr("Patience"), this, SLOT(initPatience()), CTRL+Key_F); | ||
61 | file->insertItem(tr("Freecell"), this, SLOT(initFreecell()), CTRL+Key_F); | ||
62 | menu->insertItem(tr("&Game"), file); | ||
63 | |||
64 | menu->insertSeparator(); | ||
65 | |||
66 | settings = new QPopupMenu; | ||
67 | settings->insertItem(tr("&Change Card Backs"), this, SLOT(changeCardBacks()), Key_F2); | ||
68 | snap_id = settings->insertItem(tr("&Snap To Position"), this, SLOT(snapToggle()), Key_F3); | ||
69 | settings->setCheckable(TRUE); | ||
70 | menu->insertItem(tr("&Settings"),settings); | ||
71 | |||
72 | menu->insertSeparator(); | ||
73 | |||
74 | QPopupMenu* help = new QPopupMenu; | ||
75 | help->insertItem(tr("&About"), this, SLOT(help()), Key_F1); | ||
76 | help->setItemChecked(dbf_id, TRUE); | ||
77 | menu->insertItem(tr("&Help"),help); | ||
78 | #else | ||
79 | QMenuBar* menu = menuBar(); | ||
80 | |||
81 | QPopupMenu* file = new QPopupMenu; | ||
82 | file->insertItem(tr("Patience"), this, SLOT(initPatience())); | ||
83 | file->insertItem(tr("Freecell"), this, SLOT(initFreecell())); | ||
84 | menu->insertItem(tr("Play"), file); | ||
85 | |||
86 | menu->insertSeparator(); | ||
87 | |||
88 | settings = new QPopupMenu; | ||
89 | settings->setCheckable(TRUE); | ||
90 | settings->insertItem(tr("Change Card Backs"), this, SLOT(changeCardBacks())); | ||
91 | snap_id = settings->insertItem(tr("Snap To Position"), this, SLOT(snapToggle())); | ||
92 | QString m; | ||
93 | |||
94 | drawId = settings->insertItem(tr("Turn One Card"), this, SLOT(drawnToggle())); | ||
95 | menu->insertItem(tr("Settings"),settings); | ||
96 | |||
97 | #endif | ||
98 | |||
99 | menu->show(); | ||
100 | |||
101 | Config cfg( "Patience" ); | ||
102 | cfg.setGroup( "GlobalSettings" ); | ||
103 | snapOn = cfg.readBoolEntry( "SnapOn", TRUE); | ||
104 | settings->setItemChecked(snap_id, snapOn); | ||
105 | gameType = cfg.readNumEntry( "GameType", -1 ); | ||
106 | drawThree = cfg.readBoolEntry( "DrawThree", TRUE); | ||
107 | if ( gameType == 0 ) { | ||
108 | cardGame = new PatienceCardGame( &canvas, snapOn, this ); | ||
109 | cardGame->setNumberToDraw(drawThree ? 3 : 1); | ||
110 | setCaption(tr("Patience")); | ||
111 | setCentralWidget(cardGame); | ||
112 | cardGame->readConfig( cfg ); | ||
113 | setCardBacks(); | ||
114 | } else if ( gameType == 1 ) { | ||
115 | cardGame = new FreecellCardGame( &canvas, snapOn, this ); | ||
116 | setCaption(tr("Freecell")); | ||
117 | setCentralWidget(cardGame); | ||
118 | //cardGame->newGame(); // Until we know how to handle reading freecell config | ||
119 | cardGame->readConfig( cfg ); | ||
120 | setCardBacks(); | ||
121 | } else { | ||
122 | // Probably there isn't a config file or it is broken | ||
123 | // Start a new game | ||
124 | initPatience(); | ||
125 | } | ||
126 | |||
127 | updateDraw(); | ||
128 | } | ||
129 | |||
130 | |||
131 | CanvasCardWindow::~CanvasCardWindow() | ||
132 | { | ||
133 | if (cardGame) { | ||
134 | Config cfg("Patience"); | ||
135 | cfg.setGroup( "GlobalSettings" ); | ||
136 | cfg.writeEntry( "GameType", gameType ); | ||
137 | cfg.writeEntry( "SnapOn", snapOn ); | ||
138 | cfg.writeEntry( "DrawThree", drawThree); | ||
139 | cardGame->writeConfig( cfg ); | ||
140 | delete cardGame; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | void CanvasCardWindow::resizeEvent(QResizeEvent *) | ||
146 | { | ||
147 | QSize s = centralWidget()->size(); | ||
148 | int fw = style().defaultFrameWidth(); | ||
149 | canvas.resize( s.width() - fw - 2, s.height() - fw - 2); | ||
150 | } | ||
151 | |||
152 | |||
153 | void CanvasCardWindow::initPatience() | ||
154 | { | ||
155 | // Create New Game | ||
156 | if ( cardGame ) | ||
157 | delete cardGame; | ||
158 | cardGame = new PatienceCardGame( &canvas, snapOn, this ); | ||
159 | cardGame->setNumberToDraw(drawThree ? 3 : 1); | ||
160 | gameType = 0; | ||
161 | setCaption(tr("Patience")); | ||
162 | setCentralWidget(cardGame); | ||
163 | cardGame->newGame(); | ||
164 | setCardBacks(); | ||
165 | updateDraw(); | ||
166 | } | ||
167 | |||
168 | |||
169 | void CanvasCardWindow::initFreecell() | ||
170 | { | ||
171 | // Create New Game | ||
172 | if ( cardGame ) { | ||
173 | delete cardGame; | ||
174 | } | ||
175 | cardGame = new FreecellCardGame( &canvas, snapOn, this ); | ||
176 | gameType = 1; | ||
177 | setCaption(tr("Freecell")); | ||
178 | setCentralWidget(cardGame); | ||
179 | cardGame->newGame(); | ||
180 | setCardBacks(); | ||
181 | } | ||
182 | |||
183 | |||
184 | void CanvasCardWindow::snapToggle() | ||
185 | { | ||
186 | snapOn = !snapOn; | ||
187 | settings->setItemChecked(snap_id, snapOn); | ||
188 | cardGame->toggleSnap(); | ||
189 | } | ||
190 | |||
191 | |||
192 | void CanvasCardWindow::drawnToggle() | ||
193 | { | ||
194 | cardGame->toggleCardsDrawn(); | ||
195 | updateDraw(); | ||
196 | } | ||
197 | |||
198 | void CanvasCardWindow::updateDraw() { | ||
199 | if(cardGame->cardsDrawn() == 3) | ||
200 | settings->changeItem(drawId, tr("Turn One Card")); | ||
201 | else | ||
202 | settings->changeItem(drawId, tr("Turn Three Cards")); | ||
203 | } | ||
204 | |||
205 | |||
206 | void CanvasCardWindow::setCardBacks() | ||
207 | { | ||
208 | QCanvasItemList l = canvas.allItems(); | ||
209 | |||
210 | for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { | ||
211 | if ( (*it)->rtti() == canvasCardId ) | ||
212 | ((CanvasCard *)(*it))->setCardBack( cardBack ); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | void CanvasCardWindow::changeCardBacks() | ||
218 | { | ||
219 | cardBack++; | ||
220 | |||
221 | if (cardBack == 5) | ||
222 | cardBack = 0; | ||
223 | |||
224 | setCardBacks(); | ||
225 | } | ||
226 | |||
227 | |||
diff --git a/noncore/games/solitaire/canvascardwindow.h b/noncore/games/solitaire/canvascardwindow.h new file mode 100644 index 0000000..b75d40a --- a/dev/null +++ b/noncore/games/solitaire/canvascardwindow.h | |||
@@ -0,0 +1,70 @@ | |||
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 CANVAS_CARD_WINDOW_H | ||
21 | #define CANVAS_CARD_WINDOW_H | ||
22 | |||
23 | |||
24 | #include <qmainwindow.h> | ||
25 | #include <qcanvas.h> | ||
26 | |||
27 | |||
28 | class CanvasCardGame; | ||
29 | class QPopupMenu; | ||
30 | |||
31 | |||
32 | class CanvasCardWindow : public QMainWindow { | ||
33 | Q_OBJECT | ||
34 | |||
35 | public: | ||
36 | CanvasCardWindow(QWidget* parent=0, const char* name=0, WFlags f=0); | ||
37 | virtual ~CanvasCardWindow(); | ||
38 | |||
39 | public slots: | ||
40 | void setCardBacks(); | ||
41 | void changeCardBacks(); | ||
42 | void snapToggle(); | ||
43 | void drawnToggle(); | ||
44 | |||
45 | private slots: | ||
46 | void initFreecell(); | ||
47 | void initPatience(); | ||
48 | |||
49 | protected: | ||
50 | virtual void resizeEvent(QResizeEvent *e); | ||
51 | |||
52 | void updateDraw(); | ||
53 | private: | ||
54 | QCanvas canvas; | ||
55 | bool snapOn; | ||
56 | bool drawThree; | ||
57 | int drawId; | ||
58 | int cardBack; | ||
59 | int gameType; | ||
60 | CanvasCardGame *cardGame; | ||
61 | |||
62 | QPopupMenu* options; | ||
63 | QPopupMenu* settings; | ||
64 | int dbf_id; | ||
65 | int snap_id; | ||
66 | }; | ||
67 | |||
68 | |||
69 | #endif | ||
70 | |||
diff --git a/noncore/games/solitaire/canvasshapes.cpp b/noncore/games/solitaire/canvasshapes.cpp new file mode 100644 index 0000000..28d0b4e --- a/dev/null +++ b/noncore/games/solitaire/canvasshapes.cpp | |||
@@ -0,0 +1,92 @@ | |||
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 | #include <qpainter.h> | ||
21 | #include <qcanvas.h> | ||
22 | #include "canvasshapes.h" | ||
23 | |||
24 | |||
25 | CanvasRoundRect::CanvasRoundRect(int x, int y, QCanvas *canvas) : | ||
26 | QCanvasRectangle( x, y, 23, 36, canvas) | ||
27 | { | ||
28 | setZ(0); | ||
29 | show(); | ||
30 | } | ||
31 | |||
32 | |||
33 | void CanvasRoundRect::redraw() | ||
34 | { | ||
35 | hide(); | ||
36 | show(); | ||
37 | } | ||
38 | |||
39 | |||
40 | void CanvasRoundRect::drawShape(QPainter &p) | ||
41 | { | ||
42 | p.drawRoundRect( (int)x(), (int)y(), 23, 36); | ||
43 | } | ||
44 | |||
45 | |||
46 | CanvasCircleOrCross::CanvasCircleOrCross(int x, int y, QCanvas *canvas) : | ||
47 | QCanvasRectangle( x, y, 21, 21, canvas), circleShape(TRUE) | ||
48 | { | ||
49 | show(); | ||
50 | } | ||
51 | |||
52 | |||
53 | void CanvasCircleOrCross::redraw() | ||
54 | { | ||
55 | hide(); | ||
56 | show(); | ||
57 | } | ||
58 | |||
59 | |||
60 | void CanvasCircleOrCross::setCircle() | ||
61 | { | ||
62 | circleShape = TRUE; | ||
63 | redraw(); | ||
64 | } | ||
65 | |||
66 | |||
67 | void CanvasCircleOrCross::setCross() | ||
68 | { | ||
69 | circleShape = FALSE; | ||
70 | redraw(); | ||
71 | } | ||
72 | |||
73 | |||
74 | void CanvasCircleOrCross::drawShape(QPainter &p) | ||
75 | { | ||
76 | int x1 = (int)x(), y1 = (int)y(); | ||
77 | // Green circle | ||
78 | if (circleShape == TRUE) { | ||
79 | p.setPen( QPen( QColor(0x10, 0xE0, 0x10), 1 ) ); | ||
80 | p.drawEllipse( x1 - 1, y1 - 1, 21, 21); | ||
81 | p.drawEllipse( x1 - 1, y1 - 0, 21, 19); | ||
82 | p.drawEllipse( x1 + 0, y1 + 0, 19, 19); | ||
83 | p.drawEllipse( x1 + 1, y1 + 0, 17, 19); | ||
84 | p.drawEllipse( x1 + 1, y1 + 1, 17, 17); | ||
85 | // Red cross | ||
86 | } else { | ||
87 | p.setPen( QPen( QColor(0xE0, 0x10, 0x10), 5 ) ); | ||
88 | p.drawLine( x1, y1, x1 + 20, y1 + 20); | ||
89 | p.drawLine( x1 + 20, y1, x1, y1 + 20); | ||
90 | } | ||
91 | } | ||
92 | |||
diff --git a/noncore/games/solitaire/canvasshapes.h b/noncore/games/solitaire/canvasshapes.h new file mode 100644 index 0000000..72acf6b --- a/dev/null +++ b/noncore/games/solitaire/canvasshapes.h | |||
@@ -0,0 +1,55 @@ | |||
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 CANVAS_SHAPES_H | ||
21 | #define CANVAS_SHAPES_H | ||
22 | |||
23 | |||
24 | #include <qcanvas.h> | ||
25 | |||
26 | |||
27 | class QPainter; | ||
28 | |||
29 | |||
30 | class CanvasRoundRect : QCanvasRectangle | ||
31 | { | ||
32 | public: | ||
33 | CanvasRoundRect(int x, int y, QCanvas *canvas); | ||
34 | void redraw(); | ||
35 | protected: | ||
36 | void drawShape(QPainter &p); | ||
37 | }; | ||
38 | |||
39 | |||
40 | class CanvasCircleOrCross : QCanvasRectangle | ||
41 | { | ||
42 | public: | ||
43 | CanvasCircleOrCross(int x, int y, QCanvas *canvas); | ||
44 | void redraw(); | ||
45 | void setCircle(); | ||
46 | void setCross(); | ||
47 | protected: | ||
48 | void drawShape(QPainter &p); | ||
49 | private: | ||
50 | bool circleShape; | ||
51 | }; | ||
52 | |||
53 | |||
54 | #endif | ||
55 | |||
diff --git a/noncore/games/solitaire/card.cpp b/noncore/games/solitaire/card.cpp new file mode 100644 index 0000000..609e280 --- a/dev/null +++ b/noncore/games/solitaire/card.cpp | |||
@@ -0,0 +1,53 @@ | |||
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 "card.h" | ||
22 | |||
23 | #include <qpe/config.h> | ||
24 | |||
25 | #include <qpoint.h> | ||
26 | #include <qlist.h> | ||
27 | |||
28 | /* | ||
29 | Card( eValue v, eSuit s, bool f ) : | ||
30 | val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { } | ||
31 | virtual ~Card() { } | ||
32 | eValue getValue() { return val; } | ||
33 | eSuit getSuit() { return suit; } | ||
34 | CardPile *getCardPile() { return cardPile; } | ||
35 | bool isFacing() { return faceUp; } | ||
36 | bool isShowing() { return showing; } | ||
37 | bool isRed() { return ((suit == diamonds) || (suit == hearts)); } | ||
38 | int getX(void) { return ix; } | ||
39 | int getY(void) { return iy; } | ||
40 | int getZ(void) { return iz; } | ||
41 | void setCardPile(CardPile *p) { cardPile = p; } | ||
42 | void setFace(bool f) { faceUp = f; } | ||
43 | void flip(void) { flipTo(getX(), getY()); } | ||
44 | virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; } | ||
45 | virtual void move(int x, int y) { ix = x; iy = y; } | ||
46 | virtual void move(QPoint p) { ix = p.x(); iy = p.y(); } | ||
47 | virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); } | ||
48 | virtual void showCard(void) { showing = TRUE; } | ||
49 | virtual void hideCard(void) { showing = FALSE; } | ||
50 | virtual void redraw(void) { } | ||
51 | */ | ||
52 | |||
53 | |||
diff --git a/noncore/games/solitaire/card.h b/noncore/games/solitaire/card.h new file mode 100644 index 0000000..eb30d30 --- a/dev/null +++ b/noncore/games/solitaire/card.h | |||
@@ -0,0 +1,84 @@ | |||
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 CARD_H | ||
21 | #define CARD_H | ||
22 | |||
23 | |||
24 | #include <qpoint.h> | ||
25 | |||
26 | |||
27 | class CardPile; | ||
28 | |||
29 | |||
30 | enum eSuit { | ||
31 | jokerSuit = 0, clubs, spades, diamonds, hearts | ||
32 | }; | ||
33 | |||
34 | |||
35 | enum eValue { | ||
36 | jokerVal = 0, ace, two, three, four, five, | ||
37 | six, seven, eight, nine, ten, jack, queen, king | ||
38 | }; | ||
39 | |||
40 | |||
41 | class Card | ||
42 | { | ||
43 | public: | ||
44 | Card( eValue v, eSuit s, bool f ) : | ||
45 | val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { } | ||
46 | virtual ~Card() { } | ||
47 | |||
48 | eValue getValue() { return val; } | ||
49 | eSuit getSuit() { return suit; } | ||
50 | |||
51 | void setCardPile(CardPile *p) { cardPile = p; } | ||
52 | CardPile *getCardPile() { return cardPile; } | ||
53 | |||
54 | void setFace(bool f) { faceUp = f; /* flip(); */ } | ||
55 | bool isFacing() { return faceUp; } | ||
56 | |||
57 | bool isShowing() { return showing; } | ||
58 | bool isRed() { return ((suit == diamonds) || (suit == hearts)); } | ||
59 | |||
60 | int getX(void) { return ix; } | ||
61 | int getY(void) { return iy; } | ||
62 | int getZ(void) { return iz; } | ||
63 | void flip(void) { flipTo(getX(), getY()); } | ||
64 | |||
65 | virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; } | ||
66 | virtual void move(int x, int y) { ix = x; iy = y; } | ||
67 | virtual void move(QPoint p) { ix = p.x(); iy = p.y(); } | ||
68 | virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); } | ||
69 | virtual void showCard(void) { showing = TRUE; } | ||
70 | virtual void hideCard(void) { showing = FALSE; } | ||
71 | protected: | ||
72 | virtual void redraw(void) { } | ||
73 | private: | ||
74 | eValue val; | ||
75 | eSuit suit; | ||
76 | bool faceUp; | ||
77 | bool showing; | ||
78 | int ix, iy, iz; | ||
79 | CardPile *cardPile; | ||
80 | }; | ||
81 | |||
82 | |||
83 | #endif | ||
84 | |||
diff --git a/noncore/games/solitaire/carddeck.cpp b/noncore/games/solitaire/carddeck.cpp new file mode 100644 index 0000000..87c043a --- a/dev/null +++ b/noncore/games/solitaire/carddeck.cpp | |||
@@ -0,0 +1,81 @@ | |||
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 | #include <stdlib.h> | ||
21 | #include <time.h> | ||
22 | #include "card.h" | ||
23 | #include "carddeck.h" | ||
24 | |||
25 | |||
26 | CardDeck::CardDeck(int jokers) : numberOfJokers(jokers), deckCreated(FALSE) | ||
27 | { | ||
28 | cards = new (Card *)[getNumberOfCards()]; | ||
29 | } | ||
30 | |||
31 | |||
32 | CardDeck::~CardDeck() | ||
33 | { | ||
34 | for (int i = 0; i < getNumberOfCards(); i++) | ||
35 | delete cards[i]; | ||
36 | delete cards; | ||
37 | } | ||
38 | |||
39 | |||
40 | void CardDeck::createDeck() | ||
41 | { | ||
42 | if (!deckCreated) { | ||
43 | for (int i = 0; i < 52; i++) | ||
44 | cards[i] = newCard( (eValue)((i % 13) + 1), (eSuit)((i / 13) + 1), FALSE ); | ||
45 | for (int i = 0; i < getNumberOfJokers(); i++) | ||
46 | cards[52 + i] = newCard( jokerVal, jokerSuit, FALSE ); | ||
47 | deckCreated = TRUE; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | |||
52 | void CardDeck::shuffle() | ||
53 | { | ||
54 | srand(time(NULL)); | ||
55 | for (int i = 0; i < getNumberOfCards(); i++) { | ||
56 | int index = rand() % getNumberOfCards(); | ||
57 | Card *tmpCard = cards[i]; | ||
58 | cards[i] = cards[index]; | ||
59 | cards[index] = tmpCard; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | |||
64 | int CardDeck::getNumberOfCards() | ||
65 | { | ||
66 | return 52 + getNumberOfJokers(); | ||
67 | } | ||
68 | |||
69 | |||
70 | int CardDeck::getNumberOfJokers() | ||
71 | { | ||
72 | return numberOfJokers; | ||
73 | } | ||
74 | |||
75 | |||
76 | Card *CardDeck::newCard( eValue v, eSuit s, bool f ) | ||
77 | { | ||
78 | return new Card(v, s, f); | ||
79 | } | ||
80 | |||
81 | |||
diff --git a/noncore/games/solitaire/carddeck.h b/noncore/games/solitaire/carddeck.h new file mode 100644 index 0000000..9ad35a9 --- a/dev/null +++ b/noncore/games/solitaire/carddeck.h | |||
@@ -0,0 +1,49 @@ | |||
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 CARD_DECK_H | ||
21 | #define CARD_DECK_H | ||
22 | |||
23 | |||
24 | class Card; | ||
25 | |||
26 | |||
27 | class CardDeck | ||
28 | { | ||
29 | public: | ||
30 | CardDeck(int jokers = 0); | ||
31 | virtual ~CardDeck(); | ||
32 | |||
33 | void createDeck(); | ||
34 | void shuffle(); | ||
35 | int getNumberOfCards(); | ||
36 | int getNumberOfJokers(); | ||
37 | |||
38 | virtual Card *newCard( eValue v, eSuit s, bool f ); | ||
39 | virtual void deal() { } | ||
40 | |||
41 | Card **cards; | ||
42 | private: | ||
43 | int numberOfJokers; | ||
44 | bool deckCreated; | ||
45 | }; | ||
46 | |||
47 | |||
48 | #endif | ||
49 | |||
diff --git a/noncore/games/solitaire/cardgame.cpp b/noncore/games/solitaire/cardgame.cpp new file mode 100644 index 0000000..b19aeef --- a/dev/null +++ b/noncore/games/solitaire/cardgame.cpp | |||
@@ -0,0 +1,35 @@ | |||
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 | #include "cardgame.h" | ||
21 | |||
22 | |||
23 | void CardGame::newGame() | ||
24 | { | ||
25 | // Create Cards | ||
26 | createDeck(); | ||
27 | |||
28 | // Shuffle Cards | ||
29 | shuffle(); | ||
30 | |||
31 | // Deal Cards | ||
32 | deal(); | ||
33 | } | ||
34 | |||
35 | |||
diff --git a/noncore/games/solitaire/cardgame.h b/noncore/games/solitaire/cardgame.h new file mode 100644 index 0000000..dd7efab --- a/dev/null +++ b/noncore/games/solitaire/cardgame.h | |||
@@ -0,0 +1,45 @@ | |||
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 CARD_GAME_H | ||
21 | #define CARD_GAME_H | ||
22 | |||
23 | |||
24 | #include <qpoint.h> | ||
25 | #include "card.h" | ||
26 | #include "cardpile.h" | ||
27 | #include "carddeck.h" | ||
28 | #include "cardgamelayout.h" | ||
29 | |||
30 | |||
31 | class CardGame : public CardGameLayout, public CardDeck | ||
32 | { | ||
33 | public: | ||
34 | CardGame(int numOfJokers = 0) : CardGameLayout(), CardDeck(numOfJokers) { } | ||
35 | virtual ~CardGame() { } | ||
36 | virtual void newGame(); | ||
37 | virtual void mousePress(QPoint p) { Q_UNUSED(p); } | ||
38 | virtual void mouseRelease(QPoint p) { Q_UNUSED(p); } | ||
39 | virtual void mouseMove(QPoint p) { Q_UNUSED(p); } | ||
40 | private: | ||
41 | }; | ||
42 | |||
43 | |||
44 | #endif | ||
45 | |||
diff --git a/noncore/games/solitaire/cardgamelayout.cpp b/noncore/games/solitaire/cardgamelayout.cpp new file mode 100644 index 0000000..1ceee8d --- a/dev/null +++ b/noncore/games/solitaire/cardgamelayout.cpp | |||
@@ -0,0 +1,61 @@ | |||
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 | #include "cardgamelayout.h" | ||
21 | |||
22 | |||
23 | CardGameLayout::~CardGameLayout() | ||
24 | { | ||
25 | // Should I just do setAutoDelete( TRUE ); ? | ||
26 | for (CardPile *p = first(); p != NULL; p = next()) | ||
27 | delete p; | ||
28 | } | ||
29 | |||
30 | |||
31 | CardPile *CardGameLayout::closestPile(int x, int y, int maxDistance) | ||
32 | { | ||
33 | int closestDistance = maxDistance * maxDistance; | ||
34 | CardPile *closestPile = NULL; | ||
35 | |||
36 | for (CardPile *p = first(); p != NULL; p = next()) { | ||
37 | int d = p->distanceFromNextPos(x, y); | ||
38 | if (d < closestDistance) { | ||
39 | closestDistance = d; | ||
40 | closestPile = p; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | return closestPile; | ||
45 | } | ||
46 | |||
47 | |||
48 | void CardGameLayout::beginDealing() | ||
49 | { | ||
50 | for (CardPile *p = first(); p != NULL; p = next()) | ||
51 | p->beginDealing(); | ||
52 | } | ||
53 | |||
54 | |||
55 | void CardGameLayout::endDealing() | ||
56 | { | ||
57 | for (CardPile *p = first(); p != NULL; p = next()) | ||
58 | p->endDealing(); | ||
59 | } | ||
60 | |||
61 | |||
diff --git a/noncore/games/solitaire/cardgamelayout.h b/noncore/games/solitaire/cardgamelayout.h new file mode 100644 index 0000000..bb36e6b --- a/dev/null +++ b/noncore/games/solitaire/cardgamelayout.h | |||
@@ -0,0 +1,42 @@ | |||
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 CARD_GAME_LAYOUT_H | ||
21 | #define CARD_GAME_LAYOUT_H | ||
22 | |||
23 | |||
24 | #include <qlist.h> | ||
25 | #include "cardpile.h" | ||
26 | |||
27 | |||
28 | class CardGameLayout : public QList<CardPile> | ||
29 | { | ||
30 | public: | ||
31 | CardGameLayout() { } | ||
32 | virtual ~CardGameLayout(); | ||
33 | |||
34 | void addCardPile(CardPile *pile) { append((const CardPile *)pile); } | ||
35 | CardPile *closestPile(int x, int y, int maxDistance); | ||
36 | void beginDealing(); | ||
37 | void endDealing(); | ||
38 | }; | ||
39 | |||
40 | |||
41 | #endif | ||
42 | |||
diff --git a/noncore/games/solitaire/cardpile.cpp b/noncore/games/solitaire/cardpile.cpp new file mode 100644 index 0000000..0b738d2 --- a/dev/null +++ b/noncore/games/solitaire/cardpile.cpp | |||
@@ -0,0 +1,114 @@ | |||
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 "cardpile.h" | ||
22 | #include "card.h" | ||
23 | |||
24 | #include <qpe/config.h> | ||
25 | #include <qpoint.h> | ||
26 | |||
27 | #include <qlist.h> | ||
28 | |||
29 | |||
30 | CardPile::CardPile(int x, int y) : pileX(x), pileY(y), dealing(FALSE) { | ||
31 | pileWidth = 0; | ||
32 | pileHeight = 0; | ||
33 | pileNextX = pileX; | ||
34 | pileNextY = pileY; | ||
35 | pileCenterX = x + pileWidth / 2; | ||
36 | pileCenterY = y + pileHeight / 2; | ||
37 | pileRadius = (pileWidth > pileHeight) ? pileWidth : pileHeight; | ||
38 | } | ||
39 | |||
40 | |||
41 | int CardPile::distanceFromPile(int x, int y) { | ||
42 | return (pileCenterX-x)*(pileCenterX-x)+(pileCenterY-y)*(pileCenterY-y); | ||
43 | } | ||
44 | |||
45 | |||
46 | int CardPile::distanceFromNextPos(int x, int y) { | ||
47 | return (pileNextX-x)*(pileNextX-x)+(pileNextY-y)*(pileNextY-y); | ||
48 | } | ||
49 | |||
50 | |||
51 | Card *CardPile::cardInfront(Card *c) { | ||
52 | CardPile *p = c->getCardPile(); | ||
53 | if (p) { | ||
54 | p->at(p->find(c)); | ||
55 | return p->next(); | ||
56 | } else { | ||
57 | return NULL; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | |||
62 | bool CardPile::kingOnTop() { | ||
63 | Card *top = cardOnTop(); | ||
64 | return top && top->getValue() == king; | ||
65 | } | ||
66 | |||
67 | |||
68 | bool CardPile::addCardToTop(Card *c) { | ||
69 | if (dealing || isAllowedOnTop(c)) { | ||
70 | append((const Card *)c); | ||
71 | cardAddedToTop(c); | ||
72 | return TRUE; | ||
73 | } | ||
74 | return FALSE; | ||
75 | } | ||
76 | |||
77 | |||
78 | bool CardPile::addCardToBottom(Card *c) { | ||
79 | if (dealing || isAllowedOnBottom(c)) { | ||
80 | prepend((const Card *)c); | ||
81 | cardAddedToBottom(c); | ||
82 | return TRUE; | ||
83 | } | ||
84 | return FALSE; | ||
85 | } | ||
86 | |||
87 | |||
88 | bool CardPile::removeCard(Card *c) { | ||
89 | if (dealing || isAllowedToBeMoved(c)) { | ||
90 | take(find(c)); | ||
91 | cardRemoved(c); | ||
92 | return TRUE; | ||
93 | } | ||
94 | return FALSE; | ||
95 | } | ||
96 | |||
97 | |||
98 | void CardPile::writeConfig( Config& cfg, QString name ) { | ||
99 | int numberOfCards = 0; | ||
100 | cfg.setGroup( name ); | ||
101 | Card *card = cardOnBottom(); | ||
102 | while ( card ) { | ||
103 | QString cardStr; | ||
104 | cardStr.sprintf( "%i", numberOfCards ); | ||
105 | int val = (int)card->getValue() - 1 + ( (int)card->getSuit() - 1 ) * 13; | ||
106 | cfg.writeEntry( "Card" + cardStr, val ); | ||
107 | cfg.writeEntry( "CardFacing" + cardStr, card->isFacing() ); | ||
108 | card = cardInfront( card ); | ||
109 | numberOfCards++; | ||
110 | } | ||
111 | cfg.writeEntry("NumberOfCards", numberOfCards); | ||
112 | } | ||
113 | |||
114 | |||
diff --git a/noncore/games/solitaire/cardpile.h b/noncore/games/solitaire/cardpile.h new file mode 100644 index 0000000..c515bbc --- a/dev/null +++ b/noncore/games/solitaire/cardpile.h | |||
@@ -0,0 +1,101 @@ | |||
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 CARD_PILE_H | ||
21 | #define CARD_PILE_H | ||
22 | |||
23 | |||
24 | #include <qpoint.h> | ||
25 | #include <qlist.h> | ||
26 | |||
27 | |||
28 | enum ePileStackingType { | ||
29 | pileCascades = 0, pileStacks, pileCascadesOrStacks | ||
30 | }; | ||
31 | |||
32 | |||
33 | enum ePileFaceingType { | ||
34 | pileFaceUp = 0, pileFaceDown, pileFaceUpOrDown | ||
35 | }; | ||
36 | |||
37 | |||
38 | class Card; | ||
39 | class Config; | ||
40 | |||
41 | |||
42 | class CardPile : public QList<Card> | ||
43 | { | ||
44 | public: | ||
45 | CardPile(int x, int y); | ||
46 | virtual ~CardPile() { } | ||
47 | |||
48 | int getX() { return pileX; } | ||
49 | int getY() { return pileY; } | ||
50 | int getNextX() { return pileNextX; } | ||
51 | int getNextY() { return pileNextY; } | ||
52 | int getWidth() { return pileWidth; } | ||
53 | int getHeight() { return pileHeight; } | ||
54 | |||
55 | void setX(int x) { pileX = x; } | ||
56 | void setY(int y) { pileY = y; } | ||
57 | void setNextX(int x) { pileNextX = x; } | ||
58 | void setNextY(int y) { pileNextY = y; } | ||
59 | void setWidth(int width) { pileWidth = width; } | ||
60 | void setHeight(int height) { pileHeight = height; } | ||
61 | |||
62 | void beginDealing() { dealing = TRUE; } | ||
63 | void endDealing() { dealing = FALSE; } | ||
64 | bool isDealing() { return dealing; } | ||
65 | |||
66 | int distanceFromPile(int x, int y); | ||
67 | int distanceFromNextPos(int x, int y); | ||
68 | |||
69 | Card *cardOnTop() { return getLast(); } | ||
70 | Card *cardOnBottom() { return getFirst(); } | ||
71 | Card *cardInfront(Card *c); | ||
72 | bool kingOnTop(); | ||
73 | |||
74 | bool addCardToTop(Card *c); | ||
75 | bool addCardToBottom(Card *c); | ||
76 | bool removeCard(Card *c); | ||
77 | |||
78 | virtual void cardAddedToTop(Card *) { } | ||
79 | virtual void cardAddedToBottom(Card *) { } | ||
80 | virtual void cardRemoved(Card *) { } | ||
81 | virtual bool isAllowedOnTop(Card *) { return FALSE; } | ||
82 | virtual bool isAllowedOnBottom(Card *) { return FALSE; } | ||
83 | virtual bool isAllowedToBeMoved(Card *) { return FALSE; } | ||
84 | virtual QPoint getCardPos(Card *) { return QPoint(pileX, pileY); } | ||
85 | virtual QPoint getHypertheticalNextCardPos() { return QPoint(pileX, pileY); } | ||
86 | |||
87 | void writeConfig( Config& cfg, QString name ); | ||
88 | |||
89 | protected: | ||
90 | int pileX, pileY; | ||
91 | int pileNextX, pileNextY; | ||
92 | int pileWidth, pileHeight; | ||
93 | int pileCenterX, pileCenterY; | ||
94 | int pileRadius; | ||
95 | private: | ||
96 | bool dealing; | ||
97 | }; | ||
98 | |||
99 | |||
100 | #endif | ||
101 | |||
diff --git a/noncore/games/solitaire/freecellcardgame.cpp b/noncore/games/solitaire/freecellcardgame.cpp new file mode 100644 index 0000000..e82afd4 --- a/dev/null +++ b/noncore/games/solitaire/freecellcardgame.cpp | |||
@@ -0,0 +1,137 @@ | |||
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 | #include "freecellcardgame.h" | ||
21 | |||
22 | |||
23 | extern int highestZ; | ||
24 | int numberOfFreeCells = 4; | ||
25 | |||
26 | |||
27 | FreecellCardGame::FreecellCardGame(QCanvas *c, bool snap, QWidget *parent) : CanvasCardGame(*c, snap, parent) | ||
28 | { | ||
29 | numberOfFreeCells = 4; | ||
30 | highestZ = 0; | ||
31 | |||
32 | for (int i = 0; i < 4; i++) { | ||
33 | freecellPiles[i] = new FreecellFreecellPile( 5 + i * 28, 10, canvas() ); | ||
34 | addCardPile(freecellPiles[i]); | ||
35 | } | ||
36 | for (int i = 0; i < 4; i++) { | ||
37 | discardPiles[i] = new FreecellDiscardPile( 125 + i * 28, 10, canvas() ); | ||
38 | addCardPile(discardPiles[i]); | ||
39 | } | ||
40 | for (int i = 0; i < 8; i++) { | ||
41 | workingPiles[i] = new FreecellWorkingPile( 10 + i * 28, 50, canvas() ); | ||
42 | addCardPile(workingPiles[i]); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | |||
47 | void FreecellCardGame::deal(void) | ||
48 | { | ||
49 | highestZ = 1; | ||
50 | |||
51 | beginDealing(); | ||
52 | |||
53 | for (int i = 0; i < 52; i++) { | ||
54 | Card *card = cards[i]; | ||
55 | card->setFace( TRUE ); | ||
56 | card->setPos( 0, 0, highestZ ); | ||
57 | card->setCardPile( workingPiles[i%8] ); | ||
58 | workingPiles[i%8]->addCardToTop( card ); | ||
59 | card->move( workingPiles[i%8]->getCardPos( card ) ); | ||
60 | card->showCard(); | ||
61 | highestZ++; | ||
62 | } | ||
63 | |||
64 | endDealing(); | ||
65 | } | ||
66 | |||
67 | |||
68 | bool FreecellCardGame::mousePressCard( Card *c, QPoint p ) | ||
69 | { | ||
70 | Q_UNUSED(p); | ||
71 | |||
72 | if ( !c->getCardPile()->isAllowedToBeMoved(c) ) { | ||
73 | moving = NULL; | ||
74 | return TRUE; | ||
75 | } | ||
76 | |||
77 | return FALSE; | ||
78 | } | ||
79 | |||
80 | |||
81 | void FreecellCardGame::readConfig( Config& cfg ) | ||
82 | { | ||
83 | cfg.setGroup("GameState"); | ||
84 | |||
85 | // Create Cards, but don't shuffle or deal them yet | ||
86 | createDeck(); | ||
87 | |||
88 | // Move the cards to their piles (deal them to their previous places) | ||
89 | beginDealing(); | ||
90 | |||
91 | highestZ = 1; | ||
92 | |||
93 | for (int k = 0; k < 4; k++) { | ||
94 | QString pile; | ||
95 | pile.sprintf( "FreeCellPile%i", k ); | ||
96 | readPile( cfg, freecellPiles[k], pile, highestZ ); | ||
97 | } | ||
98 | |||
99 | for (int k = 0; k < 4; k++) { | ||
100 | QString pile; | ||
101 | pile.sprintf( "DiscardPile%i", k ); | ||
102 | readPile( cfg, discardPiles[k], pile, highestZ ); | ||
103 | } | ||
104 | |||
105 | for (int k = 0; k < 8; k++) { | ||
106 | QString pile; | ||
107 | pile.sprintf( "WorkingPile%i", k ); | ||
108 | readPile( cfg, workingPiles[k], pile, highestZ ); | ||
109 | } | ||
110 | |||
111 | highestZ++; | ||
112 | |||
113 | endDealing(); | ||
114 | } | ||
115 | |||
116 | |||
117 | void FreecellCardGame::writeConfig( Config& cfg ) | ||
118 | { | ||
119 | cfg.setGroup("GameState"); | ||
120 | for ( int i = 0; i < 4; i++ ) { | ||
121 | QString pile; | ||
122 | pile.sprintf( "FreeCellPile%i", i ); | ||
123 | freecellPiles[i]->writeConfig( cfg, pile ); | ||
124 | } | ||
125 | for ( int i = 0; i < 4; i++ ) { | ||
126 | QString pile; | ||
127 | pile.sprintf( "DiscardPile%i", i ); | ||
128 | discardPiles[i]->writeConfig( cfg, pile ); | ||
129 | } | ||
130 | for ( int i = 0; i < 8; i++ ) { | ||
131 | QString pile; | ||
132 | pile.sprintf( "WorkingPile%i", i ); | ||
133 | workingPiles[i]->writeConfig( cfg, pile ); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | |||
diff --git a/noncore/games/solitaire/freecellcardgame.h b/noncore/games/solitaire/freecellcardgame.h new file mode 100644 index 0000000..f1b09ab --- a/dev/null +++ b/noncore/games/solitaire/freecellcardgame.h | |||
@@ -0,0 +1,152 @@ | |||
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 FREECELL_CARD_GAME_H | ||
21 | #define FREECELL_CARD_GAME_H | ||
22 | |||
23 | |||
24 | #include "patiencecardgame.h" | ||
25 | |||
26 | |||
27 | extern int numberOfFreeCells; | ||
28 | |||
29 | |||
30 | class FreecellDiscardPile : public PatienceDiscardPile | ||
31 | { | ||
32 | public: | ||
33 | FreecellDiscardPile(int x, int y, QCanvas *canvas) : | ||
34 | PatienceDiscardPile(x, y, canvas) { } | ||
35 | |||
36 | }; | ||
37 | |||
38 | |||
39 | class FreecellWorkingPile : public PatienceWorkingPile | ||
40 | { | ||
41 | public: | ||
42 | FreecellWorkingPile(int x, int y, QCanvas *canvas) : | ||
43 | PatienceWorkingPile(x, y, canvas) { } | ||
44 | |||
45 | virtual bool isAllowedOnTop(Card *card) { | ||
46 | if ( cardOnBottom() == NULL ) { | ||
47 | int numberOfCardsBeingMoved = 0; | ||
48 | Card *tempCard = card; | ||
49 | |||
50 | while ((tempCard != NULL)) { | ||
51 | numberOfCardsBeingMoved++; | ||
52 | tempCard = cardInfront(tempCard); | ||
53 | } | ||
54 | |||
55 | if (numberOfCardsBeingMoved > numberOfFreeCells) | ||
56 | return FALSE; | ||
57 | } | ||
58 | |||
59 | if ( card->isFacing() && | ||
60 | cardOnTop() == NULL ) | ||
61 | return TRUE; | ||
62 | return PatienceWorkingPile::isAllowedOnTop( card ); | ||
63 | } | ||
64 | |||
65 | virtual bool isAllowedToBeMoved(Card *card) { | ||
66 | int nextExpectedValue = (int)card->getValue(); | ||
67 | bool nextExpectedColor = card->isRed(); | ||
68 | int numberOfCardsBeingMoved = 0; | ||
69 | |||
70 | while ((card != NULL)) { | ||
71 | numberOfCardsBeingMoved++; | ||
72 | if ( (int)card->getValue() != nextExpectedValue ) | ||
73 | return FALSE; | ||
74 | if ( card->isRed() != nextExpectedColor ) | ||
75 | return FALSE; | ||
76 | nextExpectedValue--;; | ||
77 | nextExpectedColor = !nextExpectedColor; | ||
78 | card = cardInfront(card); | ||
79 | } | ||
80 | |||
81 | if (numberOfCardsBeingMoved <= (numberOfFreeCells + 1)) | ||
82 | return TRUE; | ||
83 | |||
84 | return FALSE; | ||
85 | } | ||
86 | virtual void cardRemoved(Card *card) { | ||
87 | if ( !isDealing() && !cardOnTop() ) | ||
88 | numberOfFreeCells++; | ||
89 | PatienceWorkingPile::cardRemoved( card ); | ||
90 | } | ||
91 | virtual void cardAddedToTop(Card *card) { | ||
92 | if ( !isDealing() && cardOnBottom() == card ) | ||
93 | numberOfFreeCells--; | ||
94 | PatienceWorkingPile::cardAddedToTop( card ); | ||
95 | } | ||
96 | }; | ||
97 | |||
98 | |||
99 | class FreecellFreecellPile : public CardPile, public CanvasRoundRect | ||
100 | { | ||
101 | public: | ||
102 | FreecellFreecellPile(int x, int y, QCanvas *canvas) | ||
103 | : CardPile(x, y), CanvasRoundRect(x, y, canvas) { } | ||
104 | virtual bool isAllowedOnTop(Card *card) { | ||
105 | if ( ( cardOnTop() == NULL ) && ( card->getCardPile()->cardInfront(card) == NULL ) ) | ||
106 | return TRUE; | ||
107 | return FALSE; | ||
108 | } | ||
109 | virtual bool isAllowedToBeMoved(Card *card) { | ||
110 | Q_UNUSED(card); | ||
111 | return TRUE; | ||
112 | } | ||
113 | virtual void cardAddedToTop(Card *card) { | ||
114 | Q_UNUSED(card); | ||
115 | numberOfFreeCells--; | ||
116 | } | ||
117 | virtual void cardRemoved(Card *card) { | ||
118 | Q_UNUSED(card); | ||
119 | numberOfFreeCells++; | ||
120 | } | ||
121 | }; | ||
122 | |||
123 | |||
124 | class FreecellCardGame : public CanvasCardGame | ||
125 | { | ||
126 | public: | ||
127 | FreecellCardGame(QCanvas *c, bool snap, QWidget *parent = 0); | ||
128 | virtual void deal(void); | ||
129 | virtual bool haveWeWon() { | ||
130 | return ( discardPiles[0]->kingOnTop() && | ||
131 | discardPiles[1]->kingOnTop() && | ||
132 | discardPiles[2]->kingOnTop() && | ||
133 | discardPiles[3]->kingOnTop() ); | ||
134 | } | ||
135 | virtual void mousePress(QPoint p) { Q_UNUSED(p); } | ||
136 | virtual void mouseRelease(QPoint p) { Q_UNUSED(p); } | ||
137 | // virtual void mouseMove(QPoint p); | ||
138 | virtual bool mousePressCard(Card *card, QPoint p); | ||
139 | virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } | ||
140 | // virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } | ||
141 | void readConfig( Config& cfg ); | ||
142 | void writeConfig( Config& cfg ); | ||
143 | bool snapOn; | ||
144 | private: | ||
145 | FreecellFreecellPile *freecellPiles[8]; | ||
146 | FreecellWorkingPile *workingPiles[8]; | ||
147 | FreecellDiscardPile *discardPiles[4]; | ||
148 | }; | ||
149 | |||
150 | |||
151 | #endif | ||
152 | |||
diff --git a/noncore/games/solitaire/main.cpp b/noncore/games/solitaire/main.cpp new file mode 100644 index 0000000..f81aa3c --- a/dev/null +++ b/noncore/games/solitaire/main.cpp | |||
@@ -0,0 +1,36 @@ | |||
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 "canvascardwindow.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | |||
26 | int main( int argc, char ** argv ) | ||
27 | { | ||
28 | QPEApplication a( argc, argv ); | ||
29 | |||
30 | CanvasCardWindow m; | ||
31 | m.setCaption( CanvasCardWindow::tr("Patience") ); | ||
32 | a.showMainWidget( &m ); | ||
33 | |||
34 | return a.exec(); | ||
35 | } | ||
36 | |||
diff --git a/noncore/games/solitaire/patiencecardgame.cpp b/noncore/games/solitaire/patiencecardgame.cpp new file mode 100644 index 0000000..5a9326a --- a/dev/null +++ b/noncore/games/solitaire/patiencecardgame.cpp | |||
@@ -0,0 +1,234 @@ | |||
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 | #include "patiencecardgame.h" | ||
21 | |||
22 | |||
23 | int highestZ = 0; | ||
24 | |||
25 | |||
26 | PatienceCardGame::PatienceCardGame(QCanvas *c, bool snap, QWidget *parent) : CanvasCardGame(*c, snap, parent) | ||
27 | { | ||
28 | numberOfTimesThroughDeck = 0; | ||
29 | highestZ = 0; | ||
30 | |||
31 | circleCross = new CanvasCircleOrCross( 7, 18, canvas() ); | ||
32 | rectangle = new CanvasRoundRect( 35, 10, canvas() ); | ||
33 | |||
34 | for (int i = 0; i < 4; i++) { | ||
35 | discardPiles[i] = new PatienceDiscardPile( 110 + i * 30, 10, canvas() ); | ||
36 | addCardPile(discardPiles[i]); | ||
37 | } | ||
38 | for (int i = 0; i < 7; i++) { | ||
39 | workingPiles[i] = new PatienceWorkingPile( 10 + i * 30, 50, canvas() ); | ||
40 | addCardPile(workingPiles[i]); | ||
41 | } | ||
42 | faceDownDealingPile = new PatienceFaceDownDeck( 5, 10, canvas() ); | ||
43 | faceUpDealingPile = new PatienceFaceUpDeck( 35, 10, canvas() ); | ||
44 | } | ||
45 | |||
46 | |||
47 | PatienceCardGame::~PatienceCardGame() | ||
48 | { | ||
49 | delete circleCross; | ||
50 | delete rectangle; | ||
51 | delete faceDownDealingPile; | ||
52 | delete faceUpDealingPile; | ||
53 | } | ||
54 | |||
55 | |||
56 | void PatienceCardGame::deal(void) | ||
57 | { | ||
58 | highestZ = 1; | ||
59 | int t = 0; | ||
60 | |||
61 | beginDealing(); | ||
62 | |||
63 | for (int i = 0; i < 7; i++) { | ||
64 | cards[t]->setFace(TRUE); | ||
65 | for (int k = i; k < 7; k++, t++) { | ||
66 | Card *card = cards[t]; | ||
67 | workingPiles[k]->addCardToTop(card); | ||
68 | card->setCardPile( workingPiles[k] ); | ||
69 | QPoint p = workingPiles[k]->getCardPos( card ); | ||
70 | card->setPos( p.x(), p.y(), highestZ ); | ||
71 | card->showCard(); | ||
72 | highestZ++; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | for ( ; t < 52; t++) { | ||
77 | Card *card = cards[t]; | ||
78 | faceDownDealingPile->addCardToTop(card); | ||
79 | card->setCardPile( faceDownDealingPile ); | ||
80 | QPoint p = faceDownDealingPile->getCardPos( card ); | ||
81 | card->setPos( p.x(), p.y(), highestZ ); | ||
82 | card->showCard(); | ||
83 | highestZ++; | ||
84 | } | ||
85 | |||
86 | endDealing(); | ||
87 | } | ||
88 | |||
89 | |||
90 | void PatienceCardGame::readConfig( Config& cfg ) | ||
91 | { | ||
92 | cfg.setGroup("GameState"); | ||
93 | |||
94 | // Do we have a config file to read in? | ||
95 | if ( !cfg.hasKey("numberOfTimesThroughDeck") ) { | ||
96 | // if not, create a new game | ||
97 | newGame(); | ||
98 | return; | ||
99 | } | ||
100 | // We have a config file, lets read it in and use it | ||
101 | |||
102 | // Create Cards, but don't shuffle or deal them yet | ||
103 | createDeck(); | ||
104 | |||
105 | // How many times through the deck have we been | ||
106 | numberOfTimesThroughDeck = cfg.readNumEntry("NumberOfTimesThroughDeck"); | ||
107 | |||
108 | // restore state to the circle/cross under the dealing pile | ||
109 | if ( canTurnOverDeck() ) | ||
110 | circleCross->setCircle(); | ||
111 | else | ||
112 | circleCross->setCross(); | ||
113 | |||
114 | // Move the cards to their piles (deal them to their previous places) | ||
115 | beginDealing(); | ||
116 | |||
117 | highestZ = 1; | ||
118 | |||
119 | for (int k = 0; k < 7; k++) { | ||
120 | QString pile; | ||
121 | pile.sprintf( "WorkingPile%i", k ); | ||
122 | readPile( cfg, workingPiles[k], pile, highestZ ); | ||
123 | } | ||
124 | |||
125 | for (int k = 0; k < 4; k++) { | ||
126 | QString pile; | ||
127 | pile.sprintf( "DiscardPile%i", k ); | ||
128 | readPile( cfg, discardPiles[k], pile, highestZ ); | ||
129 | } | ||
130 | |||
131 | readPile( cfg, faceDownDealingPile, "FaceDownDealingPile", highestZ ); | ||
132 | readPile( cfg, faceUpDealingPile, "FaceUpDealingPile", highestZ ); | ||
133 | |||
134 | highestZ++; | ||
135 | |||
136 | endDealing(); | ||
137 | } | ||
138 | |||
139 | |||
140 | void PatienceCardGame::writeConfig( Config& cfg ) | ||
141 | { | ||
142 | cfg.setGroup("GameState"); | ||
143 | cfg.writeEntry("numberOfTimesThroughDeck", numberOfTimesThroughDeck); | ||
144 | |||
145 | for ( int i = 0; i < 7; i++ ) { | ||
146 | QString pile; | ||
147 | pile.sprintf( "WorkingPile%i", i ); | ||
148 | workingPiles[i]->writeConfig( cfg, pile ); | ||
149 | } | ||
150 | for ( int i = 0; i < 4; i++ ) { | ||
151 | QString pile; | ||
152 | pile.sprintf( "DiscardPile%i", i ); | ||
153 | discardPiles[i]->writeConfig( cfg, pile ); | ||
154 | } | ||
155 | faceDownDealingPile->writeConfig( cfg, "FaceDownDealingPile" ); | ||
156 | faceUpDealingPile->writeConfig( cfg, "FaceUpDealingPile" ); | ||
157 | } | ||
158 | |||
159 | |||
160 | bool PatienceCardGame::mousePressCard( Card *card, QPoint p ) | ||
161 | { | ||
162 | Q_UNUSED(p); | ||
163 | |||
164 | CanvasCard *item = (CanvasCard *)card; | ||
165 | if (item->isFacing() != TRUE) { | ||
166 | // From facedown stack | ||
167 | if ((item->x() == 5) && ((int)item->y() == 10)) { | ||
168 | item->setZ(highestZ); | ||
169 | highestZ++; | ||
170 | |||
171 | // Added Code | ||
172 | faceDownDealingPile->removeCard(item); | ||
173 | faceUpDealingPile->addCardToTop(item); | ||
174 | item->setCardPile( faceUpDealingPile ); | ||
175 | |||
176 | item->flipTo( 35, (int)item->y() ); | ||
177 | } | ||
178 | moving = NULL; | ||
179 | moved = FALSE; | ||
180 | |||
181 | // move two other cards if we flip three at a time | ||
182 | int flipped = 1; | ||
183 | QCanvasItemList l = canvas()->collisions( p ); | ||
184 | for (QCanvasItemList::Iterator it = l.begin(); (it != l.end()) && (flipped != cardsDrawn()); ++it) { | ||
185 | if ( (*it)->rtti() == canvasCardId ) { | ||
186 | CanvasCard *item = (CanvasCard *)*it; | ||
187 | if (item->animated()) | ||
188 | continue; | ||
189 | item->setZ(highestZ); | ||
190 | highestZ++; | ||
191 | flipped++; | ||
192 | |||
193 | // Added Code | ||
194 | faceDownDealingPile->removeCard(item); | ||
195 | faceUpDealingPile->addCardToTop(item); | ||
196 | item->setCardPile( faceUpDealingPile ); | ||
197 | |||
198 | item->flipTo( 35, (int)item->y(), 8 * flipped ); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | return TRUE; | ||
203 | } | ||
204 | |||
205 | return FALSE; | ||
206 | } | ||
207 | |||
208 | |||
209 | void PatienceCardGame::mousePress(QPoint p) | ||
210 | { | ||
211 | if ( canTurnOverDeck() && | ||
212 | (p.x() > 5) && (p.x() < 28) && | ||
213 | (p.y() > 10) && (p.y() < 46) ) { | ||
214 | |||
215 | beginDealing(); | ||
216 | Card *card = faceUpDealingPile->cardOnTop(); | ||
217 | while ( card ) { | ||
218 | card->setPos( 5, 10, highestZ ); | ||
219 | card->setFace( FALSE ); | ||
220 | faceUpDealingPile->removeCard( card ); | ||
221 | faceDownDealingPile->addCardToTop( card ); | ||
222 | card->setCardPile( faceDownDealingPile ); | ||
223 | card = faceUpDealingPile->cardOnTop(); | ||
224 | highestZ++; | ||
225 | } | ||
226 | endDealing(); | ||
227 | |||
228 | throughDeck(); | ||
229 | |||
230 | moved = TRUE; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | |||
diff --git a/noncore/games/solitaire/patiencecardgame.h b/noncore/games/solitaire/patiencecardgame.h new file mode 100644 index 0000000..c4f6c48 --- a/dev/null +++ b/noncore/games/solitaire/patiencecardgame.h | |||
@@ -0,0 +1,206 @@ | |||
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 PATIENCE_CARD_GAME_H | ||
21 | #define PATIENCE_CARD_GAME_H | ||
22 | |||
23 | |||
24 | #include <qpopupmenu.h> | ||
25 | #include <qmainwindow.h> | ||
26 | #include <qintdict.h> | ||
27 | #include <qcanvas.h> | ||
28 | // #include "canvascardshapes.h" | ||
29 | // #include "canvascard.h" | ||
30 | #include "canvascardgame.h" | ||
31 | |||
32 | |||
33 | class PatienceFaceDownDeck : public CardPile, public CanvasRoundRect | ||
34 | { | ||
35 | public: | ||
36 | PatienceFaceDownDeck(int x, int y, QCanvas *canvas) | ||
37 | : CardPile(x, y), CanvasRoundRect(x, y, canvas) { } | ||
38 | virtual bool isAllowedOnTop(Card *card) { | ||
39 | Q_UNUSED(card); | ||
40 | // Need to check it is from the faceUpDealingPile | ||
41 | return TRUE; | ||
42 | } | ||
43 | virtual bool isAllowedToBeMoved(Card *card) { | ||
44 | Q_UNUSED(card); | ||
45 | //if ( ( !card->isFacing() ) && ( card == cardOnTop() ) ) | ||
46 | if ( card == cardOnTop() ) | ||
47 | return TRUE; | ||
48 | return FALSE; | ||
49 | } | ||
50 | }; | ||
51 | |||
52 | |||
53 | class PatienceFaceUpDeck : public CardPile, public CanvasRoundRect | ||
54 | { | ||
55 | public: | ||
56 | PatienceFaceUpDeck(int x, int y, QCanvas *canvas) | ||
57 | : CardPile(x, y), CanvasRoundRect(x, y, canvas) { } | ||
58 | virtual bool isAllowedOnTop(Card *card) { | ||
59 | Q_UNUSED(card); | ||
60 | // Need to check it is from the faceDownDealingPile | ||
61 | return TRUE; | ||
62 | } | ||
63 | virtual bool isAllowedToBeMoved(Card *card) { | ||
64 | Q_UNUSED(card); | ||
65 | //if ( ( card->isFacing() ) && ( card == cardOnTop() ) ) | ||
66 | if ( card == cardOnTop() ) | ||
67 | return TRUE; | ||
68 | return FALSE; | ||
69 | } | ||
70 | }; | ||
71 | |||
72 | |||
73 | class PatienceDiscardPile : public CardPile, public CanvasRoundRect | ||
74 | { | ||
75 | public: | ||
76 | PatienceDiscardPile(int x, int y, QCanvas *canvas) | ||
77 | : CardPile(x, y), CanvasRoundRect(x, y, canvas) { } | ||
78 | virtual bool isAllowedOnTop(Card *card) { | ||
79 | if ( card->isFacing() && ( card->getCardPile()->cardInfront(card) == NULL ) && | ||
80 | ( ( ( cardOnTop() == NULL ) && ( card->getValue() == ace ) ) || | ||
81 | ( ( cardOnTop() != NULL ) && | ||
82 | ( (int)card->getValue() == (int)cardOnTop()->getValue() + 1 ) && | ||
83 | ( card->getSuit() == cardOnTop()->getSuit() ) ) ) ) | ||
84 | return TRUE; | ||
85 | return FALSE; | ||
86 | } | ||
87 | virtual bool isAllowedToBeMoved(Card *card) { | ||
88 | if ( card->isFacing() && ( card == cardOnTop() ) ) | ||
89 | return TRUE; | ||
90 | return FALSE; | ||
91 | } | ||
92 | }; | ||
93 | |||
94 | |||
95 | class PatienceWorkingPile : public CardPile, public CanvasRoundRect | ||
96 | { | ||
97 | public: | ||
98 | PatienceWorkingPile(int x, int y, QCanvas *canvas) | ||
99 | : CardPile(x, y), CanvasRoundRect(x, y, canvas), top(x, y) { } | ||
100 | virtual bool isAllowedOnTop(Card *card) { | ||
101 | if ( card->isFacing() && | ||
102 | ( ( ( cardOnTop() == NULL ) && (card->getValue() == king) ) || | ||
103 | ( ( cardOnTop() != NULL ) && | ||
104 | ( (int)card->getValue() + 1 == (int)cardOnTop()->getValue() ) && | ||
105 | ( card->isRed() != cardOnTop()->isRed() ) ) ) ) | ||
106 | return TRUE; | ||
107 | return FALSE; | ||
108 | } | ||
109 | virtual bool isAllowedToBeMoved(Card *card) { | ||
110 | if ( card->isFacing() ) | ||
111 | return TRUE; | ||
112 | return FALSE; | ||
113 | } | ||
114 | virtual void cardAddedToTop(Card *card) { | ||
115 | Q_UNUSED(card); | ||
116 | top = getCardPos(NULL); | ||
117 | setNextX( top.x() ); | ||
118 | setNextY( top.y() ); | ||
119 | } | ||
120 | virtual void cardRemoved(Card *card) { | ||
121 | Q_UNUSED(card); | ||
122 | |||
123 | Card *newTopCard = cardOnTop(); | ||
124 | |||
125 | if ( !newTopCard ) { | ||
126 | top = QPoint( pileX, pileY ); | ||
127 | setNextX( pileX ); | ||
128 | setNextY( pileY ); | ||
129 | return; | ||
130 | } else { | ||
131 | top = getCardPos(NULL); | ||
132 | if ( newTopCard->isFacing() == FALSE ) { | ||
133 | // correct the position taking in to account the card is not | ||
134 | // yet flipped, but will become flipped | ||
135 | top = QPoint( top.x() - 1, top.y() - 3 ); | ||
136 | newTopCard->flipTo( top.x(), top.y() ); | ||
137 | top = QPoint( top.x(), top.y() + 13 ); | ||
138 | } | ||
139 | setNextX( top.x() ); | ||
140 | setNextY( top.y() ); | ||
141 | } | ||
142 | } | ||
143 | virtual QPoint getCardPos(Card *c) { | ||
144 | int x = pileX, y = pileY; | ||
145 | Card *card = cardOnBottom(); | ||
146 | while ((card != c) && (card != NULL)) { | ||
147 | if (card->isFacing()) { | ||
148 | y += 13; | ||
149 | } else { | ||
150 | x += 1; | ||
151 | y += 3; | ||
152 | } | ||
153 | card = cardInfront(card); | ||
154 | } | ||
155 | return QPoint( x, y ); | ||
156 | } | ||
157 | virtual QPoint getHypertheticalNextCardPos(void) { | ||
158 | return top; | ||
159 | // return QPoint( getNextX(), getNextY() ); | ||
160 | } | ||
161 | private: | ||
162 | QPoint top; | ||
163 | |||
164 | }; | ||
165 | |||
166 | |||
167 | class PatienceCardGame : public CanvasCardGame | ||
168 | { | ||
169 | public: | ||
170 | PatienceCardGame(QCanvas *c, bool snap, QWidget *parent = 0); | ||
171 | virtual ~PatienceCardGame(); | ||
172 | virtual void deal(void); | ||
173 | virtual bool haveWeWon() { | ||
174 | return ( discardPiles[0]->kingOnTop() && | ||
175 | discardPiles[1]->kingOnTop() && | ||
176 | discardPiles[2]->kingOnTop() && | ||
177 | discardPiles[3]->kingOnTop() );; | ||
178 | } | ||
179 | virtual void mousePress(QPoint p); | ||
180 | virtual void mouseRelease(QPoint p) { Q_UNUSED(p); } | ||
181 | // virtual void mouseMove(QPoint p); | ||
182 | virtual bool mousePressCard(Card *card, QPoint p); | ||
183 | virtual void mouseReleaseCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } | ||
184 | // virtual void mouseMoveCard(Card *card, QPoint p) { Q_UNUSED(card); Q_UNUSED(p); } | ||
185 | bool canTurnOverDeck(void) { return (numberOfTimesThroughDeck != 3); } | ||
186 | void throughDeck(void) { | ||
187 | numberOfTimesThroughDeck++; | ||
188 | if (numberOfTimesThroughDeck == 3) | ||
189 | circleCross->setCross(); | ||
190 | } | ||
191 | bool snapOn; | ||
192 | virtual void writeConfig( Config& cfg ); | ||
193 | virtual void readConfig( Config& cfg ); | ||
194 | private: | ||
195 | CanvasCircleOrCross *circleCross; | ||
196 | CanvasRoundRect *rectangle; | ||
197 | PatienceWorkingPile *workingPiles[7]; | ||
198 | PatienceDiscardPile *discardPiles[4]; | ||
199 | PatienceFaceDownDeck *faceDownDealingPile; | ||
200 | PatienceFaceUpDeck *faceUpDealingPile; | ||
201 | int numberOfTimesThroughDeck; | ||
202 | }; | ||
203 | |||
204 | |||
205 | #endif | ||
206 | |||
diff --git a/noncore/games/solitaire/qpe-solitaire.control b/noncore/games/solitaire/qpe-solitaire.control new file mode 100644 index 0000000..71abb0c --- a/dev/null +++ b/noncore/games/solitaire/qpe-solitaire.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/patience apps/Games/patience.desktop pics/cards | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: Game: solitaire card games | ||
9 | A solitaire game for the Qtopia environment. | ||
diff --git a/noncore/games/solitaire/solitaire.pro b/noncore/games/solitaire/solitaire.pro new file mode 100755 index 0000000..8617cab --- a/dev/null +++ b/noncore/games/solitaire/solitaire.pro | |||
@@ -0,0 +1,18 @@ | |||
1 | TEMPLATE= app | ||
2 | |||
3 | CONFIG += qt warn_on release | ||
4 | DESTDIR = $(QPEDIR)/bin | ||
5 | |||
6 | HEADERS = canvascard.h canvasshapes.h cardgame.h cardgamelayout.h cardpile.h card.h carddeck.h canvascardgame.h freecellcardgame.h patiencecardgame.h canvascardwindow.h | ||
7 | |||
8 | SOURCES = canvascard.cpp canvasshapes.cpp cardgame.cpp cardgamelayout.cpp cardpile.cpp card.cpp carddeck.cpp canvascardgame.cpp freecellcardgame.cpp patiencecardgame.cpp canvascardwindow.cpp main.cpp | ||
9 | |||
10 | TARGET = patience | ||
11 | |||
12 | INCLUDEPATH += $(QPEDIR)/include | ||
13 | DEPENDPATH+= $(QPEDIR)/include | ||
14 | LIBS += -lqpe | ||
15 | |||
16 | REQUIRES= patience | ||
17 | |||
18 | TRANSLATIONS = ../i18n/de/patience.ts | ||
diff --git a/noncore/games/tetrix/.cvsignore b/noncore/games/tetrix/.cvsignore new file mode 100644 index 0000000..edfa921 --- a/dev/null +++ b/noncore/games/tetrix/.cvsignore | |||
@@ -0,0 +1,3 @@ | |||
1 | moc_* | ||
2 | *.moc | ||
3 | Makefile | ||
diff --git a/noncore/games/tetrix/Makefile.in b/noncore/games/tetrix/Makefile.in new file mode 100644 index 0000000..3a74fdc --- a/dev/null +++ b/noncore/games/tetrix/Makefile.in | |||
@@ -0,0 +1,157 @@ | |||
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 | |||
17 | DESTDIR = ../bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= tetrix | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =minefield.h \ | ||
27 | gtetrix.h \ | ||
28 | qtetrix.h \ | ||
29 | qtetrixb.h \ | ||
30 | tpiece.h | ||
31 | SOURCES =main.cpp \ | ||
32 | gtetrix.cpp \ | ||
33 | qtetrix.cpp \ | ||
34 | qtetrixb.cpp \ | ||
35 | tpiece.cpp | ||
36 | OBJECTS =main.o \ | ||
37 | gtetrix.o \ | ||
38 | qtetrix.o \ | ||
39 | qtetrixb.o \ | ||
40 | tpiece.o | ||
41 | INTERFACES = | ||
42 | UICDECLS = | ||
43 | UICIMPLS = | ||
44 | SRCMOC =moc_qtetrix.cpp \ | ||
45 | moc_qtetrixb.cpp | ||
46 | OBJMOC =moc_qtetrix.o \ | ||
47 | moc_qtetrixb.o | ||
48 | |||
49 | |||
50 | ####### Implicit rules | ||
51 | |||
52 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
53 | |||
54 | .cpp.o: | ||
55 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
56 | |||
57 | .cxx.o: | ||
58 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
59 | |||
60 | .cc.o: | ||
61 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
62 | |||
63 | .C.o: | ||
64 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
65 | |||
66 | .c.o: | ||
67 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
68 | |||
69 | ####### Build rules | ||
70 | |||
71 | |||
72 | all: $(DESTDIR)$(TARGET) | ||
73 | |||
74 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
75 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
76 | |||
77 | moc: $(SRCMOC) | ||
78 | |||
79 | tmake: | ||
80 | tmake tetrix.pro | ||
81 | |||
82 | clean: | ||
83 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
84 | -rm -f *~ core | ||
85 | -rm -f allmoc.cpp | ||
86 | |||
87 | ####### Extension Modules | ||
88 | |||
89 | listpromodules: | ||
90 | @echo | ||
91 | |||
92 | listallmodules: | ||
93 | @echo | ||
94 | |||
95 | listaddonpromodules: | ||
96 | @echo | ||
97 | |||
98 | listaddonentmodules: | ||
99 | @echo | ||
100 | |||
101 | |||
102 | REQUIRES= | ||
103 | |||
104 | ####### Sub-libraries | ||
105 | |||
106 | |||
107 | ###### Combined headers | ||
108 | |||
109 | |||
110 | |||
111 | ####### Compile | ||
112 | |||
113 | main.o: main.cpp \ | ||
114 | qtetrix.h \ | ||
115 | qtetrixb.h \ | ||
116 | gtetrix.h \ | ||
117 | tpiece.h \ | ||
118 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
119 | |||
120 | gtetrix.o: gtetrix.cpp \ | ||
121 | gtetrix.h \ | ||
122 | tpiece.h | ||
123 | |||
124 | qtetrix.o: qtetrix.cpp \ | ||
125 | qtetrix.h \ | ||
126 | qtetrixb.h \ | ||
127 | gtetrix.h \ | ||
128 | tpiece.h \ | ||
129 | $(QPEDIR)/include/qpe/resource.h | ||
130 | |||
131 | qtetrixb.o: qtetrixb.cpp \ | ||
132 | qtetrixb.h \ | ||
133 | gtetrix.h \ | ||
134 | tpiece.h \ | ||
135 | qtetrix.h | ||
136 | |||
137 | tpiece.o: tpiece.cpp \ | ||
138 | tpiece.h | ||
139 | |||
140 | moc_qtetrix.o: moc_qtetrix.cpp \ | ||
141 | qtetrix.h \ | ||
142 | qtetrixb.h \ | ||
143 | gtetrix.h \ | ||
144 | tpiece.h | ||
145 | |||
146 | moc_qtetrixb.o: moc_qtetrixb.cpp \ | ||
147 | qtetrixb.h \ | ||
148 | gtetrix.h \ | ||
149 | tpiece.h | ||
150 | |||
151 | moc_qtetrix.cpp: qtetrix.h | ||
152 | $(MOC) qtetrix.h -o moc_qtetrix.cpp | ||
153 | |||
154 | moc_qtetrixb.cpp: qtetrixb.h | ||
155 | $(MOC) qtetrixb.h -o moc_qtetrixb.cpp | ||
156 | |||
157 | |||
diff --git a/noncore/games/tetrix/gtetrix.cpp b/noncore/games/tetrix/gtetrix.cpp new file mode 100644 index 0000000..d1f38b1 --- a/dev/null +++ b/noncore/games/tetrix/gtetrix.cpp | |||
@@ -0,0 +1,514 @@ | |||
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 "gtetrix.h" | ||
23 | |||
24 | #include <string.h> | ||
25 | |||
26 | GenericTetrix::GenericTetrix(int boardWidth,int boardHeight) | ||
27 | { | ||
28 | int i,j; | ||
29 | |||
30 | width = boardWidth; | ||
31 | height = boardHeight; | ||
32 | boardPtr = new int[height*width]; // Note the order, this makes it easier | ||
33 | // to remove full lines. | ||
34 | for(i = 0 ; i < height ; i++) | ||
35 | for(j = 0 ; j < width ; j++) | ||
36 | board(j,i) = 0; | ||
37 | currentLine = -1; // -1 if no falling piece. | ||
38 | currentPos = 0; | ||
39 | showNext = 0; // FALSE | ||
40 | nLinesRemoved = 0; | ||
41 | nPiecesDropped = 0; | ||
42 | score = 0; | ||
43 | level = 1; | ||
44 | gameID = 0; | ||
45 | nClearLines = height; | ||
46 | } | ||
47 | |||
48 | GenericTetrix::~GenericTetrix() | ||
49 | { | ||
50 | delete[] boardPtr; | ||
51 | } | ||
52 | |||
53 | |||
54 | void GenericTetrix::clearBoard(int fillRandomLines) | ||
55 | { | ||
56 | int i,j; | ||
57 | |||
58 | if (fillRandomLines >= height) | ||
59 | fillRandomLines = height - 1; | ||
60 | |||
61 | erasePiece(); | ||
62 | for(i = height - nClearLines - 1 ; i >= fillRandomLines ; i--) | ||
63 | for(j = 0 ; j < width ; j++) | ||
64 | if (board(j,i) != 0) { | ||
65 | draw(j,i,0); | ||
66 | board(j,i) = 0; | ||
67 | } | ||
68 | if (fillRandomLines != 0) | ||
69 | for (i = 0 ; i < fillRandomLines ; i++) { | ||
70 | fillRandom(i); | ||
71 | } | ||
72 | nClearLines = height - fillRandomLines; | ||
73 | } | ||
74 | |||
75 | void GenericTetrix::showBoard() | ||
76 | { | ||
77 | int i,j; | ||
78 | |||
79 | showPiece(); | ||
80 | for(i = height - nClearLines - 1 ; i >= 0 ; i--) | ||
81 | for(j = 0 ; j < width ; j++) | ||
82 | if (board(j,i) != 0) | ||
83 | draw(j,i,board(j,i)); | ||
84 | } | ||
85 | |||
86 | void GenericTetrix::hideBoard() | ||
87 | { | ||
88 | int i,j; | ||
89 | |||
90 | erasePiece(); | ||
91 | for(i = height - nClearLines - 1 ; i >= 0 ; i--) | ||
92 | for(j = 0 ; j < width ; j++) | ||
93 | if (board(j,i) != 0) | ||
94 | draw(j,i,0); | ||
95 | } | ||
96 | |||
97 | void GenericTetrix::startGame(int gameType,int fillRandomLines) | ||
98 | { | ||
99 | gameID = gameType; | ||
100 | clearBoard(fillRandomLines); | ||
101 | nLinesRemoved = 0; | ||
102 | updateRemoved(nLinesRemoved); | ||
103 | nClearLines = height; | ||
104 | nPiecesDropped = 0; | ||
105 | score = 0; | ||
106 | updateScore(score); | ||
107 | level = 1; | ||
108 | updateLevel(level); | ||
109 | newPiece(); | ||
110 | } | ||
111 | |||
112 | void GenericTetrix::revealNextPiece(int revealIt) | ||
113 | { | ||
114 | if (showNext == revealIt) | ||
115 | return; | ||
116 | showNext = revealIt; | ||
117 | if (!showNext) | ||
118 | eraseNextPiece(); | ||
119 | else | ||
120 | showNextPiece(); | ||
121 | } | ||
122 | |||
123 | void GenericTetrix::updateBoard(int x1,int y1,int x2, int y2, | ||
124 | int dontUpdateBlanks) | ||
125 | { | ||
126 | int i,j; | ||
127 | int tmp; | ||
128 | |||
129 | if (x1 > x2) { | ||
130 | tmp = x2; | ||
131 | x2 = x1; | ||
132 | x1 = tmp; | ||
133 | } | ||
134 | if (y1 > y2) { | ||
135 | tmp = y2; | ||
136 | y2 = y1; | ||
137 | y1 = tmp; | ||
138 | } | ||
139 | if (x1 < 0) | ||
140 | x1 = 0; | ||
141 | if (x2 >= width) | ||
142 | x2 = width - 1; | ||
143 | if (y1 < 0) | ||
144 | y1 = 0; | ||
145 | if (y2 >= height) | ||
146 | y2 = height - 1; | ||
147 | for(i = y1 ; i <= y2 ; i++) | ||
148 | for(j = x1 ; j <= x2 ; j++) | ||
149 | if (!dontUpdateBlanks || board(j,height - i - 1) != 0) | ||
150 | draw(j,height - i - 1,board(j,height - i - 1)); | ||
151 | showPiece(); // Remember to update piece correctly!!!! | ||
152 | } | ||
153 | |||
154 | |||
155 | void GenericTetrix::fillRandom(int line) | ||
156 | { | ||
157 | int i,j; | ||
158 | int holes; | ||
159 | |||
160 | for(i = 0 ; i < width ; i++) | ||
161 | board(i,line) = TetrixPiece::randomValue(7); | ||
162 | holes = 0; | ||
163 | for(i = 0 ; i < width ; i++) | ||
164 | if (board(i,line) == 0) // Count holes in the line. | ||
165 | holes++; | ||
166 | if (holes == 0) // Full line, make a random hole: | ||
167 | board(TetrixPiece::randomValue(width),line) = 0; | ||
168 | if (holes == width) // Empty line, make a random square: | ||
169 | board(TetrixPiece::randomValue(width),line) = | ||
170 | TetrixPiece::randomValue(6) + 1; | ||
171 | for(j = 0 ; j < width ; j++) | ||
172 | draw(j,i,board(j,i)); | ||
173 | } | ||
174 | |||
175 | void GenericTetrix::moveLeft(int steps) | ||
176 | { | ||
177 | while(steps) { | ||
178 | if (!canMoveTo(currentPos - 1,currentLine)) | ||
179 | return; | ||
180 | moveTo(currentPos - 1,currentLine); | ||
181 | steps--; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | void GenericTetrix::moveRight(int steps) | ||
186 | { | ||
187 | while(steps) { | ||
188 | if (!canMoveTo(currentPos + 1,currentLine)) | ||
189 | return; | ||
190 | moveTo(currentPos + 1,currentLine); | ||
191 | steps--; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | void GenericTetrix::rotateLeft() | ||
196 | { | ||
197 | TetrixPiece tmp(currentPiece); | ||
198 | |||
199 | tmp.rotateLeft(); | ||
200 | if (!canPosition(tmp)) | ||
201 | return; | ||
202 | position(tmp); | ||
203 | currentPiece = tmp; | ||
204 | } | ||
205 | |||
206 | void GenericTetrix::rotateRight() | ||
207 | { | ||
208 | TetrixPiece tmp(currentPiece); | ||
209 | |||
210 | tmp.rotateRight(); | ||
211 | if (!canPosition(tmp)) | ||
212 | return; | ||
213 | position(tmp); | ||
214 | currentPiece = tmp; | ||
215 | } | ||
216 | |||
217 | void GenericTetrix::dropDown() | ||
218 | { | ||
219 | if (currentLine == -1) | ||
220 | return; | ||
221 | |||
222 | int dropHeight = 0; | ||
223 | int newLine = currentLine; | ||
224 | while(newLine) { | ||
225 | if (!canMoveTo(currentPos,newLine - 1)) | ||
226 | break; | ||
227 | newLine--; | ||
228 | dropHeight++; | ||
229 | } | ||
230 | if (dropHeight != 0) | ||
231 | moveTo(currentPos,newLine); | ||
232 | internalPieceDropped(dropHeight); | ||
233 | } | ||
234 | |||
235 | void GenericTetrix::oneLineDown() | ||
236 | { | ||
237 | if (currentLine == -1) | ||
238 | return; | ||
239 | if (canMoveTo(currentPos,currentLine - 1)) { | ||
240 | moveTo(currentPos,currentLine - 1); | ||
241 | } else { | ||
242 | internalPieceDropped(0); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | void GenericTetrix::newPiece() | ||
247 | { | ||
248 | currentPiece = nextPiece; | ||
249 | if (showNext) | ||
250 | eraseNextPiece(); | ||
251 | nextPiece.setRandomType(); | ||
252 | if (showNext) | ||
253 | showNextPiece(); | ||
254 | currentLine = height - 1 + currentPiece.getMinY(); | ||
255 | currentPos = width/2 + 1; | ||
256 | if (!canMoveTo(currentPos,currentLine)) { | ||
257 | currentLine = -1; | ||
258 | gameOver(); | ||
259 | } else { | ||
260 | showPiece(); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | void GenericTetrix::removePiece() | ||
265 | { | ||
266 | erasePiece(); | ||
267 | currentLine = -1; | ||
268 | } | ||
269 | |||
270 | void GenericTetrix::drawNextSquare(int,int,int) | ||
271 | { | ||
272 | |||
273 | } | ||
274 | |||
275 | void GenericTetrix::pieceDropped(int) | ||
276 | { | ||
277 | newPiece(); | ||
278 | } | ||
279 | |||
280 | void GenericTetrix::updateRemoved(int) | ||
281 | { | ||
282 | } | ||
283 | |||
284 | void GenericTetrix::updateScore(int) | ||
285 | { | ||
286 | } | ||
287 | |||
288 | void GenericTetrix::updateLevel(int) | ||
289 | { | ||
290 | } | ||
291 | |||
292 | void GenericTetrix::removeFullLines() | ||
293 | { | ||
294 | int i,j,k; | ||
295 | int nFullLines; | ||
296 | |||
297 | for(i = 0 ; i < height - nClearLines ; i++) { | ||
298 | for(j = 0 ; j < width ; j++) | ||
299 | if (board(j,i) == 0) | ||
300 | break; | ||
301 | if (j == width) { | ||
302 | nFullLines = 1; | ||
303 | for(k = i + 1 ; k < height - nClearLines ; k++) { | ||
304 | for(j = 0 ; j < width ; j++) | ||
305 | if (board(j,k) == 0) | ||
306 | break; | ||
307 | if (j == width) { | ||
308 | nFullLines++; | ||
309 | } else { | ||
310 | for(j = 0 ; j < width ; j++) { | ||
311 | if (board(j,k - nFullLines) != board(j,k)) { | ||
312 | board(j,k - nFullLines) = board(j,k); | ||
313 | draw( j,k - nFullLines, | ||
314 | board(j,k - nFullLines)); | ||
315 | } | ||
316 | } | ||
317 | } | ||
318 | } | ||
319 | nClearLines = nClearLines + nFullLines; | ||
320 | nLinesRemoved = nLinesRemoved + nFullLines; | ||
321 | updateRemoved(nLinesRemoved); | ||
322 | score = score + 10*nFullLines; // updateScore must be | ||
323 | // called by caller! | ||
324 | for (i = height - nClearLines ; | ||
325 | i < height - nClearLines + nFullLines ; | ||
326 | i++) | ||
327 | for(j = 0 ; j < width ; j++) | ||
328 | if (board(j,i) != 0) { | ||
329 | draw(j,i,0); | ||
330 | board(j,i) = 0; | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | } | ||
335 | |||
336 | void GenericTetrix::showPiece() | ||
337 | { | ||
338 | int x,y; | ||
339 | |||
340 | if (currentLine == -1) | ||
341 | return; | ||
342 | |||
343 | for(int i = 0 ; i < 4 ; i++) { | ||
344 | currentPiece.getCoord(i,x,y); | ||
345 | draw(currentPos + x,currentLine - y,currentPiece.getType()); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | void GenericTetrix::erasePiece() | ||
350 | { | ||
351 | int x,y; | ||
352 | |||
353 | if (currentLine == -1) | ||
354 | return; | ||
355 | |||
356 | for(int i = 0 ; i < 4 ; i++) { | ||
357 | currentPiece.getCoord(i,x,y); | ||
358 | draw(currentPos + x,currentLine - y,0); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | void GenericTetrix::internalPieceDropped(int dropHeight) | ||
363 | { | ||
364 | gluePiece(); | ||
365 | nPiecesDropped++; | ||
366 | if (nPiecesDropped % 25 == 0) { | ||
367 | level++; | ||
368 | updateLevel(level); | ||
369 | } | ||
370 | score = score + 7 + dropHeight; | ||
371 | removeFullLines(); | ||
372 | updateScore(score); | ||
373 | pieceDropped(dropHeight); | ||
374 | } | ||
375 | |||
376 | void GenericTetrix::gluePiece() | ||
377 | { | ||
378 | int x,y; | ||
379 | int min; | ||
380 | |||
381 | if (currentLine == -1) | ||
382 | return; | ||
383 | |||
384 | for(int i = 0 ; i < 4 ; i++) { | ||
385 | currentPiece.getCoord(i,x,y); | ||
386 | board(currentPos + x,currentLine - y) = currentPiece.getType(); | ||
387 | } | ||
388 | min = currentPiece.getMinY(); | ||
389 | if (currentLine - min >= height - nClearLines) | ||
390 | nClearLines = height - currentLine + min - 1; | ||
391 | } | ||
392 | |||
393 | void GenericTetrix::showNextPiece(int erase) | ||
394 | { | ||
395 | int x,y; | ||
396 | int minX = nextPiece.getMinX(); | ||
397 | int minY = nextPiece.getMinY(); | ||
398 | int maxX = nextPiece.getMaxX(); | ||
399 | int maxY = nextPiece.getMaxY(); | ||
400 | |||
401 | int xOffset = (3 - (maxX - minX))/2; | ||
402 | int yOffset = (3 - (maxY - minY))/2; | ||
403 | |||
404 | for(int i = 0 ; i < 4 ; i++) { | ||
405 | nextPiece.getCoord(i,x,y); | ||
406 | if (erase) | ||
407 | drawNextSquare(x + xOffset - minX, | ||
408 | y + yOffset - minY,0); | ||
409 | else | ||
410 | drawNextSquare(x + xOffset - minX, | ||
411 | y + yOffset - minY,nextPiece.getType()); | ||
412 | } | ||
413 | } | ||
414 | |||
415 | int GenericTetrix::canPosition(TetrixPiece &piece) | ||
416 | { | ||
417 | if (currentLine == -1) | ||
418 | return 0; | ||
419 | |||
420 | int x,y; | ||
421 | |||
422 | for(int i = 0 ; i < 4 ; i++) { | ||
423 | piece.getCoord(i,x,y); | ||
424 | x = currentPos + x; | ||
425 | y = currentLine - y; // Board and pieces have inverted y-coord. systems. | ||
426 | if (x < 0 || x >= width || y < 0 || y >= height) | ||
427 | return 0; // Outside board, cannot put piece here. | ||
428 | if (board(x,y) != 0) | ||
429 | return 0; // Over a non-zero square, cannot put piece here. | ||
430 | } | ||
431 | return 1; // Inside board and no non-zero squares underneath. | ||
432 | |||
433 | } | ||
434 | |||
435 | int GenericTetrix::canMoveTo(int xPosition,int line) | ||
436 | { | ||
437 | if (currentLine == -1) | ||
438 | return 0; | ||
439 | |||
440 | int x,y; | ||
441 | |||
442 | for(int i = 0 ; i < 4 ; i++) { | ||
443 | currentPiece.getCoord(i,x,y); | ||
444 | x = xPosition + x; | ||
445 | y = line - y; // Board and pieces have inverted y-coord. systems. | ||
446 | if (x < 0 || x >= width || y < 0 || y >= height) | ||
447 | return 0; // Outside board, cannot put piece here. | ||
448 | if (board(x,y) != 0) | ||
449 | return 0; // Over a non-zero square, cannot put piece here. | ||
450 | } | ||
451 | return 1; // Inside board and no non-zero squares underneath. | ||
452 | } | ||
453 | |||
454 | void GenericTetrix::moveTo(int xPosition,int line) | ||
455 | { | ||
456 | if (currentLine == -1) | ||
457 | return; | ||
458 | optimizedMove(xPosition,line,currentPiece); | ||
459 | currentPos = xPosition; | ||
460 | currentLine = line; | ||
461 | } | ||
462 | |||
463 | void GenericTetrix::position(TetrixPiece &piece) | ||
464 | { | ||
465 | if (currentLine == -1) | ||
466 | return; | ||
467 | |||
468 | optimizedMove(currentPos,currentLine,piece); | ||
469 | } | ||
470 | |||
471 | void GenericTetrix::optimizedMove(int newPos, int newLine, | ||
472 | TetrixPiece &newPiece) | ||
473 | { | ||
474 | int updates [8][3]; | ||
475 | int nUpdates; | ||
476 | int value; | ||
477 | int x,y; | ||
478 | int i,j; | ||
479 | |||
480 | for(i = 0 ; i < 4 ; i++) { // Put the erasing coords into updates | ||
481 | currentPiece.getCoord(i,x,y); | ||
482 | updates[i][0] = currentPos + x; | ||
483 | updates[i][1] = currentLine - y; | ||
484 | updates[i][2] = 0; | ||
485 | } | ||
486 | nUpdates = 4; | ||
487 | for(i = 0 ; i < 4 ; i++) { // Any drawing coord same as an erasing one? | ||
488 | newPiece.getCoord(i,x,y); | ||
489 | x = newPos + x; | ||
490 | y = newLine - y; | ||
491 | for (j = 0 ; j < 4 ; j++) | ||
492 | if (updates[j][0] == x && updates[j][1] == y) { // Same coord, | ||
493 | // don't have to erase | ||
494 | if (currentPiece.getType() == newPiece.getType()) | ||
495 | updates[j][2] = -1; // Correct on screen, no update! | ||
496 | else | ||
497 | updates[j][2] = newPiece.getType(); | ||
498 | break; | ||
499 | } | ||
500 | if (j == 4) { // This coord does not overlap an erasing one | ||
501 | updates[nUpdates][0] = x; | ||
502 | updates[nUpdates][1] = y; | ||
503 | updates[nUpdates][2] = newPiece.getType(); | ||
504 | nUpdates++; | ||
505 | } | ||
506 | } | ||
507 | for (i = 0 ; i < nUpdates ; i++) { // Do the updating | ||
508 | x = updates[i][0]; | ||
509 | y = updates[i][1]; | ||
510 | value = updates[i][2]; | ||
511 | if (value != -1) // Only update if new value != current | ||
512 | draw(x,y,value); | ||
513 | } | ||
514 | } | ||
diff --git a/noncore/games/tetrix/gtetrix.h b/noncore/games/tetrix/gtetrix.h new file mode 100644 index 0000000..520dd89 --- a/dev/null +++ b/noncore/games/tetrix/gtetrix.h | |||
@@ -0,0 +1,104 @@ | |||
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 | #ifndef GTETRIX_H | ||
23 | #define GTETRIX_H | ||
24 | |||
25 | #include "tpiece.h" | ||
26 | |||
27 | |||
28 | class GenericTetrix | ||
29 | { | ||
30 | public: | ||
31 | GenericTetrix(int boardWidth = 10,int boardHeight = 22); | ||
32 | virtual ~GenericTetrix(); | ||
33 | |||
34 | void clearBoard(int fillRandomLines = 0); | ||
35 | void revealNextPiece(int revealIt); | ||
36 | void updateBoard(int x1,int y1,int x2,int y2,int dontUpdateBlanks = 0); | ||
37 | void updateNext(){if (showNext) showNextPiece();} | ||
38 | void hideBoard(); | ||
39 | void showBoard(); | ||
40 | void fillRandom(int line); | ||
41 | |||
42 | void moveLeft(int steps = 1); | ||
43 | void moveRight(int steps = 1); | ||
44 | void rotateLeft(); | ||
45 | void rotateRight(); | ||
46 | void dropDown(); | ||
47 | void oneLineDown(); | ||
48 | void newPiece(); | ||
49 | void removePiece(); | ||
50 | |||
51 | int noOfClearLines() {return nClearLines;} | ||
52 | int getLinesRemoved() {return nLinesRemoved;} | ||
53 | int getPiecesDropped() {return nPiecesDropped;} | ||
54 | int getScore() {return score;} | ||
55 | int getLevel() {return level;} | ||
56 | int boardHeight() {return height;} | ||
57 | int boardWidth() {return width;} | ||
58 | |||
59 | virtual void drawSquare(int x,int y,int value) = 0; | ||
60 | virtual void gameOver() = 0; | ||
61 | |||
62 | virtual void startGame(int gameType = 0,int fillRandomLines = 0); | ||
63 | virtual void drawNextSquare(int x,int y,int value); | ||
64 | virtual void pieceDropped(int dropHeight); | ||
65 | virtual void updateRemoved(int noOfLines); | ||
66 | virtual void updateScore(int newScore); | ||
67 | virtual void updateLevel(int newLevel); | ||
68 | |||
69 | private: | ||
70 | void draw(int x, int y, int value){drawSquare(x,height - y,value);} | ||
71 | void removeFullLines(); | ||
72 | void removeLine(int line); | ||
73 | void showPiece(); | ||
74 | void erasePiece(); | ||
75 | void internalPieceDropped(int dropHeight); | ||
76 | void gluePiece(); | ||
77 | void showNextPiece(int erase = 0); | ||
78 | void eraseNextPiece(){showNextPiece(1);}; | ||
79 | int canPosition(TetrixPiece &piece); // Returns a boolean value. | ||
80 | int canMoveTo(int xPosition, int line); // Returns a boolean value. | ||
81 | void moveTo(int xPosition,int line); | ||
82 | void position(TetrixPiece &piece); | ||
83 | void optimizedMove(int newPos, int newLine,TetrixPiece &newPiece); | ||
84 | |||
85 | int &board(int x,int y){return boardPtr[width*y + x];} | ||
86 | |||
87 | TetrixPiece currentPiece; | ||
88 | TetrixPiece nextPiece; | ||
89 | int currentLine; | ||
90 | int currentPos; | ||
91 | int showNext; // Boolean variable. | ||
92 | int nLinesRemoved; | ||
93 | int nPiecesDropped; | ||
94 | int score; | ||
95 | int level; | ||
96 | int gameID; | ||
97 | int nClearLines; | ||
98 | int width; | ||
99 | int height; | ||
100 | int *boardPtr; | ||
101 | }; | ||
102 | |||
103 | |||
104 | #endif | ||
diff --git a/noncore/games/tetrix/main.cpp b/noncore/games/tetrix/main.cpp new file mode 100644 index 0000000..e36d52d --- a/dev/null +++ b/noncore/games/tetrix/main.cpp | |||
@@ -0,0 +1,33 @@ | |||
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 "qtetrix.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | int main( int argc, char **argv ) | ||
26 | { | ||
27 | QPEApplication a(argc,argv); | ||
28 | |||
29 | QTetrix *tetrix = new QTetrix; | ||
30 | a.showMainWidget(tetrix); | ||
31 | |||
32 | return a.exec(); | ||
33 | } | ||
diff --git a/noncore/games/tetrix/qpe-tetrix.control b/noncore/games/tetrix/qpe-tetrix.control new file mode 100644 index 0000000..46dfdf5 --- a/dev/null +++ b/noncore/games/tetrix/qpe-tetrix.control | |||
@@ -0,0 +1,10 @@ | |||
1 | Files: bin/tetrix apps/Games/tetrix.desktop | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Arch: iPAQ | ||
7 | Version: $QPE_VERSION-3 | ||
8 | Depends: qpe-base ($QPE_VERSION) | ||
9 | Description: Game: control falling blocks | ||
10 | A game for the Qtopia environment. | ||
diff --git a/noncore/games/tetrix/qtetrix.cpp b/noncore/games/tetrix/qtetrix.cpp new file mode 100644 index 0000000..f649894 --- a/dev/null +++ b/noncore/games/tetrix/qtetrix.cpp | |||
@@ -0,0 +1,170 @@ | |||
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 "qtetrix.h" | ||
23 | |||
24 | #include <qpe/resource.h> | ||
25 | |||
26 | #include <qapplication.h> | ||
27 | #include <qlabel.h> | ||
28 | #include <qdatetime.h> | ||
29 | #include <qlayout.h> | ||
30 | |||
31 | |||
32 | |||
33 | void drawTetrixButton( QPainter *p, int x, int y, int w, int h, | ||
34 | const QColor *color ) | ||
35 | { | ||
36 | QColor fc; | ||
37 | if ( color ) { | ||
38 | QPointArray a; | ||
39 | a.setPoints( 3, x,y+h-1, x,y, x+w-1,y ); | ||
40 | p->setPen( color->light() ); | ||
41 | p->drawPolyline( a ); | ||
42 | a.setPoints( 3, x+1,y+h-1, x+w-1,y+h-1, x+w-1,y+1 ); | ||
43 | p->setPen( color->dark() ); | ||
44 | p->drawPolyline( a ); | ||
45 | x++; | ||
46 | y++; | ||
47 | w -= 2; | ||
48 | h -= 2; | ||
49 | fc = *color; | ||
50 | } | ||
51 | else | ||
52 | fc = p->backgroundColor(); | ||
53 | p->fillRect( x, y, w, h, fc ); | ||
54 | } | ||
55 | |||
56 | |||
57 | ShowNextPiece::ShowNextPiece( QWidget *parent, const char *name ) | ||
58 | : QFrame( parent, name ) | ||
59 | { | ||
60 | setFrameStyle( QFrame::Panel | QFrame::Sunken ); | ||
61 | xOffset = -1; // -1 until first resizeEvent. | ||
62 | } | ||
63 | |||
64 | void ShowNextPiece::resizeEvent( QResizeEvent *e ) | ||
65 | { | ||
66 | QSize sz = e->size(); | ||
67 | blockWidth = (sz.width() - 3)/5; | ||
68 | blockHeight = (sz.height() - 3)/6; | ||
69 | xOffset = (sz.width() - 3)/5; | ||
70 | yOffset = (sz.height() - 3)/6; | ||
71 | } | ||
72 | |||
73 | |||
74 | void ShowNextPiece::paintEvent( QPaintEvent * ) | ||
75 | { | ||
76 | QPainter p( this ); | ||
77 | drawFrame( &p ); | ||
78 | p.end(); // explicit end() so any slots can paint too | ||
79 | emit update(); | ||
80 | } | ||
81 | |||
82 | |||
83 | void ShowNextPiece::drawNextSquare(int x, int y,QColor *color) | ||
84 | { | ||
85 | if (xOffset == -1) // Before first resizeEvent? | ||
86 | return; | ||
87 | |||
88 | QPainter paint; | ||
89 | paint.begin(this); | ||
90 | drawTetrixButton( &paint, xOffset+x*blockWidth, yOffset+y*blockHeight, | ||
91 | blockWidth, blockHeight, color ); | ||
92 | paint.end(); | ||
93 | } | ||
94 | |||
95 | |||
96 | QTetrix::QTetrix( QWidget *parent, const char *name, WFlags f ) | ||
97 | : QMainWindow( parent, name, f ) | ||
98 | { | ||
99 | setIcon( Resource::loadPixmap( "tetrix_icon" ) ); | ||
100 | setCaption( tr("Tetrix" ) ); | ||
101 | |||
102 | QTime t = QTime::currentTime(); | ||
103 | TetrixPiece::setRandomSeed( (((double)t.hour())+t.minute()+t.second())/ | ||
104 | (24+60+60) ); | ||
105 | |||
106 | QWidget *gameArea = new QWidget( this ); | ||
107 | setCentralWidget( gameArea ); | ||
108 | |||
109 | QGridLayout *gl = new QGridLayout( gameArea, 5, 3, 8 ); | ||
110 | |||
111 | QLabel *l; | ||
112 | l = new QLabel( tr("Next"), gameArea ); | ||
113 | gl->addWidget( l, 0, 0 ); | ||
114 | showNext = new ShowNextPiece(gameArea); | ||
115 | showNext->setBackgroundColor(QColor(0,0,0)); | ||
116 | gl->addWidget( showNext, 0, 1 ); | ||
117 | |||
118 | l = new QLabel( tr("Score"), gameArea ); | ||
119 | gl->addWidget( l, 1, 0 ); | ||
120 | showScore = new QLabel(gameArea); | ||
121 | gl->addWidget( showScore, 1, 1 ); | ||
122 | l = new QLabel( tr("Level"), gameArea ); | ||
123 | gl->addWidget( l, 2, 0 ); | ||
124 | showLevel = new QLabel(gameArea); | ||
125 | gl->addWidget( showLevel, 2, 1 ); | ||
126 | l = new QLabel( tr("Removed"), gameArea ); | ||
127 | gl->addWidget( l, 3, 0 ); | ||
128 | showLines = new QLabel(gameArea); | ||
129 | gl->addWidget( showLines, 3, 1 ); | ||
130 | |||
131 | board = new QTetrixBoard(gameArea); | ||
132 | board->setBackgroundColor(QColor(0,0,0)); | ||
133 | board->setFixedWidth( 124 ); | ||
134 | gl->addMultiCellWidget( board, 0, 4, 2, 2 ); | ||
135 | gl->addColSpacing( 2, 100 ); | ||
136 | gl->addColSpacing( 1, 35 ); | ||
137 | gl->addRowSpacing( 0, 35 ); | ||
138 | |||
139 | QPushButton *pb = new QPushButton( tr("Start"), gameArea ); | ||
140 | pb->setFocusPolicy( NoFocus ); | ||
141 | connect( pb, SIGNAL( clicked() ), board, SLOT( start() ) ); | ||
142 | gl->addMultiCellWidget( pb, 4, 4, 0, 1 ); | ||
143 | |||
144 | connect( board, SIGNAL(gameOverSignal()), SLOT(gameOver()) ); | ||
145 | connect( board, SIGNAL(drawNextSquareSignal(int,int,QColor*)), showNext, | ||
146 | SLOT(drawNextSquare(int,int,QColor*)) ); | ||
147 | connect( showNext, SIGNAL(update()), board, SLOT(updateNext()) ); | ||
148 | connect( board, SIGNAL(updateScoreSignal(int)), showScore, | ||
149 | SLOT(setNum(int)) ); | ||
150 | connect( board, SIGNAL(updateLevelSignal(int)), showLevel, | ||
151 | SLOT(setNum(int))); | ||
152 | connect( board, SIGNAL(updateRemovedSignal(int)), showLines, | ||
153 | SLOT(setNum(int))); | ||
154 | |||
155 | showScore->setNum( 0 ); | ||
156 | showLevel->setNum( 0 ); | ||
157 | showLines->setNum( 0 ); | ||
158 | board->revealNextPiece(TRUE); | ||
159 | board->setFocusPolicy( StrongFocus ); | ||
160 | } | ||
161 | |||
162 | void QTetrix::gameOver() | ||
163 | { | ||
164 | } | ||
165 | |||
166 | |||
167 | void QTetrix::quit() | ||
168 | { | ||
169 | close(); | ||
170 | } | ||
diff --git a/noncore/games/tetrix/qtetrix.h b/noncore/games/tetrix/qtetrix.h new file mode 100644 index 0000000..b6e058a --- a/dev/null +++ b/noncore/games/tetrix/qtetrix.h | |||
@@ -0,0 +1,78 @@ | |||
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 | #ifndef QTETRIX_H | ||
23 | #define QTETRIX_H | ||
24 | |||
25 | #include "qtetrixb.h" | ||
26 | #include <qframe.h> | ||
27 | #include <qlcdnumber.h> | ||
28 | #include <qpushbutton.h> | ||
29 | #include <qpainter.h> | ||
30 | #include <qmainwindow.h> | ||
31 | |||
32 | class QLabel; | ||
33 | |||
34 | class ShowNextPiece : public QFrame | ||
35 | { | ||
36 | Q_OBJECT | ||
37 | friend class QTetrix; | ||
38 | public: | ||
39 | ShowNextPiece( QWidget *parent=0, const char *name=0 ); | ||
40 | public slots: | ||
41 | void drawNextSquare( int x, int y,QColor *color ); | ||
42 | signals: | ||
43 | void update(); | ||
44 | private: | ||
45 | void paintEvent( QPaintEvent * ); | ||
46 | void resizeEvent( QResizeEvent * ); | ||
47 | |||
48 | int blockWidth,blockHeight; | ||
49 | int xOffset,yOffset; | ||
50 | }; | ||
51 | |||
52 | |||
53 | class QTetrix : public QMainWindow | ||
54 | { | ||
55 | Q_OBJECT | ||
56 | public: | ||
57 | QTetrix( QWidget *parent=0, const char *name=0, WFlags f=0 ); | ||
58 | void startGame() { board->startGame(); } | ||
59 | |||
60 | public slots: | ||
61 | void gameOver(); | ||
62 | void quit(); | ||
63 | private: | ||
64 | void keyPressEvent( QKeyEvent *e ) { board->keyPressEvent(e); } | ||
65 | |||
66 | QTetrixBoard *board; | ||
67 | ShowNextPiece *showNext; | ||
68 | QLabel *showScore; | ||
69 | QLabel *showLevel; | ||
70 | QLabel *showLines; | ||
71 | }; | ||
72 | |||
73 | |||
74 | void drawTetrixButton( QPainter *, int x, int y, int w, int h, | ||
75 | const QColor *color ); | ||
76 | |||
77 | |||
78 | #endif | ||
diff --git a/noncore/games/tetrix/qtetrixb.cpp b/noncore/games/tetrix/qtetrixb.cpp new file mode 100644 index 0000000..521f171 --- a/dev/null +++ b/noncore/games/tetrix/qtetrixb.cpp | |||
@@ -0,0 +1,251 @@ | |||
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 "qtetrixb.h" | ||
23 | #include "qtetrix.h" | ||
24 | #include <qtimer.h> | ||
25 | #include <qkeycode.h> | ||
26 | #include <qpainter.h> | ||
27 | |||
28 | const int waitAfterLineTime = 500; | ||
29 | |||
30 | QTetrixBoard::QTetrixBoard( QWidget *p, const char *name ) | ||
31 | : QFrame( p, name ) | ||
32 | { | ||
33 | setFrameStyle( QFrame::Panel | QFrame::Sunken ); | ||
34 | paint = 0; | ||
35 | timer = new QTimer(this); | ||
36 | connect( timer, SIGNAL(timeout()), SLOT(timeout()) ); | ||
37 | |||
38 | colors[0].setRgb(200,100,100); | ||
39 | colors[1].setRgb(100,200,100); | ||
40 | colors[2].setRgb(100,100,200); | ||
41 | colors[3].setRgb(200,200,100); | ||
42 | colors[4].setRgb(200,100,200); | ||
43 | colors[5].setRgb(100,200,200); | ||
44 | colors[6].setRgb(218,170, 0); | ||
45 | |||
46 | xOffset = -1; // -1 until a resizeEvent is received. | ||
47 | blockWidth = 20; | ||
48 | yOffset = 30; | ||
49 | blockHeight = 20; | ||
50 | noGame = TRUE; | ||
51 | isPaused = FALSE; | ||
52 | waitingAfterLine = FALSE; | ||
53 | updateTimeoutTime(); // Sets timeoutTime | ||
54 | } | ||
55 | |||
56 | void QTetrixBoard::startGame(int gameType,int fillRandomLines) | ||
57 | { | ||
58 | if ( isPaused ) | ||
59 | return; // ignore if game is paused | ||
60 | noGame = FALSE; | ||
61 | GenericTetrix::startGame( gameType, fillRandomLines ); | ||
62 | // Note that the timer is started by updateLevel! | ||
63 | } | ||
64 | |||
65 | |||
66 | void QTetrixBoard::pause() | ||
67 | { | ||
68 | if ( noGame ) // game not active | ||
69 | return; | ||
70 | isPaused = !isPaused; | ||
71 | if ( isPaused ) { | ||
72 | timer->stop(); | ||
73 | hideBoard(); | ||
74 | } | ||
75 | else | ||
76 | timer->start(timeoutTime); | ||
77 | update(); | ||
78 | } | ||
79 | |||
80 | |||
81 | void QTetrixBoard::drawSquare(int x,int y,int value) | ||
82 | { | ||
83 | if (xOffset == -1) // Before first resizeEvent? | ||
84 | return; | ||
85 | |||
86 | const int X = xOffset + x*blockWidth; | ||
87 | const int Y = yOffset + (y - 1)*blockHeight; | ||
88 | |||
89 | bool localPainter = paint == 0; | ||
90 | QPainter *p; | ||
91 | if ( localPainter ) | ||
92 | p = new QPainter( this ); | ||
93 | else | ||
94 | p = paint; | ||
95 | drawTetrixButton( p, X, Y, blockWidth, blockHeight, | ||
96 | value == 0 ? 0 : &colors[value-1] ); | ||
97 | /* | ||
98 | if ( value != 0 ) { | ||
99 | QColor tc, bc; | ||
100 | tc = colors[value-1].light(); | ||
101 | bc = colors[value-1].dark(); | ||
102 | p->drawShadePanel( X, Y, blockWidth, blockHeight, | ||
103 | tc, bc, 1, colors[value-1], TRUE ); | ||
104 | } | ||
105 | else | ||
106 | p->fillRect( X, Y, blockWidth, blockHeight, backgroundColor() ); | ||
107 | */ | ||
108 | if ( localPainter ) | ||
109 | delete p; | ||
110 | } | ||
111 | |||
112 | void QTetrixBoard::drawNextSquare( int x, int y, int value ) | ||
113 | { | ||
114 | if ( value == 0 ) | ||
115 | emit drawNextSquareSignal (x, y, 0 ); | ||
116 | else | ||
117 | emit drawNextSquareSignal( x, y, &colors[value-1] ); | ||
118 | } | ||
119 | |||
120 | void QTetrixBoard::updateRemoved( int noOfLines ) | ||
121 | { | ||
122 | if ( noOfLines > 0 ) { | ||
123 | timer->stop(); | ||
124 | timer->start( waitAfterLineTime ); | ||
125 | waitingAfterLine = TRUE; | ||
126 | } | ||
127 | emit updateRemovedSignal( noOfLines ); | ||
128 | } | ||
129 | |||
130 | void QTetrixBoard::updateScore( int newScore ) | ||
131 | { | ||
132 | emit updateScoreSignal( newScore ); | ||
133 | } | ||
134 | |||
135 | void QTetrixBoard::updateLevel( int newLevel ) | ||
136 | { | ||
137 | timer->stop(); | ||
138 | updateTimeoutTime(); | ||
139 | timer->start( timeoutTime ); | ||
140 | emit updateLevelSignal( newLevel ); | ||
141 | } | ||
142 | |||
143 | void QTetrixBoard::pieceDropped(int) | ||
144 | { | ||
145 | if ( waitingAfterLine ) // give player a break if a line has been removed | ||
146 | return; | ||
147 | newPiece(); | ||
148 | } | ||
149 | |||
150 | void QTetrixBoard::gameOver() | ||
151 | { | ||
152 | timer->stop(); | ||
153 | noGame = TRUE; | ||
154 | emit gameOverSignal(); | ||
155 | } | ||
156 | |||
157 | void QTetrixBoard::timeout() | ||
158 | { | ||
159 | if ( waitingAfterLine ) { | ||
160 | timer->stop(); | ||
161 | waitingAfterLine = FALSE; | ||
162 | newPiece(); | ||
163 | timer->start( timeoutTime ); | ||
164 | } else { | ||
165 | oneLineDown(); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | void QTetrixBoard::drawContents( QPainter *p ) | ||
170 | { | ||
171 | const char *text = "Press \"Pause\""; | ||
172 | QRect r = contentsRect(); | ||
173 | paint = p; // set widget painter | ||
174 | if ( isPaused ) { | ||
175 | p->drawText( r, AlignCenter | AlignVCenter, text ); | ||
176 | return; | ||
177 | } | ||
178 | int x1,y1,x2,y2; | ||
179 | x1 = (r.left() - xOffset) / blockWidth; | ||
180 | if (x1 < 0) | ||
181 | x1 = 0; | ||
182 | if (x1 >= boardWidth()) | ||
183 | x1 = boardWidth() - 1; | ||
184 | |||
185 | x2 = (r.right() - xOffset) / blockWidth; | ||
186 | if (x2 < 0) | ||
187 | x2 = 0; | ||
188 | if (x2 >= boardWidth()) | ||
189 | x2 = boardWidth() - 1; | ||
190 | |||
191 | y1 = (r.top() - yOffset) / blockHeight; | ||
192 | if (y1 < 0) | ||
193 | y1 = 0; | ||
194 | if (y1 >= boardHeight()) | ||
195 | y1 = boardHeight() - 1; | ||
196 | |||
197 | y2 = (r.bottom() - yOffset) / blockHeight; | ||
198 | if (y2 < 0) | ||
199 | y2 = 0; | ||
200 | if (y2 >= boardHeight()) | ||
201 | y2 = boardHeight() - 1; | ||
202 | |||
203 | updateBoard( x1, y1, x2, y2, TRUE ); | ||
204 | paint = 0; // reset widget painter | ||
205 | return; | ||
206 | } | ||
207 | |||
208 | void QTetrixBoard::resizeEvent(QResizeEvent *e) | ||
209 | { | ||
210 | QSize sz = e->size(); | ||
211 | blockWidth = (sz.width() - 2)/10; | ||
212 | blockHeight = (sz.height() - 2)/22; | ||
213 | xOffset = 1; | ||
214 | //yOffset = 1; | ||
215 | yOffset = (sz.height() - 2) - (blockHeight *22); | ||
216 | } | ||
217 | |||
218 | void QTetrixBoard::keyPressEvent( QKeyEvent *e ) | ||
219 | { | ||
220 | if ( noGame || isPaused || waitingAfterLine ) | ||
221 | return; | ||
222 | switch( e->key() ) { | ||
223 | case Key_Left : | ||
224 | moveLeft(); | ||
225 | break; | ||
226 | case Key_Right : | ||
227 | moveRight(); | ||
228 | break; | ||
229 | case Key_Down : | ||
230 | // rotateRight(); | ||
231 | dropDown(); | ||
232 | break; | ||
233 | case Key_Up : | ||
234 | rotateLeft(); | ||
235 | break; | ||
236 | case Key_Space : | ||
237 | dropDown(); | ||
238 | break; | ||
239 | case Key_D : | ||
240 | oneLineDown(); | ||
241 | break; | ||
242 | default: | ||
243 | return; | ||
244 | } | ||
245 | e->accept(); | ||
246 | } | ||
247 | |||
248 | void QTetrixBoard::updateTimeoutTime() | ||
249 | { | ||
250 | timeoutTime = 1000/(1 + getLevel()); | ||
251 | } | ||
diff --git a/noncore/games/tetrix/qtetrixb.h b/noncore/games/tetrix/qtetrixb.h new file mode 100644 index 0000000..4134a84 --- a/dev/null +++ b/noncore/games/tetrix/qtetrixb.h | |||
@@ -0,0 +1,80 @@ | |||
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 | #ifndef QTETRIXB_H | ||
23 | #define QTETRIXB_H | ||
24 | |||
25 | #include "gtetrix.h" | ||
26 | #include <qframe.h> | ||
27 | |||
28 | class QTimer; | ||
29 | |||
30 | class QTetrixBoard : public QFrame, public GenericTetrix | ||
31 | { | ||
32 | Q_OBJECT | ||
33 | public: | ||
34 | QTetrixBoard( QWidget *parent=0, const char *name=0 ); | ||
35 | |||
36 | void gameOver(); | ||
37 | void startGame(int gameType = 0,int fillRandomLines = 0); | ||
38 | |||
39 | public slots: | ||
40 | void timeout(); | ||
41 | void updateNext(){ GenericTetrix::updateNext(); } | ||
42 | void key(QKeyEvent *e) { keyPressEvent(e); } | ||
43 | void start() { startGame(); } | ||
44 | void pause(); | ||
45 | |||
46 | signals: | ||
47 | void gameOverSignal(); | ||
48 | void drawNextSquareSignal(int x,int y,QColor *color1); | ||
49 | void updateRemovedSignal(int noOfLines); | ||
50 | void updateScoreSignal(int score); | ||
51 | void updateLevelSignal(int level); | ||
52 | |||
53 | public: // until we have keyboard focus, should be protected | ||
54 | void keyPressEvent( QKeyEvent * ); | ||
55 | |||
56 | private: | ||
57 | void drawContents( QPainter * ); | ||
58 | void resizeEvent( QResizeEvent * ); | ||
59 | void drawSquare(int x,int y,int value); | ||
60 | void drawNextSquare(int x,int y,int value); | ||
61 | void updateRemoved(int noOfLines); | ||
62 | void updateScore(int newScore); | ||
63 | void updateLevel(int newLlevel); | ||
64 | void pieceDropped(int dropHeight); | ||
65 | void updateTimeoutTime(); | ||
66 | |||
67 | QTimer *timer; | ||
68 | |||
69 | int xOffset,yOffset; | ||
70 | int blockWidth,blockHeight; | ||
71 | int timeoutTime; | ||
72 | bool noGame; | ||
73 | bool isPaused; | ||
74 | bool waitingAfterLine; | ||
75 | |||
76 | QColor colors[7]; | ||
77 | QPainter *paint; | ||
78 | }; | ||
79 | |||
80 | #endif | ||
diff --git a/noncore/games/tetrix/tetrix.pro b/noncore/games/tetrix/tetrix.pro new file mode 100644 index 0000000..1160585 --- a/dev/null +++ b/noncore/games/tetrix/tetrix.pro | |||
@@ -0,0 +1,17 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG = qt warn_on release | ||
3 | DESTDIR = ../bin | ||
4 | HEADERS = minefield.h \ | ||
5 | gtetrix.h \ | ||
6 | qtetrix.h \ | ||
7 | qtetrixb.h \ | ||
8 | tpiece.h | ||
9 | SOURCES = main.cpp \ | ||
10 | gtetrix.cpp \ | ||
11 | qtetrix.cpp \ | ||
12 | qtetrixb.cpp \ | ||
13 | tpiece.cpp | ||
14 | INCLUDEPATH += $(QPEDIR)/include | ||
15 | DEPENDPATH+= $(QPEDIR)/include | ||
16 | LIBS += -lqpe | ||
17 | INTERFACES= | ||
diff --git a/noncore/games/tetrix/tpiece.cpp b/noncore/games/tetrix/tpiece.cpp new file mode 100644 index 0000000..fe8b766 --- a/dev/null +++ b/noncore/games/tetrix/tpiece.cpp | |||
@@ -0,0 +1,201 @@ | |||
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 "tpiece.h" | ||
23 | #include "qstring.h" | ||
24 | #include <stdlib.h> | ||
25 | #include <time.h> | ||
26 | |||
27 | void TetrixPiece::rotateLeft() | ||
28 | { | ||
29 | if ( pieceType == 5 ) // don't rotate square piece type | ||
30 | return; | ||
31 | int tmp; | ||
32 | for (int i = 0 ; i < 4 ; i++) { | ||
33 | tmp = getXCoord(i); | ||
34 | setXCoord(i,getYCoord(i)); | ||
35 | setYCoord(i,-tmp); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | void TetrixPiece::rotateRight() | ||
40 | { | ||
41 | if ( pieceType == 5 ) // don't rotate square piece type | ||
42 | return; | ||
43 | int tmp; | ||
44 | for (int i = 0 ; i < 4 ; i++) { | ||
45 | tmp = getXCoord(i); | ||
46 | setXCoord(i,-getYCoord(i)); | ||
47 | setYCoord(i,tmp); | ||
48 | } | ||
49 | } | ||
50 | |||
51 | int TetrixPiece::getMinX() | ||
52 | { | ||
53 | int tmp = coordinates[0][0]; | ||
54 | for(int i = 1 ; i < 4 ; i++) | ||
55 | if (tmp > coordinates[i][0]) | ||
56 | tmp = coordinates[i][0]; | ||
57 | return tmp; | ||
58 | } | ||
59 | |||
60 | int TetrixPiece::getMaxX() | ||
61 | { | ||
62 | int tmp = coordinates[0][0]; | ||
63 | for(int i = 1 ; i < 4 ; i++) | ||
64 | if (tmp < coordinates[i][0]) | ||
65 | tmp = coordinates[i][0]; | ||
66 | return tmp; | ||
67 | |||
68 | } | ||
69 | |||
70 | int TetrixPiece::getMinY() | ||
71 | { | ||
72 | int tmp = coordinates[0][1]; | ||
73 | for(int i = 1 ; i < 4 ; i++) | ||
74 | if (tmp > coordinates[i][1]) | ||
75 | tmp = coordinates[i][1]; | ||
76 | return tmp; | ||
77 | } | ||
78 | |||
79 | int TetrixPiece::getMaxY() | ||
80 | { | ||
81 | int tmp = coordinates[0][1]; | ||
82 | for(int i = 1 ; i < 4 ; i++) | ||
83 | if (tmp < coordinates[i][1]) | ||
84 | tmp = coordinates[i][1]; | ||
85 | return tmp; | ||
86 | } | ||
87 | |||
88 | void TetrixPiece::initialize(int type) | ||
89 | { | ||
90 | static int pieceTypes[7][4][2] = {{{ 0,-1}, | ||
91 | { 0, 0}, | ||
92 | {-1, 0}, | ||
93 | {-1, 1}}, | ||
94 | |||
95 | {{ 0,-1}, | ||
96 | { 0, 0}, | ||
97 | { 1, 0}, | ||
98 | { 1, 1}}, | ||
99 | |||
100 | {{ 0,-1}, | ||
101 | { 0, 0}, | ||
102 | { 0, 1}, | ||
103 | { 0, 2}}, | ||
104 | |||
105 | {{-1, 0}, | ||
106 | { 0, 0}, | ||
107 | { 1, 0}, | ||
108 | { 0, 1}}, | ||
109 | |||
110 | {{ 0, 0}, | ||
111 | { 1, 0}, | ||
112 | { 0, 1}, | ||
113 | { 1, 1}}, | ||
114 | |||
115 | {{-1,-1}, | ||
116 | { 0,-1}, | ||
117 | { 0, 0}, | ||
118 | { 0, 1}}, | ||
119 | |||
120 | {{ 1,-1}, | ||
121 | { 0,-1}, | ||
122 | { 0, 0}, | ||
123 | { 0, 1}}}; | ||
124 | if (type < 1 || type > 7) | ||
125 | type = 1; | ||
126 | pieceType = type; | ||
127 | for(int i = 0 ; i < 4 ; i++) { | ||
128 | coordinates[i][0] = pieceTypes[type - 1][i][0]; | ||
129 | coordinates[i][1] = pieceTypes[type - 1][i][1]; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | |||
134 | /* | ||
135 | *Sigh, oh beautiful nostalgia! This random algorithm has | ||
136 | *been taken from the book "Adventures with your pocket calculator" | ||
137 | *and I used it in my first implemented and machine- | ||
138 | *run program of any size to speak of. Imagine how hungry I | ||
139 | *was after having programmed BASIC on paper for | ||
140 | *half a year?!!?!?!?!?!? The first program I typed in was a | ||
141 | *slot machine game and was made in BASIC on a SHARP | ||
142 | *PC-1211 with 1,47 KB RAM (one point four seven kilobytes) and | ||
143 | *a one-line LCD-display (I think it had 32 characters) in the | ||
144 | *year of our lord 1981. The man I had bought the machine from worked | ||
145 | *as a COBOL programmer and was amazed and impressed | ||
146 | *when I demonstrated the program 2 days after I had | ||
147 | *bought the machine, quote: "Gees, I have been looking so long | ||
148 | *for a "random" command in that BASIC, what is it called?" | ||
149 | *Oh, how I still get a thrill out of the thought of the | ||
150 | *explanation I then gave him... | ||
151 | */ | ||
152 | |||
153 | /* | ||
154 | *Sukk, aa vakre nostalgi! Denne random algoritmen er | ||
155 | *tatt fra boka "Adventures with your pocket calculator" | ||
156 | *og den brukte jeg i mitt foerste implementerte og maskin- | ||
157 | *kjoerte program av nevneverdig stoerrelse. Tror du jeg var | ||
158 | *noe sulten etter aa ha programmert BASIC paa papir i et | ||
159 | *halvt aar?!!?!?!?!?!? Programmet jeg tasta inn foerst var et | ||
160 | *"enarmet banditt" spill og ble laget i BASIC paa en SHARP | ||
161 | *PC-1211 med 1,47 KB RAM (en komma foertisju kilobyte) og | ||
162 | *et en-linjers LCD-display (tror det hadde 32 karakterer) i det | ||
163 | *herrens aar 1981. Mannen jeg kjoepte maskinen av jobbet til | ||
164 | *daglig med COBOL programmering og var forbloeffet og imponert | ||
165 | *da jeg demonstrerte programmet 2 dager etter at jeg hadde | ||
166 | *kjoept maskinen, sitat: "Joess, jeg som har leita saa lenge | ||
167 | *etter en random kommando i den BASICen, hva var det den | ||
168 | *het?" Aa, jeg frydes ennaa ved tanken paa forklaringen jeg | ||
169 | *deretter ga ham... | ||
170 | */ | ||
171 | |||
172 | double TetrixPiece::randomSeed = 0.33333; | ||
173 | |||
174 | void TetrixPiece::setRandomSeed(double seed) | ||
175 | { | ||
176 | #ifdef __MIPSEL__ | ||
177 | srand( clock() ); | ||
178 | #else | ||
179 | QCString buffer; | ||
180 | if (seed < 0) | ||
181 | seed = - seed; | ||
182 | if (seed >= 1) | ||
183 | seed = seed - (double) ((int) seed); | ||
184 | buffer.sprintf("%1.5f",(float) seed); | ||
185 | for (int i = 0 ; i < 5 ; i++) | ||
186 | if ((buffer[i + 2] - '0') % 2 == 0) | ||
187 | buffer[i + 2]++; | ||
188 | randomSeed = atof(buffer); | ||
189 | #endif | ||
190 | } | ||
191 | |||
192 | int TetrixPiece::randomValue(int maxPlusOne) | ||
193 | { | ||
194 | #ifdef __MIPSEL__ | ||
195 | return rand() % maxPlusOne; | ||
196 | #else | ||
197 | randomSeed = randomSeed*147; | ||
198 | randomSeed = randomSeed - (double) ((int) randomSeed); | ||
199 | return (int) (randomSeed*maxPlusOne); | ||
200 | #endif | ||
201 | } | ||
diff --git a/noncore/games/tetrix/tpiece.h b/noncore/games/tetrix/tpiece.h new file mode 100644 index 0000000..9c1c629 --- a/dev/null +++ b/noncore/games/tetrix/tpiece.h | |||
@@ -0,0 +1,62 @@ | |||
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 | #ifndef TPIECE_H | ||
23 | #define TPIECE_H | ||
24 | |||
25 | class TetrixPiece | ||
26 | { | ||
27 | public: | ||
28 | TetrixPiece() {setRandomType();} | ||
29 | TetrixPiece(int type) {initialize(type % 7 + 1);} | ||
30 | |||
31 | void setRandomType() {initialize(randomValue(7) + 1);} | ||
32 | |||
33 | void rotateLeft(); | ||
34 | void rotateRight(); | ||
35 | |||
36 | int getType() {return pieceType;} | ||
37 | int getXCoord(int index) {return coordinates[index][0];} | ||
38 | int getYCoord(int index) {return coordinates[index][1];} | ||
39 | void getCoord(int index,int &x,int&y){x = coordinates[index][0]; | ||
40 | y = coordinates[index][1];} | ||
41 | int getMinX(); | ||
42 | int getMaxX(); | ||
43 | int getMinY(); | ||
44 | int getMaxY(); | ||
45 | |||
46 | static void setRandomSeed(double seed); | ||
47 | static int randomValue(int maxPlusOne); | ||
48 | |||
49 | private: | ||
50 | void setXCoord(int index,int value) {coordinates[index][0] = value;} | ||
51 | void setYCoord(int index,int value) {coordinates[index][1] = value;} | ||
52 | void setCoords(int index,int x,int y){coordinates[index][0] = x; | ||
53 | coordinates[index][1] = y;} | ||
54 | void initialize(int type); | ||
55 | |||
56 | int pieceType; | ||
57 | int coordinates[4][2]; | ||
58 | |||
59 | static double randomSeed; | ||
60 | }; | ||
61 | |||
62 | #endif | ||
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 @@ | |||
1 | moc_* | ||
2 | Makefile | ||
3 | newgamebase.h | ||
4 | rulesbase.h | ||
5 | newgamebase.cpp | ||
6 | rulesbase.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 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= wordgame | ||
22 | TARGET1 = 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 | ||
33 | INTERFACES = newgamebase.ui \ | ||
34 | rulesbase.ui | ||
35 | UICDECLS = newgamebase.h \ | ||
36 | rulesbase.h | ||
37 | UICIMPLS = 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 | |||
69 | all: $(DESTDIR)$(TARGET) | ||
70 | |||
71 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
72 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
73 | |||
74 | moc: $(SRCMOC) | ||
75 | |||
76 | tmake: | ||
77 | tmake wordgame.pro | ||
78 | |||
79 | clean: | ||
80 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
81 | -rm -f *~ core | ||
82 | -rm -f allmoc.cpp | ||
83 | |||
84 | ####### Extension Modules | ||
85 | |||
86 | listpromodules: | ||
87 | @echo | ||
88 | |||
89 | listallmodules: | ||
90 | @echo | ||
91 | |||
92 | listaddonpromodules: | ||
93 | @echo | ||
94 | |||
95 | listaddonentmodules: | ||
96 | @echo | ||
97 | |||
98 | |||
99 | REQUIRES= | ||
100 | |||
101 | ####### Sub-libraries | ||
102 | |||
103 | |||
104 | ###### Combined headers | ||
105 | |||
106 | |||
107 | |||
108 | ####### Compile | ||
109 | |||
110 | main.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 | |||
118 | wordgame.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 | |||
130 | newgamebase.h: newgamebase.ui | ||
131 | $(UIC) newgamebase.ui -o $(INTERFACE_DECL_PATH)/newgamebase.h | ||
132 | |||
133 | newgamebase.cpp: newgamebase.ui | ||
134 | $(UIC) newgamebase.ui -i newgamebase.h -o newgamebase.cpp | ||
135 | |||
136 | rulesbase.h: rulesbase.ui | ||
137 | $(UIC) rulesbase.ui -o $(INTERFACE_DECL_PATH)/rulesbase.h | ||
138 | |||
139 | rulesbase.cpp: rulesbase.ui | ||
140 | $(UIC) rulesbase.ui -i rulesbase.h -o rulesbase.cpp | ||
141 | |||
142 | newgamebase.o: newgamebase.cpp | ||
143 | |||
144 | rulesbase.o: rulesbase.cpp | ||
145 | |||
146 | moc_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 | |||
153 | moc_newgamebase.o: moc_newgamebase.cpp \ | ||
154 | newgamebase.h | ||
155 | |||
156 | moc_rulesbase.o: moc_rulesbase.cpp \ | ||
157 | rulesbase.h | ||
158 | |||
159 | moc_wordgame.cpp: wordgame.h | ||
160 | $(MOC) wordgame.h -o moc_wordgame.cpp | ||
161 | |||
162 | moc_newgamebase.cpp: newgamebase.h | ||
163 | $(MOC) newgamebase.h -o moc_newgamebase.cpp | ||
164 | |||
165 | moc_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 | |||
12 | while (<>) { | ||
13 | chomp; | ||
14 | for $c ( split "", $_ ) { | ||
15 | $freq{$c}++; | ||
16 | $t++; | ||
17 | } | ||
18 | } | ||
19 | |||
20 | for $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 | |||
25 | int 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>&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 @@ | |||
1 | Files: bin/wordgame apps/Games/wordgame.desktop | ||
2 | Priority: optional | ||
3 | Section: qpe/games | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: 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>&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>&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 | |||
56 | enum RuleEffects { | ||
57 | Multiplier=15, | ||
58 | MultiplyAll=64, | ||
59 | Start=128 | ||
60 | }; | ||
61 | |||
62 | static const int rack_tiles=7; | ||
63 | |||
64 | const 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 | |||
111 | WordGame::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 | |||
141 | WordGame::~WordGame() | ||
142 | { | ||
143 | writeConfig(); | ||
144 | } | ||
145 | |||
146 | void 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 | |||
164 | void 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 | |||
195 | void 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 | |||
226 | void 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 | |||
246 | void 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 | |||
265 | bool 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 | |||
327 | NewGame::NewGame(QWidget* parent) : | ||
328 | NewGameBase(parent) | ||
329 | { | ||
330 | } | ||
331 | |||
332 | void 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 | |||
367 | Rules::Rules(QWidget* parent) : | ||
368 | RulesBase(parent,0,TRUE) | ||
369 | { | ||
370 | } | ||
371 | |||
372 | void Rules::editRules() | ||
373 | { | ||
374 | if ( exec() ) { | ||
375 | // ### create a new set of rules | ||
376 | emit rulesChanged(); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | void Rules::deleteRuleSet() | ||
381 | { | ||
382 | // ### delete existing rule set | ||
383 | emit rulesChanged(); | ||
384 | } | ||
385 | |||
386 | void 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 | |||
395 | void 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 | |||
407 | void 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 | |||
418 | bool 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 | |||
436 | void 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 | |||
478 | void 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 | |||
495 | void WordGame::resetTurn() | ||
496 | { | ||
497 | board->resetRack(); | ||
498 | } | ||
499 | |||
500 | void WordGame::passTurn() | ||
501 | { | ||
502 | // ######## trade? | ||
503 | nextPlayer(); | ||
504 | } | ||
505 | |||
506 | bool 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 | |||
515 | void 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 | |||
530 | Rack* WordGame::rack(int i) const | ||
531 | { | ||
532 | return (Rack*)racks->widget(i); | ||
533 | } | ||
534 | |||
535 | void 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 | |||
548 | ComputerPlayer::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 | |||
557 | ComputerPlayer::~ComputerPlayer() | ||
558 | { | ||
559 | delete [] best; | ||
560 | delete [] best_blankvalues; | ||
561 | } | ||
562 | |||
563 | bool 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 | |||
605 | void ComputerPlayer::findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar* nletter, const Tile** tiles, int n, Tile* blankvalues, int blused) | ||
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 | |||
657 | void 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 | /* | ||
661 | if (s>0 || current==QPoint(5,1)){ | ||
662 | QString st; | ||
663 | for ( int i=0; i<n; i++ ) | ||
664 | st += tiles[i]->text(); | ||
665 | qDebug("%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 | |||
682 | int TileItem::smallWidth() | ||
683 | { | ||
684 | return 16; | ||
685 | } | ||
686 | |||
687 | int TileItem::smallHeight() | ||
688 | { | ||
689 | return 16; | ||
690 | } | ||
691 | |||
692 | int TileItem::bigWidth() | ||
693 | { | ||
694 | return 22; | ||
695 | } | ||
696 | |||
697 | int TileItem::bigHeight() | ||
698 | { | ||
699 | return 22; | ||
700 | } | ||
701 | |||
702 | void TileItem::setState( State state ) | ||
703 | { | ||
704 | hide(); | ||
705 | s = state; | ||
706 | show(); // ### use update() in Qt 3.0 | ||
707 | } | ||
708 | |||
709 | void TileItem::setTile(const Tile& tile) | ||
710 | { | ||
711 | hide(); | ||
712 | t = tile; | ||
713 | show(); // ### use update() in Qt 3.0 | ||
714 | } | ||
715 | |||
716 | void TileItem::setBig(bool b) | ||
717 | { | ||
718 | big = b; | ||
719 | } | ||
720 | |||
721 | void 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 | |||
749 | Board::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 | |||
762 | Board::~Board() | ||
763 | { | ||
764 | delete canvas(); | ||
765 | } | ||
766 | |||
767 | void 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 | |||
776 | void 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 | |||
792 | void 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 | |||
802 | void Board::setCurrentRack(Rack* r) | ||
803 | { | ||
804 | turn_score = -1; | ||
805 | current_rack = r; | ||
806 | } | ||
807 | |||
808 | void Board::resetRack() | ||
809 | { | ||
810 | unshowTurn(); | ||
811 | canvas()->update(); | ||
812 | } | ||
813 | |||
814 | void Board::contentsMousePressEvent(QMouseEvent* e) | ||
815 | { | ||
816 | dragstart = e->pos(); | ||
817 | } | ||
818 | |||
819 | void 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 | |||
860 | void 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 | |||
875 | void 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 | |||
888 | void 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 | |||
905 | int 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 | |||
918 | bool 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 | |||
925 | bool 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 ) { | ||
961 | retry: | ||
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 | |||
1006 | void 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 | |||
1021 | int 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 | |||
1117 | QPoint Board::boardPos(const QPoint& p) const | ||
1118 | { | ||
1119 | return QPoint(p.x()/canvas()->tileWidth(), p.y()/canvas()->tileHeight()); | ||
1120 | } | ||
1121 | |||
1122 | void Board::contentsMouseReleaseEvent(QMouseEvent*) | ||
1123 | { | ||
1124 | if ( current_rack ) { | ||
1125 | } | ||
1126 | } | ||
1127 | |||
1128 | |||
1129 | void 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 | |||
1144 | void Board::unsetTile(const QPoint& p) | ||
1145 | { | ||
1146 | delete item(p); | ||
1147 | grid[idx(p)] = 0; | ||
1148 | } | ||
1149 | |||
1150 | void 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 | |||
1162 | Rack::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 | |||
1178 | Rack::~Rack() | ||
1179 | { | ||
1180 | clear(); | ||
1181 | delete canvas(); | ||
1182 | } | ||
1183 | |||
1184 | void Rack::clear() | ||
1185 | { | ||
1186 | for (int i=0; i<n; i++) | ||
1187 | delete item[i]; | ||
1188 | n=0; | ||
1189 | } | ||
1190 | |||
1191 | void 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 | |||
1199 | void 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 | |||
1213 | static 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 | |||
1220 | void 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 | |||
1238 | void 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 | |||
1250 | bool 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 | |||
1272 | void 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 | |||
1280 | void 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 | |||
1289 | void 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 | |||
1298 | void Rack::resizeEvent(QResizeEvent* e) | ||
1299 | { | ||
1300 | canvas()->resize(width()-frameWidth()*2,height()-frameWidth()*2); | ||
1301 | QCanvasView::resizeEvent(e); | ||
1302 | } | ||
1303 | |||
1304 | void 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 | |||
1317 | void 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 | |||
1331 | void Rack::contentsMouseReleaseEvent(QMouseEvent* e) | ||
1332 | { | ||
1333 | if ( computerized() ) | ||
1334 | return; | ||
1335 | if ( dragging ) { | ||
1336 | dragging=0; | ||
1337 | layoutTiles(); | ||
1338 | } | ||
1339 | } | ||
1340 | |||
1341 | Tile::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 | |||
1349 | QString Tile::key() const | ||
1350 | { | ||
1351 | return txt+"@"+QString::number(val); | ||
1352 | } | ||
1353 | |||
1354 | Bag::Bag() | ||
1355 | { | ||
1356 | tiles.setAutoDelete(TRUE); | ||
1357 | } | ||
1358 | |||
1359 | void 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 | |||
1367 | void 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 | |||
1375 | void Bag::add(const Tile& t) | ||
1376 | { | ||
1377 | tiles.append(new Tile(t)); | ||
1378 | } | ||
1379 | |||
1380 | Tile Bag::takeRandom() | ||
1381 | { | ||
1382 | Tile* rp = tiles.take(random()%tiles.count()); | ||
1383 | Tile r=*rp; | ||
1384 | return r; | ||
1385 | } | ||
1386 | |||
1387 | ScoreInfo::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 | |||
1396 | ScoreInfo::~ScoreInfo() | ||
1397 | { | ||
1398 | if ( score ) delete [] score; | ||
1399 | } | ||
1400 | |||
1401 | void 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 | |||
1409 | void 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 | |||
1419 | QSize ScoreInfo::sizeHint() const | ||
1420 | { | ||
1421 | return QSize(QLabel::sizeHint().width(),fontMetrics().height()); | ||
1422 | } | ||
1423 | |||
1424 | void 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 | |||
1434 | void ScoreInfo::addScore(int player, int change) | ||
1435 | { | ||
1436 | score[player] += change; | ||
1437 | showScores(); | ||
1438 | } | ||
1439 | |||
1440 | void ScoreInfo::setBoldOne(int b) | ||
1441 | { | ||
1442 | boldone=b; | ||
1443 | showScores(); | ||
1444 | } | ||
1445 | |||
1446 | void 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 | |||
1468 | void 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 | |||
33 | class QVBox; | ||
34 | class QLabel; | ||
35 | class QWidgetStack; | ||
36 | class QToolButton; | ||
37 | class Config; | ||
38 | |||
39 | class Tile { | ||
40 | public: | ||
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 | |||
76 | private: | ||
77 | QString txt; | ||
78 | int val; | ||
79 | bool blank; | ||
80 | }; | ||
81 | |||
82 | class Bag { | ||
83 | public: | ||
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(); | ||
92 | private: | ||
93 | QList<Tile> tiles; | ||
94 | }; | ||
95 | |||
96 | class TileItem : public QCanvasRectangle { | ||
97 | public: | ||
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 | |||
118 | protected: | ||
119 | void drawShape(QPainter&); | ||
120 | |||
121 | private: | ||
122 | Tile t; | ||
123 | bool big; | ||
124 | State s; | ||
125 | }; | ||
126 | |||
127 | class Rack : public QCanvasView { | ||
128 | public: | ||
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 | |||
151 | protected: | ||
152 | void resizeEvent(QResizeEvent*e); | ||
153 | void contentsMousePressEvent(QMouseEvent*); | ||
154 | void contentsMouseMoveEvent(QMouseEvent*); | ||
155 | void contentsMouseReleaseEvent(QMouseEvent*); | ||
156 | |||
157 | private: | ||
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 | |||
169 | class Board : public QCanvasView { | ||
170 | Q_OBJECT | ||
171 | public: | ||
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 | |||
214 | signals: | ||
215 | void temporaryScore(int); | ||
216 | |||
217 | protected: | ||
218 | void contentsMousePressEvent(QMouseEvent*); | ||
219 | void contentsMouseMoveEvent(QMouseEvent*); | ||
220 | void contentsMouseReleaseEvent(QMouseEvent*); | ||
221 | |||
222 | private: | ||
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 | |||
241 | class 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 | |||
258 | public: | ||
259 | ComputerPlayer(Board* b, Rack* r); | ||
260 | ~ComputerPlayer(); | ||
261 | |||
262 | bool step(); | ||
263 | |||
264 | private: | ||
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 | |||
269 | class ScoreInfo : public QLabel { | ||
270 | Q_OBJECT | ||
271 | public: | ||
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 | |||
284 | protected: | ||
285 | QSize sizeHint() const; | ||
286 | |||
287 | public slots: | ||
288 | void showTemporaryScore(int amount); | ||
289 | |||
290 | private slots: | ||
291 | void showScores(); | ||
292 | |||
293 | private: | ||
294 | QStringList names; | ||
295 | int *score; | ||
296 | QTimer* msgtimer; | ||
297 | bool showwinner; | ||
298 | int boldone; | ||
299 | }; | ||
300 | |||
301 | class NewGame; | ||
302 | |||
303 | class WordGame : public QMainWindow { | ||
304 | Q_OBJECT | ||
305 | public: | ||
306 | WordGame( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); | ||
307 | ~WordGame(); | ||
308 | |||
309 | private slots: | ||
310 | void endTurn(); | ||
311 | void resetTurn(); | ||
312 | void passTurn(); | ||
313 | void think(); | ||
314 | void endGame(); | ||
315 | void startGame(); | ||
316 | |||
317 | private: | ||
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 | |||
350 | class NewGame : public NewGameBase { | ||
351 | Q_OBJECT | ||
352 | public: | ||
353 | NewGame(QWidget* parent); | ||
354 | QStringList ruleslist; | ||
355 | |||
356 | public slots: | ||
357 | void updateRuleSets(); | ||
358 | }; | ||
359 | |||
360 | class Rules : public RulesBase { | ||
361 | Q_OBJECT | ||
362 | |||
363 | public: | ||
364 | Rules(QWidget* parent); | ||
365 | |||
366 | signals: | ||
367 | void rulesChanged(); | ||
368 | |||
369 | public slots: | ||
370 | void editRules(); | ||
371 | |||
372 | private: | ||
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 | ||
9 | INCLUDEPATH += $(QPEDIR)/include | ||
10 | DEPENDPATH+= $(QPEDIR)/include | ||
11 | LIBS += -lqpe | ||
12 | |||
13 | TRANSLATIONS = ../i18n/de/wordgame.ts | ||