summaryrefslogtreecommitdiff
path: root/noncore/games/wordgame
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (side-by-side diff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /noncore/games/wordgame
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'noncore/games/wordgame') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/wordgame/.cvsignore6
-rw-r--r--noncore/games/wordgame/Makefile.in168
-rwxr-xr-xnoncore/games/wordgame/calcdist27
-rw-r--r--noncore/games/wordgame/main.cpp34
-rw-r--r--noncore/games/wordgame/newgamebase.ui337
-rw-r--r--noncore/games/wordgame/qpe-wordgame.control10
-rw-r--r--noncore/games/wordgame/rulesbase.ui274
-rw-r--r--noncore/games/wordgame/wordgame.cpp1476
-rw-r--r--noncore/games/wordgame/wordgame.h376
-rw-r--r--noncore/games/wordgame/wordgame.pro13
10 files changed, 2721 insertions, 0 deletions
diff --git a/noncore/games/wordgame/.cvsignore b/noncore/games/wordgame/.cvsignore
new file mode 100644
index 0000000..d498858
--- a/dev/null
+++ b/noncore/games/wordgame/.cvsignore
@@ -0,0 +1,6 @@
+moc_*
+Makefile
+newgamebase.h
+rulesbase.h
+newgamebase.cpp
+rulesbase.cpp
diff --git a/noncore/games/wordgame/Makefile.in b/noncore/games/wordgame/Makefile.in
new file mode 100644
index 0000000..5627414
--- a/dev/null
+++ b/noncore/games/wordgame/Makefile.in
@@ -0,0 +1,168 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = wordgame
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = wordgame.h
+SOURCES = main.cpp \
+ wordgame.cpp
+OBJECTS = main.o \
+ wordgame.o \
+ newgamebase.o \
+ rulesbase.o
+INTERFACES = newgamebase.ui \
+ rulesbase.ui
+UICDECLS = newgamebase.h \
+ rulesbase.h
+UICIMPLS = newgamebase.cpp \
+ rulesbase.cpp
+SRCMOC = moc_wordgame.cpp \
+ moc_newgamebase.cpp \
+ moc_rulesbase.cpp
+OBJMOC = moc_wordgame.o \
+ moc_newgamebase.o \
+ moc_rulesbase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake wordgame.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ wordgame.h \
+ newgamebase.h \
+ rulesbase.h \
+ $(QPEDIR)/include/qpe/qdawg.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+wordgame.o: wordgame.cpp \
+ wordgame.h \
+ newgamebase.h \
+ rulesbase.h \
+ $(QPEDIR)/include/qpe/qdawg.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/filemanager.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+newgamebase.h: newgamebase.ui
+ $(UIC) newgamebase.ui -o $(INTERFACE_DECL_PATH)/newgamebase.h
+
+newgamebase.cpp: newgamebase.ui
+ $(UIC) newgamebase.ui -i newgamebase.h -o newgamebase.cpp
+
+rulesbase.h: rulesbase.ui
+ $(UIC) rulesbase.ui -o $(INTERFACE_DECL_PATH)/rulesbase.h
+
+rulesbase.cpp: rulesbase.ui
+ $(UIC) rulesbase.ui -i rulesbase.h -o rulesbase.cpp
+
+newgamebase.o: newgamebase.cpp
+
+rulesbase.o: rulesbase.cpp
+
+moc_wordgame.o: moc_wordgame.cpp \
+ wordgame.h \
+ newgamebase.h \
+ rulesbase.h \
+ $(QPEDIR)/include/qpe/qdawg.h \
+ $(QPEDIR)/include/qpe/applnk.h
+
+moc_newgamebase.o: moc_newgamebase.cpp \
+ newgamebase.h
+
+moc_rulesbase.o: moc_rulesbase.cpp \
+ rulesbase.h
+
+moc_wordgame.cpp: wordgame.h
+ $(MOC) wordgame.h -o moc_wordgame.cpp
+
+moc_newgamebase.cpp: newgamebase.h
+ $(MOC) newgamebase.h -o moc_newgamebase.cpp
+
+moc_rulesbase.cpp: rulesbase.h
+ $(MOC) rulesbase.h -o moc_rulesbase.cpp
+
+
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 @@
+#!/usr/bin/perl
+
+# Usage: cat dictionaries | grep -v '[^a-z]' | calcdist n score
+#
+# Given a lot of words, find an appropriate distribution
+# into n tiles with tile values proportional to the square root
+# of the ratio of score to the tile's frequency.
+
+$n = shift;
+$score = shift;
+
+while (<>) {
+ chomp;
+ for $c ( split "", $_ ) {
+ $freq{$c}++;
+ $t++;
+ }
+}
+
+for $c ( sort { $freq{$a} <=> $freq{$b} } keys %freq ) {
+ #print "$c: $freq{$c}\n";
+ $need = int($freq{$c}*$n/$t+0.5) || 1;
+ $value = int(sqrt($score/($freq{$c}*$n/$t))+0.5) || 1;
+ $t -= $freq{$c};
+ $n -= $need;
+ print "$need $c $value\n";
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "wordgame.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ WordGame mw;
+ //QPEApplication::setInputMethodHint( &mw, QPEApplication::AlwaysOff );
+ a.showMainWidget(&mw);
+
+ return a.exec();
+}
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 @@
+<!DOCTYPE UI><UI>
+<class>NewGameBase</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Form1</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>290</width>
+ <height>443</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Form1</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>8</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox1</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Players</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>7</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>2</number>
+ </property>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player0</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player1</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player2</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player3</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player4</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>AI3: Smart AI player</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>player5</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox2</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Rules</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>7</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>2</number>
+ </property>
+ <widget>
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>rules</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonOk</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Start</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>default</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+</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 @@
+Files: bin/wordgame apps/Games/wordgame.desktop
+Priority: optional
+Section: qpe/games
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Crossword game
+ A crossword game for the Qtopia environment.
+ 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 @@
+<!DOCTYPE UI><UI>
+<class>RulesBase</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>RulesBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>283</width>
+ <height>264</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Game Rules</string>
+ </property>
+ <property stdset="1">
+ <name>sizeGripEnabled</name>
+ <bool>false</bool>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Name:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>gamename</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox3</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Board</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>4</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Size:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>width</cstring>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>15</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>3</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>15</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>height</cstring>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>15</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>3</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>15</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>editboard</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Edit...</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QTable</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tiletable</cstring>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonDelete</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Delete</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonOk</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;OK</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>default</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Cancel</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>RulesBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>RulesBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+</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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "wordgame.h"
+
+#include <qpe/applnk.h>
+#include <qpe/global.h>
+#include <qpe/filemanager.h>
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qapplication.h>
+#include <qmessagebox.h>
+#include <qcombobox.h>
+#include <qdatetime.h>
+#include <qfileinfo.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qiconset.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+#include <qpe/qpetoolbar.h>
+#include <qtoolbutton.h>
+#include <qvbox.h>
+#include <qwidgetstack.h>
+#include <qpainter.h>
+#include <qlayout.h>
+#include <qregexp.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+enum RuleEffects {
+ Multiplier=15,
+ MultiplyAll=64,
+ Start=128
+};
+
+static const int rack_tiles=7;
+
+const char* sampleWGR=
+ "wordgame_shapes\n"
+ "15 15\n"
+ "400001040100004\n"
+ "030000000000030\n"
+ "002002000200200\n"
+ "000300020003000\n"
+ "000020000020000\n"
+ "102001000100201\n"
+ "000000202000000\n"
+ "400200050002004\n"
+ "000000202000000\n"
+ "102001000100201\n"
+ "000020000020000\n"
+ "000300020003000\n"
+ "002002000200200\n"
+ "030000000000030\n"
+ "400001040100004\n"
+ "1 2 3 66 67 194 100 0\n"
+ "1 j 8\n"
+ "1 q 7\n"
+ "1 x 6\n"
+ "1 z 6\n"
+ "1 w 4\n"
+ "1 k 4\n"
+ "1 v 3\n"
+ "1 f 3\n"
+ "2 y 3\n"
+ "2 h 2\n"
+ "2 b 2\n"
+ "2 m 2\n"
+ "3 p 2\n"
+ "3 g 2\n"
+ "3 u 2\n"
+ "4 d 2\n"
+ "4 c 2\n"
+ "5 l 1\n"
+ "5 o 1\n"
+ "7 t 1\n"
+ "7 n 1\n"
+ "7 a 1\n"
+ "7 r 1\n"
+ "8 s 1\n"
+ "8 i 1\n"
+ "11 e 1\n"
+ "0\n";
+
+WordGame::WordGame( QWidget* parent, const char* name, WFlags fl ) :
+ QMainWindow(parent, name, fl)
+{
+ setIcon( Resource::loadPixmap( "wordgame" ) );
+ setCaption( tr("Word Game") );
+
+ setToolBarsMovable( FALSE );
+ vbox = new QVBox(this);
+
+ setCentralWidget(vbox);
+ toolbar = new QPEToolBar(this);
+ addToolBar(toolbar, Bottom);
+ reset = new QToolButton(Resource::loadPixmap("back"), tr("Back"), "", this, SLOT(resetTurn()), toolbar);
+ done = new QToolButton(Resource::loadPixmap("done"), tr("Done"), "", this, SLOT(endTurn()), toolbar);
+ scoreinfo = new ScoreInfo(toolbar);
+ scoreinfo->setFont(QFont("Helvetica",10));
+ new QToolButton(Resource::loadPixmap("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar);
+ toolbar->setStretchableWidget(scoreinfo);
+
+ cpu = 0;
+ board = 0;
+ bag = 0;
+ racks = 0;
+
+ aiheart = new QTimer(this);
+ connect(aiheart, SIGNAL(timeout()), this, SLOT(think()));
+
+ readConfig();
+}
+
+WordGame::~WordGame()
+{
+ writeConfig();
+}
+
+void WordGame::writeConfig()
+{
+ Config cfg("WordGame");
+ cfg.setGroup("Game");
+ cfg.writeEntry("NameList",namelist,';');
+ cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1);
+ if ( !gameover ) {
+ cfg.writeEntry("Rules",rules);
+ bag->writeConfig(cfg);
+ board->writeConfig(cfg);
+ scoreinfo->writeConfig(cfg);
+ }
+ for (int p=0; p<nplayers; p++) {
+ cfg.setGroup("Player"+QString::number(p+1));
+ if ( gameover ) cfg.clearGroup(); else rack(p)->writeConfig(cfg);
+ }
+}
+
+void WordGame::readConfig()
+{
+ Config cfg("WordGame");
+ cfg.setGroup("Game");
+ int currentplayer = cfg.readNumEntry("CurrentPlayer",0);
+ QStringList pnames = cfg.readListEntry("NameList",';');
+ if ( currentplayer ) {
+ gameover = FALSE;
+ rules = cfg.readEntry("Rules");
+ if ( rules.find("x-wordgamerules") >= 0 ) {
+ // rules files moved
+ rules = "Sample.rules";
+ }
+ if ( loadRules(rules) ) {
+ startGame(pnames);
+ bag->readConfig(cfg);
+ board->readConfig(cfg);
+ scoreinfo->readConfig(cfg);
+ for (int p=0; p<nplayers; p++) {
+ cfg.setGroup("Player"+QString::number(p+1));
+ rack(p)->readConfig(cfg);
+ }
+ player=currentplayer-1;
+ readyRack(player);
+ return;
+ }
+ }
+ // fall-back
+ openGameSelector(pnames);
+}
+
+void WordGame::openGameSelector(const QStringList& initnames)
+{
+ toolbar->hide();
+ gameover = FALSE;
+
+ delete board;
+ board = 0;
+ delete racks;
+ racks = 0;
+
+ delete cpu;
+ cpu = 0;
+
+ newgame = new NewGame(vbox);
+
+ //Rules rules(this);
+ //connect(game.editrules, SIGNAL(clicked()), &rules, SLOT(editRules()));
+ //connect(&rules, SIGNAL(rulesChanged()), &game, SLOT(updateRuleSets()));
+ struct passwd* n = getpwuid(getuid());
+ QString playername = n ? n->pw_name : "";
+ if ( playername.isEmpty() ) {
+ playername = "Player";
+ }
+ newgame->player0->changeItem(playername,0);
+ newgame->player1->setCurrentItem(1);
+ newgame->updateRuleSets();
+ newgame->show();
+
+ connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame()));
+}
+
+void WordGame::startGame()
+{
+ rules = newgame->ruleslist[newgame->rules->currentItem()];
+ if ( loadRules(rules) ) {
+ QStringList names;
+ names.append(newgame->player0->currentText());
+ names.append(newgame->player1->currentText());
+ names.append(newgame->player2->currentText());
+ names.append(newgame->player3->currentText());
+ names.append(newgame->player4->currentText());
+ names.append(newgame->player5->currentText());
+ delete newgame;
+ startGame(names);
+ } else {
+ // error...
+ delete newgame;
+ close();
+ }
+}
+
+void WordGame::startGame(const QStringList& playerlist)
+{
+ toolbar->show();
+ racks = new QWidgetStack(vbox);
+ namelist.clear();
+ nplayers=0;
+ for (QStringList::ConstIterator it=playerlist.begin(); it!=playerlist.end(); ++it)
+ addPlayer(*it);
+ scoreinfo->init(namelist);
+
+ if ( nplayers ) {
+ player=0;
+ readyRack(player);
+ }
+
+ board->show();
+ racks->show();
+}
+
+bool WordGame::loadRules(const QString &name)
+{
+ QString filename = Global::applicationFileName( "wordgame", name );
+ QFile file( filename );
+ if ( !file.open( IO_ReadOnly ) )
+ return FALSE;
+
+ QTextStream ts( &file );
+
+ QString title = name;
+ title.truncate( title.length() - 6 );
+ setCaption( title );
+
+ QString shapepixmap;
+ ts >> shapepixmap;
+ int htiles,vtiles;
+ ts >> htiles >> vtiles;
+
+ if ( htiles < 3 || vtiles < 3 )
+ return FALSE;
+
+ QPixmap bgshapes = Resource::loadPixmap(shapepixmap);
+ QString rule_shapes;
+ for (int i=0; i<vtiles; i++) {
+ QString line;
+ ts >> line;
+ rule_shapes += line;
+ }
+ static int rule_effects[12];
+ int re=0,e;
+ ts >> e;
+ while ( e && re < 10 ) {
+ rule_effects[re] = e;
+ if ( re++ < 10 ) ts >> e;
+ }
+ rule_effects[re++] = 100; // default bonus
+ board = new Board(bgshapes, htiles, vtiles, vbox);
+ board->setRules(rule_shapes, rule_effects);
+ connect(board, SIGNAL(temporaryScore(int)), scoreinfo, SLOT(showTemporaryScore(int)));
+
+ bag = new Bag;
+
+ int count;
+ ts >> count;
+ while ( count ) {
+ QString text;
+ int value;
+ ts >> text >> value;
+ if ( text == "_" )
+ text = "";
+
+ Tile t(text, value);
+ for (int n=count; n--; )
+ bag->add(t);
+
+ ts >> count;
+ }
+
+ return TRUE;
+}
+
+
+NewGame::NewGame(QWidget* parent) :
+ NewGameBase(parent)
+{
+}
+
+void NewGame::updateRuleSets()
+{
+ rules->clear();
+
+ QString rulesDir = Global::applicationFileName( "wordgame", "" );
+ QDir dir( rulesDir, "*.rules" );
+ ruleslist = dir.entryList();
+ if ( ruleslist.isEmpty() ) {
+ // Provide a sample
+ QFile file( rulesDir + "Sample.rules" );
+ if ( file.open( IO_WriteOnly ) ) {
+ file.writeBlock( sampleWGR, strlen(sampleWGR) );
+ file.close();
+ updateRuleSets();
+ }
+ return;
+ }
+ int newest=0;
+ int newest_age=INT_MAX;
+ QDateTime now = QDateTime::currentDateTime();
+ QStringList::Iterator it;
+ for ( it = ruleslist.begin(); it != ruleslist.end(); ++it ) {
+ QFileInfo fi((*it));
+ int age = fi.lastModified().secsTo(now);
+ QString name = *it;
+ name.truncate( name.length()-6 ); // remove extension
+ rules->insertItem( name );
+ if ( age < newest_age ) {
+ newest_age = age;
+ newest = rules->count()-1;
+ }
+ }
+ rules->setCurrentItem(newest);
+}
+
+Rules::Rules(QWidget* parent) :
+ RulesBase(parent,0,TRUE)
+{
+}
+
+void Rules::editRules()
+{
+ if ( exec() ) {
+ // ### create a new set of rules
+ emit rulesChanged();
+ }
+}
+
+void Rules::deleteRuleSet()
+{
+ // ### delete existing rule set
+ emit rulesChanged();
+}
+
+void WordGame::addPlayer(const QString& name)
+{
+ if ( !name.isEmpty() ) {
+ int colon = name.find(':');
+ int cpu = (colon >=0 && name.left(2) == "AI") ? name.mid(2,1).toInt() : 0;
+ addPlayer(name,cpu);
+ }
+}
+
+void WordGame::addPlayer(const QString& name, int cpu)
+{
+ Rack* r = new Rack(rack_tiles,racks);
+ r->setPlayerName(name);
+ r->setComputerization(cpu);
+ racks->addWidget(r, nplayers);
+ refillRack(nplayers);
+ namelist.append(name);
+
+ ++nplayers;
+}
+
+void WordGame::nextPlayer()
+{
+ if ( !refillRack(player) ) {
+ endGame();
+ } else {
+ player = (player+1)%nplayers;
+ scoreinfo->setBoldOne(player);
+ readyRack(player);
+ }
+}
+
+bool WordGame::mayEndGame()
+{
+ int out=-1;
+ int i;
+ for (i=0; i<nplayers; i++)
+ if ( !rack(i)->count() )
+ out = i;
+ if ( out<0 ) {
+ if ( QMessageBox::warning(this,tr("End game"),
+ tr("Do you want to end the game early?"),
+ tr("Yes"), tr("No") )!=0 )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void WordGame::endGame()
+{
+ if ( gameover ) {
+ close();
+ return;
+ }
+
+ if ( !mayEndGame() )
+ return;
+ int out=-1;
+ int totalleft=0;
+ int i;
+ for (i=0; i<nplayers; i++) {
+ Rack* r = rack(i);
+ int c = r->count();
+ if ( c ) {
+ int lose=0;
+ for ( int j=0; j<c; j++ )
+ lose += r->tileRef(j)->value();
+ totalleft += lose;
+ scoreinfo->addScore(i,-lose);
+ } else {
+ out = i;
+ }
+ }
+ int highest=0;
+ int winner=0;
+ for (i=0; i<nplayers; i++) {
+ int s = scoreinfo->playerScore(i);
+ if ( s > highest ) {
+ highest = s;
+ winner = i;
+ }
+ }
+ if ( out >= 0 )
+ scoreinfo->addScore(out,totalleft);
+ scoreinfo->setBoldOne(winner);
+ gameover = TRUE;
+ done->setEnabled(TRUE);
+ reset->setEnabled(FALSE);
+}
+
+void WordGame::endTurn()
+{
+ if ( gameover ) {
+ openGameSelector(namelist);
+ } else {
+ if ( board->checkTurn() ) {
+ if ( board->turnScore() >= 0 ) {
+ scoreinfo->addScore(player,board->turnScore());
+ board->finalizeTurn();
+ } else {
+ QApplication::beep();
+ }
+ nextPlayer();
+ }
+ }
+}
+
+void WordGame::resetTurn()
+{
+ board->resetRack();
+}
+
+void WordGame::passTurn()
+{
+ // ######## trade?
+ nextPlayer();
+}
+
+bool WordGame::refillRack(int i)
+{
+ Rack* r = rack(i);
+ while ( !bag->isEmpty() && !r->isFull() ) {
+ r->addTile(bag->takeRandom());
+ }
+ return r->count() != 0;
+}
+
+void WordGame::readyRack(int i)
+{
+ Rack* r = rack(i);
+ racks->raiseWidget(i);
+ board->setCurrentRack(r);
+
+ done->setEnabled( !r->computerized() );
+ reset->setEnabled( !r->computerized() );
+
+ if ( r->computerized() ) {
+ cpu = new ComputerPlayer(board, r);
+ aiheart->start(0);
+ }
+}
+
+Rack* WordGame::rack(int i) const
+{
+ return (Rack*)racks->widget(i);
+}
+
+void WordGame::think()
+{
+ if ( !cpu->step() ) {
+ delete cpu;
+ cpu = 0;
+ aiheart->stop();
+ if ( board->turnScore() < 0 )
+ passTurn();
+ else
+ endTurn();
+ }
+}
+
+ComputerPlayer::ComputerPlayer(Board* b, Rack* r) :
+ board(b), rack(r), best(new const Tile*[rack_tiles]),
+ best_blankvalues(new Tile[rack_tiles])
+{
+ best_score = -1;
+ across=FALSE;
+ dict=0;
+}
+
+ComputerPlayer::~ComputerPlayer()
+{
+ delete [] best;
+ delete [] best_blankvalues;
+}
+
+bool ComputerPlayer::step()
+{
+ const QDawg::Node* root = dict ? Global::dawg("WordGame").root()
+ : Global::fixedDawg().root();
+ QPoint d = across ? QPoint(1,0) : QPoint(0,1);
+ const Tile* tiles[99]; // ### max board size
+ uchar nletter[4095]; // QDawg only handles 0..4095
+ memset(nletter,0,4096);
+ for (int i=0; i<rack->count(); i++) {
+ const Tile* r = rack->tileRef(i);
+ if ( r->isBlank() )
+ nletter[0]++;
+ else
+ nletter[r->text()[0].unicode()]++;
+ }
+ Tile blankvalues[99]; // ### max blanks
+ findBest(current, d, root, 0, nletter, tiles, 0, blankvalues, 0);
+ if ( ++current.rx() == board->xTiles() ) {
+ current.rx() = 0;
+ if ( ++current.ry() == board->yTiles() ) {
+ if ( across ) {
+ if ( dict == 1 ) {
+ if ( best_score >= 0 ) {
+ rack->arrangeTiles(best,best_n);
+ rack->setBlanks(best_blankvalues);
+ board->scoreTurn(best_start, best_n, best_dir);
+ board->showTurn();
+ }
+ return FALSE;
+ }
+ dict++;
+ across = FALSE;
+ current = QPoint(0,0);
+ } else {
+ across = TRUE;
+ current = QPoint(0,0);
+ }
+ }
+ }
+ return TRUE;
+}
+
+void ComputerPlayer::findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar* nletter, const Tile** tiles, int n, Tile* blankvalues, int blused)
+{
+ if ( !node )
+ return;
+ QChar l = node->letter();
+ const Tile* cur = board->tile(at);
+ if ( cur ) {
+ if ( cur->text()[0] == l ) {
+ bool nextok = board->contains(at+d);
+ if ( node->isWord() && n && (!nextok || !board->tile(at+d)) )
+ noteChoice(tiles,n,d,blankvalues,blused);
+ if ( nextok )
+ findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);
+ // #### text()[1]...
+ }
+ } else {
+ if ( nletter[l.unicode()] || nletter[0] ) {
+ int rc = rack->count();
+ ulong msk = 1;
+ for ( int x=0; x<rc; x++ ) {
+ if ( !(used&msk) ) {
+ const Tile* t = rack->tileRef(x);
+ if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s
+ bool nextok = board->contains(at+d);
+ tiles[n++] = t;
+ if ( t->isBlank() )
+ blankvalues[blused++] = Tile(l,0);
+ if ( node->isWord() && (!nextok || !board->tile(at+d)) )
+ noteChoice(tiles,n,d,blankvalues,blused);
+ used |= msk; // mark
+ nletter[t->text()[0].unicode()]--;
+ if ( nextok )
+ findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);
+ n--;
+ nletter[t->text()[0].unicode()]++;
+ if ( t->isBlank() ) {
+ // keep looking
+ blused--;
+ used &= ~msk; // unmark
+ } else {
+ break;
+ }
+ }
+ }
+ msk <<= 1;
+ }
+ }
+ // #### text()[1]...
+ }
+ findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused);
+}
+
+void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused)
+{
+ int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0);
+/*
+if (s>0 || current==QPoint(5,1)){
+QString st;
+for ( int i=0; i<n; i++ )
+ st += tiles[i]->text();
+qDebug("%d,%d: %s (%d) for %d",current.x(),current.y(),st.latin1(),n,s);
+}
+*/
+ if ( s > best_score ) {
+ int i;
+ for ( i=0; i<n; i++ )
+ best[i] = tiles[i];
+ for ( i=0; i<blused; i++ )
+ best_blankvalues[i] = blankvalues[i];
+ best_n = n;
+ best_blused = blused;
+ best_score = s;
+ best_dir = d;
+ best_start = current;
+ }
+}
+
+int TileItem::smallWidth()
+{
+ return 16;
+}
+
+int TileItem::smallHeight()
+{
+ return 16;
+}
+
+int TileItem::bigWidth()
+{
+ return 22;
+}
+
+int TileItem::bigHeight()
+{
+ return 22;
+}
+
+void TileItem::setState( State state )
+{
+ hide();
+ s = state;
+ show(); // ### use update() in Qt 3.0
+}
+
+void TileItem::setTile(const Tile& tile)
+{
+ hide();
+ t = tile;
+ show(); // ### use update() in Qt 3.0
+}
+
+void TileItem::setBig(bool b)
+{
+ big = b;
+}
+
+void TileItem::drawShape(QPainter& p)
+{
+ static QFont value_font("heletica",8);
+ static QFont big_font("smoothtimes",17);
+ static QFont small_font("smoothtimes",10);
+
+ QRect area(x(),y(),width(),height());
+ p.setBrush(s == Floating ? yellow/*lightGray*/ : white);
+ p.drawRect(area);
+ if ( big ) {
+ p.setFont(value_font);
+ QString n = QString::number(t.value());
+ int w = p.fontMetrics().width('1');
+ int h = p.fontMetrics().height();
+ w *= n.length();
+ QRect valuearea(x()+width()-w-2,y()+height()-h+1,w,h);
+ p.drawText(valuearea,AlignCenter,n);
+ p.setFont(big_font);
+ area = QRect(x(),y(),width()-2,height()-1);
+ } else {
+ p.setFont(small_font);
+ area = QRect(x(),y()+2,width(),height()-2);
+ }
+ if ( t.value() == 0 )
+ p.setPen(darkGray);
+ p.drawText(area,AlignCenter,t.text().upper());
+}
+
+Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) :
+ QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()),
+ parent)
+{
+ grid = new TileItem*[w*h];
+ memset(grid,0,w*h*sizeof(TileItem*));
+ setFrameStyle(0);
+ setHScrollBarMode(AlwaysOff);
+ setVScrollBarMode(AlwaysOff);
+ current_rack = 0;
+ shown_n = 0;
+}
+
+Board::~Board()
+{
+ delete canvas();
+}
+
+void Board::writeConfig(Config& cfg)
+{
+ QStringList t;
+ int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();
+ for (int i=0; i<n; i++)
+ t.append( grid[i] ? grid[i]->tile().key() : QString(".") );
+ cfg.writeEntry("Board",t,';');
+}
+
+void Board::readConfig(Config& cfg)
+{
+ clear();
+ QStringList t = cfg.readListEntry("Board",';');
+ int i=0;
+ int h=canvas()->tilesHorizontally();
+ for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) {
+ if ( *it != "." ) {
+ QPoint p(i%h,i/h);
+ setTile(p,Tile(*it));
+ }
+ i++;
+ }
+ canvas()->update();
+}
+
+void Board::clear()
+{
+ int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();
+ for (int i=0; i<n; i++) {
+ delete grid[i];
+ grid[i]=0;
+ }
+}
+
+
+void Board::setCurrentRack(Rack* r)
+{
+ turn_score = -1;
+ current_rack = r;
+}
+
+void Board::resetRack()
+{
+ unshowTurn();
+ canvas()->update();
+}
+
+void Board::contentsMousePressEvent(QMouseEvent* e)
+{
+ dragstart = e->pos();
+}
+
+void Board::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ if ( current_rack && !current_rack->computerized() ) {
+ QPoint d = e->pos() - dragstart;
+ if ( d.x() <= 0 && d.y() <= 0 ) {
+ // None
+ resetRack();
+ } else {
+ int n;
+ QPoint start=boardPos(dragstart);
+ QPoint end=boardPos(e->pos());
+ QPoint diff=end-start;
+ QPoint dir;
+ if ( d.x() > d.y() ) {
+ n = diff.x()+1;
+ dir = QPoint(1,0);
+ } else {
+ n = diff.y()+1;
+ dir = QPoint(0,1);
+ }
+
+ unshowTurn();
+
+ // Subtract existing tiles from n
+ QPoint t = start;
+ for ( int i=n; i--; ) {
+ if ( contains(t) && tile(t) )
+ n--;
+ t += dir;
+ }
+
+ // Move start back to real start
+ while (contains(start-dir) && tile(start-dir))
+ start -= dir;
+
+ scoreTurn(start, n, dir);
+ showTurn();
+ }
+ }
+}
+
+void Board::finalizeTurn()
+{
+ int i=0;
+ QPoint at = shown_at;
+ while ( i<shown_n && contains(at) ) {
+ if ( item(at) && item(at)->state() == TileItem::Floating ) {
+ current_rack->remove(item(at)->tile());
+ setTileState(at,TileItem::Firm);
+ i++;
+ }
+ at += shown_step;
+ }
+ canvas()->update();
+}
+
+void Board::unshowTurn()
+{
+ int i=0;
+ QPoint at = shown_at;
+ while ( i<shown_n && i<current_rack->count() && contains(at) ) {
+ if ( item(at) && item(at)->state() == TileItem::Floating ) {
+ unsetTile(at);
+ i++;
+ }
+ at += shown_step;
+ }
+}
+
+void Board::showTurn()
+{
+ unshowTurn();
+ QPoint at = shown_at;
+ int i=0;
+ while ( i<shown_n && i<current_rack->count() && contains(at) ) {
+ if ( !tile(at) ) {
+ Tile t = current_rack->tile(i);
+ setTile(at,t);
+ setTileState(at,TileItem::Floating);
+ i++;
+ }
+ at += shown_step;
+ }
+ canvas()->update();
+}
+
+int Board::bonussedValue(const QPoint& at, int base, int& all_mult) const
+{
+ int rule = rule_shape[idx(at)]-'0';
+ int effect = rule_effect[rule];
+ int mult = effect&Multiplier;
+ if ( effect & MultiplyAll ) {
+ all_mult *= mult;
+ return base;
+ } else {
+ return base * mult;
+ }
+}
+
+bool Board::isStart(const QPoint& at) const
+{
+ int rule = rule_shape[idx(at)]-'0';
+ int effect = rule_effect[rule];
+ return effect&Start;
+}
+
+bool Board::checkTurn()
+{
+ if ( current_rack->computerized() )
+ return TRUE; // computer doesn't cheat, and has already set blanks.
+
+ QPoint at = shown_at;
+ int n = shown_n;
+ QPoint d = shown_step;
+ const Tile* tiles[99];
+ Tile blankvalues[99];
+ if ( n > current_rack->count() )
+ n = current_rack->count();
+
+ QDialog check(this,0,TRUE);
+ (new QVBoxLayout(&check))->setAutoAdd(TRUE);
+
+ QHBox mw(&check);
+ new QLabel(tr("Blanks: "),&mw);
+
+ int bl=0;
+ QLineEdit* le[99];
+ for (int i=0; i<n; i++) {
+ tiles[i] = current_rack->tileRef(i);
+ if ( tiles[i]->isBlank() ) {
+ QLineEdit *l = new QLineEdit(&mw);
+ le[bl++] = l;
+ l->setMaxLength(1);
+ l->setFixedSize(l->minimumSizeHint());
+ }
+ }
+
+ QHBox btns(&check);
+ connect(new QPushButton(tr("OK"),&btns), SIGNAL(clicked()), &check, SLOT(accept()));
+ connect(new QPushButton(tr("Cancel"),&btns), SIGNAL(clicked()), &check, SLOT(reject()));
+
+ if ( bl ) {
+retry:
+ if ( !check.exec() ) {
+ unshowTurn();
+ canvas()->update();
+ return FALSE;
+ }
+
+ for (int b=0; b<bl; b++) {
+ QString v = le[b]->text();
+ blankvalues[b]=Tile(v,0);
+ if ( v.length() != 1 )
+ goto retry;
+ }
+ }
+
+ QStringList words;
+ unshowTurn();
+ turn_score = score(at,tiles,n,blankvalues,d,FALSE,&words);
+ showTurn();
+ QStringList to_add;
+ for (QStringList::Iterator it=words.begin(); it!=words.end(); ++it) {
+ if ( !Global::fixedDawg().contains(*it)
+ && !Global::dawg("WordGame").contains(*it) ) {
+ switch (QMessageBox::warning(this, tr("Unknown word"),
+ tr("<p>The word \"%1\" is not in the dictionary.").arg(*it),
+ tr("Add"), tr("Ignore"), tr("Cancel")))
+ {
+ case 0:
+ // ####### add to wordgame dictionary
+ to_add.append(*it);
+ break;
+ case 1:
+ break;
+ case 2:
+ unshowTurn();
+ canvas()->update();
+ return FALSE;
+ }
+ }
+ }
+ if ( to_add.count() )
+ Global::addWords("WordGame",to_add);
+ return TRUE;
+}
+
+void Board::scoreTurn(const QPoint& at, int n, const QPoint& d)
+{
+ unshowTurn();
+ shown_at = at;
+ shown_n = n;
+ shown_step = d;
+ const Tile* tiles[99];
+ if ( n > current_rack->count() )
+ n = current_rack->count();
+ for (int i=0; i<n; i++)
+ tiles[i] = current_rack->tileRef(i);
+ turn_score = score(at,tiles,n,0,d,FALSE,0);
+ emit temporaryScore(turn_score);
+}
+
+int Board::score(QPoint at, const Tile** tiles, int n, const Tile* blankvalue, const QPoint& d, bool checkdict, QStringList* words) const
+{
+ int total=0;
+ int totalsidetotal=0;
+
+ // words gets filled with words made
+
+ // mainword==0 ->
+ // Checks side words, but not main word
+
+ // -1 means words not in dict, or illegally positioned (eg. not connected)
+
+ // text is assumed to fit on board.
+
+ if ( words ) *words=QStringList();
+
+ QPoint otherd(d.y(), d.x());
+
+ int all_mult = 1;
+ int bl=0;
+
+ bool connected = FALSE;
+
+ QString mainword="";
+
+ if ( contains(at-d) && tile(at-d) ) {
+ return -1; // preceeding tiles
+ }
+
+ const Tile* t;
+ for (int i=0; contains(at) && ((t=tile(at)) || i<n); ) {
+ if ( t ) {
+ if ( checkdict || words ) mainword += t->text();
+ total += t->value();
+ connected = TRUE;
+ } else {
+ QString sideword;
+ QString tt;
+ if ( tiles[i]->isBlank() ) {
+ if ( blankvalue )
+ tt = blankvalue[bl++].text();
+ } else {
+ tt = tiles[i]->text();
+ }
+ sideword=tt;
+ if ( checkdict || words ) mainword += tt;
+ int side_mult = 1;
+ int tilevalue = bonussedValue(at,tiles[i]->value(),side_mult);
+ all_mult *= side_mult;
+ if ( !connected && isStart(at) )
+ connected = TRUE;
+ total += tilevalue;
+ int sidetotal = tilevalue;
+ {
+ QPoint side = at-otherd;
+
+ while ( contains(side) && (t=tile(side)) ) {
+ sidetotal += t->value();
+ sideword.prepend(t->text());
+ side -= otherd;
+ }
+ }
+ {
+ QPoint side = at+otherd;
+ while ( contains(side) && (t=tile(side)) ) {
+ sidetotal += t->value();
+ sideword.append(t->text());
+ side += otherd;
+ }
+ }
+ if ( sideword.length() > 1 ) {
+ if ( words )
+ words->append(sideword);
+ if ( checkdict && !Global::fixedDawg().contains(sideword)
+ && !Global::dawg("WordGame").contains(sideword) )
+ return -1;
+ totalsidetotal += sidetotal * side_mult;
+ connected = TRUE;
+ }
+ i++;
+ }
+ at += d;
+ }
+
+ if ( words )
+ words->append(mainword);
+ if ( checkdict && !Global::fixedDawg().contains(mainword)
+ && !Global::dawg("WordGame").contains(mainword) )
+ return -1;
+
+ if ( n == rack_tiles )
+ totalsidetotal += rack_tiles_bonus;
+
+ return connected ? totalsidetotal + total * all_mult : -1;
+}
+
+QPoint Board::boardPos(const QPoint& p) const
+{
+ return QPoint(p.x()/canvas()->tileWidth(), p.y()/canvas()->tileHeight());
+}
+
+void Board::contentsMouseReleaseEvent(QMouseEvent*)
+{
+ if ( current_rack ) {
+ }
+}
+
+
+void Board::setRules(const QString& shapes, const int* effects)
+{
+ rule_shape=shapes; rule_effect=effects;
+ int i=0;
+ int maxre=0;
+ for (int y=0; y<yTiles(); y++) {
+ for (int x=0; x<xTiles(); x++) {
+ int re = shapes[i++]-'0';
+ if ( re > maxre ) maxre = re;
+ canvas()->setTile(x,y,re);
+ }
+ }
+ rack_tiles_bonus=effects[maxre+1];
+}
+
+void Board::unsetTile(const QPoint& p)
+{
+ delete item(p);
+ grid[idx(p)] = 0;
+}
+
+void Board::setTile(const QPoint& p, const Tile& t)
+{
+ TileItem* it=item(p);
+ if ( !it ) {
+ it = grid[idx(p)] = new TileItem(t,FALSE,canvas());
+ it->move(p.x()*canvas()->tileWidth(), p.y()*canvas()->tileHeight());
+ it->show();
+ } else {
+ it->setTile(t);
+ }
+}
+
+Rack::Rack(int ntiles, QWidget* parent) : QCanvasView(
+ new QCanvas(ntiles*TileItem::bigWidth(),TileItem::bigHeight()),
+ parent),
+ item(ntiles)
+{
+ setLineWidth(1);
+ setFixedHeight(sizeHint().height());
+ n = 0;
+ for (int i=0; i<ntiles; i++)
+ item[i]=0;
+ setHScrollBarMode(AlwaysOff);
+ setVScrollBarMode(AlwaysOff);
+ canvas()->setBackgroundColor(gray);
+ dragging = 0;
+}
+
+Rack::~Rack()
+{
+ clear();
+ delete canvas();
+}
+
+void Rack::clear()
+{
+ for (int i=0; i<n; i++)
+ delete item[i];
+ n=0;
+}
+
+void Rack::writeConfig(Config& cfg)
+{
+ QStringList l;
+ for (int i=0; i<n; i++)
+ l.append(tile(i).key());
+ cfg.writeEntry("Tiles",l,';');
+}
+
+void Rack::readConfig(Config& cfg)
+{
+ clear();
+ int x=0;
+ QStringList l = cfg.readListEntry("Tiles",';');
+ for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) {
+ TileItem *i = new TileItem(Tile(*it),TRUE,canvas());
+ i->move(x++,0);
+ i->show();
+ item[n++] = i;
+ }
+ layoutTiles();
+}
+
+static int cmp_tileitem(const void *a, const void *b)
+{
+ const TileItem* ia = *(TileItem**)a;
+ const TileItem* ib = *(TileItem**)b;
+ return int(ia->x() - ib->x());
+}
+
+void Rack::layoutTiles()
+{
+ int w = TileItem::bigWidth()+2;
+
+ if ( dragging ) dragging->moveBy(dragging_adj,0);
+ qsort(item.data(), n, sizeof(TileItem*), cmp_tileitem);
+ if ( dragging ) dragging->moveBy(-dragging_adj,0);
+
+ for (int i=0; i<n ;i++)
+ if ( item[i] == dragging ) {
+ item[i]->setZ(1);
+ } else {
+ item[i]->move(i*w, 0);
+ item[i]->setZ(0);
+ }
+ canvas()->update();
+}
+
+void Rack::setBlanks(const Tile* bv)
+{
+ for (int j=0; j<n; j++) {
+ Tile tt = item[j]->tile();
+ if ( tt.isBlank() ) {
+ tt.setText(bv->text());
+ item[j]->setTile(tt);
+ bv++;
+ }
+ }
+}
+
+bool Rack::arrangeTiles(const Tile** s, int sn)
+{
+ bool could = TRUE;
+ for (int j=0; j<n; j++) {
+ Tile tt = item[j]->tile();
+ int f=-1;
+ for (int i=0; i<sn && f<0; i++) {
+ if (s[i] && *s[i] == tt ) {
+ s[i]=0;
+ f=i;
+ }
+ }
+ if ( f >= 0 ) {
+ item[j]->move(f-999,0);
+ } else {
+ could = FALSE;
+ }
+ }
+ layoutTiles();
+ return could;
+}
+
+void Rack::addTile(const Tile& t)
+{
+ TileItem *i = new TileItem(t,TRUE,canvas());
+ i->show();
+ item[n++] = i;
+ layoutTiles();
+}
+
+void Rack::remove(Tile t)
+{
+ for (int i=0; i<n ;i++)
+ if ( item[i]->tile() == t ) {
+ remove(i);
+ return;
+ }
+}
+
+void Rack::remove(int i)
+{
+ delete item[i];
+ n--;
+ for (;i<n;i++)
+ item[i]=item[i+1];
+ layoutTiles();
+}
+
+void Rack::resizeEvent(QResizeEvent* e)
+{
+ canvas()->resize(width()-frameWidth()*2,height()-frameWidth()*2);
+ QCanvasView::resizeEvent(e);
+}
+
+void Rack::contentsMousePressEvent(QMouseEvent* e)
+{
+ if ( computerized() )
+ return;
+ QCanvasItemList list = canvas()->collisions(e->pos());
+ if (list.count()) {
+ dragging = list.first();
+ dragstart = e->pos()-QPoint(int(dragging->x()),int(dragging->y()));
+ } else {
+ dragging = 0;
+ }
+}
+
+void Rack::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ if ( computerized() )
+ return;
+ //int w = TileItem::bigWidth()+2;
+ if ( dragging ) {
+ dragging_adj = TileItem::bigWidth()/2;
+ if ( dragging->x() > e->x()-dragstart.x() )
+ dragging_adj = -dragging_adj;
+ dragging->move(e->x()-dragstart.x(),0);
+ layoutTiles();
+ }
+}
+
+void Rack::contentsMouseReleaseEvent(QMouseEvent* e)
+{
+ if ( computerized() )
+ return;
+ if ( dragging ) {
+ dragging=0;
+ layoutTiles();
+ }
+}
+
+Tile::Tile(const QString& key)
+{
+ int a=key.find('@');
+ txt = key.left(a);
+ val = key.mid(a+1).toInt();
+ blank = txt.isEmpty();
+}
+
+QString Tile::key() const
+{
+ return txt+"@"+QString::number(val);
+}
+
+Bag::Bag()
+{
+ tiles.setAutoDelete(TRUE);
+}
+
+void Bag::writeConfig(Config& cfg)
+{
+ QStringList t;
+ for (QListIterator<Tile> it(tiles); it; ++it)
+ t.append((*it)->key());
+ cfg.writeEntry("Tiles",t,';');
+}
+
+void Bag::readConfig(Config& cfg)
+{
+ tiles.clear();
+ QStringList t = cfg.readListEntry("Tiles",';');
+ for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it )
+ add(Tile(*it));
+}
+
+void Bag::add(const Tile& t)
+{
+ tiles.append(new Tile(t));
+}
+
+Tile Bag::takeRandom()
+{
+ Tile* rp = tiles.take(random()%tiles.count());
+ Tile r=*rp;
+ return r;
+}
+
+ScoreInfo::ScoreInfo( QWidget* parent, const char* name, WFlags fl ) :
+ QLabel("<P>",parent,name,fl)
+{
+ score=0;
+ msgtimer = new QTimer(this);
+ connect(msgtimer, SIGNAL(timeout()), this, SLOT(showScores()));
+ setBackgroundMode( PaletteButton );
+}
+
+ScoreInfo::~ScoreInfo()
+{
+ if ( score ) delete [] score;
+}
+
+void ScoreInfo::writeConfig(Config& cfg)
+{
+ QStringList l;
+ for (int i=0; i<(int)names.count(); i++)
+ l.append(QString::number(score[i]));
+ cfg.writeEntry("Scores",l,';');
+}
+
+void ScoreInfo::readConfig(Config& cfg)
+{
+ QStringList l = cfg.readListEntry("Scores",';');
+ int i=0;
+ for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it )
+ score[i++]=(*it).toInt();
+ showScores();
+}
+
+
+QSize ScoreInfo::sizeHint() const
+{
+ return QSize(QLabel::sizeHint().width(),fontMetrics().height());
+}
+
+void ScoreInfo::init(const QStringList& namelist)
+{
+ names = namelist;
+ if ( score ) delete [] score;
+ score = new int[names.count()];
+ memset(score,0,sizeof(int)*names.count());
+ boldone = -1;
+ showScores();
+}
+
+void ScoreInfo::addScore(int player, int change)
+{
+ score[player] += change;
+ showScores();
+}
+
+void ScoreInfo::setBoldOne(int b)
+{
+ boldone=b;
+ showScores();
+}
+
+void ScoreInfo::showScores()
+{
+ QString r="<p>";
+ int i=0;
+ //int spl=(names.count()+1)/2; // 2 lines
+ for (QStringList::ConstIterator it=names.begin(); it!=names.end(); ) {
+ if ( i==boldone ) r += "<b>";
+ QString n = *it;
+ n.replace(QRegExp(":.*"),"");
+ r += n;
+ r += ":";
+ r += QString::number(score[i]);
+ if ( i==boldone ) r += "</b>";
+
+ ++i;
+ ++it;
+ if ( it != names.end() )
+ r += " ";
+ }
+ setText(r);
+}
+
+void ScoreInfo::showTemporaryScore(int amount)
+{
+ if ( amount < 0 )
+ setText(tr("<P>Invalid move"));
+ else
+ setText(tr("<P>Score: ")+QString::number(amount));
+ msgtimer->start(3000,TRUE);
+}
+
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef WORDGAME_H
+#define WORDGAME_H
+
+#include "newgamebase.h"
+#include "rulesbase.h"
+
+#include <qpe/qdawg.h>
+#include <qpe/applnk.h>
+
+#include <qmainwindow.h>
+#include <qcanvas.h>
+#include <qlabel.h>
+
+class QVBox;
+class QLabel;
+class QWidgetStack;
+class QToolButton;
+class Config;
+
+class Tile {
+public:
+ Tile() {}
+
+ Tile(const Tile& t)
+ {
+ txt = t.txt;
+ val = t.val;
+ blank = t.blank;
+ }
+
+ Tile(QString text, int value)
+ {
+ txt = text;
+ val = value;
+ blank = txt.isEmpty();
+ }
+
+ Tile(const QString& key);
+
+ int value() const { return val; }
+ bool isBlank() const { return blank; }
+ QString text() const { return txt; }
+ void setText(const QString& t)
+ {
+ txt = t;
+ }
+
+ int operator==(const Tile& o) const
+ { return o.txt == txt && o.val == val && o.blank == blank; }
+ int operator!=(const Tile& o) const
+ { return !operator==(o); }
+ Tile& operator=(const Tile& o)
+ { txt=o.txt; val=o.val; blank=o.blank; return *this; }
+
+ QString key() const;
+
+private:
+ QString txt;
+ int val;
+ bool blank;
+};
+
+class Bag {
+public:
+ Bag();
+
+ void readConfig(Config&);
+ void writeConfig(Config&);
+
+ void add(const Tile&);
+ bool isEmpty() const { return tiles.isEmpty(); }
+ Tile takeRandom();
+private:
+ QList<Tile> tiles;
+};
+
+class TileItem : public QCanvasRectangle {
+public:
+ TileItem(const Tile& tile, bool b, QCanvas* c) :
+ QCanvasRectangle(0,0,
+ b?bigWidth():smallWidth(),
+ b?bigHeight():smallHeight(),c),
+ t(tile), big(b), s(Firm)
+ {
+ }
+
+ static int smallWidth();
+ static int smallHeight();
+ static int bigWidth();
+ static int bigHeight();
+
+ enum State { Firm, Floating };
+ void setState( State state );
+ State state() const { return s; }
+ const Tile& tile() const { return t; }
+ void setTile(const Tile&);
+ void setBig(bool);
+
+protected:
+ void drawShape(QPainter&);
+
+private:
+ Tile t;
+ bool big;
+ State s;
+};
+
+class Rack : public QCanvasView {
+public:
+ Rack(int ntiles, QWidget* parent);
+ ~Rack();
+
+ void readConfig(Config&);
+ void writeConfig(Config&);
+
+ bool isFull() const { return count()==max(); }
+ int max() const { return item.count(); }
+ int count() const { return n; }
+ void addTile(const Tile& t);
+ Tile tile(int i) const { return item[i]->tile(); }
+ const Tile* tileRef(int i) const { return &item[i]->tile(); }
+ void remove(int i);
+ void remove(Tile);
+ bool arrangeTiles(const Tile** s, int sn);
+ void setBlanks(const Tile*);
+
+ void setPlayerName(const QString& name) { nm = name; }
+ QString playerName() const { return nm; }
+ void setComputerization(int level) { cpu=level; }
+ bool computerized() const { return cpu>0; }
+
+protected:
+ void resizeEvent(QResizeEvent*e);
+ void contentsMousePressEvent(QMouseEvent*);
+ void contentsMouseMoveEvent(QMouseEvent*);
+ void contentsMouseReleaseEvent(QMouseEvent*);
+
+private:
+ void clear();
+ void layoutTiles();
+ int n;
+ QArray<TileItem*> item;
+ int dragging_adj;
+ QPoint dragstart;
+ QCanvasItem* dragging;
+ QString nm;
+ int cpu;
+};
+
+class Board : public QCanvasView {
+ Q_OBJECT
+public:
+ Board(QPixmap bgshapes, int w, int h, QWidget* parent);
+ ~Board();
+
+ void readConfig(Config&);
+ void writeConfig(Config&);
+
+ int xTiles() const { return canvas()->tilesHorizontally(); }
+ int yTiles() const { return canvas()->tilesVertically(); }
+
+ bool contains(const QPoint& p) const
+ { return p.x() >= 0 && p.y() >= 0
+ && p.x() < canvas()->tilesHorizontally()
+ && p.y() < canvas()->tilesVertically(); }
+ const Tile* tile(const QPoint& p) const
+ { TileItem* it=item(p); return it ? &it->tile() : 0; }
+
+ void setRules(const QString& shapes, const int* effects);
+
+ void clear();
+ void unsetTile(const QPoint& p);
+ void setTile(const QPoint& p, const Tile& t);
+
+ void setTileState(const QPoint& p, TileItem::State s)
+ {
+ TileItem* it=item(p);
+ if (it) it->setState(s);
+ }
+
+ void setCurrentRack(Rack*);
+ void resetRack();
+ void finalizeTurn();
+ void showTurn();
+ void scoreTurn(const QPoint& at, int n, const QPoint& d);
+ bool checkTurn();
+ int score(QPoint at, const Tile** tiles, int n,
+ const Tile* blankvalue,
+ const QPoint& d, bool ignoredict, QStringList* words) const;
+ int bonussedValue(const QPoint& at, int base, int& all_mult) const;
+ bool isStart(const QPoint& at) const;
+
+ int turnScore() const { return turn_score; }
+
+signals:
+ void temporaryScore(int);
+
+protected:
+ void contentsMousePressEvent(QMouseEvent*);
+ void contentsMouseMoveEvent(QMouseEvent*);
+ void contentsMouseReleaseEvent(QMouseEvent*);
+
+private:
+ int idx(const QPoint& p) const
+ { return p.x()+p.y()*canvas()->tilesHorizontally(); }
+ TileItem*& item(const QPoint& p) const
+ { return grid[idx(p)]; }
+ TileItem **grid;
+ QString rule_shape;
+ const int* rule_effect;
+ int rack_tiles_bonus;
+ Rack* current_rack;
+ QPoint boardPos(const QPoint&) const;
+ QPoint dragstart;
+ QPoint shown_at;
+ int shown_n;
+ QPoint shown_step;
+ void unshowTurn();
+ int turn_score;
+};
+
+class ComputerPlayer
+{
+ Board* board;
+ Rack* rack;
+
+ bool across;
+ int dict;
+ QPoint current;
+
+ const Tile** best;
+ int best_n;
+ Tile* best_blankvalues;
+ int best_blused;
+ int best_score;
+ QPoint best_dir;
+ QPoint best_start;
+
+public:
+ ComputerPlayer(Board* b, Rack* r);
+ ~ComputerPlayer();
+
+ bool step();
+
+private:
+ void findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar *nletter, const Tile** tiles, int n, Tile* blankvalues, int blused);
+ void noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused);
+};
+
+class ScoreInfo : public QLabel {
+ Q_OBJECT
+public:
+ ScoreInfo( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~ScoreInfo();
+
+ void init(const QStringList&);
+ void addScore(int player, int change);
+ int playerScore(int player) const { return score[player]; }
+ void setShowWinner(bool);
+ void setBoldOne(int);
+
+ void readConfig(Config&);
+ void writeConfig(Config&);
+
+protected:
+ QSize sizeHint() const;
+
+public slots:
+ void showTemporaryScore(int amount);
+
+private slots:
+ void showScores();
+
+private:
+ QStringList names;
+ int *score;
+ QTimer* msgtimer;
+ bool showwinner;
+ int boldone;
+};
+
+class NewGame;
+
+class WordGame : public QMainWindow {
+ Q_OBJECT
+public:
+ WordGame( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~WordGame();
+
+private slots:
+ void endTurn();
+ void resetTurn();
+ void passTurn();
+ void think();
+ void endGame();
+ void startGame();
+
+private:
+ void writeConfig();
+ void readConfig();
+
+ void startGame(const QStringList& pnames);
+ bool mayEndGame();
+ void openGameSelector(const QStringList& initnames);
+ bool loadRules(const QString& filename);
+ void addPlayer(const QString& name);
+ void addPlayer(const QString& name, int cpu);
+ void nextPlayer();
+ bool refillRack(int i);
+ void readyRack(int i);
+ Rack* rack(int i) const;
+
+ QWidgetStack *racks;
+ QToolBar* toolbar;
+ QVBox *vbox;
+ Board *board;
+ Bag *bag;
+ ScoreInfo *scoreinfo;
+ QToolButton *done;
+ QToolButton *reset;
+ QTimer* aiheart;
+ ComputerPlayer *cpu;
+ int player;
+ int nplayers;
+ QStringList namelist;
+ bool gameover;
+ QString rules;
+ NewGame* newgame;
+};
+
+class NewGame : public NewGameBase {
+ Q_OBJECT
+public:
+ NewGame(QWidget* parent);
+ QStringList ruleslist;
+
+public slots:
+ void updateRuleSets();
+};
+
+class Rules : public RulesBase {
+ Q_OBJECT
+
+public:
+ Rules(QWidget* parent);
+
+signals:
+ void rulesChanged();
+
+public slots:
+ void editRules();
+
+private:
+ void deleteRuleSet();
+};
+
+#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 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = wordgame.h
+SOURCES = main.cpp \
+ wordgame.cpp
+INTERFACES = newgamebase.ui rulesbase.ui
+TARGET = wordgame
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/wordgame.ts