📄 cardsmodel.cpp
字号:
#include "CardsModel.h"#include <QPoint>#include <QImage>#include <QStringList>#include <QSettings> #include <QApplication>#include <QFont>const int CardsModel::MAX_CARDS_NUM = 16;const int CardsModel::ROW_NUM = 4;const int CardsModel::COL_NUM = 4;const QString CardsModel::imgName = "./bear.jpg"; CardsModel::CardsModel(QObject* parent) : QAbstractTableModel(parent), isRandomized(false), bShowNumber(false){ // init arrays initMap(); sliceImage();}QVariant CardsModel::data(const QModelIndex &index, int role) const{ int number = mCardsList[index.row()*columnCount() + index.column()]; switch(role) { default: case Qt::DisplayRole: return number + 1; case Qt::BackgroundColorRole: return Qt::white; case Qt::FontRole: if (qApp) { QFont f = qApp->font(); f.setPixelSize(16); f.setBold(true); return f; } break; case Qt::UserRole: if (mImages.count() == 0) return 0; return mImages.at(number); case Qt::UserRole + 1: return bShowNumber; } return QVariant();}CardsModel::~CardsModel(){ }void CardsModel::saveConfig(){ QSettings cfg("./PuzzleGame.ini", QSettings::IniFormat); cfg.beginGroup("SavedGame"); QStringList map; for (int i = 0; i < 16; i++) map.append(QString::number(mCardsList[i])); cfg.setValue("CardsList", map.join(QString('-'))); cfg.setValue("ShowNumber", bShowNumber);}void CardsModel::loadConfig(){ QSettings cfg("./PuzzleGame.ini", QSettings::IniFormat); cfg.beginGroup("SavedGame"); QStringList map = cfg.value("CardsList").toString().split('-'); bShowNumber = cfg.value("ShowNumber", false).toBool(); int i = 0; for (QStringList::Iterator it = map.begin(); it != map.end(); ++it) { mCardsList[i] = (*it).toInt(); i++; if (i > 15) break; } isRandomized = true; sliceImage(); emit updateMenu(bShowNumber);}void CardsModel::sliceImage(){ mImages.clear(); QImage img(imgName); int w = img.width() / COL_NUM; int h = img.height() / ROW_NUM; for (int row = 0; row < rowCount() ; row++) { for (int col = 0 ; col < columnCount() ; col++) mImages.append(img.copy(col * w, row * h, w, h)); }}void CardsModel::showNumber(bool checked){ bShowNumber = checked; emit dataChanged(createIndex(0,0), createIndex(3,3));}void CardsModel::initMap(){ mCardsList.clear(); for (int i = 0; i < MAX_CARDS_NUM; i++) mCardsList.append(i); isRandomized = false;}void CardsModel::randomize(){ initMap(); isRandomized = true; int step = 0; while (step < 333) { // randomize move position int row = rand() % ROW_NUM; int col = rand() % COL_NUM; if (moveCards(&col, &row)) step++; } emit dataChanged(createIndex(0,0), createIndex(3,3));}void CardsModel::checkwin(){ if(!isRandomized) return; int i; for (i = 0; i < MAX_CARDS_NUM; i++) if(i != mCardsList[i]) break; if (i == MAX_CARDS_NUM ) { isRandomized = false; emit gameWon(); }}void CardsModel::reset(){ initMap(); emit dataChanged(createIndex(0,0), createIndex(3,3));}void CardsModel::moveLeft(){ QPoint fpos = getEmptyPoint(); move(fpos + QPoint(1,0));}void CardsModel::moveRight(){ QPoint fpos = getEmptyPoint(); move(fpos + QPoint(-1,0));}void CardsModel::moveUp(){ QPoint fpos = getEmptyPoint(); move(fpos + QPoint(0,1));}void CardsModel::moveDown(){ QPoint fpos = getEmptyPoint(); move(fpos + QPoint(0,-1));}QPoint CardsModel::getEmptyPoint(){ // calculate the empty position // the value of empty card is "MAX_CARDS_NUM - 1" int pos = mCardsList.indexOf(MAX_CARDS_NUM - 1); if (pos == -1) // fail to find the empty position return QPoint(-1, -1); int emptyRow = pos / columnCount(); int emptyCol = pos - emptyRow * columnCount(); qDebug("Empty point: %d, %d", emptyRow, emptyCol); return QPoint(emptyCol, emptyRow);}void CardsModel::move(int col, int row){ int tCol = col; int tRow = row; if (moveCards(&tCol, &tRow)) { qDebug("target point: %d, %d", tCol, tRow); emit dataChanged(createIndex(tCol, tRow), createIndex(row, col)); // check if the player wins with this move checkwin(); }}//// To move selected card// Input: pCol and pRow are pointer to current selected// card's column and row number.// Output: the position after the move// Return: return false if the selected card cannot be moved;// return true if been moved successfully//bool CardsModel::moveCards(int* pCol, int* pRow){ int emptyCol = getEmptyPoint().x(); int emptyRow = getEmptyPoint().y(); int col = *pCol; int row = *pRow; // sanity check if (row < 0 || row >= rowCount()) return false; if (col < 0 || col >= columnCount()) return false; // check if the selected card can be moved if (row != emptyRow && col != emptyCol) return false; // rows match -> shift cards if(row == emptyRow) { if (col < emptyCol) { for(int c = emptyCol; c > col; c--) mCardsList[c + row * columnCount()] = mCardsList[ c-1 + row *columnCount()]; } else if (col > emptyCol) { for(int c = emptyCol; c < col; c++) mCardsList[c + row * columnCount()] = mCardsList[ c+1 + row *columnCount()]; } *pCol = emptyCol; } // cols match -> shift cards else if (col == emptyCol) { if (row < emptyRow) { for(int r = emptyRow; r > row; r--) mCardsList[col + r * columnCount()] = mCardsList[ col + (r-1) *columnCount()]; } else if (row > emptyRow) { for(int r = emptyRow; r < row; r++) mCardsList[col + r * columnCount()] = mCardsList[ col + (r+1) *columnCount()]; } *pRow = emptyRow; } // move free cell to click position mCardsList[col + row * columnCount()] = 15; return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -