网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
04月20日漏签0天
c语言吧 关注:801,962贴子:4,377,449
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 12回复贴,共1页
<<返回c语言吧
>0< 加载中...

2048算法讨论

  • 取消只看楼主
  • 收藏

  • 回复
  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
之前说过要发帖说一下2048算法问题,今天有时间,就试着写写看。
也许有人觉得这个问题太小儿科了,所以请大神勿喷!
先上一张效果图,一年前做的,现在回去看代码觉得不太满意!


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
吃完饭了,现在接着写!


2026-04-20 01:55:44
广告
不感兴趣
开通SVIP免广告
  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
先将问题隐含的规则提取出来:
1、2048是一个4X4的矩阵(二维数组);
2、矩阵内数字的移动有四个方向,上下左右;
3、数字按某一方向移动时,若前一个数字为0(空格),则后一个数字移动到前者位置;
若前一个数字与后一个数字相同,则前者X2,后者为0;
如前后两个数字不等,且前者不为0,则两者相对位置保持不变;
规则就这三条,重点是第三条规则的实现。


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
对二维数组的操作,可以看出是对一维数组的分步操作。
二维数组的移动只有两个方向,即左右,或者说逆移,顺移;顺移等效于二维数组的右下,逆移等效于二维数组的左上。顺移和逆移的区别在于,第一个数和递减(增)规律;数的移动方式都是一样的。
顺移时第一个数是a[3],递减(-1);逆移时第一个数是a[0],递增(+1);这里可以定义两个全局变量或者结构体,记录这两个数。
稍后上代码,别急~!


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
typedef enum
{
MOVE_LEFT,
MOVE_UP,
MOVE_RIGHT,
MOVE_DOWN,
MOVE_MAX
}MOVE_TYPE
typedef struct
{
int first_n;
int inc;
}MOVE_PARA;
#define MAX_NUM 4
int array[MAX_NUM][MAX_NUM] = {0};
MOVE_PARA Move_Para(MOVE_TYPE move_fx)
{
MOVE_PARA para;
if(move_fx == MOVE_LEFT || move_fx == MOVE_UP)
{
para.first_n = 0;
para.inc = 1;
}
else
if(move_fx == MOVE_RIGHT || move_fx == MOVE_DOWN)
{
para.first_n = MAX_NUM - 1;
para.inc = -1;
}
return para;
}


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
移动函数:
void Move(MOVE_TYPE move_fx)
{
int i,j,k;
MOVE_PARA para;
para = Move_Para(move_fx);
if(move_fx == MOVE_LEFT || move_fx == MOVE_RIGHT)
{
for(i = 0; i < MAX_NUM; i++)
{
for(k = 0; k < MAX_NUM/2; k++)
{
for(j = para.first_n; j = MAX_NUM - para.first_n; j += para.inc)
{
if(array[i][j] == 0)
{
array[i][j] = array[i][j + para.inc];
array[i][j + para.inc] = 0;
}
else
if(array[i][j] == array[i][j + para.inc])
{
array[i][j] *=2;
array[i][j + para.inc] = 0;
}
}
}
}
}
else
if(move_fx == MOVE_UP || move_fx == MOVE_DOWN)
{
for(j = 0; j < MAX_NUM; j++)
{
for(k = 0; k < MAX_NUM/2; k++)
{
for(i = para.first_n; i = MAX_NUM - para.first_n; i += para.inc)
{
if(array[i][j] == 0)
{
array[i][j] = array[i + para.inc][j];
array[i + para.inc][j] = 0;
}
else
if(array[i][j] == array[i + para.inc][j])
{
array[i][j] *=2;
array[i + para.inc][j] = 0;
}
}
}
}
}
}


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
解决了数组的移动,还有几个比较重要的问题要解决:
1、判断数组在某个方向能否移动
2、判断整个数组能否移动,各个方向都不能移动,则游戏结束。
3、数的新增
4、判断某个数是否为2048。
5、得分计算。
加入这几个规则,即可得到一个完整的游戏。


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
先写一个函数,得到数组内为0的个数:
int Empty_N(void)
{
int i,j;
int n = 0;
for(i = 0; i < MAX_NUM; i++)
{
for(j = 0; j < MAX_NUM; j++)
{
if(array[i][j] == 0)
{
n++;
}
}
}
return n;
}


2026-04-20 01:49:44
广告
不感兴趣
开通SVIP免广告
  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
产生新数的函数:
void Add_New(void)
{
int i,j;
if(Empty_N() > 0)
{
while(1)
{
i=rand()%MAX_NUM;
j=rand()%MAX_NUM;
if(array[i][j] == 0)
{
if(rand()%100 < 80)//2和4按8:2的比例出现
{
array[i][j]=2;
}
else
{
array[i][j]=4;
}
break;
}
}
}
}


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
判断数组能否移动,返回1表示能移动,0表示不能移动:
int Check_Move(void)
{
int i,j;
int a = 0;
int b = 0;
if(Empty_N() == 0)
{
for(i=0;i< MAX_NUM;i++)
{
for(j=0;j<MAX_NUM -1;j++)
{
if(array[i][j]==array[i][j+1])
a=1;
}
}
for(j=0;j<MAX_NUM;j++)
{
for(i=0;i<MAX_NUM -1;i++)
{
if(array[i][j]==array[i+1][j])
b=1;
}
}
if(a==0 && b==0)
return 0;
else
return 1;
}
else
return 1;
}


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
由于游戏得分是在移动时,相同两个数合并产生的,每次合并就在的得分上加上合并后的数。所以,要定义一个全局变量记录得分,还要在移动函数中加入得分计算。上面的移动函数重写。
加入两行代码即可。
int score = 0;//全局变量,记录得分
void Move(MOVE_TYPE move_fx)
{
int i,j,k;
MOVE_PARA para;
para = Move_Para(move_fx);
if(move_fx == MOVE_LEFT || move_fx == MOVE_RIGHT)
{
for(i = 0; i < MAX_NUM; i++)
{
for(k = 0; k < MAX_NUM/2; k++)
{
for(j = para.first_n; j = MAX_NUM - para.first_n; j += para.inc)
{
if(array[i][j] == 0)
{
array[i][j] = array[i][j + para.inc];
array[i][j + para.inc] = 0;
}
else
if(array[i][j] == array[i][j + para.inc])
{
array[i][j] *=2;
array[i][j + para.inc] = 0;
score += array[i][j];//计算得分
}
}
}
}
}
else
if(move_fx == MOVE_UP || move_fx == MOVE_DOWN)
{
for(j = 0; j < MAX_NUM; j++)
{
for(k = 0; k < MAX_NUM/2; k++)
{
for(i = para.first_n; i = MAX_NUM - para.first_n; i += para.inc)
{
if(array[i][j] == 0)
{
array[i][j] = array[i + para.inc][j];
array[i + para.inc][j] = 0;
}
else
if(array[i][j] == array[i + para.inc][j])
{
array[i][j] *=2;
array[i + para.inc][j] = 0;
score += array[i][j];//计算得分
}
}
}
}
}
}


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
检测2048的函数:
int Check_Win(void)
{
int i,j;
int a=0;
if(Check_Move())
{
for(i=0;i<MAX_NUM;i++)
{
for(j=0;j<MAX_NUM;j++)
{
if(array[i][j]==2048)
a=1;
break;
}
if(a == 1)
break;
}
}
return a;
}


  • james19791
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
该做的准备工作都做完了,剩下的就是在main函数里将它们组合起来运行。有兴趣的可以自行完成,欢迎交流~!


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 12回复贴,共1页
<<返回c语言吧
分享到:
©2026 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示