📄 mindbreaker.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 "mindbreaker.h"#include <qtopia/resource.h>#include <qtopia/config.h>#include <qtopia/qpeapplication.h>#include <qtopia/qpetoolbar.h>#include <qpainter.h>#include <qpixmap.h>#include <qtoolbutton.h>#include <qpushbutton.h>#include <qmessagebox.h>#include <qlabel.h>#include <qlayout.h>#include <qtimer.h>#include <stdlib.h>#include <sys/time.h>#include <unistd.h>static int pegRTTI = 3393393;static int adjusted_panel_height;static int adjusted_panel_width;static int adjusted_bin_margin;static int adjusted_peg_size;static int adjusted_answerpeg_size;static int adjusted_title_height;static int adjusted_title_width;static int adjusted_first_peg_x_diff;static int adjusted_first_peg_y_diff;static int adjusted_peg_spacing;static int adjusted_answerpegx;static int adjusted_answerpegy;static int adjusted_answerpeg_xdiff;static int adjusted_answerpeg_ydiff;static int adjusted_board_height;static int adjusted_board_width;static void setupBoardSize(int w, int h){ adjusted_panel_width = w * 3/4; adjusted_title_width = w * 3/4; adjusted_title_height = h/10; adjusted_panel_height = (h-adjusted_title_height)/9; adjusted_bin_margin = w * 10/240; adjusted_peg_size = adjusted_panel_height*3/4; adjusted_answerpeg_size = QMIN(adjusted_panel_width*15/180,adjusted_panel_height*15/25); // looks a bit dodgy on larger sizes if ( adjusted_peg_size > 40 ) adjusted_peg_size = 40; adjusted_first_peg_x_diff = w * 31/240-adjusted_peg_size/2; adjusted_first_peg_y_diff = (adjusted_panel_height - adjusted_peg_size)/2; adjusted_peg_spacing = w * 30/240; // looks a bit dodgy on larger sizes (still does though, but not as much...) if ( adjusted_answerpeg_size > 22 ) adjusted_answerpeg_size = 22; adjusted_answerpegx = adjusted_panel_width * 159/180 - adjusted_answerpeg_size/2; adjusted_answerpegy = adjusted_panel_height/3 - adjusted_answerpeg_size/2; adjusted_answerpeg_xdiff = adjusted_panel_width * 10/180; adjusted_answerpeg_ydiff = adjusted_panel_height * 9/25; adjusted_board_height = adjusted_title_height + (adjusted_panel_height * 9); adjusted_board_width = adjusted_panel_width + (adjusted_bin_margin * 2) + adjusted_peg_size;// qDebug("Adjusted width %d height %d", adjusted_board_width, adjusted_board_height);}/* helper class, */class Peg : public QCanvasRectangle{public: Peg(QCanvas *canvas, int type, int go = -1, int pos = -1); int rtti() const {return pegRTTI; } void advance(int phase); bool hit( const QPoint &) const;/* a placed peg is one that has been set down on the board correctly and should not be moved, only copied */ bool placed() const; void setPlaced(bool); int pegGo() const; int pegPos() const; void setPegPos(int); int type() const; static void buildImages(); static QImage imageForType(int t); static int eggLevel;protected: void drawShape(QPainter &);private: static QVector<QImage> normalPegs; static QVector<QImage> specialPegs; bool isplaced; int pegtype; int peg_go; int peg_pos; int aniStep;};int Peg::eggLevel = 0;QVector<QImage> Peg::normalPegs;QVector<QImage> Peg::specialPegs;void Peg::buildImages(){ QImage pegs = Resource::loadImage("mindbreaker/pegs"); int x = 0; int y = 0; int i; eggLevel = 0; normalPegs.resize(10); for (i = 0; i < 6; i++) { normalPegs.insert(i, new QImage(pegs.copy(x, y, peg_size, peg_size). smoothScale(adjusted_peg_size, adjusted_peg_size) )); x += peg_size; } specialPegs.resize(5); for (i = 0; i < 5; i++) { specialPegs.insert(i, new QImage(pegs.copy(x,y,peg_size, peg_size). smoothScale(adjusted_peg_size, adjusted_peg_size) )); x += peg_size; } QImage image = Resource::loadImage("mindbreaker/mindbreaker"); /* copy from master image to functional images */ x = 0; y = panel_height; normalPegs.insert(8, new QImage( image.copy(x, y, panel_width, panel_height). smoothScale( adjusted_panel_width, adjusted_panel_height) )); y += panel_height; y += title_height; normalPegs.insert(9, new QImage(image.copy(x, y, title_width, title_height). smoothScale( adjusted_title_width, adjusted_title_height) )); y += title_height; x = 6 * peg_size; normalPegs.insert(6, new QImage(image.copy(x, y, answerpeg_size, answerpeg_size). smoothScale( adjusted_answerpeg_size, adjusted_answerpeg_size) )); x += answerpeg_size; normalPegs.insert(7, new QImage(image.copy(x, y, answerpeg_size, answerpeg_size). smoothScale( adjusted_answerpeg_size, adjusted_answerpeg_size) ));}QImage Peg::imageForType(int t) { if (eggLevel > t ) { if( t < 5) { return *specialPegs[t]; } else { return *normalPegs[rand() % 6]; } } return *normalPegs[t];}Peg::Peg(QCanvas *canvas , int t, int g, int p) : QCanvasRectangle(canvas){ setSize(normalPegs[t]->width(), normalPegs[t]->height() ); pegtype = t; isplaced = FALSE; peg_pos = p; peg_go = g; aniStep = rand() % 6; setAnimated(TRUE);}void Peg::advance(int phase) { if (phase == 0) aniStep = (++aniStep) % 6; else { hide(); show(); }}void Peg::drawShape(QPainter &p ){ if ((pegtype == 5) && eggLevel > 5) { p.drawImage(int(x()), int(y()), *normalPegs[aniStep]); } else p.drawImage(int(x()), int(y()), imageForType(pegtype));}bool Peg::hit( const QPoint &p ) const{ int ix = p.x() - int(x()); int iy = p.y() - int(y()); if (!normalPegs[pegtype]->valid(ix, iy)) return FALSE; QRgb pixel = normalPegs[pegtype]->pixel(ix, iy); return (qAlpha(pixel ) != 0);}inline bool Peg::placed() const{ return isplaced;}inline int Peg::pegGo() const{ return peg_go;}inline int Peg::pegPos() const{ return peg_pos;}inline void Peg::setPegPos(int p) { peg_pos = p;}inline void Peg::setPlaced(bool p) { isplaced = p;}inline int Peg::type() const { return pegtype;}/* Load the main image, copy from it the pegs, the board, and the answer image * and use these to create the tray, answer and board */MindBreaker::MindBreaker( QWidget *parent, const char *name, WFlags f) : QMainWindow(parent, name, f){ QPEApplication::setInputMethodHint(this,QPEApplication::AlwaysOff); setMinimumSize(160,210); setCaption(tr("Mindbreaker")); QWidget *w = new QWidget( this ); w->setBackgroundColor( black ); QHBoxLayout *hb = new QHBoxLayout( w ); hb->addStretch(); board = new MindBreakerBoard(w); hb->addWidget( board, 100 ); hb->addStretch(); setCentralWidget(w); setToolBarsMovable( FALSE ); QPEToolBar *tb = new QPEToolBar(this); tb->setHorizontalStretchable( TRUE ); QIconSet newicon = Resource::loadIconSet("new"); new QToolButton(newicon, tr("New Game"), 0, board, SLOT(clear()), tb, "NewGame"); score = new QToolButton(tb); score->setText(""); score->setMaximumHeight(20); score->setUsesTextLabel(TRUE); tb->setStretchableWidget(score); connect(board, SIGNAL(scoreChanged(int,int)), this, SLOT(setScore(int,int))); connect(score, SIGNAL(clicked()), board, SLOT(resetScore())); int a, b; board->getScore(&a, &b); setScore(a,b); layout()->setResizeMode(QLayout::FreeResize);}void MindBreaker::setScore(int turns, int games){ double average; double total_turns = turns; double total_games = games; if(total_games > 0) average = total_turns / total_games; else average = 0.0; score->setText(tr("win avg: %1 turns (%2 games)").arg(average, 0, 'g', 2).arg(games));}void MindBreaker::resizeEvent( QResizeEvent *e ){ board->fixSize(); QMainWindow::resizeEvent( e );}MindBreakerBoard::MindBreakerBoard( QWidget *parent, const char *name, int wFlags ) : QCanvasView(0, parent, name, wFlags), moving(0), game_over(FALSE), total_turns(0), total_games(0){ setFrameStyle( NoFrame ); setupBoardSize(qApp->desktop()->width(),qApp->desktop()->height()); cnv.resize(100,100); setCanvas(&cnv); setBackgroundColor( black ); struct timeval tv; current_go = 0; gettimeofday(&tv, 0); srand(tv.tv_usec); canvas()->setAdvancePeriod(500); current_highlight = 0; widthTimer = new QTimer( this ); connect(widthTimer, SIGNAL(timeout()), this, SLOT(doFixSize()) ); setMaximumWidth( QMIN(qApp->desktop()->height(),qApp->desktop()->width()) ); //doFixSize(); // build images... needs to be done before reading config. //readConfig(); // first read... to ensure initial labels and side look right.}void MindBreakerBoard::readConfig(){ Config c("MindBreaker", Config::User); c.setGroup("Board"); game_over = FALSE; int i; if (c.readNumEntry("Answer0") < 0) { for (i = 0; i < 4; i++) { answer[i] = rand() % 6; current_guess[i] = 6; } total_turns = 0; total_games = 0; } else { int j; c.setGroup("Score"); total_turns = c.readNumEntry("Turns"); total_games = c.readNumEntry("Games"); if(total_turns < 0) total_turns = 0; if(total_games < 0) total_games = 0; checkScores(); c.setGroup("Board"); for(i = 0; i < 4; i++) answer[i] = c.readNumEntry(QString("Answer%1").arg(i)); /* read, and parse past guesses */ current_go = 0; for(j=0; j < 9; j++) { current_guess[0] = c.readNumEntry(QString("Go%1p0").arg(j)); if (current_guess[0] < 0) break; placeGuessPeg(0, current_guess[0]); current_guess[1] = c.readNumEntry(QString("Go%1p1").arg(j)); placeGuessPeg(1, current_guess[1]); current_guess[2] = c.readNumEntry(QString("Go%1p2").arg(j)); placeGuessPeg(2, current_guess[2]); current_guess[3] = c.readNumEntry(QString("Go%1p3").arg(j)); placeGuessPeg(3, current_guess[3]); checkGuess(); } for(i = 0; i < 4; i++) { current_guess[i] = c.readNumEntry(QString("CurrentGo%1").arg(i)); if (current_guess[i] != 6) placeGuessPeg(i, current_guess[i]); } }}MindBreakerBoard::~MindBreakerBoard(){ int i; if (game_over) { current_go = 0; /* clear the answer, clear the guess */ for (i = 0; i < 4; i++) { answer[i] = rand() % 6; current_guess[i] = 6; } } writeConfig();}void MindBreakerBoard::writeConfig(){ Config c("MindBreaker", Config::User); c.setGroup("Board"); c.clearGroup(); /* write the board */ int i,j; for (i = 0; i < current_go; i++) { for(j = 0; j < 4; j++) c.writeEntry(QString("Go%1p%2").arg(i).arg(j), past_guesses[4*i+j]); } for(j = 0; j < 4; j++) c.writeEntry(QString("CurrentGo%1").arg(j), current_guess[j]); for(j = 0; j < 4; j++) c.writeEntry(QString("Answer%1").arg(j), answer[j]); c.setGroup("Score"); /* write the score */ c.writeEntry("Turns", total_turns); c.writeEntry("Games", total_games);}void MindBreakerBoard::getScore(int *a, int *b){ *a = total_turns; *b = total_games; return;}void MindBreakerBoard::fixSize(){ hide(); setMaximumWidth( parentWidget()->height() ); widthTimer->start( 20, TRUE );}void MindBreakerBoard::doFixSize(){ QSize s = size(); int fw = frameWidth(); s.setWidth(s.width() - fw); s.setHeight(s.height() - fw);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -