Vs 2015 + EasyX
上下左右移动,相同数字相加
一个游戏类,包含一个4*4的数组和一个记录一共有多少个非零数的变量;
方法包括,画图,上下左右,判断游戏是否结束,和产生一个新数
首先应初始化这个类,然后画出初始化的结果;然后根据上下左右键的输入,执行相关的函数并判断是否需要产生新的数,然后判断游戏是否结束,重复此过程,直到游戏结束。
头文件主要完成这个类的定义
#pragma once
# include <conio.h>
#include <graphics.h>
#include <time.h>
enum Ch { up = 72, down = 80, left = 75, right = 77 };
class Game
{
private:
int map[4][4];
int num;//非零数的个数
public:
Game();
void DrawMap();//画地图
void NewNum();
bool Up();
bool Down();
bool Left();
bool Right();
bool GameOver();
};
Game::Game()
{
//数组中的每个元素清零
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
map[i][j] = 0;
}
}
num = 0;
NewNum();
//int n = 0;//产生的随机数
//n = rand() % 5 == 0 ? 4 : 2;
//int m = 0;//随机数的位置
//m = rand() % 16;
//map[m / 4][m % 4] = n;
}
//画地图
void Game::DrawMap()
{
cleardevice();
settextstyle(80, 80, TEXT("宋体"));
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
rectangle(j * 100, i * 100, j * 100 + 100, i * 100 + 100);
/*if (map[i][j] != 0)
outtextxy(j * 100+10, i * 100+10, map[i][j] + 48);*/
switch (map[i][j])
{
case 2:
case 4:
case 8:
settextstyle(80, 80, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, map[i][j] + 48);
break;
case 16:
settextstyle(80, 40, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, TEXT("16"));
break;
case 32:
settextstyle(80, 40, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, TEXT("32"));
break;
case 64:
settextstyle(80, 40, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, TEXT("64"));
break;
case 128:
settextstyle(80, 27, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, TEXT("128"));
break;
case 256:
settextstyle(80, 27, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, TEXT("256"));
break;
case 512:
settextstyle(80, 27, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, TEXT("512"));
break;
case 1024:
settextstyle(80, 20, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, TEXT("1024"));
break;
case 2048:
settextstyle(80, 20, TEXT("宋体"));
outtextxy(j * 100 + 10, i * 100 + 10, TEXT("2048"));
break;
}
}
}
}
void Game::NewNum()
{
int n = 0;//产生的随机数
n = rand() % 5 == 0 ? 4 : 2;
while (1)
{
int m = 0;//随机数的位置
m = rand() % 16;
if (map[m / 4][m % 4] == 0)
{
map[m / 4][m % 4] = n;
break;
}
}
num++;//每产生一个新书非零个数加1
}
bool Game::Up()
{
bool rescult = false;
for (int j = 0; j < 4; j++)
{
for (int i = 0; i <4; i++)
{
if (map[i][j] != 0)//找到第一个非0的数
{
for (int t = i + 1; t <4; t++)
{
if (map[t][j] != 0)//找到第二个非0的数
{
if (map[i][j] == map[t][j])//如果两个非零数相同,则相加
{
map[i][j] += map[t][j];
map[t][j] = 0;
rescult = true;
num--;
}
break;
}
}
}
}
for (int i = 0; i <4; i++)
{
if (map[i][j] == 0)//找到0
{
for (int t = i + 1; t <4; t++)
{
if (map[t][j] != 0)//找到下一个非0的数
{
map[i][j] = map[t][j];
map[t][j] = 0;
rescult = true;
break;
}
}
}
}
}
return rescult;
}
bool Game::Down()
{
bool rescult = false;
for (int j = 0; j < 4; j++)
{
for (int i = 3; i >= 0; i--)
{
if (map[i][j] != 0)//找到第一个非0的数
{
for (int t = i - 1; t >= 0; t--)
{
if (map[t][j] != 0)//找到第二个非0的数
{
if (map[i][j] == map[t][j])//如果两个非零数相同,则相加
{
map[i][j] += map[t][j];
map[t][j] = 0;
rescult = true;
num--;
}
break;
}
}
}
}
for (int i = 3; i >= 1; i--)
{
if (map[i][j] == 0)//找到0
{
for (int t = i - 1; t >= 0; t--)
{
if (map[t][j] != 0)//找到下一个非0的数
{
map[i][j] = map[t][j];
map[t][j] = 0;
rescult = true;
break;
}
}
}
}
}
return rescult;
}
bool Game::Left()
{
bool rescult = false;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j <4; j++)
{
if (map[i][j] != 0)//找到第一个非0的数
{
for (int t = j + 1; t <4; t++)
{
if (map[i][t] != 0)//找到第二个非0的数
{
if (map[i][j] == map[i][t])//如果两个非零数相同,则相加
{
map[i][j] += map[i][t];
map[i][t] = 0;
rescult = true;
num--;
}
break;
}
}
}
}
for (int j = 0; j <4; j++)
{
if (map[i][j] == 0)//找到0
{
for (int t = j + 1; t <4; t++)
{
if (map[i][t] != 0)//找到下一个非0的数
{
map[i][j] = map[i][t];
map[i][t] = 0;
rescult = true;
break;
}
}
}
}
}
return rescult;
}
bool Game::Right()
{
bool rescult = false;
for (int i = 0; i < 4; i++)
{
for (int j = 3; j >= 0; j--)
{
if (map[i][j] != 0)//找到第一个非0的数
{
for (int t = j - 1; t >= 0; t--)
{
if (map[i][t] != 0)//找到第二个非0的数
{
if (map[i][j] == map[i][t])//如果两个非零数相同,则相加
{
map[i][j] += map[i][t];
map[i][t] = 0;
rescult = true;
num--;
}
break;
}
}
}
}
for (int j = 3; j >= 1; j--)
{
if (map[i][j] == 0)//找到0
{
for (int t = j - 1; t >= 0; t--)
{
if (map[i][t] != 0)//找到下一个非0的数
{
map[i][j] = map[i][t];
map[i][t] = 0;
rescult = true;
break;
}
}
}
}
}
return rescult;
}
bool Game::GameOver()
{
if (num < 16)
return false;
//非0的个数等于16,并且无相邻的两个相同的数
if (num == 16)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (i < 3 && j < 3)
{
if (map[i][j] == map[i + 1][j] || map[i][j] == map[i][j + 1])
return false;
}
else if (i < 3 && j == 3)
{
if (map[i][j] == map[i + 1][j])
return false;
}
else if (i == 3 && j < 3)
{
if (map[i][j] == map[i][j + 1])
return false;
}
else if (i==3 && j==3)
return true;
}
}
}
}
源文件主要执行的是主函数
#include "game.h"
int main()
{
srand((unsigned int)time(NULL));
Game game;
initgraph(400, 400);
game.DrawMap();
while (1)
{
int ch=_getch();
bool r = false;//是否可以上下左右移动
switch (ch)
{
case up:
r = game.Up();
break;
case down:
r = game.Down();
break;
case left:
r = game.Left();
break;
case right:
r = game.Right();
break;
default:
continue;
}
if (true == r)
game.NewNum();
game.DrawMap();
if (game.GameOver())
break;
Sleep(10);
}
system("pause");
return 0;
}
上下左右的逻辑