版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/D_K_01/article/details/78881460
- C语言的一个小作业;
玩法:
- 初始有两个格子有数字2;
- 每次可以选择上下左右一个方向滑动,每滑动一次,所有的数字方块都会向滑动方向靠拢;在空白的地方会生成一个数字;相同数字的方块在靠拢、相撞时会相加合并;
- 系统生成的数字不是2就是4,玩家要想办法在这16格中凑出“2048”这个数字;
思路:
- 这可以看成一个地图数组;4*4大小,其中存储着2,4,6,8…等数字;
- 以向上移动为例:当前格子有元素 ,就向下寻找第一个不为0的格子,检测和第一格元素是否一样,如果一样就合并,不一样就什么都不做;
- 假如当前格子没有元素,就向后寻找一个不为0的元素,把它移到第一格;
- GG规则:遍历整个数组,检查横向和纵向是否存在相邻相等的元素;
- 感谢~相关参考:https://www.cnblogs.com/judgeyoung/p/3760515.html
/************************************************************************/
/* Name: 2048 */
/* Author: D&K */
/* Date: 2017.12.21 */
/* Version: Beta_0.1 */
/************************************************************************/
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
int g_nNum[4][4] = { 0 }; //全局数组;
void Draw(); //绘图;
void AddNum(); //添加数字;
void Up(); //上;
void Down(); //下;
void Left(); //左;
void Right(); //右;
bool GG(); //GG;
void play(); //方向判断;
int main()
{
//设置随机种子;
srand(unsigned int(time(0)));
//初始化两个数;
AddNum();
AddNum();
//初始化绘图;
Draw();
while (true)
{
play();
}
return 0;
}
void Draw()
{
system("cls");
for (int i = 0; i < 4; i++)
{
printf(" ————————————————————\n");
for (int j = 0; j < 4; j++)
{
printf("|%4d", g_nNum[i][j]);
}
printf(" | \n");
}
printf(" ————————————————————\n");
printf("\n\n通过W,S,A,D,来移动\n");
}
void AddNum()
{
while (true)
{
int i = rand() % 4;
int j = rand() % 4;
if (g_nNum[i][j] == 0)
{
g_nNum[i][j] = rand() % 3 ? 2 : 4; //设置出现2的几率更大;
break;
}
}
}
void Up()
{
//x代表行;在数组中右边下标;
for (int x = 0; x < 4; x++)
{
//y代表列;在数组中左边下标;
for (int y = 1, z = 0; y < 4; y++)
{
//找出第一个非空数;
if (g_nNum[y][x] > 0)
{
//和第一行第一个对比;
//相等;
if (g_nNum[y][x] == g_nNum[z][x])
{
g_nNum[z][x] *= 2;
g_nNum[y][x] = 0;
}
//第一个为空;移动至第一位;
else if (g_nNum[z][x] == 0)
{
g_nNum[z][x] = g_nNum[y][x];
g_nNum[y][x] = 0;
}
//否则移动至第z+1位;
else
{
g_nNum[++z][x] = g_nNum[y][x];
//判断y是否是第z+1位;非2将yx设0;z+1;
if (y != z)
{
g_nNum[y][x] = 0;
}
}
}
}
}
}
void Down()
{
//与上方向逆序相反;
//x代表行;在数组中右边下标;
for (int x = 3; x >= 0; x--)
{
//y代表列;在数组中左边下标;
for (int y = 2, z = 3; y >= 0; y--)
{
//找出第一个非空数;
if (g_nNum[y][x] > 0)
{
//和第一行第一个对比;
//相等;
if (g_nNum[y][x] == g_nNum[z][x])
{
g_nNum[z][x] *= 2;
g_nNum[y][x] = 0;
}
//第一个为空;移动至第一位;
else if (g_nNum[z][x] == 0)
{
g_nNum[z][x] = g_nNum[y][x];
g_nNum[y][x] = 0;
}
//否则移动至第z+1位;
else
{
g_nNum[--z][x] = g_nNum[y][x];
//判断y是否是第z-1位;非2将yx设0;z-1;
if (y != z)
{
g_nNum[y][x] = 0;
}
}
}
}
}
}
void Left()
{
//与上方向互换xy;
for (int x = 0; x < 4; x++)
{
for (int y = 1, z = 0; y < 4; y++)
{
//找出第一个非空数;
if (g_nNum[x][y] > 0)
{
//和第一行第一个对比;
//相等;
if (g_nNum[x][y] == g_nNum[x][z])
{
g_nNum[x][z] *= 2;
g_nNum[x][y] = 0;
}
//第一个为空;移动至第一位;
else if (g_nNum[x][z] == 0)
{
g_nNum[x][z] = g_nNum[x][y];
g_nNum[x][y] = 0;
}
//否则移动至第z+1位;
else
{
g_nNum[x][++z] = g_nNum[x][y];
//判断y是否是第z+1位;非2将yx设0;z+1;
if (y != z)
{
g_nNum[x][y] = 0;
}
}
}
}
}
}
void Right()
{
//互换xy;
//与左逆序相反;
for (int x = 3; x >= 0; x--)
{
for (int y = 2, z = 3; y >= 0; y--)
{
//找出第一个非空数;
if (g_nNum[x][y] > 0)
{
//和第一行第一个对比;
//相等;
if (g_nNum[x][y] == g_nNum[x][z])
{
g_nNum[x][z] *= 2;
g_nNum[x][y] = 0;
}
//第一个为空;移动至第一位;
else if (g_nNum[x][z] == 0)
{
g_nNum[x][z] = g_nNum[x][y];
g_nNum[x][y] = 0;
}
//否则移动至第z+1位;
else
{
g_nNum[x][--z] = g_nNum[x][y];
//判断y是否是第z-1位;非2将yx设0;z-1;
if (y != z)
{
g_nNum[x][y] = 0;
}
}
}
}
}
}
bool GG()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
if (g_nNum[i][j] == g_nNum[i][j + 1] || g_nNum[j][i] == g_nNum[j + 1][i])
{
return false;
}
}
}
return true;
}
void play()
{
if (GG())
{
system("cls");
printf("GG!\n即将退出!\n");
Sleep(3000);
exit(0);
}
switch (_getch())
{
case 'W':
case 'w':
Up();
AddNum();
Draw();
break;
case 'S':
case 's':
Down();
AddNum();
Draw();
break;
case 'A':
case 'a':
Left();
AddNum();
Draw();
break;
case 'D':
case 'd':
Right();
AddNum();
Draw();
break;
case 27:
exit(0);
break;
default:
printf("输入有误\n");
break;
}
}