📄 wordgame.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** 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 <qtopia/applnk.h>#include <qtopia/global.h>#include <qtopia/filemanager.h>#include <qtopia/resource.h>#include <qtopia/config.h>#include <qtopia/qpetoolbar.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 <qtoolbutton.h>#include <qvbox.h>#include <qwidgetstack.h>#include <qpainter.h>#include <qlayout.h>#include <qregexp.h>#include <qgroupbox.h>#include <qscrollview.h>#include <stdlib.h>#ifndef Q_OS_WIN32#include <unistd.h>#include <pwd.h>#else#include <stdlib.h> // needed for rand()#include <time.h>#endif#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/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){#ifdef Q_OS_WIN32 srand( (unsigned)time( NULL ) );#endif landscape=qApp->desktop()->width() > qApp->desktop()->height(); if ( qApp->desktop()->width() < 240 ) { tile_smallw = 10; tile_smallh = 10; tile_bigw = 16; tile_bigh = 16; tile_stweak = 0; tile_btweak = 0; } else if ( qApp->desktop()->height() < 320 ) { tile_smallw = 14; tile_smallh = 12; tile_stweak = -1; } else if ( qApp->desktop()->height() > 420 ) { int s = QMIN(qApp->desktop()->width()/18, qApp->desktop()->height()/18); tile_smallw = s; tile_smallh = s; tile_stweak = 0; } setCaption( tr("Word Game") ); setToolBarsMovable( FALSE ); vbox = new QVBox(this); setCentralWidget(vbox); toolbar = new QPEToolBar(this); toolbar->setBackgroundMode(PaletteBackground); if ( landscape ) toolbar->setFixedWidth(qApp->desktop()->width()-16*tile_smallw); addToolBar(toolbar, landscape ? Right : Bottom); reset = new QToolButton(Resource::loadIconSet("back"), tr("Back"), "", this, SLOT(resetTurn()), toolbar); done = new QToolButton(Resource::loadIconSet("done"), tr("Done"), "", this, SLOT(endTurn()), toolbar); scoreinfo = new ScoreInfo(toolbar); scoreinfo->setFont(QFont("Helvetica",10)); new QToolButton(Resource::loadIconSet("finish"), tr("Close"), "", this, SLOT(endGame()), toolbar); toolbar->setStretchableWidget(scoreinfo); cpu = 0; board = 0; bag = 0; racks = 0; nplayers = 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("DefaultName",defaultname); cfg.writeEntry("NameList",namelist,';'); cfg.writeEntry("CurrentPlayer",gameover ? 0 : player+1); if ( !gameover ) { cfg.writeEntry("Rules",rules); if (bag) { bag->writeConfig(cfg); } if (board) { board->writeConfig(cfg); } if (scoreinfo) { scoreinfo->writeConfig(cfg); } } for (int p=0; p<nplayers; p++) { cfg.setGroup("Player"+QString::number(p+1)); if ( gameover ) { cfg.clearGroup(); } else { if (rack(p)) { rack(p)->writeConfig(cfg); } } }}void WordGame::readConfig(){ Config cfg("WordGame"); cfg.setGroup("Game"); defaultname = cfg.readEntry("DefaultName",tr("Player")); 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(); delete board; board = 0; delete racks; racks = 0; delete cpu; cpu = 0; sv = new QScrollView(vbox); sv->setResizePolicy(QScrollView::AutoOneFit); sv->setFrameStyle(QFrame::NoFrame); newgame = new NewGame(vbox); sv->addChild(newgame); newgame->player0->changeItem(defaultname,0); newgame->player1->setCurrentItem(1); newgame->updateRuleSets(); newgame->playersbox->setColumnLayout(landscape ? 2 : 1, Horizontal); sv->show(); connect(newgame->buttonOk, SIGNAL(clicked()), this, SLOT(startGame())); setCaption(tr("Word Game"));}void WordGame::startGame(){ gameover = FALSE; rules = newgame->ruleslist[newgame->rules->currentItem()]; if ( loadRules(rules) ) { QStringList names; names.append(defaultname=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; delete sv; startGame(names); } else { // error... delete newgame; close(); }}void WordGame::startGame(const QStringList& playerlist){ 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); } toolbar->show(); 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 = tr("Word Game"); if (name) { 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(shapepixmap); 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" ); // No tr 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("<qt>Do you want to end the game early?</qt>"), 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 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -