头文件
#ifndef TWOZERO_H
#define TWOZERO_H
#define private public
#include <QWidget>
#include <QPushButton>
#include <QPoint>
class Twozero : public QWidget
{
Q_OBJECT
public:
explicit Twozero(QWidget *parent = 0);
void replay();
bool isFail();
signals:
public slots:
protected:
void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *event);
private:
bool addNum(int num);
void epoch(int loc);
QPoint newPoint;
int * *arr;
int n;
};
#endif // TWOZERO_H
cpp文件
#include "twozero.h"
#include <QPainter>
#include <QKeyEvent>
#include <QMessageBox>
#include <queue>
#include <ctime>
using namespace std;
Twozero::Twozero(QWidget *parent) : QWidget(parent)
{
n = 4;
arr = new int *[100];
for (int i = 0; i < 100; i++) {
arr[i] = new int[100];
arr[i][10] = 100;
}
replay();
setFocusPolicy(Qt::StrongFocus);
}
void Twozero::replay()
{
srand(time(NULL));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
arr[i][j] = 0;
}
}
int t = 1;
while (t--)
addNum(2);
}
bool Twozero::addNum(int num)
{
int cntNum = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (arr[i][j]) {
cntNum++;
}
}
}
if (cntNum >= n * n) {
return false;
}
while (true) {
int row = qrand() % n + 1;
int col = qrand() % n + 1;
if (arr[row][col] == 0) {
arr[row][col] = num;
newPoint.rx() = row;
newPoint.ry() = col;
return true;
}
}
}
bool Twozero::isFail()
{
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (arr[i][j] == 0) {
return false;
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i > 1) {
if (arr[i][j] == arr[i - 1][j]) {
return false;
}
}
if (j > 1) {
if (arr[i][j] == arr[i][j - 1]) {
return false;
}
}
}
}
return true;
}
void Twozero::epoch(int loc)
{
bool isT = false;
int dx[] = { -1, 0, 1, 0 };
int dy[] = { 0, 1, 0, -1 };
if (loc == 0) {
for (int i = 1; i <= n; i++) {
int cur = 1;
queue<int> q;
for (int j = 1; j <= n; j++) {
if (arr[j][i] == 0)
continue;
int num = arr[j][i];
arr[j][i] = 0;
if (q.empty()) {
q.push(num);
arr[cur++][i] = num;
} else {
int pren = q.front();
q.pop();
if (pren == num) {
arr[cur - 1][i] = 2 * pren;
} else {
arr[cur++][i] = num;
q.push(num);
}
}
if (arr[j][i] != num) {
isT = true;
}
}
}
} else if (loc == 2) {
for (int i = 1; i <= n; i++) {
int cur = n;
queue<int> q;
for (int j = n; j >= 1; j--) {
if (arr[j][i] == 0)
continue;
int num = arr[j][i];
arr[j][i] = 0;
if (q.empty()) {
q.push(num);
arr[cur--][i] = num;
} else {
int pren = q.front();
q.pop();
if (pren == num) {
arr[cur + 1][i] = 2 * pren;
} else {
arr[cur--][i] = num;
q.push(num);
}
}
if (arr[j][i] != num) {
isT = true;
}
}
}
} else if (loc == 1) {
for (int i = 1; i <= n; i++) {
int cur = n;
queue<int> q;
for (int j = n; j >= 1; j--) {
if (arr[i][j] == 0)
continue;
int num = arr[i][j];
arr[i][j] = 0;
if (q.empty()) {
q.push(num);
arr[i][cur--] = num;
} else {
int pren = q.front();
q.pop();
if (pren == num) {
arr[i][cur + 1] = 2 * pren;
} else {
arr[i][cur--] = num;
q.push(num);
}
}
if (arr[i][j] != num) {
isT = true;
}
}
}
} else if (loc == 3) {
for (int i = 1; i <= n; i++) {
int cur = 1;
queue<int> q;
for (int j = 1; j <= n; j++) {
if (arr[i][j] == 0)
continue;
int num = arr[i][j];
arr[i][j] = 0;
if (q.empty()) {
q.push(num);
arr[i][cur++] = num;
} else {
int pren = q.front();
q.pop();
if (pren == num) {
arr[i][cur - 1] = 2 * pren;
} else {
arr[i][cur++] = num;
q.push(num);
}
}
if (arr[i][j] != num) {
isT = true;
}
}
}
}
if (isT) {
addNum(2);
update();
if (isFail()) {
QMessageBox::information(this, "fail", "fail");
replay();
}
}
}
void Twozero::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Left:
epoch(0);
break;
case Qt::Key_Down:
epoch(1);
break;
case Qt::Key_Right:
epoch(2);
break;
case Qt::Key_Up:
epoch(3);
break;
case Qt::Key_R:
replay();
break;
default:
break;
}
update();
}
void Twozero::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
painter.setPen(QPen(QColor(Qt::black)));
painter.drawRect(i * 50, (j - 1) * 50, 50, 50);
if (arr[i][j] == 0)
continue;
if (i == newPoint.x() && j == newPoint.y()) {
painter.setPen(QPen(QColor(Qt::green)));
} else {
painter.setPen(QPen(QColor(Qt::black)));
}
painter.setFont(QFont("consolas", 13));
painter.drawText(i * 50, j * 50, QString::number(arr[i][j]));
}
}
}