summaryrefslogtreecommitdiff
path: root/noncore/games/wordgame
Side-by-side diff
Diffstat (limited to 'noncore/games/wordgame') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/wordgame/wordgame.cpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/noncore/games/wordgame/wordgame.cpp b/noncore/games/wordgame/wordgame.cpp
index 47d6725..52e2be2 100644
--- a/noncore/games/wordgame/wordgame.cpp
+++ b/noncore/games/wordgame/wordgame.cpp
@@ -1,500 +1,508 @@
/**********************************************************************
** 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 <opie2/oresource.h>
+
#include <qpe/global.h>
-#include <qpe/resource.h>
#include <qpe/config.h>
#include <qapplication.h>
#include <qmessagebox.h>
#include <qcombobox.h>
#include <qdir.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qtextstream.h>
#include <qtimer.h>
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qvbox.h>
#include <qwidgetstack.h>
#include <qlayout.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
enum RuleEffects {
Multiplier=15,
MultiplyAll=64,
Start=128
};
static int tile_smallw = 16;
static int tile_smallh = 16;
static int tile_bigw = 22;
static int tile_bigh = 22;
static int tile_stweak = -2;
static int tile_btweak = -1;
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)
{
if ( qApp->desktop()->width() < 240 ) {
tile_smallw = 10;
tile_smallh = 10;
tile_bigw = 16;
tile_bigh = 16;
tile_stweak = 0;
tile_btweak = 0;
}
- setIcon( Resource::loadPixmap( "wordgame/WordGame.png" ) );
+ setIcon( Opie::Core::OResource::loadPixmap( "wordgame/WordGame" ) );
setCaption( tr("Word Game") );
setToolBarsMovable( FALSE );
vbox = new QVBox(this);
setCentralWidget(vbox);
toolbar = new QToolBar(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);
+ bool useBigIcon = qApp->desktop()->size().width() > 330;
+ reset = new QToolButton(Opie::Core::OResource::loadPixmap("back", Opie::Core::OResource::SmallIcon),
+ tr("Back"), "", this, SLOT(resetTurn()), toolbar);
+ reset->setUsesBigPixmap( useBigIcon );
+ done = new QToolButton(Opie::Core::OResource::loadPixmap("done", Opie::Core::OResource::SmallIcon),
+ tr("Done"), "", this, SLOT(endTurn()), toolbar);
+ done->setUsesBigPixmap( useBigIcon );
scoreinfo = new ScoreInfo(toolbar);
scoreinfo->setFont(QFont("Helvetica",10));
- new QToolButton(Resource::loadPixmap("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar);
+ QToolButton *btn = new QToolButton(Opie::Core::OResource::loadPixmap("finish", Opie::Core::OResource::SmallIcon),
+ tr("Close"), "", this, SLOT(endGame()), toolbar);
+ btn->setUsesBigPixmap( useBigIcon );
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);
racks->setFixedHeight(TileItem::bigHeight()+2);
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;
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;
}
- QImage shim = Resource::loadImage("wordgame/wordgame_shapes");
+ QImage shim = Opie::Core::OResource::loadImage("wordgame/wordgame_shapes");
shim = shim.smoothScale((re-1)*TileItem::smallWidth(),TileItem::smallHeight());
QPixmap bgshapes;
bgshapes.convertFromImage(shim);
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 {
@@ -1173,338 +1181,338 @@ void Board::setRules(const QString& shapes, const int* effects)
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();
}
QSize Rack::sizeHint() const
{
return QSize(-1,TileItem::bigHeight()+2);
}
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)
+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);
}