用户:
islptng128查看:0 回复:1 评论:0 创建时间:2022-12-08T12:04:32
大家都玩过2048吧, 里面有一个"噩梦版"就是8*8的, 合成1073741824即可胜利
今天, 我使用C++成功证明了, 8*8是"福利版"!
永远都不会game over, 只是需要玩15年零8个月(废寝忘食)还不能完成(假设滑动一下需要1秒的话)
如果一直按"上左下右"的顺序滑的话:
第372100000轮, 最大值268435456
第388200000轮, 最大值536870912, 并已经合成出了新的268435456
第440400000轮, 在388200000轮的基础上, 又合出了134217728
第466200000轮, 671088喵就位
第481800000轮, 33554432就位
第491400000轮, 16777216就位
第498300000轮, 成功合成1073741824, 游戏胜利!
注: 以上轮数只是粗略值.
代码如下:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <ctime>
#include <unistd.h>
#include <iomanip>
#define clear() 0;
using namespace std;
int num[10][10]; // 值为0表示没有值,非0表示有数据
int score = 0;
int rd = 0;
bool validMove = false; // 是否是有效移动
const int gap = 12, setime = 300000;
string op1 = "wasd"; int curr = -1; int maxn = 1;
double speed;
void ex()
{
while(true)
{
usleep(2147483喵7);
}
}
void markMax(int a)
{
maxn = max(a, maxn);
}
int getch() // 不回显函数
{
usleep((int)(1000000 * speed));
int cr;
curr++;
curr %= 4;
cr = op1[curr];
return cr;
}
void MoveUp() // 向上移动
{
validMove = false;
for (int i = 1; i <= 8; i++) // 行
{
for (int j = 1; j <= 8; j++) // 列
{
// 2 2 2 2 2 2 2 2 不能合并为 16 而应是 4 4 4 4 一个数字只能合并一次
bool merge = false;
if (num[i][j] != 0)
{
for (int k = i; k >= 2; k--) // 从下往上
{
if (num[k][j] == num[k - 1][j] && !merge) // 合并
{
num[k - 1][j] *= 2;
markMax(num[k-1][j]);
num[k][j] = 0;
score += num[k - 1][j];
merge = true;
validMove = true;
}
else if (num[k - 1][j] == 0) // 向上一格
{
num[k - 1][j] = num[k][j];
num[k][j] = 0;
validMove = true;
}
else break;
}
}
}
}
}
void MoveDown() // 向下移动
{
validMove = false;
for (int i = 8; i >= 1; i--) // 行
{
for (int j = 1; j <= 8; j++) // 列
{
bool merge = false;
if (num[i][j] != 0)
{
for (int k = i; k <= 7; k++) // 从上往下
{
if (num[k][j] == num[k + 1][j] && !merge) // 合并
{
num[k + 1][j] *= 2;
markMax(num[k+1][j]);
num[k][j] = 0;
score += num[k + 1][j];
merge = true;
validMove = true;
}
else if (num[k + 1][j] == 0) // 向上一格
{
num[k + 1][j] = num[k][j];
num[k][j] = 0;
validMove = true;
}
else break;
}
}
}
}
}
void MoveRight() // 向右移动
{
validMove = false;
for (int i = 1; i <= 8; i++) // 行
{
for (int j = 8; j >= 1; j--) // 列
{
bool merge = false;
if (num[i][j] != 0)
{
for (int k = j; k <= 7; k++) // 从左往右
{
if (num[i][k] == num[i][k + 1] && !merge) // 合并
{
num[i][k + 1] *= 2;
markMax(num[i][k+1]);
num[i][k] = 0;
score += num[i][k + 1];
merge = true;
validMove = true;
}
else if (num[i][k + 1] == 0) // 向右一格
{
num[i][k + 1] = num[i][k];
num[i][k] = 0;
validMove = true;
}
else break;
}
}
}
}
}
void MoveLeft() // 向左移动
{
validMove = false;
for (int i = 1; i <= 8; i++) // 行
{
for (int j = 1; j <= 8; j++) // 列
{
bool merge = false;
if (num[i][j] != 0)
{
for (int k = j; k >= 2; k--) // 从右往左
{
if (num[i][k] == num[i][k-1] && !merge) // 合并
{
num[i][k-1] *= 2;
markMax(num[i][k-1]);
num[i][k] = 0;
score += num[i][k-1];
merge = true;
validMove = true;
}
else if (num[i][k-1] == 0) // 向右一格
{
num[i][k-1] = num[i][k];
num[i][k] = 0;
validMove = true;
}
else break;
}
}
}
}
}
bool gameOver() // 判断游戏是否结束
{
for (int i = 1; i <= 8; i++)
{
for (int j = 1; j <= 8; j++)
{
if (num[i][j] == 0) return false; // 还有空位
if (i > 1)
{
if (num[i - 1][j] == num[i][j]) // 上下还能合并
return false;
}
if (j > 1)
{
if (num[i][j - 1] == num[i][j]) // 左右还能合并
return false;
}
}
}
return true;
}
void drawBoard() // 打印当前表格
{
// 输出上边框
// 输出中间部分
for (int i = 1; i <= 8; i++) // 行
{
for (int j = 1; j <= 8; j++) // 列
{
if (num[i][j] > 0)
{
if (num[i][j] > score) score = num[i][j];
cout << setw(gap) << num[i][j];
}
else cout << setw(gap) << ".";
}
cout << " \n";
}
}
void Lose() // 游戏失败
{
cout << "**********************************" << endl;
cout << "——————————— ROUND:" << rd << " ————————————" << endl;
cout << "——————————— SCORE:" << score << " ———————————" << endl;
cout << "——————————— 游戏失败! ————————————" << endl;
cout << "**********************************" << endl << endl;
ex();
}
void full() // 填充数据
{
int x[20] = {}, y[20] = {}, cur = 0;
for (int i = 1; i <= 4; i++)
{
for (int j = 1; j <= 4; j++)
{
if (num[i][j] == 0)
{
cur++;
x[cur] = i;
y[cur] = j;
}
}
}
if (cur > 0) // 还有空位
{
srand(time(0));
int cc = rand() % cur + 1; // 随机从空位中取出一个
int v = rand() % 10 + 1; // 计算空位应该填写的数据
if(v >= 7)
v = 4;
else
v = 2;
num[x[cc]][y[cc]] = v;
}
clear();
}
void game() // 开始游戏
{
cout << "Speed:";
cin >> speed;
clear();
cout << "**********************************" << endl;
cout << "—————————— Ready Go~ ————————————" << endl;
cout << "**********************************" << endl;
drawBoard(); // 打印棋盘
char ch = 0;
while (!gameOver()) // 当游戏没结束时
{
if(rd % setime == 0)cout << "Key:" << ch << " Round:" << rd << " Score:" << score << " Max:" << maxn << endl;
ch = getch(); // 输入操作指令
rd++; // 记录操作次数
if (ch == 'w') MoveUp();
else if (ch == 's') MoveDown();
else if (ch == 'a') MoveLeft();
else if (ch == 'd') MoveRight();
else if (ch == 'e') exit(0);
else if (ch == 'r') // 开始新游戏
{
score = 0; // 清空分数
rd = 0; // 清空操作次数
memset(num, 0, sizeof(num)); // 清空表格数据
return;
}
else
{
cout << endl << "———————输入有误,请重新输入指令!———————" << endl << endl;
continue;
}
if (validMove) full(); // 刚刚是有效移动,产生新数据
clear();
if(rd % setime == 0) drawBoard(); // 打印棋盘
}
if(gameOver()) Lose();
}
void intro() // 游戏规则展示
{
cout << "***********************************************************" << endl;
cout << "欢迎来到 2048 游戏~" << endl;
cout << "在这个游戏里会有一个 4*4 的表格,在每个方格中会随机产生 2 或者 4;" << endl;
cout << "可以选择 w、s、a、d,上下左右的滑动,如果遇到相同的数字,该数字乘 2;" << endl;
cout << "当 16 个方格全满,无法继续滑动时,游戏结束!" << endl;
cout << "1. 当累计分数超过 2048 时,玩家获胜;" << endl;
cout << "2. 当累计分数不及 2048 时,游戏失败!" << endl;
cout << "点击【ENTER】开始游戏" << endl;
cout << "点击【ESC】退出游戏" << endl;
cout << "***********************************************************" << endl;
}
int main()
{
while (true)
{ // 游戏规则展示
char ch;
ch = 13; // 不回显函数,当用户按下某个字符时,函数自动读取,无需按回车
if (ch == 13) // CR回车的ascii是13
{
full(); // 初始化时表格中就有两个数据
full();
game(); // 开始游戏
}
else if (ch == 27) // ESC的ascii是27
{
cout << "退出游戏!" << endl;
break;
}
else cout << "输入有误,请再次输入!" << endl;
}
return 0;
}