⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fifteen.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 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 "fifteen.h"#include <qtopia/resource.h>#include <qtopia/config.h>#include <qtopia/contextmenu.h>#include <qvbox.h>#include <qaction.h>#include <qlayout.h>#include <qpainter.h>#include <qpopupmenu.h>#include <qmessagebox.h>#include <qtopia/qpetoolbar.h>#include <qtopia/qpemenubar.h>#include <qstringlist.h>#include <qapplication.h>#include <qtoolbutton.h>#include <stdlib.h>#include <time.h>FifteenMainWindow::FifteenMainWindow(QWidget *parent, const char* name, WFlags fl)  : QMainWindow( parent, name, fl ){    // random seed    srand(time(0));    setCaption(tr("Fifteen Pieces"));    setToolBarsMovable( FALSE );    QVBox *vbox = new QVBox( this );    PiecesTable *table = new PiecesTable( vbox );    table->setFocus();    setCentralWidget(vbox);    QIconSet   newicon( Resource::loadPixmap("Fifteen"));#ifdef QTOPIA_PHONE    ContextMenu* menu = new ContextMenu(this);    menu->insertItem(newicon, tr("Shuffle"), table, SLOT(slotRandomize()));#else    QPEToolBar *toolbar = new QPEToolBar(this);    toolbar->setHorizontalStretchable( FALSE );    (void)new QToolButton(newicon, tr("Shuffle"), 0,	  table, SLOT(slotRandomize()), toolbar, "New Game");    /* This is pointless and confusing.    a = new QAction( tr( "Solve" ), Resource::loadIconSet( "repeat" ),		     QString::null, 0, this, 0 );    connect( a, SIGNAL( activated() ), table, SLOT( slotReset() ) );    a->addTo( game );    a->addTo( toolbar );    */#endif}PiecesTable::PiecesTable(QWidget* parent, const char* name )  : QTableView(parent, name), _menu(0), _randomized(false){  // setup table view  setFrameStyle(NoFrame);  setBackgroundMode(NoBackground);  setMouseTracking(true);  setNumRows(4);  setNumCols(4);  // init arrays  initMap();  readConfig();  initColors();  // set font  QFont f = font();  f.setPixelSize(18);  f.setBold( TRUE );  setFont(f);}PiecesTable::~PiecesTable(){  writeConfig();}void PiecesTable::writeConfig(){  Config cfg("Fifteen");  cfg.setGroup("Game");  QStringList map;  for (int i = 0; i < 16; i++)    map.append( QString::number( _map[i] ) );  cfg.writeEntry("Map", map, '-');  cfg.writeEntry("Randomized", _randomized );}void PiecesTable::readConfig(){  Config cfg("Fifteen");  cfg.setGroup("Game");  QStringList map = cfg.readListEntry("Map", '-');  _randomized = cfg.readBoolEntry( "Randomized", FALSE );  int i = 0;  for ( QStringList::Iterator it = map.begin(); it != map.end(); ++it ) {    _map[i] = (*it).toInt();    i++;    if ( i > 15 ) break;  }}void PiecesTable::paintCell(QPainter *p, int row, int col){  int w = cellWidth();  int h = cellHeight();  int x2 = w - 1;  int y2 = h - 1;  int number = _map[col + row * numCols()] + 1;  // draw cell background  if(number == 16)    p->setBrush(colorGroup().background());  else    p->setBrush(_colors[number-1]);  p->setPen(NoPen);  p->drawRect(0, 0, w, h);  if (number == 16) return;  // draw borders  if (height() > 40) {    p->setBrush(_colors[number-1].light(130));    p->drawPolygon(light_border);    p->setBrush(_colors[number-1].dark(130));    p->drawPolygon(dark_border);  }  // draw number  p->setPen(black);  p->drawText(0, 0, x2, y2, AlignHCenter | AlignVCenter, QString::number(number));}void PiecesTable::resizeEvent(QResizeEvent *e){  QTableView::resizeEvent(e);  setCellWidth(contentsRect().width()/ numRows());  setCellHeight(contentsRect().height() / numCols());  //  // Calculate 3d-effect borders  //  int	cell_w = cellWidth();  int	cell_h = cellHeight();  int	x_offset = cell_w - int(cell_w * 0.9);	// 10% should be enough  int	y_offset = cell_h - int(cell_h * 0.9);  light_border.setPoints(6,    0, 0,    cell_w, 0,    cell_w - x_offset, y_offset,    x_offset, y_offset,    x_offset, cell_h - y_offset,    0, cell_h);  dark_border.setPoints(6,    cell_w, 0,    cell_w, cell_h,    0, cell_h,    x_offset, cell_h - y_offset,    cell_w - x_offset, cell_h - y_offset,    cell_w - x_offset, y_offset);}void PiecesTable::initColors(){  _colors.resize(numRows() * numCols());  for (int r = 0; r < numRows(); r++)    for (int c = 0; c < numCols(); c++)      _colors[c + r *numCols()] = QColor(255 - 70 * c,255 - 70 * r, 150);}void PiecesTable::initMap(){  _map.resize(16);  for ( int i = 0; i < 16; i++)    _map[i] = i;  _randomized = false;}void PiecesTable::randomizeMap(){  initMap();  _randomized = true;  // find the free position  int pos = _map.find(15);  int move = 0;  while ( move < 333 ) {    int frow = pos / numCols();    int fcol = pos - frow * numCols();    // find click position    int row = rand()%4;    int col = rand()%4;    // sanity check    if ( row < 0 || row >= numRows() ) continue;    if ( col < 0 || col >= numCols() ) continue;    if ( row != frow && col != fcol ) continue;    move++;    // rows match -> shift pieces    if(row == frow) {      if (col < fcol) {	for(int c = fcol; c > col; c--) {	  _map[c + row * numCols()] = _map[ c-1 + row *numCols()];	}      }      else if (col > fcol) {	for(int c = fcol; c < col; c++) {	  _map[c + row * numCols()] = _map[ c+1 + row *numCols()];	}      }    }    // cols match -> shift pieces    else if (col == fcol) {      if (row < frow) {	for(int r = frow; r > row; r--) {	  _map[col + r * numCols()] = _map[ col + (r-1) *numCols()];	}      }      else if (row > frow) {	for(int r = frow; r < row; r++) {	  _map[col + r * numCols()] = _map[ col + (r+1) *numCols()];	}      }    }    // move free cell to click position    _map[pos=(col + row * numCols())] = 15;  }  repaint();}void PiecesTable::checkwin(){  if(!_randomized) return;  int i;  for (i = 0; i < 16; i++)    if(i != _map[i])      break;  if (i == 16) {    QMessageBox::information(this, tr("Fifteen Pieces"),			     tr("Congratulations!<br>You win the game!"));    _randomized = FALSE;  }}void PiecesTable::slotRandomize(){  randomizeMap();}void PiecesTable::slotReset(){  initMap();  repaint();}void PiecesTable::keyPressEvent(QKeyEvent* e){    int fpos = _map.find(15);    int y = fpos / numCols();    int x = fpos % numCols();    switch ( e->key() ) {	case Key_Right: x--; x--;	case Key_Left: x++; y++;	case Key_Down: y--; y--;	case Key_Up: y++;	push(x,y);	e->accept();    default:	QTableView::keyPressEvent(e);	return;    }}void PiecesTable::mousePressEvent(QMouseEvent* e){  QTableView::mousePressEvent(e);  if (e->button() == RightButton) {    // setup RMB pupup menu    if(!_menu) {      _menu = new QPopupMenu(this);      _menu->insertItem(tr("R&andomize Pieces"), mRandomize);      _menu->insertItem(tr("&Reset Pieces"), mReset);      _menu->adjustSize();    }    // execute RMB popup and check result    switch(_menu->exec(mapToGlobal(e->pos()))) {    case mRandomize:      randomizeMap();      break;    case mReset:      initMap();      repaint();      break;    default:      break;    }  } else {    // find click position    int row = findRow(e->y());    int col = findCol(e->x());    push(col,row);  }}void PiecesTable::push(int col, int row){    // GAME LOGIC    // find the free position    int pos = _map.find(15);    if(pos < 0) return;    int frow = pos / numCols();    int fcol = pos - frow * numCols();    // sanity check    if (row < 0 || row >= numRows()) return;    if (col < 0 || col >= numCols()) return;    if ( row != frow && col != fcol ) return;    // valid move?    if(row != frow && col != fcol) return;    // rows match -> shift pieces    if(row == frow) {      if (col < fcol) {	for(int c = fcol; c > col; c--) {	  _map[c + row * numCols()] = _map[ c-1 + row *numCols()];	  updateCell(row, c, false);	}      }      else if (col > fcol) {	for(int c = fcol; c < col; c++) {	  _map[c + row * numCols()] = _map[ c+1 + row *numCols()];	  updateCell(row, c, false);	}      }    }    // cols match -> shift pieces    else if (col == fcol) {      if (row < frow) {	for(int r = frow; r > row; r--) {	  _map[col + r * numCols()] = _map[ col + (r-1) *numCols()];	  updateCell(r, col, false);	}      }      else if (row > frow) {	for(int r = frow; r < row; r++) {	  _map[col + r * numCols()] = _map[ col + (r+1) *numCols()];	  updateCell(r, col, false);	}      }    }    // move free cell to click position    _map[col + row * numCols()] = 15;    updateCell(row, col, false);    // check if the player wins with this move    checkwin();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -