page contents

C语言小游戏——2048

/* ---------------------2048------------------------ */ /* 实现思路: 是否有数据?  数据如何存放   整数  4*4    int  short long ... int  4*4的数组 数组一般搭配循环 如...

/*

---------------------2048------------------------

*/


/*

实现思路:

是否有数据?  数据如何存放  

整数  4*4    int  short long ...

int  4*4的数组


数组一般搭配循环


如果两个相同元素  会进行合并 分支


不断进行游戏  (函数)

---->按键-->一轮合并-->判断输赢--->按键


1. 按键  按上下左右 都要移动  生成一个新的数字

2. 移动过程中相同的数字碰到了会进行合并成一个更大的数字

3. 移动之后会判断输赢  如果合成了比2048更大的数字  游戏结束

4. 如果游戏最后无法移动(已经满了并且没法移动)


游戏刚刚开始时候的状态 --->两个数字  任意位置  2和4中的一个

任意位置   随机数

   srand((unsigned)time(NULL));

   rand()//用求余控制范围

*/


//头文件

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#include<string.h>

#include<conio.h>

#include<easyx.h>

//全局变量



//函数声明

void play(int map[][4]);

void drawMap(int map[][4]);//函数声明和函数定义记得写一样

int win(int map[][4]);

void newNum(int map[][4]);


//主函数

int main()    //主函数  程序的入口

{

initgraph(400,400);//窗口大小


settextcolor(LIGHTBLUE);

settextstyle(40, 0, "黑体");


int map[4][4];//数组  下标从0开始算

//先把数组全部赋值为0   给数组 循环

memset(map, 0, sizeof(int)* 4 * 4);//初始化一块内存

srand((unsigned)time(NULL));

int x, y;

for (int i = 0; i < 2; )

{

x = rand() % 4;

y = rand() % 4;

//if (map[x][y] == 0)

if (0 == map[x][y])

{

++i;//每次找到新位置  i加1  不然i就不加 确保找到两个新位置


map[x][y] = rand() % 2 * 2 + 2;//随机的2或者4

//if (rand() % 10 == 0) map[x][y] = 2;

//else map[x][y] = 4;


//控制概率   10%生成2  90%生成一个4

/*switch (rand() % 10)

{

case 0:

case 1:

case 2:

case 3:

case 4:

map[x][y] = 2; break;

case 5:

case 6:

case 7:

case 8:

case 9:

map[x][y] = 4; break;

}*/

}

}

while (1)

{

drawMap(map);

play(map);

switch (win(map))

{

case 0://赢

//弹窗

return 0;

break;

case -1:

return 0;

break;

case 1:


break;

case 2:

//newNum(map);

break;

default:

break;

}

}

/*for (int i = 0; i < 4; ++i)

{

for (int j = 0; j < 4; ++j)

{

printf("%d\t", map[i][j]);

}

printf("\n");

}*/

getchar();


closegraph();

return 0;

}


//函数定义


//获取用户的一个按键 根据按键 执行往上或者往下移动(需要数组)  需要参数

//如果可以移动 就生成一个新的数字

//这里没有需要结果的必要  所以可以不用返回值

void play(int map[][4])  //kbhit   用户按一下 操作一下  贪吃蛇 用户按也会走 不按也会走  

{

int len;//表示一行或者一列的元素的个数

switch (_getch())

{

case 'W':

case 'w'://上

case 72:

for (int y = 0; y < 4; ++y)//四列

{

len = 4;//每一行默认四个元素

//先把0往右移动

for (int i = 0; i < len-1; ++i)

{

if (map[i][y] == 0)

{

for (int j = i; j < 3; ++j)

{

map[j][y] = map[j+1][y];

}

map[3][y] = 0;

len--;//出现一个0  那么len--一次

--i;

}

}

//合并操作

for (int i = 0; i < len-1; ++i)

{

if (map[i][y] == 0) break;

if (map[i][y] == map[i+1][y])//合并

{

map[i][y] *= 2;

for (int j = i + 1; j < 3; ++j)

{

map[j][y] = map[j+1][y];

}

map[3][y] = 0;

}

}

}


newNum(map);

break;

case 'A':

case 'a'://左

case 75:

for (int x = 0; x < 4; ++x)//四行

{

len = 4;//每一行默认四个元素

//先把0往右移动

for (int i = 0; i < len-1; ++i)

{

if (map[x][i] == 0)

{

for (int j = i; j < 3; ++j)

{

map[x][j] = map[x][j + 1];

}

map[x][3] = 0;

len--;//出现一个0  那么len--一次

--i;

}

}

//合并操作

for (int i = 0; i < len-1; ++i)

{

if (map[x][i] == 0) break;

if (map[x][i] == map[x][i + 1])//合并

{

map[x][i] *= 2;

for (int j = i + 1; j < 3; ++j)

{

map[x][j] = map[x][j + 1];

}

map[x][3] = 0;

}

}

}


newNum(map);

break;

case 'S':

case 's'://往下

case 80:

for (int y = 0; y < 4; ++y)//四列

{

len = 0;

//先把0往上移动

for (int i = 3; i >len; --i)

{

if (map[i][y] == 0)

{

for (int j = i; j >0; --j)//或者j>=1 

{

map[j][y] = map[j-1][y];

}

map[0][y] = 0;

len++;

i++;

}

}

//合并操作

for (int i = 3; i >0; --i)

{

if (map[i][y] == 0) break;

if (map[i][y] == map[i-1][y])//合并

{

map[i][y] *= 2;

for (int j = i - 1; j >0; --j)

{

map[j][y] = map[j-1][y];

}

map[0][y] = 0;

}

}

}


newNum(map);

break;


case 'D':

case 'd'://往右

case 77:

for (int x = 0; x < 4; ++x)//四行

{

len = 0;//这里表示0的个数

//先把0往左移动

//找到一个0 len++

for (int i = 3; i >len; --i)

{

if (map[x][i] == 0)

{

for (int j = i; j >0; --j)//或者j>=1 

{

map[x][j] = map[x][j - 1];

}

map[x][0] = 0;

len++;

++i;//如果有移动 i的位置先不变  ..这里++  循环有一个--

}

}

//合并操作

for (int i = 3; i >len; --i)

{

if (map[x][i] == 0) break;

if (map[x][i] == map[x][i - 1])//合并

{

map[x][i] *= 2;

for (int j = i - 1; j >0; --j)

{

map[x][j] = map[x][j - 1];

}

map[x][0] = 0;

}

}

}


newNum(map);

break;

default: break;

}

}


///判断是否输赢

///输 全满并且不可合并   -1

///如果是赢 看看里面有没有数字大于等于2048就行 0

///否则看是不是  满 1

//没有满  2

int win(int map[][4])

{

int num = 0;//记录0的个数

int flag = 0;//如果存在一组可以合并的元素 那么flag置为1

for (int i = 0; i < 4; ++i)

{

for (int j = 0; j < 4; ++j)

{

if (map[i][j] >= 2048) return 0;//赢

if (map[i][j] == 0) num++;//记录0的个数

if (j + 1 < 4 && map[i][j] == map[i][j + 1]) flag = 1;//右边是不是一样

if (i + 1 < 4 && map[i][j] == map[i + 1][j]) flag = 1;//下方是不是一样

}

}

if (num == 0 && flag == 0)  return -1;//满了并且不能合并  输

if (num == 0) return 1;//满了 但是可以合并

return 2;

}


//随机生成一个新数字的函数

void newNum(int map[][4])

{

//随机位置生成一个随机的2或者4

int x, y;

do

{

x = rand() % 4;

y = rand() % 4;

} while (map[x][y] != 0);//不是0就继续找

map[x][y] = rand() % 2 * 2 + 2;//随机赋值2或者4

}


//图形库的画图函数

void drawMap(int map[][4])

{

//这个全部元素都是数字   图形库 outtextxy  输出字符或者是一个字符串

//需要改多字节字符集

char arr[20];

BeginBatchDraw();//开始批量绘图,为了效果更好看

cleardevice();

for (int i = 1; i <= 3; ++i)

{

line(100 * i, 0, 100 * i, 400);//竖线

line(0, 100 * i, 400, 100 * i);//横线

}

for (int i = 0; i < 4; ++i)

{

for (int j = 0; j < 4; ++j)

{

sprintf(arr, "%d", map[i][j]); //将数字写入字符串

outtextxy(j*100+20, i*100+30, arr);//指定位置输出字符串

}

}

EndBatchDraw();//结束批量绘图

}


void fun(int arr[])//元素有4个

{

int size;//表示

for (int i = 0; i < 4; ++i)

{

if (arr[i] == 0)

{

for (int j = i; j < 4-1; ++j)

{

arr[j] = arr[j + 1];//后面的元素往前移动  j+1<4

}

arr[3] = 0;//最后一个元素赋值为0

}

}

for (int i = 0; i < 3; ++i)

{

if (arr[i] == 0) break;//表明后面已经没有元素了 直接结束

if (arr[i] == arr[i + 1])//这个元素和后面的元素相等 合并

{

arr[i] *= 2;//合并  这里变成两倍

arr[i + 1] = 0;

for (int j = i + 1; j < 3; ++j)//后面的元素补上来 最后一个变成0

{

arr[j] = arr[j + 1];

}

arr[3] = 0;

}

}

}


  • 发表于 2021-05-20 14:32
  • 阅读 ( 663 )
  • 分类:C/C++开发

0 条评论

请先 登录 后评论
小威
小威

64 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章