summaryrefslogtreecommitdiff
path: root/noncore/games
Unidiff
Diffstat (limited to 'noncore/games') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/chess/Makefile.in134
-rw-r--r--noncore/games/chess/boardview.cw23
-rw-r--r--noncore/games/chess/chess.cpp358
-rw-r--r--noncore/games/chess/chess.db2
-rw-r--r--noncore/games/chess/chess.h128
-rw-r--r--noncore/games/chess/chess.pro14
-rw-r--r--noncore/games/chess/main.cpp51
-rw-r--r--noncore/games/chess/mainwindow.ui220
-rw-r--r--noncore/games/chess/pieces.pngbin0 -> 5696 bytes
-rw-r--r--noncore/games/chess/qpe-chess.control9
-rw-r--r--noncore/games/chess/simple-l.pngbin0 -> 16143 bytes
-rw-r--r--noncore/games/fifteen/.cvsignore2
-rw-r--r--noncore/games/fifteen/Makefile.in118
-rw-r--r--noncore/games/fifteen/fifteen.cpp364
-rw-r--r--noncore/games/fifteen/fifteen.h83
-rw-r--r--noncore/games/fifteen/fifteen.pro10
-rw-r--r--noncore/games/fifteen/main.cpp33
-rw-r--r--noncore/games/fifteen/qpe-fifteen.control11
-rw-r--r--noncore/games/go/.cvsignore2
-rw-r--r--noncore/games/go/Makefile.in158
-rw-r--r--noncore/games/go/README3
-rw-r--r--noncore/games/go/README.AMIGO42
-rw-r--r--noncore/games/go/README.XAMIGO26
-rw-r--r--noncore/games/go/amigo.c656
-rw-r--r--noncore/games/go/amigo.h146
-rw-r--r--noncore/games/go/go.h81
-rw-r--r--noncore/games/go/go.pro19
-rw-r--r--noncore/games/go/goplayer.c1499
-rw-r--r--noncore/games/go/goplayutils.c1317
-rw-r--r--noncore/games/go/goplayutils.h85
-rw-r--r--noncore/games/go/gowidget.cpp449
-rw-r--r--noncore/games/go/gowidget.h111
-rw-r--r--noncore/games/go/killable.c373
-rw-r--r--noncore/games/go/main.cpp35
-rw-r--r--noncore/games/go/qpe-go.control9
-rw-r--r--noncore/games/mindbreaker/.cvsignore4
-rw-r--r--noncore/games/mindbreaker/Makefile.in117
-rw-r--r--noncore/games/mindbreaker/main.cpp35
-rw-r--r--noncore/games/mindbreaker/mindbreaker.cpp818
-rw-r--r--noncore/games/mindbreaker/mindbreaker.h122
-rw-r--r--noncore/games/mindbreaker/mindbreaker.pro12
-rw-r--r--noncore/games/mindbreaker/qpe-mindbreaker.control9
-rw-r--r--noncore/games/minesweep/.cvsignore2
-rw-r--r--noncore/games/minesweep/Makefile.in134
-rw-r--r--noncore/games/minesweep/main.cpp34
-rw-r--r--noncore/games/minesweep/minefield.cpp623
-rw-r--r--noncore/games/minesweep/minefield.h87
-rw-r--r--noncore/games/minesweep/minesweep.cpp390
-rw-r--r--noncore/games/minesweep/minesweep.h67
-rw-r--r--noncore/games/minesweep/minesweep.pro14
-rw-r--r--noncore/games/minesweep/qpe-minesweep.control9
-rw-r--r--noncore/games/parashoot/.cvsignore3
-rw-r--r--noncore/games/parashoot/Makefile.in203
-rw-r--r--noncore/games/parashoot/base.cpp71
-rw-r--r--noncore/games/parashoot/base.h38
-rw-r--r--noncore/games/parashoot/bullet.cpp142
-rw-r--r--noncore/games/parashoot/bullet.h51
-rw-r--r--noncore/games/parashoot/cannon.cpp140
-rw-r--r--noncore/games/parashoot/cannon.h58
-rw-r--r--noncore/games/parashoot/codes.h25
-rw-r--r--noncore/games/parashoot/helicopter.cpp114
-rw-r--r--noncore/games/parashoot/helicopter.h45
-rw-r--r--noncore/games/parashoot/interface.cpp247
-rw-r--r--noncore/games/parashoot/interface.h79
-rw-r--r--noncore/games/parashoot/main.cpp36
-rw-r--r--noncore/games/parashoot/man.cpp174
-rw-r--r--noncore/games/parashoot/man.h52
-rw-r--r--noncore/games/parashoot/parashoot.pro11
-rw-r--r--noncore/games/parashoot/qpe-parashoot.control9
-rw-r--r--noncore/games/qasteroids/.cvsignore2
-rw-r--r--noncore/games/qasteroids/Makefile.in155
-rw-r--r--noncore/games/qasteroids/ledmeter.cpp135
-rw-r--r--noncore/games/qasteroids/ledmeter.h72
-rw-r--r--noncore/games/qasteroids/main.cpp36
-rw-r--r--noncore/games/qasteroids/qasteroids.pro11
-rw-r--r--noncore/games/qasteroids/qpe-qasteroids.control9
-rw-r--r--noncore/games/qasteroids/sprites.h147
-rw-r--r--noncore/games/qasteroids/toplevel.cpp514
-rw-r--r--noncore/games/qasteroids/toplevel.h99
-rw-r--r--noncore/games/qasteroids/view.cpp884
-rw-r--r--noncore/games/qasteroids/view.h156
-rw-r--r--noncore/games/snake/.cvsignore3
-rw-r--r--noncore/games/snake/Makefile.in159
-rw-r--r--noncore/games/snake/codes.h20
-rw-r--r--noncore/games/snake/interface.cpp224
-rw-r--r--noncore/games/snake/interface.h69
-rw-r--r--noncore/games/snake/main.cpp35
-rw-r--r--noncore/games/snake/obstacle.cpp51
-rw-r--r--noncore/games/snake/obstacle.h30
-rw-r--r--noncore/games/snake/qpe-snake.control9
-rw-r--r--noncore/games/snake/snake.cpp246
-rw-r--r--noncore/games/snake/snake.h64
-rw-r--r--noncore/games/snake/snake.pro11
-rw-r--r--noncore/games/snake/target.cpp77
-rw-r--r--noncore/games/snake/target.h37
-rw-r--r--noncore/games/solitaire/.cvsignore3
-rw-r--r--noncore/games/solitaire/Makefile.in235
-rw-r--r--noncore/games/solitaire/canvascard.cpp282
-rw-r--r--noncore/games/solitaire/canvascard.h82
-rw-r--r--noncore/games/solitaire/canvascardgame.cpp380
-rw-r--r--noncore/games/solitaire/canvascardgame.h95
-rw-r--r--noncore/games/solitaire/canvascardwindow.cpp227
-rw-r--r--noncore/games/solitaire/canvascardwindow.h70
-rw-r--r--noncore/games/solitaire/canvasshapes.cpp92
-rw-r--r--noncore/games/solitaire/canvasshapes.h55
-rw-r--r--noncore/games/solitaire/card.cpp53
-rw-r--r--noncore/games/solitaire/card.h84
-rw-r--r--noncore/games/solitaire/carddeck.cpp81
-rw-r--r--noncore/games/solitaire/carddeck.h49
-rw-r--r--noncore/games/solitaire/cardgame.cpp35
-rw-r--r--noncore/games/solitaire/cardgame.h45
-rw-r--r--noncore/games/solitaire/cardgamelayout.cpp61
-rw-r--r--noncore/games/solitaire/cardgamelayout.h42
-rw-r--r--noncore/games/solitaire/cardpile.cpp114
-rw-r--r--noncore/games/solitaire/cardpile.h101
-rw-r--r--noncore/games/solitaire/freecellcardgame.cpp137
-rw-r--r--noncore/games/solitaire/freecellcardgame.h152
-rw-r--r--noncore/games/solitaire/main.cpp36
-rw-r--r--noncore/games/solitaire/patiencecardgame.cpp234
-rw-r--r--noncore/games/solitaire/patiencecardgame.h206
-rw-r--r--noncore/games/solitaire/qpe-solitaire.control9
-rwxr-xr-xnoncore/games/solitaire/solitaire.pro18
-rw-r--r--noncore/games/tetrix/.cvsignore3
-rw-r--r--noncore/games/tetrix/Makefile.in157
-rw-r--r--noncore/games/tetrix/gtetrix.cpp514
-rw-r--r--noncore/games/tetrix/gtetrix.h104
-rw-r--r--noncore/games/tetrix/main.cpp33
-rw-r--r--noncore/games/tetrix/qpe-tetrix.control10
-rw-r--r--noncore/games/tetrix/qtetrix.cpp170
-rw-r--r--noncore/games/tetrix/qtetrix.h78
-rw-r--r--noncore/games/tetrix/qtetrixb.cpp251
-rw-r--r--noncore/games/tetrix/qtetrixb.h80
-rw-r--r--noncore/games/tetrix/tetrix.pro17
-rw-r--r--noncore/games/tetrix/tpiece.cpp201
-rw-r--r--noncore/games/tetrix/tpiece.h62
-rw-r--r--noncore/games/wordgame/.cvsignore6
-rw-r--r--noncore/games/wordgame/Makefile.in168
-rwxr-xr-xnoncore/games/wordgame/calcdist27
-rw-r--r--noncore/games/wordgame/main.cpp34
-rw-r--r--noncore/games/wordgame/newgamebase.ui337
-rw-r--r--noncore/games/wordgame/qpe-wordgame.control10
-rw-r--r--noncore/games/wordgame/rulesbase.ui274
-rw-r--r--noncore/games/wordgame/wordgame.cpp1476
-rw-r--r--noncore/games/wordgame/wordgame.h376
-rw-r--r--noncore/games/wordgame/wordgame.pro13
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
17DESTDIR = ../bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= chess
22TARGET1 = 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
32INTERFACES = mainwindow.ui
33UICDECLS = mainwindow.h
34UICIMPLS = 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
63all: $(DESTDIR)$(TARGET)
64
65$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
66 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
67
68moc: $(SRCMOC)
69
70tmake:
71 tmake chess.pro
72
73clean:
74 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
75 -rm -f *~ core
76 -rm -f allmoc.cpp
77
78####### Extension Modules
79
80listpromodules:
81 @echo
82
83listallmodules:
84 @echo
85
86listaddonpromodules:
87 @echo
88
89listaddonentmodules:
90 @echo
91
92
93REQUIRES=
94
95####### Sub-libraries
96
97
98###### Combined headers
99
100
101
102####### Compile
103
104chess.o: chess.cpp \
105 $(QPEDIR)/include/qpe/config.h \
106 $(QPEDIR)/include/qpe/resource.h \
107 chess.h
108
109main.o: main.cpp \
110 mainwindow.h
111
112mainwindow.h: mainwindow.ui
113 $(UIC) mainwindow.ui -o $(INTERFACE_DECL_PATH)/mainwindow.h
114
115mainwindow.cpp: mainwindow.ui
116 $(UIC) mainwindow.ui -i mainwindow.h -o mainwindow.cpp
117
118mainwindow.o: mainwindow.cpp \
119 mainwindow.h \
120 mainwindow.ui
121
122moc_chess.o: moc_chess.cpp \
123 chess.h
124
125moc_mainwindow.o: moc_mainwindow.cpp \
126 mainwindow.h
127
128moc_chess.cpp: chess.h
129 $(MOC) chess.h -o moc_chess.cpp
130
131moc_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
39int pieceSize = 40;
40static QVector < QImage > imgList;
41int timeMoves, timeTime;
42
43int 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
53char 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
62int 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
71int 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
81Piece::Piece(QCanvas * canvas, int t):QCanvasRectangle(canvas)
82{
83 type = t;
84 setSize(pieceSize, pieceSize);
85 show();
86}
87
88Piece *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
96void BoardView::deletePiece(Piece * p)
97{
98 list.remove(p);
99 canvas()->update();
100}
101
102void Piece::drawShape(QPainter & p)
103{
104 p.drawImage(int (x()), int (y()), *(imgList[type]));
105}
106
107void 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
125void 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
156void 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
178void BoardView::undo()
179{
180 crafty->writeToStdin("undo\n");
181 crafty->writeToStdin("savepos\nclock\n");
182}
183
184void 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
192void 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
200Piece *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
213void 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
227void 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
248void 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
280void 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
324void BoardView::swapSides()
325{
326 if (activeSide == humanSide && playingGame) {
327 humanSide = !humanSide;
328 crafty->writeToStdin("savepos\ngo\n");
329 } else
330 emitErrorMessage();
331}
332
333BoardView::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
52class 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
65class 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
75class 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
3DESTDIR = ../bin
4TARGET = chess
5 DEPENDPATH+= $(QPEDIR)/include
6INTERFACES = 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
10INCLUDEPATH += $(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
29class CanvasMainWindow : public QMainWindow {
30public:
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
39private:
40 QCanvas canvas;
41 BoardView *view;
42};
43
44
45int 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&amp;)</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&amp;)</signal>
214 <receiver>TextLabel1</receiver>
215 <slot>setText(const QString&amp;)</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 @@
1Files: bin/chess apps/Games/chess.desktop
2Priority: optional
3Section: qpe/games
4Maintainer: Luke Graham <luke@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: 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 @@
1moc_*
2Makefile
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
17DESTDIR = ../bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= fifteen
22TARGET1 = 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
31INTERFACES =
32UICDECLS =
33UICIMPLS =
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
60all: $(DESTDIR)$(TARGET)
61
62$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
63 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
64
65moc: $(SRCMOC)
66
67tmake:
68 tmake fifteen.pro
69
70clean:
71 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
72 -rm -f *~ core
73 -rm -f allmoc.cpp
74
75####### Extension Modules
76
77listpromodules:
78 @echo
79
80listallmodules:
81 @echo
82
83listaddonpromodules:
84 @echo
85
86listaddonentmodules:
87 @echo
88
89
90REQUIRES=
91
92####### Sub-libraries
93
94
95###### Combined headers
96
97
98
99####### Compile
100
101fifteen.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
108main.o: main.cpp \
109 fifteen.h \
110 $(QPEDIR)/include/qpe/qpeapplication.h
111
112moc_fifteen.o: moc_fifteen.cpp \
113 fifteen.h
114
115moc_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
40FifteenMainWindow::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
79PiecesTable::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
102PiecesTable::~PiecesTable()
103{
104 writeConfig();
105}
106
107void 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
118void 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
132void 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
165void PiecesTable::resizeEvent(QResizeEvent *e)
166{
167 QTableView::resizeEvent(e);
168
169 setCellWidth(contentsRect().width()/ numRows());
170 setCellHeight(contentsRect().height() / numCols());
171}
172
173void 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
181void 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
190void 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
248void 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
265void PiecesTable::slotRandomize()
266{
267 randomizeMap();
268}
269
270void PiecesTable::slotReset()
271{
272 initMap();
273 repaint();
274}
275
276void 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
28class QPopupMenu;
29
30class 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
64class FifteenWidget : public QWidget
65{
66 Q_OBJECT
67
68public:
69 FifteenWidget(QWidget *parent = 0, const char *name = 0);
70
71private:
72 PiecesTable *_table;
73};
74
75class FifteenMainWindow : public QMainWindow
76{
77 Q_OBJECT
78
79public:
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
7INCLUDEPATH += $(QPEDIR)/include
8 DEPENDPATH+= $(QPEDIR)/include
9LIBS += -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
25int 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 @@
1Files: bin/fifteen apps/Games/fifteen.desktop pics/Fifteen.png
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Arch: iPAQ
7Version: $QPE_VERSION-4
8Depends: qpe-base ($QPE_VERSION)
9Description: 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 @@
1moc_*
2Makefile
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
17DESTDIR = ../bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= go
22TARGET1 = 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
42INTERFACES =
43UICDECLS =
44UICIMPLS =
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
71all: $(DESTDIR)$(TARGET)
72
73$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
74 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
75
76moc: $(SRCMOC)
77
78tmake:
79 tmake go.pro
80
81clean:
82 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
83 -rm -f *~ core
84 -rm -f allmoc.cpp
85
86####### Extension Modules
87
88listpromodules:
89 @echo
90
91listallmodules:
92 @echo
93
94listaddonpromodules:
95 @echo
96
97listaddonentmodules:
98 @echo
99
100
101REQUIRES=
102
103####### Sub-libraries
104
105
106###### Combined headers
107
108
109
110####### Compile
111
112amigo.o: amigo.c \
113 go.h \
114 goplayutils.h \
115 amigo.h
116
117goplayer.o: goplayer.c \
118 go.h \
119 goplayutils.h \
120 amigo.h
121
122goplayutils.o: goplayutils.c \
123 goplayutils.h \
124 amigo.h \
125 go.h
126
127killable.o: killable.c \
128 go.h \
129 goplayutils.h \
130 amigo.h
131
132gowidget.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
142main.o: main.cpp \
143 gowidget.h \
144 amigo.h \
145 go.h \
146 goplayutils.h \
147 $(QPEDIR)/include/qpe/qpeapplication.h
148
149moc_gowidget.o: moc_gowidget.cpp \
150 gowidget.h \
151 amigo.h \
152 go.h \
153 goplayutils.h
154
155moc_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 @@
1This Go player For Qtopia is based on Xamigo, which in turn was
2based on Amigo. The original README files are included as README.XAMIGO
3and 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.
2The Amiga interface and board manager were written by Todd R. Johnson.
3The player is a C port of a Pascal player written by Stoney Ballard.
4The interface allows you to play human vs. human, human vs. Amiga, or
5Amiga vs. Amiga.
6
7 The board manager and player could both use some work. Currently,
8you cannot save/load games, take back a move, or automatically score a
9game. It is also limited to a 19 by 19 board. I'm releasing AmiGo
10now because 1) I'm in the final phases of my dissertation and probably
11won't have much time to do any further work on AmiGo, and 2) a lot of
12people have been asking for an Amiga Go player. I am also releasing
13all of the source code so that others can add to and modify AmiGo.
14Note that all of my code in this release is public domain, while the
15ported go player retains the original copyright.
16
17 If you distribute AmiGo, I urge you to include the source
18code. If anyone makes changes, I would appreciate a copy. In fact, I
19am willing to act as a clearinghouse for AmiGo changes.
20
21Todd R. Johnson
22tj@cis.ohio-state.edu
238/8/89
24
25Here is the message attached to the original USENET posting of Stoney
26Ballard's Pascal code. Note that the board manager mentioned here is
27not included in this distribution.
28
29This go board manager and rudimentary go player was written by
30Stoney Ballard at Perq Systems in 1983-1984. It is written in
31Perq Pascal and utilizes some Perq libraries for I/O. The code
32is offered here if someone is interested to convert it to Unix.
33
34The wonderful part about it is that a game is recorded as a tree
35and can be played forward or backward, branching at any point
36where there were alternate moves.
37
38For some time, this program was also used to generate the go
39boards displayed in the American Go Journal. For this it used
40some large font digits which are now lost.
41
42Fred 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
4This is an alpha release of xamigo --- a port (read: quick hack) of the
5Amiga Go program AmiGo. I don't have time to get it real nice now,
6but will spend some more time on it when my thesis is out of the way.
7Sadly this is the second time I've said that :-)
8
9The `readme' from the original distribution is included as README.AMIGO
10
11An Imakefile is included, so you should be able to type
12 xmkmf
13 make
14to build xamigo. Let me know if you have problems with the Imakefile,
15preferably with fixes :-)
16
17You *have* to install the app-defaults file (Xamigo.ad) before you use
18xamigo. This should either go in /usr/lib/X11/app-defaults,
19or in your own app-defaults directory, as file Xamigo (ie lose the '.ad')
20If you do the latter, you have to:
21 setenv XAPPLRESDIR <full path of your app-defaults directory>
22
23Feel free to mail me any comments and suggestions for improvements.
24
25Neil
26neilb@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
34short
35member(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? */
50short
51Connect( 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 */
89short
90Maxlibs(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
103DeleteGroupFromStone(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 */
111short
112Suicide(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 */
144short
145StoneLibs(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
162void
163EraseMarks()
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 */
174short
175GoPlaceStone(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 */
236void
237GoRemoveStone(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
246list. Fixes stone count of groups. This does not fix anything else.
247FixLibs must be called to fix liberties, etc. */
248void
249MergeGroups(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 */
263void
264DeleteGroup(code)
265 shortcode;
266{
267 DeletedGroups[DeletedGroupCount++] = code;
268}
269
270/* Re-evaluate the groups given the last move. This assumes that the
271last move has been merged into adjoining groups and all liberty counts
272are correct. Handles capture. Checks for Ko. Keeps track of captured
273stones. code is the group number of the stone just played. */
274void
275ReEvalGroups(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 --*/
313void
314GroupCapture(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. */
339void
340FixLibs( 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
358void
359goSetHandicap(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
386void
387goRestart(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. */
410void
411RelabelGroups()
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 */
434short
435CountAndMarkLibs( 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 */
458void
459CountLiberties( 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
471void
472CheckForEye( 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 */
490void 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----------------------------------------------------------------*/
554CountUp( 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\
579Black : %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
592FillPoints(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
614short
615CountFromPoint(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
43extern "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
56enum bVal {BLACK, WHITE, EMPTY};
57typedef enum bVal sType;
58struct 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
71struct 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
14INCLUDEPATH += $(QPEDIR)/include
15 DEPENDPATH+= $(QPEDIR)/include
16LIBS += -lqpe
17 TARGET = go
18
19TRANSLATIONS = ../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:
4Go Move Generator
5Copyright (c) 1983 by Three Rivers Computer Corp.
6
7Written: January 17, 1983 by Stoney Ballard
8Edit 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 */
18extern struct bRec goboard[19][19];
19extern short ko, koX, koY;
20
21/* From goplayutils.c */
22extern intBoard bord;
23extern intBoard ndbord;
24extern intBoard claim;
25extern intBoard legal;
26extern intBoard connectMap;
27extern intBoard threatBord;
28extern short maxGroupID;
29extern short treeLibLim;
30extern short killFlag;
31extern short depthLimit;
32extern short showTrees;
33extern short utilPlayLevel;
34extern groupRec gList[maxGroup];
35extern short sGlist[maxGroup + 1];
36extern pointList pList;
37extern pointList pList1;
38extern pointList plist2;
39extern pointList plist3;
40extern intBoard groupIDs;
41extern intBoard protPoints;
42extern sType mySType;
43
44
45short saveNLibs;
46pointList dapList1, dapList2, dapList3;
47char *playReason;
48short maxPlayLevel = 7;
49short playLevel = 7;
50
51genBord(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
96short getMove( x, y )
97short *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
122short genMove( color, x, y )
123enum bVal color;
124short *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
136short checkPos(x, y, field)
137short 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
152short takeCorner( x, y )
153short *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
183printBoard(brd, name)
184intBoard brd;
185char *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
197short noNbrs( x, y )
198short 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
207short extend(x, y)
208short *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
243short extend2( x, y )
244short *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 */
315short lookForSave(x, y)
316short *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 */
331short lookForSaveN(x, y)
332short *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----------------------------------------------------------------*/
356short
357lookForKill(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
380short doubleAtari(x, y)
381short *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
415short lookForAttack(x, y)
416short *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 */
439short threaten(x, y)
440short *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 */
478short connectCut(x, y)
479short *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
735short heCanCut(x, y)
736short 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 */
754short safeMove(x, y)
755short 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 */
782short extendWall(x, y)
783short *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 */
818short findAttack2(x, y)
819short *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 */
849short blockCut(x, y)
850short *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 */
922short cutHim(x, y)
923short *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 */
1108short atariAnyway(x, y)
1109short *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 */
1158short underCut(x, y)
1159short *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 */
1212short dropToEdge(x, y)
1213short *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 */
1344short pushWall(x, y)
1345short *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 */
1396short reduceHisLiberties(x, y)
1397short *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 */
1425short dropToEdge2(x, y)
1426short *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:
4Copyright (c) 1983 by Three Rivers Computer Corp.
5
6Written: January 17, 1983 by Stoney Ballard
7*/
8
9#include "goplayutils.h"
10#include "amigo.h"
11#include "go.h"
12
13extern struct bRec goboard[19][19];
14
15intBoard claim, extra, bord, ndbord, sGroups, threatBord,
16 groupIDs, connectMap, protPoints;
17boolBoard groupSeen, legal;
18short maxGroupID;
19pointList pList, pList1, plist2, plist3, pPlist;
20intList nlcGroup, aList;
21sgRec sList[401];
22groupRec gList[maxGroup];
23short killFlag,
24 numCapt,
25 utilPlayLevel,
26 treeLibLim;
27sType mySType;
28short showTrees;
29short sGlist[maxGroup+1];
30short depthLimit;
31intBoard markBoard;
32short marker;
33
34short adjInAtari, adj2Libs,
35 intersectNum, spanNum, libMark;
36playRec playStack[1025];
37short playMark,
38 newGID,
39 tryLevel,
40 grpMark,
41 gMap[maxGroup];
42short 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
56sstone(w, x, y, numb)
57short 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
67rstone(x, y)
68short x, y;
69{ /* rstone */
70 removestone(x, y);
71} /* rstone */
72
73initBoolBoard(bb)
74boolBoard 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
85sortLibs()
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
103spanGroupspan(x, y, libs, lookFor)
104short x, y, lookFor;
105pointList *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
133spanGroup(x, y, libs)
134short x, y;
135pointList *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
154sSpanGroupspan(x, y, libs, lookFor)
155short x, y, lookFor;
156sPointList *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
187sSpanGroup(x, y, libs)
188short x, y;
189sPointList *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
208LAspan(x, y, me, him, iL)
209short x, y, me, him;
210intList *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
236listAdjacents(x, y, iL)
237short x, y;
238intList *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
257LDspan(x, y, me, diags)
258short x, y, me;
259sPointList *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
335listDiags(x, y, diags)
336short x, y;
337sPointList *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
354intersectPlist(p1, p2, pr)
355pointList *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
380initArray(ary)
381intBoard 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
389initState()
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
403copyArray( dest, src )
404intBoard 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*/
428stake()
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*/
457spread()
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*/
473Resspan(x, y, gID, gSize, libCount, who)
474short 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
498respreicen()
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*/
544killGroup(x, y, me, him)
545short 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
605mergeGroup(sGID, myGID)
606short 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
623tryPlay(x, y, z)
624short 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
758saveState()
759{ /* saveState */
760 playMark = 0;
761 tryLevel = 0;
762 newGID = maxGroupID;
763} /* saveState */
764
765/*
766 undoes a move sequence back to uMark
767*/
768undoTo(uMark)
769short 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*/
810restoreState()
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*/
830short saveable(gx, gy, savex, savey)
831short 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;
938one:
939 restoreState();
940/* sClearChar(sChar, rXor); */
941 return result;
942} /* saveable */
943
944/*
945 marks unsavable groups as dead
946*/
947markDead()
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*/
971MLspan(x, y, saw1, sawm1, size, sMark)
972short 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
993short CLspan(x, y, numEyes, who)
994short 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
1028short checkLive(x, y)
1029short 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
1041markLive()
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*/
1079genConnects()
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*/
1205genState()
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*/
1232short tencen(x, y)
1233short 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
1297initGPUtils()
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
28typedef short intBoard[19][19]; /* these were -2 to maxPoint + 2 */
29
30typedef short boolBoard[19][19];
31
32typedef struct
33{
34 short px, py;
35} point;
36
37typedef struct
38{
39 point p[401];
40 short indx;
41} pointList;
42
43typedef struct
44{
45 point p[maxSPoint+1];
46 short indx;
47} sPointList;
48
49typedef struct
50{
51 short indx,
52 v[401];
53} intList;
54
55typedef struct { short w, s, sm; } sgRec;
56
57typedef struct
58{
59 short groupMark,
60 atLevel,
61 isLive,
62 isDead,
63 libC,
64 numEyes,
65 size,
66 lx, ly;
67} groupRec;
68
69typedef enum {rem, add, chLib, reMap} playType;
70
71typedef struct { short who, xl, yl, nextGID, sNumber; } remAddRec;
72typedef struct { short oldLC, oldLevel; } chLibRec;
73typedef struct { short oldGID; } reMapRec;
74typedef 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
40static const enum bVal computer_color = BLACK;
41
42static int current_handicap = 1;
43
44static QBrush *goBrush;
45//static QImage *newBlackStone;
46//static QImage *blackStone;
47//static QImage *whiteStone;
48static QPixmap *newBlackStone;
49static QPixmap *blackStone;
50static QPixmap *whiteStone;
51
52GoMainWidget::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
104void 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
115GoWidget *GoWidget::self = 0;
116
117GoWidget::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
145GoWidget::~GoWidget()
146{
147 writeConfig();
148}
149
150void 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
169void 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
194void 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
202void 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
221void 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
265void 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
283void GoWidget::pass()
284{
285 if ( !gameActive )
286 return;
287 nPassed++;
288 if ( nPassed >= 2 )
289 endGame();
290 else if ( !twoplayer )
291 doComputerMove();
292}
293
294void GoWidget::resign()
295{
296 if ( gameActive )
297 endGame();
298}
299
300
301void GoWidget::newGame()
302{
303 init();
304 update();
305}
306
307
308void 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
324void 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
347void 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
356void 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
366void 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
385void GoWidget::mouseReleaseEvent( QMouseEvent * )
386{
387 if ( gameActive && newX > -1 )
388 doMove( newX, newY );
389 newX = newY = -1;
390}
391
392void 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
397void GoWidget::removeStone(short x, short y)
398{
399 board[x][y]=-1;
400 refresh( x, y );
401}
402
403void GoWidget::placeStone (enum bVal c, short x, short y )
404{
405 board[x][y]=c;
406 refresh( x, y );
407}
408
409void 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
415void GoWidget::setTwoplayer( bool b )
416{
417 twoplayer = b;
418}
419
420void GoWidget::setHandicap( int h )
421{
422 current_handicap = h;
423}
424
425
426extern "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
28class QToolBar;
29
30class GoMainWidget : public QMainWindow
31{
32 Q_OBJECT
33public:
34 GoMainWidget( QWidget *parent=0, const char* name=0);
35protected:
36 void resizeEvent( QResizeEvent * );
37private:
38 QToolBar *toolbar;
39
40};
41
42
43class QLabel;
44class GoWidget : public QWidget
45{
46 Q_OBJECT
47public:
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
57public slots:
58 void pass();
59 void resign();
60 void newGame();
61 void setTwoplayer( bool );
62 void setHandicap( int );
63signals:
64 void showScore( const QString& );
65 void showTurn( const QPixmap& );
66
67protected:
68 void paintEvent( QPaintEvent * );
69 void mousePressEvent( QMouseEvent * );
70 void mouseMoveEvent( QMouseEvent * );
71 void mouseReleaseEvent( QMouseEvent * );
72 void resizeEvent( QResizeEvent * );
73private:
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
8extern intBoard bord, groupIDs;
9extern boolBoard legal;
10extern groupRec gList[maxGroup];
11extern short gMap[maxGroup], adjInAtari, adj2Libs, playMark, treeLibLim,
12 utilPlayLevel, killFlag, depthLimit, dbStop, showTrees;
13extern 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
27short mtNbrs(x, y)
28short 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
42short killTree(tx, ty, gx, gy, escape, tkMark)
43short 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
263short tKillTree(tx, ty, gx, gy)
264short 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
272short killable(gx, gy, killx, killy)
273short 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
27int 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 @@
1Files: bin/go apps/Games/go.desktop
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: 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 @@
1Makefile
2moc_*
3helpdialog.cpp
4helpdialog.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
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= mindbreaker
22TARGET1 = 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
31INTERFACES =
32UICDECLS =
33UICIMPLS =
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
60all: $(DESTDIR)$(TARGET)
61
62$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
63 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
64
65moc: $(SRCMOC)
66
67tmake:
68 tmake mindbreaker.pro
69
70clean:
71 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
72 -rm -f *~ core
73 -rm -f allmoc.cpp
74
75####### Extension Modules
76
77listpromodules:
78 @echo
79
80listallmodules:
81 @echo
82
83listaddonpromodules:
84 @echo
85
86listaddonentmodules:
87 @echo
88
89
90REQUIRES=
91
92####### Sub-libraries
93
94
95###### Combined headers
96
97
98
99####### Compile
100
101main.o: main.cpp \
102 mindbreaker.h \
103 $(QPEDIR)/include/qpe/qpeapplication.h
104
105mindbreaker.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
111moc_mindbreaker.o: moc_mindbreaker.cpp \
112 mindbreaker.h
113
114moc_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
25int 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
39static int pegRTTI = 3393393;
40
41/* helper class, */
42class Peg : public QCanvasRectangle
43{
44public:
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
67protected:
68 void drawShape(QPainter &);
69private:
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
81int Peg::eggLevel = 0;
82QVector<QImage> Peg::normalPegs;
83QVector<QImage> Peg::specialPegs;
84
85void 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
124QImage 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
136Peg::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
148void Peg::advance(int phase) {
149 if (phase == 0)
150 aniStep = (++aniStep) % 6;
151 else {
152 hide();
153 show();
154 }
155}
156
157void 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
165bool 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
175inline bool Peg::placed() const
176{
177 return isplaced;
178}
179
180inline int Peg::pegGo() const
181{
182 return peg_go;
183}
184
185inline int Peg::pegPos() const
186{
187 return peg_pos;
188}
189
190inline void Peg::setPegPos(int p)
191{
192 peg_pos = p;
193}
194
195inline void Peg::setPlaced(bool p)
196{
197 isplaced = p;
198}
199
200inline 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 */
208MindBreaker::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
238void 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
253MindBreakerBoard::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
341MindBreakerBoard::~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
373void MindBreakerBoard::getScore(int *a, int *b)
374{
375 *a = total_turns;
376 *b = total_games;
377 return;
378}
379
380void 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
395void 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
456void 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
563void 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
595void 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
613void 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
676void 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
687void 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
779void 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 */
799void 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
31static const int panel_height = 26;
32static const int panel_width = 180;
33
34static const int title_height = 25;
35static const int title_width = 180;
36
37static const int bin_margin = 10;
38static const int peg_size = 20;
39static const int answerpeg_size = 13;
40
41static const int first_peg_x_diff = 21;
42static const int first_peg_y_diff = ((panel_height - peg_size) >> 1);
43static const int peg_spacing = 30;
44
45static const int answerpegx = 152;
46static const int answerpegy = 2;
47static const int answerpeg_diff = 9;
48
49static const int board_height = (title_height + (panel_height * 9));
50static const int board_width = (panel_width + (bin_margin * 2) + peg_size);
51
52class Peg;
53class QToolButton;
54
55class MindBreakerBoard : public QCanvasView // QWidget
56{
57 Q_OBJECT
58public:
59 MindBreakerBoard(QCanvas &c, QWidget *parent=0, const char *name=0, int wFlags=0 );
60 ~MindBreakerBoard();
61
62 void getScore(int *, int *);
63signals:
64 void scoreChanged(int, int);
65
66public slots:
67 void clear();
68 void resetScore();
69
70protected:
71 void contentsMousePressEvent(QMouseEvent *);
72 void contentsMouseMoveEvent(QMouseEvent *);
73 void contentsMouseReleaseEvent(QMouseEvent *);
74 void resizeEvent(QResizeEvent *);
75
76private:
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
105class MindBreaker : public QMainWindow // QWidget
106{
107 Q_OBJECT
108public:
109 MindBreaker(QWidget *parent=0, const char *name=0, int wFlags=0 );
110
111public slots:
112 void setScore(int, int);
113
114private:
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 @@
1TEMPLATE = app
2CONFIG += qt warn_on release
3DESTDIR = $(QPEDIR)/bin
4 HEADERS = mindbreaker.h
5 SOURCES = main.cpp \
6 mindbreaker.cpp
7TARGET = mindbreaker
8INCLUDEPATH += $(QPEDIR)/include
9DEPENDPATH += $(QPEDIR)/include
10LIBS += -lqpe
11
12TRANSLATIONS = ../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 @@
1Files: bin/mindbreaker apps/Games/mindbreaker.desktop pics/mindbreaker
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: 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 @@
1moc_*
2Makefile
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
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= minesweep
22TARGET1 = 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
34INTERFACES =
35UICDECLS =
36UICIMPLS =
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
65all: $(DESTDIR)$(TARGET)
66
67$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
68 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
69
70moc: $(SRCMOC)
71
72tmake:
73 tmake minesweep.pro
74
75clean:
76 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
77 -rm -f *~ core
78 -rm -f allmoc.cpp
79
80####### Extension Modules
81
82listpromodules:
83 @echo
84
85listallmodules:
86 @echo
87
88listaddonpromodules:
89 @echo
90
91listaddonentmodules:
92 @echo
93
94
95REQUIRES=
96
97####### Sub-libraries
98
99
100###### Combined headers
101
102
103
104####### Compile
105
106main.o: main.cpp \
107 minesweep.h \
108 $(QPEDIR)/include/qpe/qpeapplication.h
109
110minefield.o: minefield.cpp \
111 minefield.h \
112 $(QPEDIR)/include/qpe/config.h
113
114minesweep.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
122moc_minefield.o: moc_minefield.cpp \
123 minefield.h
124
125moc_minesweep.o: moc_minesweep.cpp \
126 minesweep.h
127
128moc_minefield.cpp: minefield.h
129 $(MOC) minefield.h -o moc_minefield.cpp
130
131moc_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
25int 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
32static 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
51static 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
70class Mine : public QTableItem
71{
72public:
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
101private:
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
113QPixmap* Mine::knownField = 0;
114QPixmap* Mine::unknownField = 0;
115QPixmap* Mine::flag_pix = 0;
116QPixmap* Mine::mine_pix = 0;
117
118Mine::Mine( QTable *t )
119: QTableItem( t, Never, QString::null )
120{
121 mined = FALSE;
122 st = Hidden;
123 hint = 0;
124}
125
126void 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
154void Mine::setState( MineState s )
155{
156 st = s;
157}
158
159void Mine::setHint( int h )
160{
161 hint = h;
162}
163
164void 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
176void 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
264MineField::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
295MineField::~MineField()
296{
297}
298
299void MineField::setState( State st )
300{
301 stat = st;
302}
303
304
305void 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
358void 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
374void MineField::paintFocus( QPainter*, const QRect& )
375{
376}
377
378void MineField::viewportMousePressEvent( QMouseEvent* e )
379{
380 QTable::viewportMousePressEvent( e );
381}
382
383void MineField::viewportMouseReleaseEvent( QMouseEvent* e )
384{
385 QTable::viewportMouseReleaseEvent( e );
386 if ( flagAction == FlagNext ) {
387 flagAction = NoAction;
388 }
389}
390
391void 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
400void MineField::keyReleaseEvent( QKeyEvent* )
401{
402 flagAction = NoAction;
403}
404
405int 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
418void 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*/
449void 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
459void 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
471void 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
494void 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
537void 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
553void MineField::paletteChange( const QPalette &o )
554{
555 Mine::paletteChange();
556 QTable::paletteChange( o );
557}
558
559void 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
576void 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
25class Mine;
26class Config;
27
28class MineField : public QTable
29{
30 Q_OBJECT
31public:
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
44public slots:
45 void setup( int level );
46
47 void showMines();
48
49signals:
50 void gameOver( bool won );
51 void gameStarted();
52 void mineCount( int );
53
54protected:
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
66protected slots:
67 void cellPressed( int row, int col );
68 void cellClicked( int row, int col );
69 void held();
70
71private:
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
45static 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 */
73static 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 */
101static 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 */
129static 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
156class ResultIndicator : private QLabel
157{
158public:
159 static void showResult( QWidget *ref, bool won );
160private:
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
170void 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
194void 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
207void 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
222MineSweep::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
296MineSweep::~MineSweep()
297{
298 writeConfig();
299}
300
301void 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
313void MineSweep::newGame()
314{
315 newGame(field->level());
316}
317
318void 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
326void MineSweep::startPlaying()
327{
328 newGameButton->setPixmap( QPixmap( worried_xpm ) );
329 starttime = QDateTime::currentDateTime();
330 timer->start( 1000 );
331}
332
333void MineSweep::beginner()
334{
335 newGame(1);
336}
337
338void MineSweep::advanced()
339{
340 newGame(2);
341}
342
343void MineSweep::expert()
344{
345 newGame(3);
346}
347
348void MineSweep::setCounter( int c )
349{
350 if ( !guessLCD )
351 return;
352
353 guessLCD->display( c );
354}
355
356void 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
368void 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
377void 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
26class MineField;
27class QLCDNumber;
28class QPushButton;
29
30class MineSweep : public QMainWindow
31{
32 Q_OBJECT
33public:
34 MineSweep( QWidget* parent = 0, const char* name = 0, WFlags f = 0 );
35 ~MineSweep();
36
37public slots:
38 void gameOver( bool won );
39 void newGame();
40
41protected slots:
42 void setCounter( int );
43 void updateTime();
44
45 void beginner();
46 void advanced();
47 void expert();
48
49private slots:
50 void startPlaying();
51
52private:
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
9INCLUDEPATH += $(QPEDIR)/include
10 DEPENDPATH+= $(QPEDIR)/include
11LIBS += -lqpe
12 INTERFACES=
13
14TRANSLATIONS = ../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 @@
1Files: bin/minesweep apps/Games/minesweep.desktop
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: 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 @@
1moc_*
2*.moc
3Makefile
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
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= parashoot
22TARGET1 = 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
46INTERFACES =
47UICDECLS =
48UICIMPLS =
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
79all: $(DESTDIR)$(TARGET)
80
81$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
82 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
83
84moc: $(SRCMOC)
85
86tmake:
87 tmake parashoot.pro
88
89clean:
90 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
91 -rm -f *~ core
92 -rm -f allmoc.cpp
93
94####### Extension Modules
95
96listpromodules:
97 @echo
98
99listallmodules:
100 @echo
101
102listaddonpromodules:
103 @echo
104
105listaddonentmodules:
106 @echo
107
108
109REQUIRES=
110
111####### Sub-libraries
112
113
114###### Combined headers
115
116
117
118####### Compile
119
120main.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
129interface.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
140man.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
147cannon.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
154base.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
161bullet.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
170helicopter.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
177moc_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
185moc_cannon.o: moc_cannon.cpp \
186 cannon.h \
187 bullet.h \
188 $(QPEDIR)/include/qpe/sound.h
189
190moc_bullet.o: moc_bullet.cpp \
191 bullet.h \
192 $(QPEDIR)/include/qpe/sound.h
193
194moc_interface.cpp: interface.h
195 $(MOC) interface.h -o moc_interface.cpp
196
197moc_cannon.cpp: cannon.h
198 $(MOC) cannon.h -o moc_cannon.cpp
199
200moc_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
28int damage;
29
30Base::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
47void 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
59bool Base::baseDestroyed()
60{
61 return (damage >= 3);
62}
63
64Base::~Base()
65{
66}
67
68int 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
25class Base : public QCanvasSprite
26{
27
28public:
29 Base(QCanvas*);
30 ~Base();
31 void damageBase();
32 int rtti() const;
33 static bool baseDestroyed();
34
35private:
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
30int limit;
31int shotcount;
32int nobullets;
33
34Bullet::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
53void 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
67void Bullet::setLimit(int amount)
68{
69 limit = amount;
70}
71
72void Bullet::setNobullets(int amount)
73{
74 nobullets = amount;
75}
76
77void 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
115void Bullet::advance(int phase)
116{
117 QCanvasSprite::advance(phase);
118
119 if (phase == 0)
120 checkCollision();
121
122}
123
124int Bullet::getShotCount()
125{
126 return shotcount;
127}
128
129void Bullet::setShotCount(int amount)
130{
131 shotcount = amount;
132}
133
134Bullet::~Bullet()
135{
136
137}
138
139int 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
28class Bullet : public QObject, public QCanvasSprite
29{
30 Q_OBJECT
31public:
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
43signals:
44 void score(int);
45
46private:
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
28Cannon::Cannon(QCanvas* canvas) :
29 QCanvasSprite(0, canvas)
30{
31shotsfired=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
51void 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
70void Cannon::pointCannon(Direction dir)
71{
72 movedir = dir;
73 moveDelay = 0;
74 advance(1);
75 moveDelay = 1;
76}
77
78void 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
101double 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
125void 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
133Cannon::~Cannon()
134{
135}
136
137int 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
24class Cannon : public QObject, public QCanvasSprite
25{
26 Q_OBJECT
27
28public:
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
40int shotsFired() { return shotsfired; };
41
42protected:
43 void advance(int stage);
44
45signals:
46 void score(int);
47
48private:
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
21const int man_rtti = 1500;
22const int bullet_rtti = 1600;
23const int cannon_rtti = 1700;
24const int base_rtti = 1800;
25const 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
29static QList<Helicopter> all;
30
31Helicopter::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
49Helicopter::~Helicopter()
50{
51 all.remove(this);
52}
53
54int fr = 0;
55
56void Helicopter::advance(int phase)
57{
58 QCanvasSprite::advance(phase);
59 if (phase == 0) {
60 setFrame(fr%3);
61 fr++;
62 checkCollision();
63 }
64}
65
66void Helicopter::checkCollision()
67{
68 if (x() == 6) {
69 setAnimated(false); //setVelocity(0, 0);
70 dropman();
71 }
72 if (x() < 0)
73 done();
74}
75
76void Helicopter::dropman()
77{
78 (void)new Man(canvas(), 15, 25);
79 (void)new Man(canvas(), 35, 25);
80 takeOff();
81}
82
83void Helicopter::done()
84{
85 hits++;
86 if (hits >= 2) {
87 setAnimated(false);
88 delete this;
89 }
90}
91
92void Helicopter::takeOff()
93{
94 setVelocity(-1, 0);
95}
96
97int Helicopter::rtti() const
98{
99 return helicopter_rtti;
100}
101
102void Helicopter::silenceAll()
103{
104 for (Helicopter* h = all.first(); h; h = all.next())
105 h->chikachika.stop();
106}
107
108void 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
25class Helicopter : public QCanvasSprite
26{
27
28public:
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
42private:
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
33ParaShoot::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
77void 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
85void ParaShoot::showScore( int score, int level )
86{
87 levelscore->setText(tr(" Level: %1 Score: %2 ").arg(score).arg(level) );
88}
89
90
91void 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
116void 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
126void 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
159void ParaShoot::wait()
160{
161 waitover = true;
162 pauseTimer->stop();
163}
164
165void ParaShoot::play()
166{
167 if (Man::getManCount() < nomen ) {
168 new Man(&canvas);
169 }
170 if (Base::baseDestroyed()) {
171 gameOver();
172 return;
173 }
174}
175
176void ParaShoot::increaseScore(int x)
177{
178 score += x;
179 if ( score / 150 != (score-x) / 150 )
180 levelUp();
181 showScore(level,score);
182}
183
184void 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
205void ParaShoot::moveFaster()
206{
207 if (updatespeed > 50)
208 updatespeed = updatespeed-5;
209 else
210 updatespeed = updatespeed-3;
211 canvas.setAdvancePeriod(updatespeed);
212}
213
214void 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
243void 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
31class QCanvas;
32class Helicopter;
33
34//enum Direction{
35// left, right, up, down };
36
37class ParaShoot : public QMainWindow {
38 Q_OBJECT
39
40public:
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
49protected:
50 virtual void keyPressEvent(QKeyEvent*);
51 virtual void keyReleaseEvent(QKeyEvent*);
52 virtual void resizeEvent(QResizeEvent *e);
53
54private slots:
55 void increaseScore(int);
56 void newGame();
57 void play();
58 void wait();
59
60private:
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
25int 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
29int mancount;
30
31Man::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
46Man::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}
73int f = 0;
74
75void 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
99void 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
112void 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
128void 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
147void Man::done()
148{
149 splat.play();
150 count = 0;
151 dead = true;
152 setFrame(6);
153}
154
155int Man::getManCount()
156{
157 return mancount;
158}
159
160void Man::setManCount(int count)
161{
162 mancount = count;
163}
164
165
166int Man::rtti() const
167{
168 return man_rtti;
169}
170
171Man::~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
28class Man : public QCanvasSprite
29{
30
31public:
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
45private:
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
7INCLUDEPATH += $(QPEDIR)/include
8 DEPENDPATH+= $(QPEDIR)/include
9LIBS += -lqpe
10
11TRANSLATIONS = ../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 @@
1Files: bin/parashoot apps/Games/parashoot.desktop pics/parashoot
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: 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 @@
1moc_*.cpp
2Makefile
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
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= qasteroids
22TARGET1 = 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
38INTERFACES =
39UICDECLS =
40UICIMPLS =
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
71all: $(DESTDIR)$(TARGET)
72
73$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
74 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
75
76moc: $(SRCMOC)
77
78tmake:
79 tmake qasteroids.pro
80
81clean:
82 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
83 -rm -f *~ core
84 -rm -f allmoc.cpp
85
86####### Extension Modules
87
88listpromodules:
89 @echo
90
91listallmodules:
92 @echo
93
94listaddonpromodules:
95 @echo
96
97listaddonentmodules:
98 @echo
99
100
101REQUIRES=
102
103####### Sub-libraries
104
105
106###### Combined headers
107
108
109
110####### Compile
111
112ledmeter.o: ledmeter.cpp \
113 ledmeter.h
114
115toplevel.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
123view.o: view.cpp \
124 view.h \
125 sprites.h \
126 $(QPEDIR)/include/qpe/resource.h
127
128main.o: main.cpp \
129 toplevel.h \
130 view.h \
131 sprites.h \
132 $(QPEDIR)/include/qpe/qpeapplication.h
133
134moc_ledmeter.o: moc_ledmeter.cpp \
135 ledmeter.h
136
137moc_toplevel.o: moc_toplevel.cpp \
138 toplevel.h \
139 view.h \
140 sprites.h
141
142moc_view.o: moc_view.cpp \
143 view.h \
144 sprites.h
145
146moc_ledmeter.cpp: ledmeter.h
147 $(MOC) ledmeter.h -o moc_ledmeter.cpp
148
149moc_toplevel.cpp: toplevel.h
150 $(MOC) toplevel.h -o moc_toplevel.cpp
151
152moc_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
28KALedMeter::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
38void KALedMeter::setRange( int r )
39{
40 mRange = r;
41 if ( mRange < 1 )
42 mRange = 1;
43 setValue( mValue );
44 update();
45}
46
47void 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
58void 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
73void 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
82void 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
90void 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
125void 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
33class KALedMeter : public QFrame
34{
35 Q_OBJECT
36public:
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
49public slots:
50 void setValue( int v );
51
52protected:
53 virtual void resizeEvent( QResizeEvent * );
54 virtual void drawContents( QPainter * );
55 void calcColorRanges();
56
57protected:
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
25int 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
7INCLUDEPATH += $(QPEDIR)/include
8 DEPENDPATH+= $(QPEDIR)/include
9LIBS += -lqpe
10
11TRANSLATIONS = ../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 @@
1Files: bin/qasteroids apps/Games/qasteroids.desktop pics/qasteroids pics/Asteroids.png
2Priority: optional
3Section: qpe/games
4Maintainer: Martin Jones <mjones@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: 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
52class KMissile : public QCanvasSprite
53{
54public:
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
63private:
64 int myAge;
65};
66
67class KBit : public QCanvasSprite
68{
69public:
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
79private:
80 int death;
81};
82
83class KExhaust : public QCanvasSprite
84{
85public:
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
95private:
96 int death;
97};
98
99class KPowerup : public QCanvasSprite
100{
101public:
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
110protected:
111 int myAge;
112 int type;
113};
114
115class KRock : public QCanvasSprite
116{
117public:
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
131private:
132 int type;
133 int skip;
134 int cskip;
135 int step;
136};
137
138class KShield : public QCanvasSprite
139{
140public:
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
43struct SLevel
44{
45 int nrocks;
46 double rockSpeed;
47};
48
49 #define MAX_LEVELS16
50
51SLevel 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
70const char *soundEvents[] =
71{
72 "ShipDestroyed",
73 "RockDestroyed",
74 0
75};
76
77const char *soundDefaults[] =
78{
79 "Explosion.wav",
80 "ploop.wav",
81 0
82};
83
84
85KAstTopLevel::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
272KAstTopLevel::~KAstTopLevel()
273{
274}
275
276void KAstTopLevel::playSound( const char * )
277{
278}
279
280void 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
327void 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
403void KAstTopLevel::showEvent( QShowEvent *e )
404{
405 QMainWindow::showEvent( e );
406 view->pause( FALSE );
407 setFocus();
408}
409
410void KAstTopLevel::hideEvent( QHideEvent *e )
411{
412 QMainWindow::hideEvent( e );
413 view->pause( TRUE );
414}
415
416void KAstTopLevel::focusInEvent( QFocusEvent * )
417{
418 view->pause( FALSE );
419 setFocus();
420}
421
422void KAstTopLevel::focusOutEvent( QFocusEvent * )
423{
424 view->pause( TRUE );
425}
426
427void 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
444void 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
463void 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
484void 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
497void 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
507void 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
35class KALedMeter;
36class QLCDNumber;
37
38class KAstTopLevel : public QMainWindow
39{
40 Q_OBJECT
41public:
42 KAstTopLevel( QWidget *parent=0, const char *name=0 );
43 virtual ~KAstTopLevel();
44
45private:
46 void playSound( const char *snd );
47 void readSoundMapping();
48 void doStats();
49
50protected:
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
58private slots:
59 void slotNewGame();
60
61 void slotShipKilled();
62 void slotRockHit( int size );
63 void slotRocksRemoved();
64
65 void slotUpdateVitals();
66
67private:
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
61struct
62{
63 int id;
64 const char *path;
65 int frames;
66}
67kas_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
87KAsteroidsView::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
126KAsteroidsView::~KAsteroidsView()
127{
128}
129
130// - - -
131
132void 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
160void 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
175void KAsteroidsView::endGame()
176{
177}
178
179void 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
193void 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
223void KAsteroidsView::setShield( bool s )
224{
225 if ( shieldTimer->isActive() && !s ) {
226 shieldTimer->stop();
227 hideShield();
228 } else {
229 shieldOn = s && mShieldCount;
230 }
231}
232
233void 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
251void 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
276void 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
307void 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
327void KAsteroidsView::hideText()
328{
329 textDy = -TEXT_SPEED;
330}
331
332// - - -
333
334void 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
343void 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
404void 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
422void 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
511void 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
527void 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
540void 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
579void 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
793void 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
868void KAsteroidsView::hideShield()
869{
870 shield->hide();
871 mShieldCount = 0;
872 shieldOn = FALSE;
873}
874
875double KAsteroidsView::randDouble()
876{
877 int v = rand();
878 return (double)v / (double)RAND_MAX;
879}
880
881int 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
40class KAsteroidsView : public QWidget
41{
42 Q_OBJECT
43public:
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
77signals:
78 void shipKilled();
79 void rockHit( int size );
80 void rocksRemoved();
81 void updateVitals();
82
83private slots:
84 void hideShield();
85
86protected:
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
102private:
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 @@
1moc_*
2*.moc
3Makefile
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
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= snake
22TARGET1 = 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
41INTERFACES =
42UICDECLS =
43UICIMPLS =
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
72all: $(DESTDIR)$(TARGET)
73
74$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
75 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
76
77moc: $(SRCMOC)
78
79tmake:
80 tmake snake.pro
81
82clean:
83 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
84 -rm -f *~ core
85 -rm -f allmoc.cpp
86
87####### Extension Modules
88
89listpromodules:
90 @echo
91
92listallmodules:
93 @echo
94
95listaddonpromodules:
96 @echo
97
98listaddonentmodules:
99 @echo
100
101
102REQUIRES=
103
104####### Sub-libraries
105
106
107###### Combined headers
108
109
110
111####### Compile
112
113snake.o: snake.cpp \
114 snake.h \
115 target.h \
116 codes.h \
117 $(QPEDIR)/include/qpe/resource.h
118
119target.o: target.cpp \
120 target.h \
121 codes.h \
122 $(QPEDIR)/include/qpe/resource.h
123
124obstacle.o: obstacle.cpp \
125 obstacle.h \
126 codes.h \
127 $(QPEDIR)/include/qpe/resource.h
128
129interface.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
137main.o: main.cpp \
138 interface.h \
139 snake.h \
140 target.h \
141 obstacle.h \
142 $(QPEDIR)/include/qpe/qpeapplication.h
143
144moc_snake.o: moc_snake.cpp \
145 snake.h
146
147moc_interface.o: moc_interface.cpp \
148 interface.h \
149 snake.h \
150 target.h \
151 obstacle.h
152
153moc_snake.cpp: snake.h
154 $(MOC) snake.h -o moc_snake.cpp
155
156moc_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;
20const 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
31SnakeGame::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
71SnakeGame::~SnakeGame()
72{
73 delete snake;
74}
75
76void 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
83void 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
111void 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
137void SnakeGame::showScore(int score)
138{
139 scorelabel->setText(tr(" Score : %1 ").arg(score) );
140}
141
142
143void SnakeGame::scoreInc()
144{
145 showScore( snake->getScore() );
146}
147
148void 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
163void SnakeGame::createTargets()
164{
165 for (int i = 0; i < targetamount; i++)
166 (void)new Target(&canvas);
167 notargets = targetamount;
168}
169
170void 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
180void 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
198void 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
211void 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
30class SnakeGame : public QMainWindow {
31 Q_OBJECT
32
33public:
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
41protected:
42 virtual void keyPressEvent(QKeyEvent*);
43 virtual void resizeEvent(QResizeEvent *e);
44
45signals:
46 void moveFaster();
47
48private slots:
49 void newGame();
50 void gameOver();
51 void wait();
52 void levelUp();
53 void scoreInc();
54
55private:
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
26int 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
26Obstacle::Obstacle(QCanvas* canvas, int x, int y)
27 : QCanvasSprite(0, canvas)
28{
29 newObstacle(x, y);
30}
31
32void 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
44int Obstacle::rtti() const
45{
46 return obstacle_rtti;
47}
48
49Obstacle::~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
22class Obstacle : public QCanvasSprite
23{
24
25public:
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 @@
1Files: bin/snake apps/Games/snake.desktop pics/snake
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: 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
29static int Piecekey[4][4] = { {6, 0, 4, 3 }, {0, 6, 2, 1 }, { 1, 3, 5, 0 }, {2, 4, 0, 5 } };
30
31Snake::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
41void 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
75void Snake::increaseSpeed()
76{
77 if (speed > 150)
78 speed = speed - 5;
79 autoMoveTimer->start(speed);
80}
81
82void 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
100void 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
128void 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
151void 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
170int Snake::lookUpPiece(Direction currentdir, Direction newdir)
171{
172 return Piecekey[currentdir][newdir];
173}
174
175void Snake::extendSnake()
176{
177 grow++;
178}
179
180void 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
192void 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
232void Snake::setScore(int amount)
233{
234 score = score + amount;
235 emit scorechanged();
236}
237
238int Snake::getScore()
239{
240 return score;
241}
242
243Snake::~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
23class Snake : public QObject
24{
25 Q_OBJECT
26
27public:
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
43signals:
44 void dead();
45 void targethit();
46 void scorechanged();
47
48private slots:
49 void moveSnake();
50 void increaseSpeed();
51
52private:
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
7INCLUDEPATH += $(QPEDIR)/include
8 DEPENDPATH+= $(QPEDIR)/include
9LIBS += -lqpe
10
11TRANSLATIONS = ../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
28Target::Target(QCanvas* canvas)
29 : QCanvasSprite(0, canvas)
30{
31 mouse = new QCanvasPixmapArray(Resource::findPixmap("snake/mouse"));
32 setSequence(mouse);
33 newTarget();
34}
35
36void 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
54bool 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
65void Target::done()
66{
67 delete this;
68}
69
70int Target::rtti() const
71{
72 return target_rtti;
73}
74
75Target::~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
23class Target : public QCanvasSprite
24{
25
26public:
27 Target(QCanvas*);
28 ~Target();
29 void newTarget();
30 void done();
31 void createMouse();
32 bool onTop();
33 int rtti() const;
34
35private:
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 @@
1moc_*
2*.moc
3Makefile
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
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= patience
22TARGET1 = 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
61INTERFACES =
62UICDECLS =
63UICIMPLS =
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
90all: $(DESTDIR)$(TARGET)
91
92$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
93 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
94
95moc: $(SRCMOC)
96
97tmake:
98 tmake solitaire.pro
99
100clean:
101 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
102 -rm -f *~ core
103 -rm -f allmoc.cpp
104
105####### Extension Modules
106
107listpromodules:
108 @echo
109
110listallmodules:
111 @echo
112
113listaddonpromodules:
114 @echo
115
116listaddonentmodules:
117 @echo
118
119
120REQUIRES=patience
121
122####### Sub-libraries
123
124
125###### Combined headers
126
127
128
129####### Compile
130
131canvascard.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
140canvasshapes.o: canvasshapes.cpp \
141 canvasshapes.h
142
143cardgame.o: cardgame.cpp \
144 cardgame.h \
145 card.h \
146 cardpile.h \
147 carddeck.h \
148 cardgamelayout.h
149
150cardgamelayout.o: cardgamelayout.cpp \
151 cardgamelayout.h \
152 cardpile.h
153
154cardpile.o: cardpile.cpp \
155 cardpile.h \
156 card.h \
157 $(QPEDIR)/include/qpe/config.h
158
159card.o: card.cpp \
160 card.h \
161 $(QPEDIR)/include/qpe/config.h
162
163carddeck.o: carddeck.cpp \
164 card.h \
165 carddeck.h
166
167canvascardgame.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
180freecellcardgame.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
195patiencecardgame.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
209canvascardwindow.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
225main.o: main.cpp \
226 canvascardwindow.h \
227 $(QPEDIR)/include/qpe/qpeapplication.h
228
229moc_canvascardwindow.o: moc_canvascardwindow.cpp \
230 canvascardwindow.h
231
232moc_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
43QBitmap *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
62QPixmap *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
93QPixmap *CanvasCard::cardsFaces = NULL;
94QPixmap *CanvasCard::cardsBacks = NULL;
95QBitmap *CanvasCard::cardsChars = NULL;
96QBitmap *CanvasCard::cardsSuits = NULL;
97QBitmap *CanvasCard::cardsCharsUpsideDown = NULL;
98QBitmap *CanvasCard::cardsSuitsUpsideDown = NULL;
99
100
101CanvasCard::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
120void 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
148void 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
210static const double flipLift = 1.5;
211
212
213void 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
236void 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
266void 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???
33static const int canvasCardId = 2434321;
34
35
36class CanvasCard : public Card, public QCanvasRectangle
37{
38public:
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
59protected:
60 /*virtual*/ void flip(void) { redraw(); }
61
62private:
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
39extern int highestZ;
40
41
42class CanvasCardPile : public QCanvasRectangle
43{
44public:
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
57protected:
58 virtual void draw( QPainter& p );
59
60private:
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
72void 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
116void 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
136void 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
154void CanvasCardPile::draw( QPainter& p )
155{
156 int ix = (int)x(), iy = (int)y();
157 p.drawImage( ix, iy, tempImage32 );
158}
159
160
161CanvasCardGame::~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
170void 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
188void 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//
243void 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
266void 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
297void 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
359void 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
38class CanvasCardPile;
39
40
41class CanvasCardGame : public QCanvasView, public CardGame
42{
43public:
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
76protected:
77 void contentsMousePressEvent(QMouseEvent *e);
78 void contentsMouseReleaseEvent(QMouseEvent *e);
79 void contentsMouseMoveEvent(QMouseEvent *e);
80
81protected:
82 // Mouse event state variables
83 bool moved;
84 CanvasCard *moving;
85 CanvasCardPile *alphaCardPile;
86 int cardXOff, cardYOff;
87
88private:
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
32CanvasCardWindow::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
131CanvasCardWindow::~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
145void 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
153void 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
169void 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
184void CanvasCardWindow::snapToggle()
185{
186 snapOn = !snapOn;
187 settings->setItemChecked(snap_id, snapOn);
188 cardGame->toggleSnap();
189}
190
191
192void CanvasCardWindow::drawnToggle()
193{
194 cardGame->toggleCardsDrawn();
195 updateDraw();
196}
197
198void 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
206void 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
217void 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
28class CanvasCardGame;
29class QPopupMenu;
30
31
32class CanvasCardWindow : public QMainWindow {
33 Q_OBJECT
34
35public:
36 CanvasCardWindow(QWidget* parent=0, const char* name=0, WFlags f=0);
37 virtual ~CanvasCardWindow();
38
39public slots:
40 void setCardBacks();
41 void changeCardBacks();
42 void snapToggle();
43 void drawnToggle();
44
45private slots:
46 void initFreecell();
47 void initPatience();
48
49protected:
50 virtual void resizeEvent(QResizeEvent *e);
51
52 void updateDraw();
53private:
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
25CanvasRoundRect::CanvasRoundRect(int x, int y, QCanvas *canvas) :
26 QCanvasRectangle( x, y, 23, 36, canvas)
27{
28 setZ(0);
29 show();
30}
31
32
33void CanvasRoundRect::redraw()
34{
35 hide();
36 show();
37}
38
39
40void CanvasRoundRect::drawShape(QPainter &p)
41{
42 p.drawRoundRect( (int)x(), (int)y(), 23, 36);
43}
44
45
46CanvasCircleOrCross::CanvasCircleOrCross(int x, int y, QCanvas *canvas) :
47 QCanvasRectangle( x, y, 21, 21, canvas), circleShape(TRUE)
48{
49 show();
50}
51
52
53void CanvasCircleOrCross::redraw()
54{
55 hide();
56 show();
57}
58
59
60void CanvasCircleOrCross::setCircle()
61{
62 circleShape = TRUE;
63 redraw();
64}
65
66
67void CanvasCircleOrCross::setCross()
68{
69 circleShape = FALSE;
70 redraw();
71}
72
73
74void 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
27class QPainter;
28
29
30class CanvasRoundRect : QCanvasRectangle
31{
32public:
33 CanvasRoundRect(int x, int y, QCanvas *canvas);
34 void redraw();
35protected:
36 void drawShape(QPainter &p);
37};
38
39
40class CanvasCircleOrCross : QCanvasRectangle
41{
42public:
43 CanvasCircleOrCross(int x, int y, QCanvas *canvas);
44 void redraw();
45 void setCircle();
46 void setCross();
47protected:
48 void drawShape(QPainter &p);
49private:
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/*
29Card( eValue v, eSuit s, bool f ) :
30 val(v), suit(s), faceUp(f), showing(FALSE), ix(0), iy(0), iz(0), cardPile(NULL) { }
31virtual ~Card() { }
32eValue getValue() { return val; }
33eSuit getSuit() { return suit; }
34CardPile *getCardPile() { return cardPile; }
35bool isFacing() { return faceUp; }
36bool isShowing() { return showing; }
37bool isRed() { return ((suit == diamonds) || (suit == hearts)); }
38int getX(void) { return ix; }
39int getY(void) { return iy; }
40int getZ(void) { return iz; }
41void setCardPile(CardPile *p) { cardPile = p; }
42void setFace(bool f) { faceUp = f; }
43void flip(void) { flipTo(getX(), getY()); }
44virtual void setPos(int x, int y, int z) { ix = x; iy = y; iz = z; }
45virtual void move(int x, int y) { ix = x; iy = y; }
46virtual void move(QPoint p) { ix = p.x(); iy = p.y(); }
47virtual void flipTo(int x, int y, int steps = 8) { ix = x; iy = y; faceUp = !faceUp; redraw(); Q_UNUSED(steps); }
48virtual void showCard(void) { showing = TRUE; }
49virtual void hideCard(void) { showing = FALSE; }
50virtual 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
27class CardPile;
28
29
30enum eSuit {
31 jokerSuit = 0, clubs, spades, diamonds, hearts
32};
33
34
35enum eValue {
36 jokerVal = 0, ace, two, three, four, five,
37 six, seven, eight, nine, ten, jack, queen, king
38};
39
40
41class Card
42{
43public:
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; }
71protected:
72 virtual void redraw(void) { }
73private:
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
26CardDeck::CardDeck(int jokers) : numberOfJokers(jokers), deckCreated(FALSE)
27{
28 cards = new (Card *)[getNumberOfCards()];
29}
30
31
32CardDeck::~CardDeck()
33{
34 for (int i = 0; i < getNumberOfCards(); i++)
35 delete cards[i];
36 delete cards;
37}
38
39
40void 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
52void 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
64int CardDeck::getNumberOfCards()
65{
66 return 52 + getNumberOfJokers();
67}
68
69
70int CardDeck::getNumberOfJokers()
71{
72 return numberOfJokers;
73}
74
75
76Card *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
24class Card;
25
26
27class CardDeck
28{
29public:
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;
42private:
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
23void 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
31class CardGame : public CardGameLayout, public CardDeck
32{
33public:
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); }
40private:
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
23CardGameLayout::~CardGameLayout()
24{
25 // Should I just do setAutoDelete( TRUE ); ?
26 for (CardPile *p = first(); p != NULL; p = next())
27 delete p;
28}
29
30
31CardPile *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
48void CardGameLayout::beginDealing()
49{
50 for (CardPile *p = first(); p != NULL; p = next())
51 p->beginDealing();
52}
53
54
55void 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
28class CardGameLayout : public QList<CardPile>
29{
30public:
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
30CardPile::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
41int CardPile::distanceFromPile(int x, int y) {
42 return (pileCenterX-x)*(pileCenterX-x)+(pileCenterY-y)*(pileCenterY-y);
43}
44
45
46int CardPile::distanceFromNextPos(int x, int y) {
47 return (pileNextX-x)*(pileNextX-x)+(pileNextY-y)*(pileNextY-y);
48}
49
50
51Card *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
62bool CardPile::kingOnTop() {
63 Card *top = cardOnTop();
64 return top && top->getValue() == king;
65}
66
67
68bool 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
78bool 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
88bool 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
98void 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
28enum ePileStackingType {
29 pileCascades = 0, pileStacks, pileCascadesOrStacks
30};
31
32
33enum ePileFaceingType {
34 pileFaceUp = 0, pileFaceDown, pileFaceUpOrDown
35};
36
37
38class Card;
39class Config;
40
41
42class CardPile : public QList<Card>
43{
44public:
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
89protected:
90 int pileX, pileY;
91 int pileNextX, pileNextY;
92 int pileWidth, pileHeight;
93 int pileCenterX, pileCenterY;
94 int pileRadius;
95private:
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
23extern int highestZ;
24int numberOfFreeCells = 4;
25
26
27FreecellCardGame::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
47void 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
68bool 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
81void 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
117void 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
27extern int numberOfFreeCells;
28
29
30class FreecellDiscardPile : public PatienceDiscardPile
31{
32public:
33 FreecellDiscardPile(int x, int y, QCanvas *canvas) :
34 PatienceDiscardPile(x, y, canvas) { }
35
36};
37
38
39class FreecellWorkingPile : public PatienceWorkingPile
40{
41public:
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
99class FreecellFreecellPile : public CardPile, public CanvasRoundRect
100{
101public:
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
124class FreecellCardGame : public CanvasCardGame
125{
126public:
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;
144private:
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
26int 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
23int highestZ = 0;
24
25
26PatienceCardGame::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
47PatienceCardGame::~PatienceCardGame()
48{
49 delete circleCross;
50 delete rectangle;
51 delete faceDownDealingPile;
52 delete faceUpDealingPile;
53}
54
55
56void 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
90void 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
140void 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
160bool 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
209void 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
33class PatienceFaceDownDeck : public CardPile, public CanvasRoundRect
34{
35public:
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
53class PatienceFaceUpDeck : public CardPile, public CanvasRoundRect
54{
55public:
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
73class PatienceDiscardPile : public CardPile, public CanvasRoundRect
74{
75public:
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
95class PatienceWorkingPile : public CardPile, public CanvasRoundRect
96{
97public:
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 }
161private:
162 QPoint top;
163
164};
165
166
167class PatienceCardGame : public CanvasCardGame
168{
169public:
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 );
194private:
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 @@
1Files: bin/patience apps/Games/patience.desktop pics/cards
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: 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
12INCLUDEPATH += $(QPEDIR)/include
13 DEPENDPATH+= $(QPEDIR)/include
14LIBS += -lqpe
15
16 REQUIRES= patience
17
18TRANSLATIONS = ../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 @@
1moc_*
2*.moc
3Makefile
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
17DESTDIR = ../bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= tetrix
22TARGET1 = 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
41INTERFACES =
42UICDECLS =
43UICIMPLS =
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
72all: $(DESTDIR)$(TARGET)
73
74$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
75 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
76
77moc: $(SRCMOC)
78
79tmake:
80 tmake tetrix.pro
81
82clean:
83 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
84 -rm -f *~ core
85 -rm -f allmoc.cpp
86
87####### Extension Modules
88
89listpromodules:
90 @echo
91
92listallmodules:
93 @echo
94
95listaddonpromodules:
96 @echo
97
98listaddonentmodules:
99 @echo
100
101
102REQUIRES=
103
104####### Sub-libraries
105
106
107###### Combined headers
108
109
110
111####### Compile
112
113main.o: main.cpp \
114 qtetrix.h \
115 qtetrixb.h \
116 gtetrix.h \
117 tpiece.h \
118 $(QPEDIR)/include/qpe/qpeapplication.h
119
120gtetrix.o: gtetrix.cpp \
121 gtetrix.h \
122 tpiece.h
123
124qtetrix.o: qtetrix.cpp \
125 qtetrix.h \
126 qtetrixb.h \
127 gtetrix.h \
128 tpiece.h \
129 $(QPEDIR)/include/qpe/resource.h
130
131qtetrixb.o: qtetrixb.cpp \
132 qtetrixb.h \
133 gtetrix.h \
134 tpiece.h \
135 qtetrix.h
136
137tpiece.o: tpiece.cpp \
138 tpiece.h
139
140moc_qtetrix.o: moc_qtetrix.cpp \
141 qtetrix.h \
142 qtetrixb.h \
143 gtetrix.h \
144 tpiece.h
145
146moc_qtetrixb.o: moc_qtetrixb.cpp \
147 qtetrixb.h \
148 gtetrix.h \
149 tpiece.h
150
151moc_qtetrix.cpp: qtetrix.h
152 $(MOC) qtetrix.h -o moc_qtetrix.cpp
153
154moc_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
26GenericTetrix::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
48GenericTetrix::~GenericTetrix()
49{
50 delete[] boardPtr;
51}
52
53
54void 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
75void 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
86void 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
97void 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
112void 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
123void 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
155void 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
175void 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
185void 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
195void 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
206void 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
217void 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
235void 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
246void 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
264void GenericTetrix::removePiece()
265{
266 erasePiece();
267 currentLine = -1;
268}
269
270void GenericTetrix::drawNextSquare(int,int,int)
271{
272
273}
274
275void GenericTetrix::pieceDropped(int)
276{
277 newPiece();
278}
279
280void GenericTetrix::updateRemoved(int)
281{
282}
283
284void GenericTetrix::updateScore(int)
285{
286}
287
288void GenericTetrix::updateLevel(int)
289{
290}
291
292void 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
336void 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
349void 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
362void 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
376void 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
393void 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
415int 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
435int 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
454void 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
463void GenericTetrix::position(TetrixPiece &piece)
464{
465 if (currentLine == -1)
466 return;
467
468 optimizedMove(currentPos,currentLine,piece);
469}
470
471void 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
28class GenericTetrix
29{
30public:
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
69private:
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
25int 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 @@
1Files: bin/tetrix apps/Games/tetrix.desktop
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Arch: iPAQ
7Version: $QPE_VERSION-3
8Depends: qpe-base ($QPE_VERSION)
9Description: 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
33void 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
57ShowNextPiece::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
64void 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
74void 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
83void 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
96QTetrix::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
162void QTetrix::gameOver()
163{
164}
165
166
167void 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
32class QLabel;
33
34class ShowNextPiece : public QFrame
35{
36 Q_OBJECT
37 friend class QTetrix;
38public:
39 ShowNextPiece( QWidget *parent=0, const char *name=0 );
40public slots:
41 void drawNextSquare( int x, int y,QColor *color );
42signals:
43 void update();
44private:
45 void paintEvent( QPaintEvent * );
46 void resizeEvent( QResizeEvent * );
47
48 int blockWidth,blockHeight;
49 int xOffset,yOffset;
50};
51
52
53class QTetrix : public QMainWindow
54{
55 Q_OBJECT
56public:
57 QTetrix( QWidget *parent=0, const char *name=0, WFlags f=0 );
58 void startGame() { board->startGame(); }
59
60public slots:
61 void gameOver();
62 void quit();
63private:
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
74void 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
28const int waitAfterLineTime = 500;
29
30QTetrixBoard::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
56void 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
66void 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
81void 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
112void 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
120void 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
130void QTetrixBoard::updateScore( int newScore )
131{
132 emit updateScoreSignal( newScore );
133}
134
135void QTetrixBoard::updateLevel( int newLevel )
136{
137 timer->stop();
138 updateTimeoutTime();
139 timer->start( timeoutTime );
140 emit updateLevelSignal( newLevel );
141}
142
143void QTetrixBoard::pieceDropped(int)
144{
145 if ( waitingAfterLine ) // give player a break if a line has been removed
146 return;
147 newPiece();
148}
149
150void QTetrixBoard::gameOver()
151{
152 timer->stop();
153 noGame = TRUE;
154 emit gameOverSignal();
155}
156
157void 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
169void 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
208void 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
218void 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
248void 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
28class QTimer;
29
30class QTetrixBoard : public QFrame, public GenericTetrix
31{
32 Q_OBJECT
33public:
34 QTetrixBoard( QWidget *parent=0, const char *name=0 );
35
36 void gameOver();
37 void startGame(int gameType = 0,int fillRandomLines = 0);
38
39public slots:
40 void timeout();
41 void updateNext(){ GenericTetrix::updateNext(); }
42 void key(QKeyEvent *e) { keyPressEvent(e); }
43 void start() { startGame(); }
44 void pause();
45
46signals:
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
53public: // until we have keyboard focus, should be protected
54 void keyPressEvent( QKeyEvent * );
55
56private:
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
14INCLUDEPATH += $(QPEDIR)/include
15 DEPENDPATH+= $(QPEDIR)/include
16LIBS += -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
27void 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
39void 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
51int 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
60int 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
70int 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
79int 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
88void 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
172double TetrixPiece::randomSeed = 0.33333;
173
174void 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
192int 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
25class TetrixPiece
26{
27public:
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
49private:
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 @@
1moc_*
2Makefile
3newgamebase.h
4rulesbase.h
5newgamebase.cpp
6rulesbase.cpp
diff --git a/noncore/games/wordgame/Makefile.in b/noncore/games/wordgame/Makefile.in
new file mode 100644
index 0000000..5627414
--- a/dev/null
+++ b/noncore/games/wordgame/Makefile.in
@@ -0,0 +1,168 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= wordgame
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =wordgame.h
27 SOURCES =main.cpp \
28 wordgame.cpp
29 OBJECTS =main.o \
30 wordgame.o \
31 newgamebase.o \
32 rulesbase.o
33INTERFACES = newgamebase.ui \
34 rulesbase.ui
35UICDECLS = newgamebase.h \
36 rulesbase.h
37UICIMPLS = newgamebase.cpp \
38 rulesbase.cpp
39 SRCMOC =moc_wordgame.cpp \
40 moc_newgamebase.cpp \
41 moc_rulesbase.cpp
42 OBJMOC =moc_wordgame.o \
43 moc_newgamebase.o \
44 moc_rulesbase.o
45
46
47####### Implicit rules
48
49.SUFFIXES: .cpp .cxx .cc .C .c
50
51.cpp.o:
52 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
53
54.cxx.o:
55 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
56
57.cc.o:
58 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
59
60.C.o:
61 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
62
63.c.o:
64 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
65
66####### Build rules
67
68
69all: $(DESTDIR)$(TARGET)
70
71$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
72 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
73
74moc: $(SRCMOC)
75
76tmake:
77 tmake wordgame.pro
78
79clean:
80 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
81 -rm -f *~ core
82 -rm -f allmoc.cpp
83
84####### Extension Modules
85
86listpromodules:
87 @echo
88
89listallmodules:
90 @echo
91
92listaddonpromodules:
93 @echo
94
95listaddonentmodules:
96 @echo
97
98
99REQUIRES=
100
101####### Sub-libraries
102
103
104###### Combined headers
105
106
107
108####### Compile
109
110main.o: main.cpp \
111 wordgame.h \
112 newgamebase.h \
113 rulesbase.h \
114 $(QPEDIR)/include/qpe/qdawg.h \
115 $(QPEDIR)/include/qpe/applnk.h \
116 $(QPEDIR)/include/qpe/qpeapplication.h
117
118wordgame.o: wordgame.cpp \
119 wordgame.h \
120 newgamebase.h \
121 rulesbase.h \
122 $(QPEDIR)/include/qpe/qdawg.h \
123 $(QPEDIR)/include/qpe/applnk.h \
124 $(QPEDIR)/include/qpe/global.h \
125 $(QPEDIR)/include/qpe/filemanager.h \
126 $(QPEDIR)/include/qpe/resource.h \
127 $(QPEDIR)/include/qpe/config.h \
128 $(QPEDIR)/include/qpe/qpetoolbar.h
129
130newgamebase.h: newgamebase.ui
131 $(UIC) newgamebase.ui -o $(INTERFACE_DECL_PATH)/newgamebase.h
132
133newgamebase.cpp: newgamebase.ui
134 $(UIC) newgamebase.ui -i newgamebase.h -o newgamebase.cpp
135
136rulesbase.h: rulesbase.ui
137 $(UIC) rulesbase.ui -o $(INTERFACE_DECL_PATH)/rulesbase.h
138
139rulesbase.cpp: rulesbase.ui
140 $(UIC) rulesbase.ui -i rulesbase.h -o rulesbase.cpp
141
142newgamebase.o: newgamebase.cpp
143
144rulesbase.o: rulesbase.cpp
145
146moc_wordgame.o: moc_wordgame.cpp \
147 wordgame.h \
148 newgamebase.h \
149 rulesbase.h \
150 $(QPEDIR)/include/qpe/qdawg.h \
151 $(QPEDIR)/include/qpe/applnk.h
152
153moc_newgamebase.o: moc_newgamebase.cpp \
154 newgamebase.h
155
156moc_rulesbase.o: moc_rulesbase.cpp \
157 rulesbase.h
158
159moc_wordgame.cpp: wordgame.h
160 $(MOC) wordgame.h -o moc_wordgame.cpp
161
162moc_newgamebase.cpp: newgamebase.h
163 $(MOC) newgamebase.h -o moc_newgamebase.cpp
164
165moc_rulesbase.cpp: rulesbase.h
166 $(MOC) rulesbase.h -o moc_rulesbase.cpp
167
168
diff --git a/noncore/games/wordgame/calcdist b/noncore/games/wordgame/calcdist
new file mode 100755
index 0000000..faf31f1
--- a/dev/null
+++ b/noncore/games/wordgame/calcdist
@@ -0,0 +1,27 @@
1#!/usr/bin/perl
2
3# Usage: cat dictionaries | grep -v '[^a-z]' | calcdist n score
4#
5# Given a lot of words, find an appropriate distribution
6# into n tiles with tile values proportional to the square root
7# of the ratio of score to the tile's frequency.
8
9$n = shift;
10$score = shift;
11
12while (<>) {
13 chomp;
14 for $c ( split "", $_ ) {
15 $freq{$c}++;
16 $t++;
17 }
18}
19
20for $c ( sort { $freq{$a} <=> $freq{$b} } keys %freq ) {
21 #print "$c: $freq{$c}\n";
22 $need = int($freq{$c}*$n/$t+0.5) || 1;
23 $value = int(sqrt($score/($freq{$c}*$n/$t))+0.5) || 1;
24 $t -= $freq{$c};
25 $n -= $need;
26 print "$need $c $value\n";
27}
diff --git a/noncore/games/wordgame/main.cpp b/noncore/games/wordgame/main.cpp
new file mode 100644
index 0000000..cd4600e
--- a/dev/null
+++ b/noncore/games/wordgame/main.cpp
@@ -0,0 +1,34 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "wordgame.h"
22
23#include <qpe/qpeapplication.h>
24
25int main( int argc, char ** argv )
26{
27 QPEApplication a( argc, argv );
28
29 WordGame mw;
30 //QPEApplication::setInputMethodHint( &mw, QPEApplication::AlwaysOff );
31 a.showMainWidget(&mw);
32
33 return a.exec();
34}
diff --git a/noncore/games/wordgame/newgamebase.ui b/noncore/games/wordgame/newgamebase.ui
new file mode 100644
index 0000000..3b6570b
--- a/dev/null
+++ b/noncore/games/wordgame/newgamebase.ui
@@ -0,0 +1,337 @@
1<!DOCTYPE UI><UI>
2<class>NewGameBase</class>
3<widget>
4 <class>QWidget</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>Form1</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>290</width>
15 <height>443</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Form1</string>
21 </property>
22 <property>
23 <name>layoutMargin</name>
24 </property>
25 <property>
26 <name>layoutSpacing</name>
27 </property>
28 <vbox>
29 <property stdset="1">
30 <name>margin</name>
31 <number>8</number>
32 </property>
33 <property stdset="1">
34 <name>spacing</name>
35 <number>3</number>
36 </property>
37 <widget>
38 <class>QGroupBox</class>
39 <property stdset="1">
40 <name>name</name>
41 <cstring>GroupBox1</cstring>
42 </property>
43 <property stdset="1">
44 <name>title</name>
45 <string>Players</string>
46 </property>
47 <property>
48 <name>layoutMargin</name>
49 </property>
50 <property>
51 <name>layoutSpacing</name>
52 </property>
53 <vbox>
54 <property stdset="1">
55 <name>margin</name>
56 <number>7</number>
57 </property>
58 <property stdset="1">
59 <name>spacing</name>
60 <number>2</number>
61 </property>
62 <widget>
63 <class>QComboBox</class>
64 <item>
65 <property>
66 <name>text</name>
67 <string></string>
68 </property>
69 </item>
70 <item>
71 <property>
72 <name>text</name>
73 <string>AI3: Smart AI player</string>
74 </property>
75 </item>
76 <property stdset="1">
77 <name>name</name>
78 <cstring>player0</cstring>
79 </property>
80 <property stdset="1">
81 <name>editable</name>
82 <bool>true</bool>
83 </property>
84 </widget>
85 <widget>
86 <class>QComboBox</class>
87 <item>
88 <property>
89 <name>text</name>
90 <string></string>
91 </property>
92 </item>
93 <item>
94 <property>
95 <name>text</name>
96 <string>AI3: Smart AI player</string>
97 </property>
98 </item>
99 <property stdset="1">
100 <name>name</name>
101 <cstring>player1</cstring>
102 </property>
103 <property stdset="1">
104 <name>editable</name>
105 <bool>true</bool>
106 </property>
107 </widget>
108 <widget>
109 <class>QComboBox</class>
110 <item>
111 <property>
112 <name>text</name>
113 <string></string>
114 </property>
115 </item>
116 <item>
117 <property>
118 <name>text</name>
119 <string>AI3: Smart AI player</string>
120 </property>
121 </item>
122 <property stdset="1">
123 <name>name</name>
124 <cstring>player2</cstring>
125 </property>
126 <property stdset="1">
127 <name>editable</name>
128 <bool>true</bool>
129 </property>
130 </widget>
131 <widget>
132 <class>QComboBox</class>
133 <item>
134 <property>
135 <name>text</name>
136 <string></string>
137 </property>
138 </item>
139 <item>
140 <property>
141 <name>text</name>
142 <string>AI3: Smart AI player</string>
143 </property>
144 </item>
145 <property stdset="1">
146 <name>name</name>
147 <cstring>player3</cstring>
148 </property>
149 <property stdset="1">
150 <name>editable</name>
151 <bool>true</bool>
152 </property>
153 </widget>
154 <widget>
155 <class>QComboBox</class>
156 <item>
157 <property>
158 <name>text</name>
159 <string></string>
160 </property>
161 </item>
162 <item>
163 <property>
164 <name>text</name>
165 <string>AI3: Smart AI player</string>
166 </property>
167 </item>
168 <property stdset="1">
169 <name>name</name>
170 <cstring>player4</cstring>
171 </property>
172 <property stdset="1">
173 <name>editable</name>
174 <bool>true</bool>
175 </property>
176 </widget>
177 <widget>
178 <class>QComboBox</class>
179 <item>
180 <property>
181 <name>text</name>
182 <string></string>
183 </property>
184 </item>
185 <item>
186 <property>
187 <name>text</name>
188 <string>AI3: Smart AI player</string>
189 </property>
190 </item>
191 <property stdset="1">
192 <name>name</name>
193 <cstring>player5</cstring>
194 </property>
195 <property stdset="1">
196 <name>editable</name>
197 <bool>true</bool>
198 </property>
199 </widget>
200 </vbox>
201 </widget>
202 <widget>
203 <class>QGroupBox</class>
204 <property stdset="1">
205 <name>name</name>
206 <cstring>GroupBox2</cstring>
207 </property>
208 <property stdset="1">
209 <name>title</name>
210 <string>Rules</string>
211 </property>
212 <property>
213 <name>layoutMargin</name>
214 </property>
215 <property>
216 <name>layoutSpacing</name>
217 </property>
218 <hbox>
219 <property stdset="1">
220 <name>margin</name>
221 <number>7</number>
222 </property>
223 <property stdset="1">
224 <name>spacing</name>
225 <number>2</number>
226 </property>
227 <widget>
228 <class>QComboBox</class>
229 <property stdset="1">
230 <name>name</name>
231 <cstring>rules</cstring>
232 </property>
233 <property stdset="1">
234 <name>sizePolicy</name>
235 <sizepolicy>
236 <hsizetype>3</hsizetype>
237 <vsizetype>0</vsizetype>
238 </sizepolicy>
239 </property>
240 </widget>
241 </hbox>
242 </widget>
243 <spacer>
244 <property>
245 <name>name</name>
246 <cstring>Spacer1</cstring>
247 </property>
248 <property stdset="1">
249 <name>orientation</name>
250 <enum>Vertical</enum>
251 </property>
252 <property stdset="1">
253 <name>sizeType</name>
254 <enum>Expanding</enum>
255 </property>
256 <property>
257 <name>sizeHint</name>
258 <size>
259 <width>20</width>
260 <height>20</height>
261 </size>
262 </property>
263 <property>
264 <name>sizeHint</name>
265 <size>
266 <width>20</width>
267 <height>20</height>
268 </size>
269 </property>
270 </spacer>
271 <widget>
272 <class>QLayoutWidget</class>
273 <property stdset="1">
274 <name>name</name>
275 <cstring>Layout1</cstring>
276 </property>
277 <hbox>
278 <property stdset="1">
279 <name>margin</name>
280 <number>0</number>
281 </property>
282 <property stdset="1">
283 <name>spacing</name>
284 <number>6</number>
285 </property>
286 <spacer>
287 <property>
288 <name>name</name>
289 <cstring>Horizontal Spacing2</cstring>
290 </property>
291 <property stdset="1">
292 <name>orientation</name>
293 <enum>Horizontal</enum>
294 </property>
295 <property stdset="1">
296 <name>sizeType</name>
297 <enum>Expanding</enum>
298 </property>
299 <property>
300 <name>sizeHint</name>
301 <size>
302 <width>20</width>
303 <height>20</height>
304 </size>
305 </property>
306 <property>
307 <name>sizeHint</name>
308 <size>
309 <width>20</width>
310 <height>20</height>
311 </size>
312 </property>
313 </spacer>
314 <widget>
315 <class>QPushButton</class>
316 <property stdset="1">
317 <name>name</name>
318 <cstring>buttonOk</cstring>
319 </property>
320 <property stdset="1">
321 <name>text</name>
322 <string>&amp;Start</string>
323 </property>
324 <property stdset="1">
325 <name>autoDefault</name>
326 <bool>true</bool>
327 </property>
328 <property stdset="1">
329 <name>default</name>
330 <bool>true</bool>
331 </property>
332 </widget>
333 </hbox>
334 </widget>
335 </vbox>
336</widget>
337</UI>
diff --git a/noncore/games/wordgame/qpe-wordgame.control b/noncore/games/wordgame/qpe-wordgame.control
new file mode 100644
index 0000000..2293f52
--- a/dev/null
+++ b/noncore/games/wordgame/qpe-wordgame.control
@@ -0,0 +1,10 @@
1Files: bin/wordgame apps/Games/wordgame.desktop
2Priority: optional
3Section: qpe/games
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Crossword game
9 A crossword game for the Qtopia environment.
10 Play against the computer or human opponents.
diff --git a/noncore/games/wordgame/rulesbase.ui b/noncore/games/wordgame/rulesbase.ui
new file mode 100644
index 0000000..31cc402
--- a/dev/null
+++ b/noncore/games/wordgame/rulesbase.ui
@@ -0,0 +1,274 @@
1<!DOCTYPE UI><UI>
2<class>RulesBase</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>RulesBase</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>283</width>
15 <height>264</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Game Rules</string>
21 </property>
22 <property stdset="1">
23 <name>sizeGripEnabled</name>
24 <bool>false</bool>
25 </property>
26 <vbox>
27 <property stdset="1">
28 <name>margin</name>
29 <number>11</number>
30 </property>
31 <property stdset="1">
32 <name>spacing</name>
33 <number>6</number>
34 </property>
35 <widget>
36 <class>QLayoutWidget</class>
37 <property stdset="1">
38 <name>name</name>
39 <cstring>Layout3</cstring>
40 </property>
41 <hbox>
42 <property stdset="1">
43 <name>margin</name>
44 <number>0</number>
45 </property>
46 <property stdset="1">
47 <name>spacing</name>
48 <number>6</number>
49 </property>
50 <widget>
51 <class>QLabel</class>
52 <property stdset="1">
53 <name>name</name>
54 <cstring>TextLabel1</cstring>
55 </property>
56 <property stdset="1">
57 <name>text</name>
58 <string>Name:</string>
59 </property>
60 </widget>
61 <widget>
62 <class>QLineEdit</class>
63 <property stdset="1">
64 <name>name</name>
65 <cstring>gamename</cstring>
66 </property>
67 </widget>
68 </hbox>
69 </widget>
70 <widget>
71 <class>QGroupBox</class>
72 <property stdset="1">
73 <name>name</name>
74 <cstring>GroupBox3</cstring>
75 </property>
76 <property stdset="1">
77 <name>title</name>
78 <string>Board</string>
79 </property>
80 <property>
81 <name>layoutMargin</name>
82 </property>
83 <property>
84 <name>layoutSpacing</name>
85 </property>
86 <hbox>
87 <property stdset="1">
88 <name>margin</name>
89 <number>5</number>
90 </property>
91 <property stdset="1">
92 <name>spacing</name>
93 <number>4</number>
94 </property>
95 <widget>
96 <class>QLabel</class>
97 <property stdset="1">
98 <name>name</name>
99 <cstring>TextLabel2</cstring>
100 </property>
101 <property stdset="1">
102 <name>sizePolicy</name>
103 <sizepolicy>
104 <hsizetype>0</hsizetype>
105 <vsizetype>1</vsizetype>
106 </sizepolicy>
107 </property>
108 <property stdset="1">
109 <name>text</name>
110 <string>Size:</string>
111 </property>
112 </widget>
113 <widget>
114 <class>QSpinBox</class>
115 <property stdset="1">
116 <name>name</name>
117 <cstring>width</cstring>
118 </property>
119 <property stdset="1">
120 <name>maxValue</name>
121 <number>15</number>
122 </property>
123 <property stdset="1">
124 <name>minValue</name>
125 <number>3</number>
126 </property>
127 <property stdset="1">
128 <name>value</name>
129 <number>15</number>
130 </property>
131 </widget>
132 <widget>
133 <class>QSpinBox</class>
134 <property stdset="1">
135 <name>name</name>
136 <cstring>height</cstring>
137 </property>
138 <property stdset="1">
139 <name>maxValue</name>
140 <number>15</number>
141 </property>
142 <property stdset="1">
143 <name>minValue</name>
144 <number>3</number>
145 </property>
146 <property stdset="1">
147 <name>value</name>
148 <number>15</number>
149 </property>
150 </widget>
151 <widget>
152 <class>QPushButton</class>
153 <property stdset="1">
154 <name>name</name>
155 <cstring>editboard</cstring>
156 </property>
157 <property stdset="1">
158 <name>text</name>
159 <string>Edit...</string>
160 </property>
161 </widget>
162 </hbox>
163 </widget>
164 <widget>
165 <class>QTable</class>
166 <property stdset="1">
167 <name>name</name>
168 <cstring>tiletable</cstring>
169 </property>
170 </widget>
171 <widget>
172 <class>QLayoutWidget</class>
173 <property stdset="1">
174 <name>name</name>
175 <cstring>Layout3</cstring>
176 </property>
177 <hbox>
178 <property stdset="1">
179 <name>margin</name>
180 <number>0</number>
181 </property>
182 <property stdset="1">
183 <name>spacing</name>
184 <number>6</number>
185 </property>
186 <widget>
187 <class>QPushButton</class>
188 <property stdset="1">
189 <name>name</name>
190 <cstring>buttonDelete</cstring>
191 </property>
192 <property stdset="1">
193 <name>text</name>
194 <string>Delete</string>
195 </property>
196 <property stdset="1">
197 <name>autoDefault</name>
198 <bool>true</bool>
199 </property>
200 </widget>
201 <spacer>
202 <property>
203 <name>name</name>
204 <cstring>Horizontal Spacing2</cstring>
205 </property>
206 <property stdset="1">
207 <name>orientation</name>
208 <enum>Horizontal</enum>
209 </property>
210 <property stdset="1">
211 <name>sizeType</name>
212 <enum>Expanding</enum>
213 </property>
214 <property>
215 <name>sizeHint</name>
216 <size>
217 <width>20</width>
218 <height>20</height>
219 </size>
220 </property>
221 </spacer>
222 <widget>
223 <class>QPushButton</class>
224 <property stdset="1">
225 <name>name</name>
226 <cstring>buttonOk</cstring>
227 </property>
228 <property stdset="1">
229 <name>text</name>
230 <string>&amp;OK</string>
231 </property>
232 <property stdset="1">
233 <name>autoDefault</name>
234 <bool>true</bool>
235 </property>
236 <property stdset="1">
237 <name>default</name>
238 <bool>true</bool>
239 </property>
240 </widget>
241 <widget>
242 <class>QPushButton</class>
243 <property stdset="1">
244 <name>name</name>
245 <cstring>buttonCancel</cstring>
246 </property>
247 <property stdset="1">
248 <name>text</name>
249 <string>&amp;Cancel</string>
250 </property>
251 <property stdset="1">
252 <name>autoDefault</name>
253 <bool>true</bool>
254 </property>
255 </widget>
256 </hbox>
257 </widget>
258 </vbox>
259</widget>
260<connections>
261 <connection>
262 <sender>buttonOk</sender>
263 <signal>clicked()</signal>
264 <receiver>RulesBase</receiver>
265 <slot>accept()</slot>
266 </connection>
267 <connection>
268 <sender>buttonCancel</sender>
269 <signal>clicked()</signal>
270 <receiver>RulesBase</receiver>
271 <slot>reject()</slot>
272 </connection>
273</connections>
274</UI>
diff --git a/noncore/games/wordgame/wordgame.cpp b/noncore/games/wordgame/wordgame.cpp
new file mode 100644
index 0000000..ca4352d
--- a/dev/null
+++ b/noncore/games/wordgame/wordgame.cpp
@@ -0,0 +1,1476 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21
22#include "wordgame.h"
23
24#include <qpe/applnk.h>
25#include <qpe/global.h>
26#include <qpe/filemanager.h>
27#include <qpe/resource.h>
28#include <qpe/config.h>
29
30#include <qapplication.h>
31#include <qmessagebox.h>
32#include <qcombobox.h>
33#include <qdatetime.h>
34#include <qfileinfo.h>
35#include <qfile.h>
36#include <qdir.h>
37#include <qiconset.h>
38#include <qlabel.h>
39#include <qlineedit.h>
40#include <qpushbutton.h>
41#include <qtextstream.h>
42#include <qtimer.h>
43#include <qpe/qpetoolbar.h>
44#include <qtoolbutton.h>
45#include <qvbox.h>
46#include <qwidgetstack.h>
47#include <qpainter.h>
48#include <qlayout.h>
49#include <qregexp.h>
50
51#include <stdlib.h>
52#include <unistd.h>
53#include <pwd.h>
54#include <sys/types.h>
55
56enum RuleEffects {
57 Multiplier=15,
58 MultiplyAll=64,
59 Start=128
60};
61
62static const int rack_tiles=7;
63
64const char* sampleWGR=
65 "wordgame_shapes\n"
66 "15 15\n"
67 "400001040100004\n"
68 "030000000000030\n"
69 "002002000200200\n"
70 "000300020003000\n"
71 "000020000020000\n"
72 "102001000100201\n"
73 "000000202000000\n"
74 "400200050002004\n"
75 "000000202000000\n"
76 "102001000100201\n"
77 "000020000020000\n"
78 "000300020003000\n"
79 "002002000200200\n"
80 "030000000000030\n"
81 "400001040100004\n"
82 "1 2 3 66 67 194 100 0\n"
83 "1 j 8\n"
84 "1 q 7\n"
85 "1 x 6\n"
86 "1 z 6\n"
87 "1 w 4\n"
88 "1 k 4\n"
89 "1 v 3\n"
90 "1 f 3\n"
91 "2 y 3\n"
92 "2 h 2\n"
93 "2 b 2\n"
94 "2 m 2\n"
95 "3 p 2\n"
96 "3 g 2\n"
97 "3 u 2\n"
98 "4 d 2\n"
99 "4 c 2\n"
100 "5 l 1\n"
101 "5 o 1\n"
102 "7 t 1\n"
103 "7 n 1\n"
104 "7 a 1\n"
105 "7 r 1\n"
106 "8 s 1\n"
107 "8 i 1\n"
108 "11 e 1\n"
109 "0\n";
110
111WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) :
112 QMainWindow(parent, name, fl)
113{
114 setIcon( Resource::loadPixmap( "wordgame" ) );
115 setCaption( tr("Word Game") );
116
117 setToolBarsMovable( FALSE );
118 vbox = new QVBox(this);
119
120 setCentralWidget(vbox);
121 toolbar = new QPEToolBar(this);
122 addToolBar(toolbar, Bottom);
123 reset = new QToolButton(Resource::loadPixmap("back"), tr("Back"), "", this, SLOT(resetTurn()), toolbar);
124 done = new QToolButton(Resource::loadPixmap("done"), tr("Done"), "", this, SLOT(endTurn()), toolbar);
125 scoreinfo = new ScoreInfo(toolbar);
126 scoreinfo->setFont(QFont("Helvetica",10));
127 new QToolButton(Resource::loadPixmap("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar);
128 toolbar->setStretchableWidget(scoreinfo);
129
130 cpu = 0;
131 board = 0;
132 bag = 0;
133 racks = 0;
134
135 aiheart = new QTimer(this);
136 connect(aiheart, SIGNAL(timeout()), this, SLOT(think()));
137
138 readConfig();
139}
140
141WordGame::~WordGame()
142{
143 writeConfig();
144}
145
146void WordGame::writeConfig()
147{
148 Config cfg("WordGame");
149 cfg.setGroup("Game");
150 cfg.writeEntry("NameList",namelist,';');
151 cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1);
152 if ( !gameover ) {
153 cfg.writeEntry("Rules",rules);
154 bag->writeConfig(cfg);
155 board->writeConfig(cfg);
156 scoreinfo->writeConfig(cfg);
157 }
158 for (int p=0; p<nplayers; p++) {
159 cfg.setGroup("Player"+QString::number(p+1));
160 if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg);
161 }
162}
163
164void WordGame::readConfig()
165{
166 Config cfg("WordGame");
167 cfg.setGroup("Game");
168 int currentplayer = cfg.readNumEntry("CurrentPlayer",0);
169 QStringList pnames = cfg.readListEntry("NameList",';');
170 if ( currentplayer ) {
171 gameover = FALSE;
172 rules = cfg.readEntry("Rules");
173 if ( rules.find("x-wordgamerules") >= 0 ) {
174 // rules files moved
175 rules = "Sample.rules";
176 }
177 if ( loadRules(rules) ) {
178 startGame(pnames);
179 bag->readConfig(cfg);
180 board->readConfig(cfg);
181 scoreinfo->readConfig(cfg);
182 for (int p=0; p<nplayers; p++) {
183 cfg.setGroup("Player"+QString::number(p+1));
184 rack(p)->readConfig(cfg);
185 }
186 player=currentplayer-1;
187 readyRack(player);
188 return;
189 }
190 }
191 // fall-back
192 openGameSelector(pnames);
193}
194
195void WordGame::openGameSelector(const QStringList& initnames)
196{
197 toolbar->hide();
198 gameover = FALSE;
199
200 delete board;
201 board = 0;
202 delete racks;
203 racks = 0;
204
205 delete cpu;
206 cpu = 0;
207
208 newgame = new NewGame(vbox);
209
210 //Rules rules(this);
211 //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules()));
212 //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets()));
213 struct passwd* n = getpwuid(getuid());
214 QString playername = n ? n->pw_name : "";
215 if ( playername.isEmpty() ) {
216 playername = "Player";
217 }
218 newgame->player0->changeItem(playername,0);
219 newgame->player1->setCurrentItem(1);
220 newgame->updateRuleSets();
221 newgame->show();
222
223 connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame()));
224}
225
226void WordGame::startGame()
227{
228 rules = newgame->ruleslist[newgame->rules->currentItem()];
229 if ( loadRules(rules) ) {
230 QStringList names;
231 names.append(newgame->player0->currentText());
232 names.append(newgame->player1->currentText());
233 names.append(newgame->player2->currentText());
234 names.append(newgame->player3->currentText());
235 names.append(newgame->player4->currentText());
236 names.append(newgame->player5->currentText());
237 delete newgame;
238 startGame(names);
239 } else {
240 // error...
241 delete newgame;
242 close();
243 }
244}
245
246void WordGame::startGame(const QStringList& playerlist)
247{
248 toolbar->show();
249 racks = new QWidgetStack(vbox);
250 namelist.clear();
251 nplayers=0;
252 for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it)
253 addPlayer(*it);
254 scoreinfo->init(namelist);
255
256 if ( nplayers ) {
257 player=0;
258 readyRack(player);
259 }
260
261 board->show();
262 racks->show();
263}
264
265bool WordGame::loadRules(const QString &name)
266{
267 QString filename = Global::applicationFileName( "wordgame", name );
268 QFile file( filename );
269 if ( !file.open( IO_ReadOnly ) )
270 return FALSE;
271
272 QTextStream ts( &file );
273
274 QString title = name;
275 title.truncate( title.length() - 6 );
276 setCaption( title );
277
278 QString shapepixmap;
279 ts >> shapepixmap;
280 int htiles,vtiles;
281 ts >> htiles >> vtiles;
282
283 if ( htiles < 3 || vtiles < 3 )
284 return FALSE;
285
286 QPixmap bgshapes = Resource::loadPixmap(shapepixmap);
287 QString rule_shapes;
288 for (int i=0; i<vtiles; i++) {
289 QString line;
290 ts >> line;
291 rule_shapes += line;
292 }
293 static int rule_effects[12];
294 int re=0,e;
295 ts >> e;
296 while ( e && re < 10 ) {
297 rule_effects[re] = e;
298 if ( re++ < 10 ) ts >> e;
299 }
300 rule_effects[re++] = 100; // default bonus
301 board = new Board(bgshapes, htiles, vtiles, vbox);
302 board->setRules(rule_shapes, rule_effects);
303 connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int)));
304
305 bag = new Bag;
306
307 int count;
308 ts >> count;
309 while ( count ) {
310 QString text;
311 int value;
312 ts >> text >> value;
313 if ( text == "_" )
314 text = "";
315
316 Tile t(text, value);
317 for (int n=count; n--; )
318 bag->add(t);
319
320 ts >> count;
321 }
322
323 return TRUE;
324}
325
326
327NewGame::NewGame(QWidget* parent) :
328 NewGameBase(parent)
329{
330}
331
332void NewGame::updateRuleSets()
333{
334 rules->clear();
335
336 QString rulesDir = Global::applicationFileName( "wordgame", "" );
337 QDir dir( rulesDir, "*.rules" );
338 ruleslist = dir.entryList();
339 if ( ruleslist.isEmpty() ) {
340 // Provide a sample
341 QFile file( rulesDir + "Sample.rules" );
342 if ( file.open( IO_WriteOnly ) ) {
343 file.writeBlock( sampleWGR, strlen(sampleWGR) );
344 file.close();
345 updateRuleSets();
346 }
347 return;
348 }
349 int newest=0;
350 int newest_age=INT_MAX;
351 QDateTime now = QDateTime::currentDateTime();
352 QStringList::Iterator it;
353 for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) {
354 QFileInfo fi((*it));
355 int age = fi.lastModified().secsTo(now);
356 QString name = *it;
357 name.truncate( name.length()-6 ); // remove extension
358 rules->insertItem( name );
359 if ( age < newest_age ) {
360 newest_age = age;
361 newest = rules->count()-1;
362 }
363 }
364 rules->setCurrentItem(newest);
365}
366
367Rules::Rules(QWidget* parent) :
368 RulesBase(parent,0,TRUE)
369{
370}
371
372void Rules::editRules()
373{
374 if ( exec() ) {
375 // ### create a new set of rules
376 emit rulesChanged();
377 }
378}
379
380void Rules::deleteRuleSet()
381{
382 // ### delete existing rule set
383 emit rulesChanged();
384}
385
386void WordGame::addPlayer(const QString& name)
387{
388 if ( !name.isEmpty() ) {
389 int colon = name.find(':');
390 int cpu = (colon >=0 && name.left(2) == "AI") ? name.mid(2,1).toInt() : 0;
391 addPlayer(name,cpu);
392 }
393}
394
395void WordGame::addPlayer(const QString& name, int cpu)
396{
397 Rack* r = new Rack(rack_tiles,racks);
398 r->setPlayerName(name);
399 r->setComputerization(cpu);
400 racks->addWidget(r, nplayers);
401 refillRack(nplayers);
402 namelist.append(name);
403
404 ++nplayers;
405}
406
407void WordGame::nextPlayer()
408{
409 if ( !refillRack(player) ) {
410 endGame();
411 } else {
412 player = (player+1)%nplayers;
413 scoreinfo->setBoldOne(player);
414 readyRack(player);
415 }
416}
417
418bool WordGame::mayEndGame()
419{
420 int out=-1;
421 int i;
422 for (i=0; i<nplayers; i++)
423 if ( !rack(i)->count() )
424 out = i;
425 if ( out<0 ) {
426 if ( QMessageBox::warning(this,tr("End game"),
427 tr("Do you want to end the game early?"),
428 tr("Yes"), tr("No") )!=0 )
429 {
430 return FALSE;
431 }
432 }
433 return TRUE;
434}
435
436void WordGame::endGame()
437{
438 if ( gameover ) {
439 close();
440 return;
441 }
442
443 if ( !mayEndGame() )
444 return;
445 int out=-1;
446 int totalleft=0;
447 int i;
448 for (i=0; i<nplayers; i++) {
449 Rack* r = rack(i);
450 int c = r->count();
451 if ( c ) {
452 int lose=0;
453 for ( int j=0; j<c; j++ )
454 lose += r->tileRef(j)->value();
455 totalleft += lose;
456 scoreinfo->addScore(i,-lose);
457 } else {
458 out = i;
459 }
460 }
461 int highest=0;
462 int winner=0;
463 for (i=0; i<nplayers; i++) {
464 int s = scoreinfo->playerScore(i);
465 if ( s > highest ) {
466 highest = s;
467 winner = i;
468 }
469 }
470 if ( out >= 0 )
471 scoreinfo->addScore(out,totalleft);
472 scoreinfo->setBoldOne(winner);
473 gameover = TRUE;
474 done->setEnabled(TRUE);
475 reset->setEnabled(FALSE);
476}
477
478void WordGame::endTurn()
479{
480 if ( gameover ) {
481 openGameSelector(namelist);
482 } else {
483 if ( board->checkTurn() ) {
484 if ( board->turnScore() >= 0 ) {
485 scoreinfo->addScore(player,board->turnScore());
486 board->finalizeTurn();
487 } else {
488 QApplication::beep();
489 }
490 nextPlayer();
491 }
492 }
493}
494
495void WordGame::resetTurn()
496{
497 board->resetRack();
498}
499
500void WordGame::passTurn()
501{
502 // ######## trade?
503 nextPlayer();
504}
505
506bool WordGame::refillRack(int i)
507{
508 Rack* r = rack(i);
509 while ( !bag->isEmpty() && !r->isFull() ) {
510 r->addTile(bag->takeRandom());
511 }
512 return r->count() != 0;
513}
514
515void WordGame::readyRack(int i)
516{
517 Rack* r = rack(i);
518 racks->raiseWidget(i);
519 board->setCurrentRack(r);
520
521 done->setEnabled( !r->computerized() );
522 reset->setEnabled( !r->computerized() );
523
524 if ( r->computerized() ) {
525 cpu = new ComputerPlayer(board, r);
526 aiheart->start(0);
527 }
528}
529
530Rack* WordGame::rack(int i) const
531{
532 return (Rack*)racks->widget(i);
533}
534
535void WordGame::think()
536{
537 if ( !cpu->step() ) {
538 delete cpu;
539 cpu = 0;
540 aiheart->stop();
541 if ( board->turnScore() < 0 )
542 passTurn();
543 else
544 endTurn();
545 }
546}
547
548ComputerPlayer::ComputerPlayer(Board* b, Rack* r) :
549 board(b), rack(r), best(new const Tile*[rack_tiles]),
550 best_blankvalues(new Tile[rack_tiles])
551{
552 best_score = -1;
553 across=FALSE;
554 dict=0;
555}
556
557ComputerPlayer::~ComputerPlayer()
558{
559 delete [] best;
560 delete [] best_blankvalues;
561}
562
563bool ComputerPlayer::step()
564{
565 const QDawg::Node* root = dict ? Global::dawg("WordGame").root()
566 : Global::fixedDawg().root();
567 QPoint d = across ? QPoint(1,0) : QPoint(0,1);
568 const Tile* tiles[99]; // ### max board size
569 uchar nletter[4095]; // QDawg only handles 0..4095
570 memset(nletter,0,4096);
571 for (int i=0; i<rack->count(); i++) {
572 const Tile* r = rack->tileRef(i);
573 if ( r->isBlank() )
574 nletter[0]++;
575 else
576 nletter[r->text()[0].unicode()]++;
577 }
578 Tile blankvalues[99]; // ### max blanks
579 findBest(current, d, root, 0, nletter, tiles, 0, blankvalues, 0);
580 if ( ++current.rx() == board->xTiles() ) {
581 current.rx() = 0;
582 if ( ++current.ry() == board->yTiles() ) {
583 if ( across ) {
584 if ( dict == 1 ) {
585 if ( best_score >= 0 ) {
586 rack->arrangeTiles(best,best_n);
587 rack->setBlanks(best_blankvalues);
588 board->scoreTurn(best_start, best_n, best_dir);
589 board->showTurn();
590 }
591 return FALSE;
592 }
593 dict++;
594 across = FALSE;
595 current = QPoint(0,0);
596 } else {
597 across = TRUE;
598 current = QPoint(0,0);
599 }
600 }
601 }
602 return TRUE;
603}
604
605void ComputerPlayer::findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar* nletter, const Tile** tiles, int n, Tile* blankvalues, int blused)
606{
607 if ( !node )
608 return;
609 QChar l = node->letter();
610 const Tile* cur = board->tile(at);
611 if ( cur ) {
612 if ( cur->text()[0] == l ) {
613 bool nextok = board->contains(at+d);
614 if ( node->isWord() && n && (!nextok || !board->tile(at+d)) )
615 noteChoice(tiles,n,d,blankvalues,blused);
616 if ( nextok )
617 findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);
618 // #### text()[1]...
619 }
620 } else {
621 if ( nletter[l.unicode()] || nletter[0] ) {
622 int rc = rack->count();
623 ulong msk = 1;
624 for ( int x=0; x<rc; x++ ) {
625 if ( !(used&msk) ) {
626 const Tile* t = rack->tileRef(x);
627 if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s
628 bool nextok = board->contains(at+d);
629 tiles[n++] = t;
630 if ( t->isBlank() )
631 blankvalues[blused++] = Tile(l,0);
632 if ( node->isWord() && (!nextok || !board->tile(at+d)) )
633 noteChoice(tiles,n,d,blankvalues,blused);
634 used |= msk; // mark
635 nletter[t->text()[0].unicode()]--;
636 if ( nextok )
637 findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);
638 n--;
639 nletter[t->text()[0].unicode()]++;
640 if ( t->isBlank() ) {
641 // keep looking
642 blused--;
643 used &= ~msk; // unmark
644 } else {
645 break;
646 }
647 }
648 }
649 msk <<= 1;
650 }
651 }
652 // #### text()[1]...
653 }
654 findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused);
655}
656
657void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused)
658{
659 int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0);
660/*
661if (s>0 || current==QPoint(5,1)){
662QString st;
663for ( int i=0; i<n; i++ )
664 st += tiles[i]->text();
665qDebug("%d,%d: %s (%d) for %d",current.x(),current.y(),st.latin1(),n,s);
666}
667*/
668 if ( s > best_score ) {
669 int i;
670 for ( i=0; i<n; i++ )
671 best[i] = tiles[i];
672 for ( i=0; i<blused; i++ )
673 best_blankvalues[i] = blankvalues[i];
674 best_n = n;
675 best_blused = blused;
676 best_score = s;
677 best_dir = d;
678 best_start = current;
679 }
680}
681
682int TileItem::smallWidth()
683{
684 return 16;
685}
686
687int TileItem::smallHeight()
688{
689 return 16;
690}
691
692int TileItem::bigWidth()
693{
694 return 22;
695}
696
697int TileItem::bigHeight()
698{
699 return 22;
700}
701
702void TileItem::setState( State state )
703{
704 hide();
705 s = state;
706 show(); // ### use update() in Qt 3.0
707}
708
709void TileItem::setTile(const Tile& tile)
710{
711 hide();
712 t = tile;
713 show(); // ### use update() in Qt 3.0
714}
715
716void TileItem::setBig(bool b)
717{
718 big = b;
719}
720
721void TileItem::drawShape(QPainter& p)
722{
723 static QFont value_font("heletica",8);
724 static QFont big_font("smoothtimes",17);
725 static QFont small_font("smoothtimes",10);
726
727 QRect area(x(),y(),width(),height());
728 p.setBrush(s == Floating ? yellow/*lightGray*/ : white);
729 p.drawRect(area);
730 if ( big ) {
731 p.setFont(value_font);
732 QString n = QString::number(t.value());
733 int w = p.fontMetrics().width('1');
734 int h = p.fontMetrics().height();
735 w *= n.length();
736 QRect valuearea(x()+width()-w-2,y()+height()-h+1,w,h);
737 p.drawText(valuearea,AlignCenter,n);
738 p.setFont(big_font);
739 area = QRect(x(),y(),width()-2,height()-1);
740 } else {
741 p.setFont(small_font);
742 area = QRect(x(),y()+2,width(),height()-2);
743 }
744 if ( t.value() == 0 )
745 p.setPen(darkGray);
746 p.drawText(area,AlignCenter,t.text().upper());
747}
748
749Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) :
750 QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()),
751 parent)
752{
753 grid = new TileItem*[w*h];
754 memset(grid,0,w*h*sizeof(TileItem*));
755 setFrameStyle(0);
756 setHScrollBarMode(AlwaysOff);
757 setVScrollBarMode(AlwaysOff);
758 current_rack = 0;
759 shown_n = 0;
760}
761
762Board::~Board()
763{
764 delete canvas();
765}
766
767void Board::writeConfig(Config& cfg)
768{
769 QStringList t;
770 int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();
771 for (int i=0; i<n; i++)
772 t.append( grid[i] ? grid[i]->tile().key() : QString(".") );
773 cfg.writeEntry("Board",t,';');
774}
775
776void Board::readConfig(Config& cfg)
777{
778 clear();
779 QStringList t = cfg.readListEntry("Board",';');
780 int i=0;
781 int h=canvas()->tilesHorizontally();
782 for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) {
783 if ( *it != "." ) {
784 QPoint p(i%h,i/h);
785 setTile(p,Tile(*it));
786 }
787 i++;
788 }
789 canvas()->update();
790}
791
792void Board::clear()
793{
794 int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();
795 for (int i=0; i<n; i++) {
796 delete grid[i];
797 grid[i]=0;
798 }
799}
800
801
802void Board::setCurrentRack(Rack* r)
803{
804 turn_score = -1;
805 current_rack = r;
806}
807
808void Board::resetRack()
809{
810 unshowTurn();
811 canvas()->update();
812}
813
814void Board::contentsMousePressEvent(QMouseEvent* e)
815{
816 dragstart = e->pos();
817}
818
819void Board::contentsMouseMoveEvent(QMouseEvent* e)
820{
821 if ( current_rack && !current_rack->computerized() ) {
822 QPoint d = e->pos() - dragstart;
823 if ( d.x() <= 0 && d.y() <= 0 ) {
824 // None
825 resetRack();
826 } else {
827 int n;
828 QPoint start=boardPos(dragstart);
829 QPoint end=boardPos(e->pos());
830 QPoint diff=end-start;
831 QPoint dir;
832 if ( d.x() > d.y() ) {
833 n = diff.x()+1;
834 dir = QPoint(1,0);
835 } else {
836 n = diff.y()+1;
837 dir = QPoint(0,1);
838 }
839
840 unshowTurn();
841
842 // Subtract existing tiles from n
843 QPoint t = start;
844 for ( int i=n; i--; ) {
845 if ( contains(t) && tile(t) )
846 n--;
847 t += dir;
848 }
849
850 // Move start back to real start
851 while (contains(start-dir) && tile(start-dir))
852 start -= dir;
853
854 scoreTurn(start, n, dir);
855 showTurn();
856 }
857 }
858}
859
860void Board::finalizeTurn()
861{
862 int i=0;
863 QPoint at = shown_at;
864 while ( i<shown_n && contains(at) ) {
865 if ( item(at) && item(at)->state() == TileItem::Floating ) {
866 current_rack->remove(item(at)->tile());
867 setTileState(at,TileItem::Firm);
868 i++;
869 }
870 at += shown_step;
871 }
872 canvas()->update();
873}
874
875void Board::unshowTurn()
876{
877 int i=0;
878 QPoint at = shown_at;
879 while ( i<shown_n && i<current_rack->count() && contains(at) ) {
880 if ( item(at) && item(at)->state() == TileItem::Floating ) {
881 unsetTile(at);
882 i++;
883 }
884 at += shown_step;
885 }
886}
887
888void Board::showTurn()
889{
890 unshowTurn();
891 QPoint at = shown_at;
892 int i=0;
893 while ( i<shown_n && i<current_rack->count() && contains(at) ) {
894 if ( !tile(at) ) {
895 Tile t = current_rack->tile(i);
896 setTile(at,t);
897 setTileState(at,TileItem::Floating);
898 i++;
899 }
900 at += shown_step;
901 }
902 canvas()->update();
903}
904
905int Board::bonussedValue(const QPoint& at, int base, int& all_mult) const
906{
907 int rule = rule_shape[idx(at)]-'0';
908 int effect = rule_effect[rule];
909 int mult = effect&Multiplier;
910 if ( effect & MultiplyAll ) {
911 all_mult *= mult;
912 return base;
913 } else {
914 return base * mult;
915 }
916}
917
918bool Board::isStart(const QPoint& at) const
919{
920 int rule = rule_shape[idx(at)]-'0';
921 int effect = rule_effect[rule];
922 return effect&Start;
923}
924
925bool Board::checkTurn()
926{
927 if ( current_rack->computerized() )
928 return TRUE; // computer doesn't cheat, and has already set blanks.
929
930 QPoint at = shown_at;
931 int n = shown_n;
932 QPoint d = shown_step;
933 const Tile* tiles[99];
934 Tile blankvalues[99];
935 if ( n > current_rack->count() )
936 n = current_rack->count();
937
938 QDialog check(this,0,TRUE);
939 (new QVBoxLayout(&check))->setAutoAdd(TRUE);
940
941 QHBox mw(&check);
942 new QLabel(tr("Blanks: "),&mw);
943
944 int bl=0;
945 QLineEdit* le[99];
946 for (int i=0; i<n; i++) {
947 tiles[i] = current_rack->tileRef(i);
948 if ( tiles[i]->isBlank() ) {
949 QLineEdit *l = new QLineEdit(&mw);
950 le[bl++] = l;
951 l->setMaxLength(1);
952 l->setFixedSize(l->minimumSizeHint());
953 }
954 }
955
956 QHBox btns(&check);
957 connect(new QPushButton(tr("OK"),&btns), SIGNAL(clicked()), &check, SLOT(accept()));
958 connect(new QPushButton(tr("Cancel"),&btns), SIGNAL(clicked()), &check, SLOT(reject()));
959
960 if ( bl ) {
961retry:
962 if ( !check.exec() ) {
963 unshowTurn();
964 canvas()->update();
965 return FALSE;
966 }
967
968 for (int b=0; b<bl; b++) {
969 QString v = le[b]->text();
970 blankvalues[b]=Tile(v,0);
971 if ( v.length() != 1 )
972 goto retry;
973 }
974 }
975
976 QStringList words;
977 unshowTurn();
978 turn_score = score(at,tiles,n,blankvalues,d,FALSE,&words);
979 showTurn();
980 QStringList to_add;
981 for (QStringList::Iterator it=words.begin(); it!=words.end(); ++it) {
982 if ( !Global::fixedDawg().contains(*it)
983 && !Global::dawg("WordGame").contains(*it) ) {
984 switch (QMessageBox::warning(this, tr("Unknown word"),
985 tr("<p>The word \"%1\" is not in the dictionary.").arg(*it),
986 tr("Add"), tr("Ignore"), tr("Cancel")))
987 {
988 case 0:
989 // ####### add to wordgame dictionary
990 to_add.append(*it);
991 break;
992 case 1:
993 break;
994 case 2:
995 unshowTurn();
996 canvas()->update();
997 return FALSE;
998 }
999 }
1000 }
1001 if ( to_add.count() )
1002 Global::addWords("WordGame",to_add);
1003 return TRUE;
1004}
1005
1006void Board::scoreTurn(const QPoint& at, int n, const QPoint& d)
1007{
1008 unshowTurn();
1009 shown_at = at;
1010 shown_n = n;
1011 shown_step = d;
1012 const Tile* tiles[99];
1013 if ( n > current_rack->count() )
1014 n = current_rack->count();
1015 for (int i=0; i<n; i++)
1016 tiles[i] = current_rack->tileRef(i);
1017 turn_score = score(at,tiles,n,0,d,FALSE,0);
1018 emit temporaryScore(turn_score);
1019}
1020
1021int Board::score(QPoint at, const Tile** tiles, int n, const Tile* blankvalue, const QPoint& d, bool checkdict, QStringList* words) const
1022{
1023 int total=0;
1024 int totalsidetotal=0;
1025
1026 // words gets filled with words made
1027
1028 // mainword==0 ->
1029 // Checks side words, but not main word
1030
1031 // -1 means words not in dict, or illegally positioned (eg. not connected)
1032
1033 // text is assumed to fit on board.
1034
1035 if ( words ) *words=QStringList();
1036
1037 QPoint otherd(d.y(), d.x());
1038
1039 int all_mult = 1;
1040 int bl=0;
1041
1042 bool connected = FALSE;
1043
1044 QString mainword="";
1045
1046 if ( contains(at-d) && tile(at-d) ) {
1047 return -1; // preceeding tiles
1048 }
1049
1050 const Tile* t;
1051 for (int i=0; contains(at) && ((t=tile(at)) || i<n); ) {
1052 if ( t ) {
1053 if ( checkdict || words ) mainword += t->text();
1054 total += t->value();
1055 connected = TRUE;
1056 } else {
1057 QString sideword;
1058 QString tt;
1059 if ( tiles[i]->isBlank() ) {
1060 if ( blankvalue )
1061 tt = blankvalue[bl++].text();
1062 } else {
1063 tt = tiles[i]->text();
1064 }
1065 sideword=tt;
1066 if ( checkdict || words ) mainword += tt;
1067 int side_mult = 1;
1068 int tilevalue = bonussedValue(at,tiles[i]->value(),side_mult);
1069 all_mult *= side_mult;
1070 if ( !connected && isStart(at) )
1071 connected = TRUE;
1072 total += tilevalue;
1073 int sidetotal = tilevalue;
1074 {
1075 QPoint side = at-otherd;
1076
1077 while ( contains(side) && (t=tile(side)) ) {
1078 sidetotal += t->value();
1079 sideword.prepend(t->text());
1080 side -= otherd;
1081 }
1082 }
1083 {
1084 QPoint side = at+otherd;
1085 while ( contains(side) && (t=tile(side)) ) {
1086 sidetotal += t->value();
1087 sideword.append(t->text());
1088 side += otherd;
1089 }
1090 }
1091 if ( sideword.length() > 1 ) {
1092 if ( words )
1093 words->append(sideword);
1094 if ( checkdict && !Global::fixedDawg().contains(sideword)
1095 && !Global::dawg("WordGame").contains(sideword) )
1096 return -1;
1097 totalsidetotal += sidetotal * side_mult;
1098 connected = TRUE;
1099 }
1100 i++;
1101 }
1102 at += d;
1103 }
1104
1105 if ( words )
1106 words->append(mainword);
1107 if ( checkdict && !Global::fixedDawg().contains(mainword)
1108 && !Global::dawg("WordGame").contains(mainword) )
1109 return -1;
1110
1111 if ( n == rack_tiles )
1112 totalsidetotal += rack_tiles_bonus;
1113
1114 return connected ? totalsidetotal + total * all_mult : -1;
1115}
1116
1117QPoint Board::boardPos(const QPoint& p) const
1118{
1119 return QPoint(p.x()/canvas()->tileWidth(), p.y()/canvas()->tileHeight());
1120}
1121
1122void Board::contentsMouseReleaseEvent(QMouseEvent*)
1123{
1124 if ( current_rack ) {
1125 }
1126}
1127
1128
1129void Board::setRules(const QString& shapes, const int* effects)
1130{
1131 rule_shape=shapes; rule_effect=effects;
1132 int i=0;
1133 int maxre=0;
1134 for (int y=0; y<yTiles(); y++) {
1135 for (int x=0; x<xTiles(); x++) {
1136 int re = shapes[i++]-'0';
1137 if ( re > maxre ) maxre = re;
1138 canvas()->setTile(x,y,re);
1139 }
1140 }
1141 rack_tiles_bonus=effects[maxre+1];
1142}
1143
1144void Board::unsetTile(const QPoint& p)
1145{
1146 delete item(p);
1147 grid[idx(p)] = 0;
1148}
1149
1150void Board::setTile(const QPoint& p, const Tile& t)
1151{
1152 TileItem* it=item(p);
1153 if ( !it ) {
1154 it = grid[idx(p)] = new TileItem(t,FALSE,canvas());
1155 it->move(p.x()*canvas()->tileWidth(), p.y()*canvas()->tileHeight());
1156 it->show();
1157 } else {
1158 it->setTile(t);
1159 }
1160}
1161
1162Rack::Rack(int ntiles, QWidget* parent) : QCanvasView(
1163 new QCanvas(ntiles*TileItem::bigWidth(),TileItem::bigHeight()),
1164 parent),
1165 item(ntiles)
1166{
1167 setLineWidth(1);
1168 setFixedHeight(sizeHint().height());
1169 n = 0;
1170 for (int i=0; i<ntiles; i++)
1171 item[i]=0;
1172 setHScrollBarMode(AlwaysOff);
1173 setVScrollBarMode(AlwaysOff);
1174 canvas()->setBackgroundColor(gray);
1175 dragging = 0;
1176}
1177
1178Rack::~Rack()
1179{
1180 clear();
1181 delete canvas();
1182}
1183
1184void Rack::clear()
1185{
1186 for (int i=0; i<n; i++)
1187 delete item[i];
1188 n=0;
1189}
1190
1191void Rack::writeConfig(Config& cfg)
1192{
1193 QStringList l;
1194 for (int i=0; i<n; i++)
1195 l.append(tile(i).key());
1196 cfg.writeEntry("Tiles",l,';');
1197}
1198
1199void Rack::readConfig(Config& cfg)
1200{
1201 clear();
1202 int x=0;
1203 QStringList l = cfg.readListEntry("Tiles",';');
1204 for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) {
1205 TileItem *i = new TileItem(Tile(*it),TRUE,canvas());
1206 i->move(x++,0);
1207 i->show();
1208 item[n++] = i;
1209 }
1210 layoutTiles();
1211}
1212
1213static int cmp_tileitem(const void *a, const void *b)
1214{
1215 const TileItem* ia = *(TileItem**)a;
1216 const TileItem* ib = *(TileItem**)b;
1217 return int(ia->x() - ib->x());
1218}
1219
1220void Rack::layoutTiles()
1221{
1222 int w = TileItem::bigWidth()+2;
1223
1224 if ( dragging ) dragging->moveBy(dragging_adj,0);
1225 qsort(item.data(), n, sizeof(TileItem*), cmp_tileitem);
1226 if ( dragging ) dragging->moveBy(-dragging_adj,0);
1227
1228 for (int i=0; i<n ;i++)
1229 if ( item[i] == dragging ) {
1230 item[i]->setZ(1);
1231 } else {
1232 item[i]->move(i*w, 0);
1233 item[i]->setZ(0);
1234 }
1235 canvas()->update();
1236}
1237
1238void Rack::setBlanks(const Tile* bv)
1239{
1240 for (int j=0; j<n; j++) {
1241 Tile tt = item[j]->tile();
1242 if ( tt.isBlank() ) {
1243 tt.setText(bv->text());
1244 item[j]->setTile(tt);
1245 bv++;
1246 }
1247 }
1248}
1249
1250bool Rack::arrangeTiles(const Tile** s, int sn)
1251{
1252 bool could = TRUE;
1253 for (int j=0; j<n; j++) {
1254 Tile tt = item[j]->tile();
1255 int f=-1;
1256 for (int i=0; i<sn && f<0; i++) {
1257 if (s[i] && *s[i] == tt ) {
1258 s[i]=0;
1259 f=i;
1260 }
1261 }
1262 if ( f >= 0 ) {
1263 item[j]->move(f-999,0);
1264 } else {
1265 could = FALSE;
1266 }
1267 }
1268 layoutTiles();
1269 return could;
1270}
1271
1272void Rack::addTile(const Tile& t)
1273{
1274 TileItem *i = new TileItem(t,TRUE,canvas());
1275 i->show();
1276 item[n++] = i;
1277 layoutTiles();
1278}
1279
1280void Rack::remove(Tile t)
1281{
1282 for (int i=0; i<n ;i++)
1283 if ( item[i]->tile() == t ) {
1284 remove(i);
1285 return;
1286 }
1287}
1288
1289void Rack::remove(int i)
1290{
1291 delete item[i];
1292 n--;
1293 for (;i<n;i++)
1294 item[i]=item[i+1];
1295 layoutTiles();
1296}
1297
1298void Rack::resizeEvent(QResizeEvent* e)
1299{
1300 canvas()->resize(width()-frameWidth()*2,height()-frameWidth()*2);
1301 QCanvasView::resizeEvent(e);
1302}
1303
1304void Rack::contentsMousePressEvent(QMouseEvent* e)
1305{
1306 if ( computerized() )
1307 return;
1308 QCanvasItemList list = canvas()->collisions(e->pos());
1309 if (list.count()) {
1310 dragging = list.first();
1311 dragstart = e->pos()-QPoint(int(dragging->x()),int(dragging->y()));
1312 } else {
1313 dragging = 0;
1314 }
1315}
1316
1317void Rack::contentsMouseMoveEvent(QMouseEvent* e)
1318{
1319 if ( computerized() )
1320 return;
1321 //int w = TileItem::bigWidth()+2;
1322 if ( dragging ) {
1323 dragging_adj = TileItem::bigWidth()/2;
1324 if ( dragging->x() > e->x()-dragstart.x() )
1325 dragging_adj = -dragging_adj;
1326 dragging->move(e->x()-dragstart.x(),0);
1327 layoutTiles();
1328 }
1329}
1330
1331void Rack::contentsMouseReleaseEvent(QMouseEvent* e)
1332{
1333 if ( computerized() )
1334 return;
1335 if ( dragging ) {
1336 dragging=0;
1337 layoutTiles();
1338 }
1339}
1340
1341Tile::Tile(const QString& key)
1342{
1343 int a=key.find('@');
1344 txt = key.left(a);
1345 val = key.mid(a+1).toInt();
1346 blank = txt.isEmpty();
1347}
1348
1349QString Tile::key() const
1350{
1351 return txt+"@"+QString::number(val);
1352}
1353
1354Bag::Bag()
1355{
1356 tiles.setAutoDelete(TRUE);
1357}
1358
1359void Bag::writeConfig(Config& cfg)
1360{
1361 QStringList t;
1362 for (QListIterator<Tile> it(tiles); it; ++it)
1363 t.append((*it)->key());
1364 cfg.writeEntry("Tiles",t,';');
1365}
1366
1367void Bag::readConfig(Config& cfg)
1368{
1369 tiles.clear();
1370 QStringList t = cfg.readListEntry("Tiles",';');
1371 for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it )
1372 add(Tile(*it));
1373}
1374
1375void Bag::add(const Tile& t)
1376{
1377 tiles.append(new Tile(t));
1378}
1379
1380Tile Bag::takeRandom()
1381{
1382 Tile* rp = tiles.take(random()%tiles.count());
1383 Tile r=*rp;
1384 return r;
1385}
1386
1387ScoreInfo::ScoreInfo( QWidget* parent, const char* name, WFlags fl ) :
1388 QLabel("<P>",parent,name,fl)
1389{
1390 score=0;
1391 msgtimer = new QTimer(this);
1392 connect(msgtimer, SIGNAL(timeout()), this, SLOT(showScores()));
1393 setBackgroundMode( PaletteButton );
1394}
1395
1396ScoreInfo::~ScoreInfo()
1397{
1398 if ( score ) delete [] score;
1399}
1400
1401void ScoreInfo::writeConfig(Config& cfg)
1402{
1403 QStringList l;
1404 for (int i=0; i<(int)names.count(); i++)
1405 l.append(QString::number(score[i]));
1406 cfg.writeEntry("Scores",l,';');
1407}
1408
1409void ScoreInfo::readConfig(Config& cfg)
1410{
1411 QStringList l = cfg.readListEntry("Scores",';');
1412 int i=0;
1413 for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it )
1414 score[i++]=(*it).toInt();
1415 showScores();
1416}
1417
1418
1419QSize ScoreInfo::sizeHint() const
1420{
1421 return QSize(QLabel::sizeHint().width(),fontMetrics().height());
1422}
1423
1424void ScoreInfo::init(const QStringList& namelist)
1425{
1426 names = namelist;
1427 if ( score ) delete [] score;
1428 score = new int[names.count()];
1429 memset(score,0,sizeof(int)*names.count());
1430 boldone = -1;
1431 showScores();
1432}
1433
1434void ScoreInfo::addScore(int player, int change)
1435{
1436 score[player] += change;
1437 showScores();
1438}
1439
1440void ScoreInfo::setBoldOne(int b)
1441{
1442 boldone=b;
1443 showScores();
1444}
1445
1446void ScoreInfo::showScores()
1447{
1448 QString r="<p>";
1449 int i=0;
1450 //int spl=(names.count()+1)/2; // 2 lines
1451 for (QStringList::ConstIterator it=names.begin(); it!=names.end(); ) {
1452 if ( i==boldone ) r += "<b>";
1453 QString n = *it;
1454 n.replace(QRegExp(":.*"),"");
1455 r += n;
1456 r += ":";
1457 r += QString::number(score[i]);
1458 if ( i==boldone ) r += "</b>";
1459
1460 ++i;
1461 ++it;
1462 if ( it != names.end() )
1463 r += " ";
1464 }
1465 setText(r);
1466}
1467
1468void ScoreInfo::showTemporaryScore(int amount)
1469{
1470 if ( amount < 0 )
1471 setText(tr("<P>Invalid move"));
1472 else
1473 setText(tr("<P>Score: ")+QString::number(amount));
1474 msgtimer->start(3000,TRUE);
1475}
1476
diff --git a/noncore/games/wordgame/wordgame.h b/noncore/games/wordgame/wordgame.h
new file mode 100644
index 0000000..0ffa56a
--- a/dev/null
+++ b/noncore/games/wordgame/wordgame.h
@@ -0,0 +1,376 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef WORDGAME_H
21#define WORDGAME_H
22
23#include "newgamebase.h"
24#include "rulesbase.h"
25
26#include <qpe/qdawg.h>
27#include <qpe/applnk.h>
28
29#include <qmainwindow.h>
30#include <qcanvas.h>
31#include <qlabel.h>
32
33class QVBox;
34class QLabel;
35class QWidgetStack;
36class QToolButton;
37class Config;
38
39class Tile {
40public:
41 Tile() {}
42
43 Tile(const Tile& t)
44 {
45 txt = t.txt;
46 val = t.val;
47 blank = t.blank;
48 }
49
50 Tile(QString text, int value)
51 {
52 txt = text;
53 val = value;
54 blank = txt.isEmpty();
55 }
56
57 Tile(const QString& key);
58
59 int value() const { return val; }
60 bool isBlank() const { return blank; }
61 QString text() const { return txt; }
62 void setText(const QString& t)
63 {
64 txt = t;
65 }
66
67 int operator==(const Tile& o) const
68 { return o.txt == txt && o.val == val && o.blank == blank; }
69 int operator!=(const Tile& o) const
70 { return !operator==(o); }
71 Tile& operator=(const Tile& o)
72 { txt=o.txt; val=o.val; blank=o.blank; return *this; }
73
74 QString key() const;
75
76private:
77 QString txt;
78 int val;
79 bool blank;
80};
81
82class Bag {
83public:
84 Bag();
85
86 void readConfig(Config&);
87 void writeConfig(Config&);
88
89 void add(const Tile&);
90 bool isEmpty() const { return tiles.isEmpty(); }
91 Tile takeRandom();
92private:
93 QList<Tile> tiles;
94};
95
96class TileItem : public QCanvasRectangle {
97public:
98 TileItem(const Tile& tile, bool b, QCanvas* c) :
99 QCanvasRectangle(0,0,
100 b?bigWidth():smallWidth(),
101 b?bigHeight():smallHeight(),c),
102 t(tile), big(b), s(Firm)
103 {
104 }
105
106 static int smallWidth();
107 static int smallHeight();
108 static int bigWidth();
109 static int bigHeight();
110
111 enum State { Firm, Floating };
112 void setState( State state );
113 State state() const { return s; }
114 const Tile& tile() const { return t; }
115 void setTile(const Tile&);
116 void setBig(bool);
117
118protected:
119 void drawShape(QPainter&);
120
121private:
122 Tile t;
123 bool big;
124 State s;
125};
126
127class Rack : public QCanvasView {
128public:
129 Rack(int ntiles, QWidget* parent);
130 ~Rack();
131
132 void readConfig(Config&);
133 void writeConfig(Config&);
134
135 bool isFull() const { return count()==max(); }
136 int max() const { return item.count(); }
137 int count() const { return n; }
138 void addTile(const Tile& t);
139 Tile tile(int i) const { return item[i]->tile(); }
140 const Tile* tileRef(int i) const { return &item[i]->tile(); }
141 void remove(int i);
142 void remove(Tile);
143 bool arrangeTiles(const Tile** s, int sn);
144 void setBlanks(const Tile*);
145
146 void setPlayerName(const QString& name) { nm = name; }
147 QString playerName() const { return nm; }
148 void setComputerization(int level) { cpu=level; }
149 bool computerized() const { return cpu>0; }
150
151protected:
152 void resizeEvent(QResizeEvent*e);
153 void contentsMousePressEvent(QMouseEvent*);
154 void contentsMouseMoveEvent(QMouseEvent*);
155 void contentsMouseReleaseEvent(QMouseEvent*);
156
157private:
158 void clear();
159 void layoutTiles();
160 int n;
161 QArray<TileItem*> item;
162 int dragging_adj;
163 QPoint dragstart;
164 QCanvasItem* dragging;
165 QString nm;
166 int cpu;
167};
168
169class Board : public QCanvasView {
170 Q_OBJECT
171public:
172 Board(QPixmap bgshapes, int w, int h, QWidget* parent);
173 ~Board();
174
175 void readConfig(Config&);
176 void writeConfig(Config&);
177
178 int xTiles() const { return canvas()->tilesHorizontally(); }
179 int yTiles() const { return canvas()->tilesVertically(); }
180
181 bool contains(const QPoint& p) const
182 { return p.x() >= 0 && p.y() >= 0
183 && p.x() < canvas()->tilesHorizontally()
184 && p.y() < canvas()->tilesVertically(); }
185 const Tile* tile(const QPoint& p) const
186 { TileItem* it=item(p); return it ? &it->tile() : 0; }
187
188 void setRules(const QString& shapes, const int* effects);
189
190 void clear();
191 void unsetTile(const QPoint& p);
192 void setTile(const QPoint& p, const Tile& t);
193
194 void setTileState(const QPoint& p, TileItem::State s)
195 {
196 TileItem* it=item(p);
197 if (it) it->setState(s);
198 }
199
200 void setCurrentRack(Rack*);
201 void resetRack();
202 void finalizeTurn();
203 void showTurn();
204 void scoreTurn(const QPoint& at, int n, const QPoint& d);
205 bool checkTurn();
206 int score(QPoint at, const Tile** tiles, int n,
207 const Tile* blankvalue,
208 const QPoint& d, bool ignoredict, QStringList* words) const;
209 int bonussedValue(const QPoint& at, int base, int& all_mult) const;
210 bool isStart(const QPoint& at) const;
211
212 int turnScore() const { return turn_score; }
213
214signals:
215 void temporaryScore(int);
216
217protected:
218 void contentsMousePressEvent(QMouseEvent*);
219 void contentsMouseMoveEvent(QMouseEvent*);
220 void contentsMouseReleaseEvent(QMouseEvent*);
221
222private:
223 int idx(const QPoint& p) const
224 { return p.x()+p.y()*canvas()->tilesHorizontally(); }
225 TileItem*& item(const QPoint& p) const
226 { return grid[idx(p)]; }
227 TileItem **grid;
228 QString rule_shape;
229 const int* rule_effect;
230 int rack_tiles_bonus;
231 Rack* current_rack;
232 QPoint boardPos(const QPoint&) const;
233 QPoint dragstart;
234 QPoint shown_at;
235 int shown_n;
236 QPoint shown_step;
237 void unshowTurn();
238 int turn_score;
239};
240
241class ComputerPlayer
242{
243 Board* board;
244 Rack* rack;
245
246 bool across;
247 int dict;
248 QPoint current;
249
250 const Tile** best;
251 int best_n;
252 Tile* best_blankvalues;
253 int best_blused;
254 int best_score;
255 QPoint best_dir;
256 QPoint best_start;
257
258public:
259 ComputerPlayer(Board* b, Rack* r);
260 ~ComputerPlayer();
261
262 bool step();
263
264private:
265 void findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar *nletter, const Tile** tiles, int n, Tile* blankvalues, int blused);
266 void noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused);
267};
268
269class ScoreInfo : public QLabel {
270 Q_OBJECT
271public:
272 ScoreInfo( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
273 ~ScoreInfo();
274
275 void init(const QStringList&);
276 void addScore(int player, int change);
277 int playerScore(int player) const { return score[player]; }
278 void setShowWinner(bool);
279 void setBoldOne(int);
280
281 void readConfig(Config&);
282 void writeConfig(Config&);
283
284protected:
285 QSize sizeHint() const;
286
287public slots:
288 void showTemporaryScore(int amount);
289
290private slots:
291 void showScores();
292
293private:
294 QStringList names;
295 int *score;
296 QTimer* msgtimer;
297 bool showwinner;
298 int boldone;
299};
300
301class NewGame;
302
303class WordGame : public QMainWindow {
304 Q_OBJECT
305public:
306 WordGame( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
307 ~WordGame();
308
309private slots:
310 void endTurn();
311 void resetTurn();
312 void passTurn();
313 void think();
314 void endGame();
315 void startGame();
316
317private:
318 void writeConfig();
319 void readConfig();
320
321 void startGame(const QStringList& pnames);
322 bool mayEndGame();
323 void openGameSelector(const QStringList& initnames);
324 bool loadRules(const QString& filename);
325 void addPlayer(const QString& name);
326 void addPlayer(const QString& name, int cpu);
327 void nextPlayer();
328 bool refillRack(int i);
329 void readyRack(int i);
330 Rack* rack(int i) const;
331
332 QWidgetStack *racks;
333 QToolBar* toolbar;
334 QVBox *vbox;
335 Board *board;
336 Bag *bag;
337 ScoreInfo *scoreinfo;
338 QToolButton *done;
339 QToolButton *reset;
340 QTimer* aiheart;
341 ComputerPlayer *cpu;
342 int player;
343 int nplayers;
344 QStringList namelist;
345 bool gameover;
346 QString rules;
347 NewGame* newgame;
348};
349
350class NewGame : public NewGameBase {
351 Q_OBJECT
352public:
353 NewGame(QWidget* parent);
354 QStringList ruleslist;
355
356public slots:
357 void updateRuleSets();
358};
359
360class Rules : public RulesBase {
361 Q_OBJECT
362
363public:
364 Rules(QWidget* parent);
365
366signals:
367 void rulesChanged();
368
369public slots:
370 void editRules();
371
372private:
373 void deleteRuleSet();
374};
375
376#endif // WORDGAME_H
diff --git a/noncore/games/wordgame/wordgame.pro b/noncore/games/wordgame/wordgame.pro
new file mode 100644
index 0000000..7feacf9
--- a/dev/null
+++ b/noncore/games/wordgame/wordgame.pro
@@ -0,0 +1,13 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4 HEADERS = wordgame.h
5 SOURCES = main.cpp \
6 wordgame.cpp
7 INTERFACES= newgamebase.ui rulesbase.ui
8 TARGET = wordgame
9INCLUDEPATH += $(QPEDIR)/include
10 DEPENDPATH+= $(QPEDIR)/include
11LIBS += -lqpe
12
13TRANSLATIONS = ../i18n/de/wordgame.ts