2048源代码~~小游戏。C++实现

来源:互联网 发布:vb.net安装 编辑:程序博客网 时间:2024/05/16 15:53

每一个学习软件工程的人,都很想自己写出游戏的代码,我也不例外,但是,能写出一些小游戏的代码,并不能说明你很厉害,而只能说明你对于这门语言你比较熟悉了。

2048这个游戏,是一两年前很火的游戏,不过现在也没什么人在玩了,闲来没事,就写了一下这个游戏,控制台上实现的,目前我还不会写窗口,所以很多东西都只能在控制台上来实现了。

2048这个小游戏,主要的是上下左右移动后,相同的数合并,不相同的数原样输出,而你就是要判断每一行或每一列有没有相同的,还有一点就是,数字有移动,就产生新的数,没有,什么都不用做。

下面是头文件的:

class New2048{public:New2048()                       //构造函数,初始话数据。{ for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++)a[i][j] = 0;num = 0;}void make_frame();             //打印框架函数。void display_num();            //打印数字函数。void creat_num();              //随机产生数函数void RightMove();              //右移函数void LeftMove();               //左移函数void UpMove();       //上移函数void DownMove();       //下移函数int cheak();                   //检查游戏是否结束函数void clean();                  //清理显示出来的数字~New2048(){}private:int a[4][4];int num;};


下面是各个函数的cpp文件:

# include <iostream># include <Windows.h># include <time.h># include <conio.h># include "2048.h"using namespace std;HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);    //获取句柄void gotoxy(HANDLE hOut, int x, int y)            //输出位置的函数{COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(hOut, pos);}void New2048::make_frame()                       //打印框架{gotoxy(hOut, 0, 0);cout << "         得分" << endl;cout << "┏━━┳━━┳━━┳━━┓" << endl;cout << "┃    ┃    ┃    ┃    ┃" << endl;cout << "┣━━╋━━╋━━╋━━┫" << endl;cout << "┃    ┃    ┃    ┃    ┃" << endl;cout << "┣━━╋━━╋━━╋━━┫" << endl;cout << "┃    ┃    ┃    ┃    ┃" << endl;cout << "┣━━╋━━╋━━╋━━┫" << endl;cout << "┃    ┃    ┃    ┃    ┃" << endl;cout << "┗━━┻━━┻━━┻━━┛" << endl;}void New2048::clean(){int k = 0, l = 0;for (int i = 2; i < 21, k < 4; i = i + 6)    //找到对应的框,输入空格{l = 0;for (int j = 2; j < 9; j = j + 2){gotoxy(hOut, i, j);printf("    ");l++;}k++;}}void New2048::display_num()                          //打印数字{int k = 0, l = 0;for (int i = 2; i < 21, k < 4; i = i + 6)    //找到对应的框,输入数字,这个尝试了好久,才搞定了。{l = 0;for (int j = 2; j < 9; j = j + 2){gotoxy(hOut, i, j);          //找到各个位置并输出数字a[l][k] == 0 ? printf(" ") : printf("%d", a[l][k]);l++;}k++;}gotoxy(hOut, 13, 0);cout << num * 100;gotoxy(hOut, 0, 10);}void New2048::creat_num()                     //随机产生坐标位置和该位置的数 2 或 4{int i, j, num;srand((unsigned)time(NULL));             //随机数产生初始化,不然产生的数一直相同        i = (rand() % (4)) + 0;j = (rand() % (4)) + 0;while (a[i][j])                           //该位置上的数不是0,重新产生{i = (rand() % (4)) + 0;j = (rand() % (4)) + 0;}num = (rand() % (4)) + 1;                //产生的是1就自增,是3便自减或自增,都可以的if (num == 1)++num;if (num == 3)--num;a[i][j] = num;}int New2048::cheak(){int i, j, flag = 0, tag = 0;for (i = 0; i < 4; i++)                  //检查是否还有位置,有,tag = 1。{for (j = 0; j < 4; j++){if (a[i][j] == 0){tag = 1;break;}}if (tag == 1)break;}if (tag)                               //有,返回1。return 1;for (i = 0; i < 4; i++)                //检查左右的相邻是否有相等,是,flag = 1,退出循环{for (j = 0; j < 3; j++){if (a[i][j] == a[i][j + 1]){flag = 1;break;}}if (flag == 1)break;}for (j = 0; j < 4; j++)                //检查上下的相邻是否有想等,是,flag = 1,退出循环{for (i = 0; i < 3; i++){if (a[i][j] == a[i + 1][j]){flag = 1;break;}}if (flag == 1)break;}if (tag == 0 && flag == 0)            //flag = 0 和 tag = 0,游戏结束。return 0;else                                  //否则,继续游戏return 1;}void New2048::DownMove()                  //下移的情况{int k, tag = 0;for (int i = 0; i < 4; i++)           //从每一列开始{int b[4] = { 0 }; //定义一个临时数组来存储相加之后的情况k = 3;for (int j = 3; j > 0; j--){if (a[j][i] != 0){int flag = 0;for (int l = j - 1; l >= 0; l--)    //找是否有相同的数{if (a[l][i] != 0){flag = 1;if (a[l][i] == a[j][i]){b[k--] = 2 * a[j][i];num++;         a[l][i] = a[j][i] = 0;break;}else{b[k--] = a[j][i];break;}}}if (flag == 0)b[k--] = a[j][i];}}b[k] = a[0][i];                 //最后一个没有检查,赋值过去,不管是否为0,都无所谓的for (int j = 0; j < 4; j++)     //检查是否有移动{if (a[j][i] != b[j]){tag = 1;break;}}for (int j = 0; j < 4; j++)    //将结果覆盖回去a[j][i] = b[j];}if (tag)                          //存在移动,产生新的数creat_num();}void New2048::LeftMove()                 //同上{int k, tag = 0;for (int i = 0; i < 4; i++){int b[4] = { 0 };k = 0;for (int j = 0; j < 3; j++){if (a[i][j] != 0){int flag = 0;for (int l = j + 1; l < 4; l++){if (a[i][l] != 0){flag = 1;if (a[i][l] == a[i][j]){b[k++] = 2 * a[i][j];num++;a[i][j] = a[i][l] = 0;break;}else{b[k++] = a[i][j];break;}}}if (flag == 0)b[k++] = a[i][j];}}b[k] = a[i][3];for (int j = 0; j < 4; j++){if (a[i][j] != b[j]){tag = 1;break;}}for (int j = 0; j < 4; j++)a[i][j] = b[j];}if (tag)creat_num();}void New2048::RightMove()              //同上{int k, tag = 0;for (int i = 0; i < 4; i++){int b[4] = { 0 };k = 3;for (int j = 3; j > 0; j--){if (a[i][j] != 0){int flag = 0;for (int l = j - 1; l >= 0; l--){if (a[i][l] != 0){flag = 1;if (a[i][l] == a[i][j]){b[k--] = 2 * a[i][j];num++;a[i][j] = a[i][l] = 0;break;}else{b[k--] = a[i][j];break;}}}if (flag == 0)b[k--] = a[i][j];}}b[k] = a[i][0];for (int j = 0; j < 4; j++){if (a[i][j] != b[j]){tag = 1;break;}}for (int j = 0; j < 4; j++)a[i][j] = b[j];}if (tag)creat_num();}void New2048::UpMove(){int k, tag = 0;for (int i = 0; i < 4; i++){int b[4] = { 0 };                 //定义一个临时数组来存储相加之后的情况k = 0;for (int j = 0; j < 3; j++){if (a[j][i] != 0){int flag = 0;for (int l = j + 1; l < 4; l++)    //找是否有相同的数{if (a[l][i] != 0){flag = 1;if (a[l][i] == a[j][i]){b[k++] = 2 * a[j][i];num++;a[l][i] = a[j][i] = 0;break;}else{b[k++] = a[j][i];break;}}}if (flag == 0)b[k++] = a[j][i];}}b[k] = a[3][i];for (int j = 0; j < 4; j++){if (a[j][i] != b[j]){tag = 1;break;}}for (int j = 0; j < 4; j++)      //将结果覆盖回去a[j][i] = b[j];}if (tag)creat_num();}

主函数的cpp文件:

# include <iostream># include <conio.h># include "2048.h"using namespace std;int main(){while (1){char ch;system("cls");                        //清屏system("color 3B");                   //改变背景和字体颜色New2048 s;s.make_frame();                       //打印框架s.creat_num();s.creat_num();                        //产生两个随机数s.display_num();                      //显示数字while (1){ch = _getch();                   //如果不是VS的,_getch应该改成getchif (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')break;}p:switch (ch){case 's':case 'S':{while (s.cheak()){s.DownMove();             //下移s.clean();                //清理s.display_num();          //显示数字while (1){ch = _getch();if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' ||ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')break;}goto p;}}break;case 'd':case 'D':{while (s.cheak()){s.RightMove();                //右移s.clean();                    //清理s.display_num();              //显示数字while (1){ch = _getch();if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')break;}goto p;}}break;case 'a':case 'A':{while (s.cheak()){s.LeftMove();              //左移s.clean();                 //清理s.display_num();           //显示数字while (1){ch = _getch();if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')break;}goto p;}}break;case 'w':case 'W':{while (s.cheak()){s.UpMove();               //上移s.clean();                //清理s.display_num();          //显示数字while (1){ch = _getch();if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || ch == 'A' || ch == 'S' || ch == 'D' || ch == 'W')break;}goto p;}}break;default:break;}                            //退出switch,游戏结束system("cls");               //清屏cout << "               PLAY AGAIN ? YES(Y) : NO(N)" << endl;while (1){ch = _getch();if (ch == 'y' || ch == 'n' || ch == 'Y' || ch == 'N')break;}if (ch == 'y' || ch == 'Y')          //Y继续continue;else                                 //否则退出break;}return 0;}

游戏开始图片:



游戏过程中的图片:



游戏结束图片:


这个或多或少的存在bug,如果发现了,欢迎来告诉我,好让我改正!~~


2 0