本人写的C++2048源码加注释,用的DOS做界面所以界面可能就没法看了....游戏还是基本没问题,调试了很久,用Vector做了棋盘,事实证明容器确实不适合做数组的工作,调试的时候经常out of range 如果有人发现BUG了可以回复我,我会再做修改的
#include<iostream>
#include<regex>
#include<string>
#include<fstream>
#include<iomanip>
#include<random>
#include<vector>
#include<algorithm>
#include<ctime>
#include <conio.h>
using namespace std;
#define winnumber 2048
void hello()
{
cout << setw(50) << "欢迎来到李琦2048" << endl;
double start = double(clock()) / CLOCKS_PER_SEC;
while ((double(clock()) / CLOCKS_PER_SEC - start) < 1);
system("cls");
cout << "\n\n\n\t\t\t" << "即将进入游戏"<<endl;
for (int i = 3; i > 0; i--)
{
system("cls");
cout << "\n\n\n\t\t\t倒计时" << i << "秒" << endl;
double start = double(clock()) / CLOCKS_PER_SEC;
while ((double(clock()) / CLOCKS_PER_SEC - start) < 1);
}
}
class Qipan
{
public:
Qipan() {
vector<int> pan;
int m, n;//开始数字位置
for (int i = 0; i < 4; i++)
pan.push_back(0);
for (int i = 0; i < 4; i++)
{
pane.push_back(pan);
}
//for (int i = 0; i <= 3; i++) //初始化棋盘
// for (int j = 0; j <= 3; j++)//开始用二维数组 很奇怪的是使用全部初始化得到结果并不是0语句为:pane[4][4]={0};
// {
//
// if (i == 3) pane[i][j] = 2;
// }
for (int i = 0; i < 2; i++)
{
m = rand() % 4;
n = rand() % 4;
pane[m][n] = 2;
}
}
Qipan(Qipan &qipan1)=default; //拷贝控制成员,没有指针成员可以不写。
int operator =(int);
void update();
void randpane();
bool ifzero(int x);
int moveup();
int movedown();
int moveleft();
int moveright();
int GetDirection();
bool wingame();
int maxnumber();
private:
vector<vector<int>> pane;
};
int Qipan::operator=(int x)
{
cout << "lilili" << endl;
return 3;
}
int Qipan::maxnumber()
{
int max = pane[0][0];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (pane[i][j] > max)
max = pane[i][j];
}
}
return max;
}
//Qipan::Qipan(Qipan &qipan1)
//{
// vector<int> pan;
// int m, n;//开始数字位置
// for (int i = 0; i < 4; i++)
// pane.push_back(qipan1.pane[i]);
// //for (int i = 0; i < 4; i++)
// //{
// // this->pane.push_back(pan);
// //}
// //for (int i = 0; i < 4; i++)
// // for (int j = 0; j < 4; j++)
// // {
// // this->pane[i][j] = qipan1.pane[i][j];
// // }
//}
void Qipan::update()
{
system("cls");
cout << setw(36) << "李琦版2048" << endl;
cout << setw(46) << "|-----|-----|-----|-----|" << endl;
for(int i=0;i<4;i++)
for (int j = 0; j < 4; j++)
{
if (pane[i][j] == 0) {
if (j == 0)
cout << setw(20) << "" << setw(2) << "|" << setw(4)<<"";
else
cout << setw(2) << "|" << setw(4)<<"";
if (j == 3)
{
cout << setw(2) << "|" << endl;
cout << setw(46) << "|-----|-----|-----|-----|" << endl;
}
}
else {
if (j == 0)
cout << setw(20) << "" << setw(2) << "|" << setw(3)<< pane[i][j] << " ";
else
cout << setw(2) << "|" << setw(3) << pane[i][j] << " ";
if (j == 3)
{
cout << setw(2) << "|" << endl;
cout << setw(46) << "|-----|-----|-----|-----|" << endl;
}
}
}
}
void Qipan::randpane()
{
static default_random_engine e(time(0)); //C++新标准的随机引擎
static uniform_int_distribution<unsigned>u(1, 2);
int i,m,n;
i = u(e);
int newnumber = pow(2, i);
//while ((i = u(e)) !=2|| (i = u(e)) != 4);
do {
m = rand() % 4;
n = rand() % 4;
} while (pane[m][n] != 0);
pane[m][n] = newnumber;
}
bool Qipan::ifzero(int x)
{
if (x != 0);
return true;
return false;
}
int Qipan::moveup()
{
int flag = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 1; j < 4; j++)
{
int k = j;
for (; k > 0; k--) //数字合并后再向上靠拢一次。
{
if (pane[k - 1][i] == 0)
{
pane[k - 1][i] = pane[k][i];
pane[k][i] = 0;
flag = 1;
}
}
}
}
this->update();
for (int i = 0; i < 4; i++) //数字合并
{
for (int j = 1; j < 4; j++)
{
if (pane[j - 1][i] == pane[j][i])
{
pane[j - 1][i] *= 2;
pane[j][i] = 0;
flag = 1;
}
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 1; j < 4; j++)
{
int k = j;
for (; k > 0; k--) //用的是冒泡算法
{
if (pane[k - 1][i] == 0)
{
pane[k - 1][i] = pane[k][i];
pane[k][i] = 0;
}
}
}
}
return flag;
}
int Qipan::movedown()
{
int flag = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 2; j >= 0; j--)
{
int k = j;
for (; k <3; k++) //数字合并后再向xia靠拢一次。
{
if (pane[k + 1][i] == 0)
{
pane[k + 1][i] = pane[k][i];
pane[k][i] = 0;
flag = 1;
}
}
}
}
for (int i = 0; i < 4; i++) //数字合并
{
for (int j = 2; j >=0; j--)
{
if (pane[j +1][i] == pane[j][i])
{
pane[j + 1][i] *= 2;
pane[j][i] = 0;
flag = 1;
}
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 2; j >= 0; j--)
{
int k = j;
for (; k <3; k++) //数字合并后再向xia靠拢一次。
{
if (pane[k + 1][i] == 0)
{
pane[k + 1][i] = pane[k][i];
pane[k][i] = 0;
}
}
}
}
return flag;
}
int Qipan::moveleft()
{
int flag = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 1; j<4; j++)
{
int k = j;
for (; k >0; k--) //数字合并后再向zuo靠拢一次。
{
if (pane[i][k-1] == 0)
{
pane[i][k-1] = pane[i][k];
pane[i][k] = 0;
flag = 1;
}
}
}
}
for (int i = 0; i < 4; i++) //数字合并
{
for (int j = 1; j <4; j++)
{
if (pane[i][j-1] == pane[i][j])
{
pane[i][j-1] *= 2;
pane[i][j] = 0;
flag = 1;
}
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 1; j<4; j++)
{
int k = j;
for (; k >0; k--) //数字合并后再向zuo靠拢一次。
{
if (pane[i][k - 1] == 0)
{
pane[i][k - 1] = pane[i][k];
pane[i][k] = 0;
}
}
}
}
return flag;
}
int Qipan::moveright()
{
int flag = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 2; j>=0; j--)
{
int k = j;
for (; k <3; k++) //数字合并后再向you靠拢一次。
{
if (pane[i][k +1] == 0)
{
pane[i][k +1] = pane[i][k];
pane[i][k] = 0;
flag = 1;
}
}
}
}
for (int i = 0; i < 4; i++) //数字合并
{
for (int j = 2; j >=0; j--)
{
if (pane[i][j + 1] == pane[i][j])
{
pane[i][j + 1] *= 2;
pane[i][j] = 0;
flag = 1;
}
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 2; j >= 0; j--)
{
int k = j;
for (; k <3; k++) //数字合并后再向you靠拢一次。
{
if (pane[i][k + 1] == 0)
{
pane[i][k + 1] = pane[i][k];
pane[i][k] = 0;
}
}
}
}
return flag;
}
bool Qipan::wingame()
{
for(int i=0;i<4;i++)
for (int j = 0; j < 4; j++)
{
if (pane[i][j] >= winnumber)
{
cout << setw(45) << "You Win!" << endl;
return false;
}
}
return true;
}
bool gameover(Qipan qipan)
{
if (!(qipan.movedown() || qipan.moveleft() || qipan.moveup() || qipan.moveright()))
{
cout << setw(45) << "Game over" << endl;
cout<< setw(45) << "Your score is " << qipan.maxnumber();
return false;
}
return true;
}
int Qipan::GetDirection()
{
int ret = 0;
do
{
int ch = _getch();
if (isascii(ch))
continue;
ch = _getch();
switch (ch)
{
case 72:
ret = 2; // top
break;
case 75:
ret = 1; // left
break;
case 77:
ret = 3; // right
break;
case 80:
ret = 4; // down
break;
default:
break;
}
} while (ret == 0);
return ret;
}
int main()
{
while (1)
{
system("color e4");
Qipan qipan;
hello();
qipan.update();
int testup, testdown,testleft, testright;
while (qipan.wingame() && gameover(qipan))
{
int i = qipan.GetDirection();
switch (i)
{
case 2:
if (testup = qipan.moveup())
{
qipan.randpane();
qipan.update();
}
break;
case 4:
if (testdown = qipan.movedown())
{
qipan.randpane();
qipan.update();
}
break;
case 1:
if (testleft = qipan.moveleft())
{
qipan.randpane();
qipan.update();
}
break;
case 3:
if (testright = qipan.moveright())
{
qipan.randpane();
qipan.update();
}
break;
default:
break;
}
}
int a=qipan.maxnumber();
char x;
loop:
cout << "Do you want to play again?Y/N";
cin >> x;
if (x == 'Y' || x == 'y')
continue;
else if (x == 'N' || x == 'n')
break;
else
{
cout << "Invalid input";
goto loop;
}
}
return 0;
}