一个可通过控制台设定格子数,用键盘方向键操控的2048游戏。
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<conio.h>
#include <iomanip>
#include<stdlib.h>
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPERECATE
#define up 72 //上
#define down 80 //下
#define left 75 //左
#define right 77 //右
using namespace std;
class Game
{
int N;//控制方格大小
int map[10][10];//方格最大为10
char ch;//用于存储方向键的ASCII码值
public:
void zero();//初始化函数
void inti(int _N);//赋值函数
void ran();//生成函数
int OnKeyboard();//键入函数
int score();//得分函数
int end();//终止函数
void out();//显示函数
int change();//变换函数,并判断操作是否违规
void Swap(int& a, int& b);//交换函数
};
void Game::inti(int _N) { N = _N; }
void Game::zero() {//对矩阵按大小进行初始化
for (int a = 0; a < N; a++) {
for (int b = 0; b < N; b++) {
map[a][b] = 0;
}
}
}
void Game::ran() {//随机生成2或4
srand((unsigned int)time(NULL));
while (1) {
int num = rand() % 4;
int i = rand() % N;
int j = rand() % N;
if (map[i][j] != 0) {//保证在0处生成数字
continue;
}
if (num <= 1) {//随机的结果为{0,1,2,3},故生成2或4为等概率
map[i][j] = 2;
break;
}
else map[i][j] = 4;
break;
}
}
int Game::OnKeyboard() {
return (ch=_getch());
}
int Game::score() {//总得分为全部数字之和
int sum = 0;
for (int a = 0; a < N; a++) {
for (int b = 0; b < N; b++) {
sum += map[a][b];
}
}
return sum;
}
int Game::end() {//判断游戏是否结束
int e = 0;
for (int a = 0; a < N - 1; a++) {
for (int b = 0; b < N - 1; b++) {
//游戏结束情况为没有相邻的一样的数且没有0,
if (map[a][b] == map[a + 1][b] || map[a][b] == map[a][b + 1] || map[a + 1][b] == map[a + 1][b + 1] || map[a][b + 1] == map[a + 1][b + 1] || map[a][b] == 0 || map[a + 1][b + 1] == 0 || map[a + 1][b] == 0 || map[a][b + 1] == 0) {
e += 1;
}
}
}
return e;//若e为0,则游戏结束,反之继续。
}
void Game::out() {//输出棋盘情况
for (int a = 0, c = 0; a < N; a++) {
for (int b = 0; b < N; b++) {
cout << setw(3) << map[a][b] << "|";
c++;
if (c % N == 0) {
cout << endl;
for (int i=0;i<(N);i++) {
cout << setw(3) << "----";//保证输出的格子与数字相匹配。
}
cout << endl;
}
}
}
}
void Game::Swap(int &a, int &b) {
int z=a;
a = b;
b = z;
}
int Game::change() {//
int p[10][10];
int num = 0, i = 0;
//先用p纪录map变换前的数据
for (int a = 0; a < N; a++) {
for (int b = 0; b < N; b++) {
p[a][b] = map[a][b];
}
}
//开始变换
switch (ch) {
case up:
//先把0都排到最下面
for (int a = 0; a < N - 1; a++) {
for (int b = 0; b < N; b++) {
int i = 0;
for (; map[a + i][b] == 0; i++) {
if (a + 1 + i == N) { break; }
}
Swap(map[a][b], map[a + i][b]);
}
}
//再对能合成的部分进行合成
for (int a = 0; a < N - 1; a++) {
for (int b = 0; b < N; b++) {
if (map[a][b] == map[a + 1][b] && map[a][b] != 0) {
map[a][b] *= 2;
map[a + 1][b] = 0;
}
else continue;
}
}
//再把合成时产生的0排到最下面
for (int a = 0; a < N - 1; a++) {
for (int b = 0; b < N; b++) {
int i = 0;
for (; map[a + i][b] == 0; i++) {
if (a + 1 + i == N) { break; }
}
Swap(map[a][b], map[a + i][b]);
}
}
break;
case down:
for (int a = N - 1; a > 0; a--) {
for (int b = 0; b < N; b++) {
int i = 0;
for (; map[a - i][b] == 0; i++) {
if (a - i - 1 < 0) { break; }
}
Swap(map[a][b], map[a - i][b]);
}
}
for (int a = N - 1; a > 0; a--) {
for (int b = 0; b < N; b++) {
if (map[a][b] == map[a - 1][b] && map[a][b] != 0) {
map[a][b] *= 2;
map[a - 1][b] = 0;
}
else continue;
}
}
for (int a = N - 1; a > 0; a--) {
for (int b = 0; b < N; b++) {
int i = 0;
for (; map[a - i][b] == 0; i++) {
if (a - i - 1 < 0) { break; }
}
Swap(map[a][b], map[a - i][b]);
}
}
break;
case left:
for (int a = 0; a < N; a++) {
for (int b = 0; b < N - 1; b++) {
int i = 0;
for (; map[a][b + i] == 0; i++) {
if (b + i + 1 == N) { break; }
}
Swap(map[a][b], map[a][b + i]);
}
}
for (int a = 0; a < N; a++) {
for (int b = 0; b < N - 1; b++) {
if (map[a][b] == map[a][b + 1] && map[a][b] != 0) {
map[a][b] *= 2;
map[a][b + 1] = 0;
}
else continue;
}
}
for (int a = 0; a < N; a++) {
for (int b = 0; b < N - 1; b++) {
int i = 0;
for (; map[a][b + i] == 0; i++) {
if (b + i + 1 == N) { break; }
}
Swap(map[a][b], map[a][b + i]);
}
}
break;
case right:
for (int a = 0; a < N; a++) {
for (int b = N - 1; b > 0; b--) {
int i = 0;
for (; map[a][b - i] == 0; i++) {
if (b - i - 1 < 0) { break; }
}
Swap(map[a][b], map[a][b - i]);
}
}
for (int a = 0; a < N; a++) {
for (int b = N - 1; b > 0; b--) {
if (map[a][b] == map[a][b - 1] && map[a][b] != 0) {
map[a][b] *= 2;
map[a][b - 1] = 0;
}
else continue;
}
}
for (int a = 0; a < N; a++) {
for (int b = N - 1; b > 0; b--) {
int i = 0;
for (; map[a][b - i] == 0; i++) {
if (b - i - 1 < 0) { break; }
}
Swap(map[a][b], map[a][b - i]);
}
}
break;
}
//此部分对变换后的数组与变换前进行比对,即判定操作是否合理
for (int a = 0; a < N; a++) {
for (int b = 0; b < N; b++) {
if (p[a][b] == map[a][b]) { num += 1; }
i += 1;
}
}
if (num == i) { return 0; }
else return 1;
}
int main() {
cout << "请决定2048的大小(2~10),并用方向键进行操纵" << endl;
int N;
for (;;) {
cin >> N;
if (N > 1 && N < 11) { break; }
else cout << "请重新输入2~10的值" << endl;
}
Game g1;
g1.inti(N);
g1.zero();
g1.ran();
g1.out();
for (; g1.end() != 0;) {
g1.OnKeyboard();
system("CLS");
if (g1.change() == 0) { //操作不合理时,便不会生成新数字,因为等同于没操作
g1.out();
cout << "当前得分为" << g1.score() << endl;
continue;
}
else system("CLS");
g1.ran();
g1.out();
cout << "当前得分为" << g1.score() << endl;
}
cout << "Game over" << endl;
system("PAUSE");
return 0;
}