用C挑战无准备写2048
下午在刷题过程中,忽然想写2048了,以弥补以前写的那个千多行的,所以简单思考了一下准备采取的数据结构就开始了,本以为一个小时能搞定,结果后面改bug还是多花了些时间。因为在医院,所以声音不敢太大,如果看,建议耳机+声音最大,可以考虑倍速。个人感觉用C写这些东西的意义在于,你去掉了一些花里胡哨的东西,而真的用你的逻辑思考出了这个东西怎么写,并写出来了。乱花渐欲迷人眼,难的是坚守本心!明白学一个东西的意义,有时候比学习它更重要!嗯就这样。下面贴上代码和录制的视频链接。
//2019年3月16日 17:29:07
//2048
//1、地图数据结构 2、合并和移动? 3、判断胜负
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<string.h>
#define N 5//地图大小
#define M 13//table表的长度
#define WINFLAG 11 char map[N][N];//地图
int table[M];//查表使用 void Init();
void Run();
void Print();
int Win();
void Lose();
int IsLose();
int Up(int *isChange);
int Down(int *isChange);
int Left(int *isChange);
int Right(int *isChange);
void Generator(int dir); void gotoxy(int x, int y); //将光标调整到(x,y)的位置 //光标隐藏
void HideCursor() ; //隐藏光标显示 int main(void)
{
srand((unsigned)time(NULL));
HideCursor();
Init();
Run();
return ;
} void Generator(int dir)
{
//按下右,就按列扫,从左往右随机选一个数生成
//按下上,就按行扫,从下网上随机选一个数生成
// int begin;
// int end;
// int mul;//增量
// for(int i = begin;i != end;i += mul)
// for(int i = 0;i < N;++i)
// for(j = N-1;j >= 0;--j)
int flag = ;
int i1 = -,i2 = -;
if(dir == || dir == )
{
int begin,end,mul;
dir == ?begin = ,end = N,mul = :begin = N-,end = -,mul = -;
for(int i = ;i < N;++i)
for(int j = begin;j != end;j += mul)
{
//保证选一个数,然后其他的随机
if(map[i][j] == )//选到了一个数
{
if(flag == )//之前没选到过
{
i1 = i;
i2 = j;
flag = ;
}
else
{
if(rand()% < )
{
i1 = i;
i2 = j;
}
}
}
}
}
else if(dir == || dir == )
{
int begin,end,mul;
dir == ?begin = ,end = N,mul = :begin = N-,end = -,mul = -;
for(int j = begin;j != end;j += mul)
for(int i = ;i < N;++i)
{
//保证选一个数,然后其他的随机
if(map[i][j] == )//选到了一个数
{
if(flag == )//之前没选到过
{
i1 = i;
i2 = j;
flag = ;
}
else
{
if(rand()% < )
{
i1 = i;
i2 = j;
}
}
}
}
}
if(i1 == i2 && i2 == -)
return;
map[i1][i2] = ;
} int Up(int *isChange)
{
//往上,所以是从上往下扫描
//一列一列的算 for(int j = ;j < N;++j)
{
int k = ;
for(int i = ;i < N;++i)
{
if(map[i][j] != )//当前处理的这一位是有数字的
{
//只要是非0,且没有合并,则相加
//这里保证map[i][j]是有数字的
if(map[i][j] == map[k][j])
{
//与那个数字进行交互。合并操作
map[k][j] += ;
map[i][j] = ;
if(map[k][j] == )
return ;
*isChange = ;
}
else if(map[k][j] == )//我们是说k是第一个非零的,但初始的时候我们为了好运算,是没做判断的
{
//把当前位置上的数移过去 特判的移动操作
map[k][j] = map[i][j];
map[i][j] = ;
*isChange = ;
}
else if(k+ != i)//移动操作
{
map[k+][j] = map[i][j];//2 0 0 4 2 4 0 0
map[i][j] = ;//4 2 0 0
++k;
*isChange = ;
} else//没有合并,且不是特判的
++k;
}
}
}
return ;
}
int Down(int *isChange)
{
for(int j = ;j < N;++j)
{
int k = N-;
for(int i = N-;i >= ;--i)
{
if(map[i][j] != )//当前处理的这一位是有数字的
{
//只要是非0,且没有合并,则相加
//这里保证map[i][j]是有数字的
if(map[i][j] == map[k][j])
{
//与那个数字进行交互。合并操作
map[k][j] += ;
map[i][j] = ;
if(map[k][j] == )
return ;
*isChange = ;
}
else if(map[k][j] == )//我们是说k是第一个非零的,但初始的时候我们为了好运算,是没做判断的
{
//把当前位置上的数移过去 特判的移动操作
map[k][j] = map[i][j];
map[i][j] = ;
*isChange = ;
}
else if(k- != i)//移动操作
{
map[k-][j] = map[i][j];//2 0 0 4 2 4 0 0
map[i][j] = ;//4 2 0 0
--k;
*isChange = ;
}
else//没有合并,且不是特判的
--k;
}
}
}
return ;
}
int Left(int *isChange)
{
//合并?什么情况下合并?什么情况下移动?
//一行一行处理
//从左往右处理
//这个有数字,我们才需要处理,没数字不用管 2 0 4 8 2 4 0 8 2 4 8 0
for(int i = ;i < N;++i)
{
int k = ;
for(int j = ;j < N;++j)
{
if(map[i][j] != )//当前处理的这一位是有数字的
{
//这里保证map[i][j]是有数字的
if(map[i][j] == map[i][k])
{
//与那个数字进行交互。合并操作
map[i][k] += ;
map[i][j] = ;
if(map[i][k] == )
return ;
*isChange = ;
}
else if(map[i][k] == )//我们是说k是第一个非零的,但初始的时候我们为了好运算,是没做判断的
{
//把当前位置上的数移过去 特判的移动操作
map[i][k] = map[i][j];
map[i][j] = ;
*isChange = ;
}
else if(k+ != j)//移动操作
{
map[i][k+] = map[i][j];//2 0 0 4 2 4 0 0
map[i][j] = ;//4 2 0 0
++k;
*isChange = ;
}
else
++k;
}
}
}
return ;
}
int Right(int *isChange)
{
//从右至左
for(int i = ;i < N;++i)
{
int k = N-;
for(int j = N-;j >= ;--j)
{
if(map[i][j] != )//当前处理的这一位是有数字的
{
//这里保证map[i][j]是有数字的
if(map[i][j] == map[i][k])
{
//与那个数字进行交互。合并操作
map[i][k] += ;
map[i][j] = ;
if(map[i][k] == )
return ;
*isChange = ;
}
else if(map[i][k] == )//我们是说k是第一个非零的,但初始的时候我们为了好运算,是没做判断的
{
map[i][k] = map[i][j];
map[i][j] = ;
*isChange = ;
}
else if(k- != j)//移动操作
{
map[i][k-] = map[i][j];
map[i][j] = ;
--k;
*isChange = ;
}
else
--k;
}
}
}
return ;
} void Init()
{
int n = ;//随机地图的数目
//先求table
table[] = ;
for(int i = ;i < M;++i)
table[i] = table[i-]<<;//等同于*2
// for(int i = 0;i < M;++i)
// printf("%5d",table[i]);
//及时测试,验证正确性,免得日后找bug麻烦 //随机地图 随机生成3个2?
memset(map,,sizeof(map));
for(int i = ;i < n;++i)
{
int i1 = rand()%N;
int i2 = rand()%N;
//随机一组下标,让地图那个位置变成1
map[i1][i2] = ; //这个1代表2的一次,最终展现的是2
}
}
void Run()
{
int isChange = ;//检测是否发生了变化
int flag = ;
while()
{
Print();
isChange = ;
switch(getch())
{
case 'w':flag = Up(&isChange);break;
case 's':flag = Down(&isChange);break;
case 'a':flag = Left(&isChange);break;
case 'd':flag = Right(&isChange);break;
}
if(flag != && isChange)
Generator(flag);
if(flag == )
{
Win();
break;
}
else if(IsLose())
{
Print();
Lose();
break;
}
}
}
void Print()
{
gotoxy(,);
for(int i = ;i < N;++i)
{
for(int j = ;j < N;++j)
if(map[i][j] != )
printf("%3d ",table[map[i][j]]);
else
printf(" ");
putchar('\n');
}
}
int Win()
{
printf("You are winner!\n");
}
void Lose()
{
printf("You are loser!\n");
}
int IsLose()
{
//判断是否还具备可操作空间
for(int i = ;i < N;++i)
for(int j = ;j < N-;++j)
{
if(map[i][j] == map[i][j+])
return ;
else if(map[i][j]*map[i][j+] == )
return ;
}
for(int j = ;j < N;++j)
for(int i = ;i < N-;++i)
{
if(map[i][j] == map[i+][j])
return ;
else if(map[i][j]*map[i+][j] == )
return ;
}
Print();
return ;
}
//光标跳转
void gotoxy(int x, int y) //将光标调整到(x,y)的位置
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
} //光标隐藏
void HideCursor() //隐藏光标显示
{
CONSOLE_CURSOR_INFO cursor_info = { , };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
哔哩哔哩配套视频链接:https://www.bilibili.com/video/av46465862/
用C挑战无准备写2048的更多相关文章
- 用python实现一个无界面的2048
转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5519453.html 以前游戏2048火的时候,正好用其他的语言编写了一个,现在学习python,正好想起来,便决定 ...
- js280行代码写2048
2048 原作者就是用Js写的,一直想尝试.但久久未动手. 昨天教学生学习JS代码.最好还是就做个有趣的游戏好了.2048这么火,是一个不错的选择. 思路: 1. 数组 ,2维数组4x4 2. 移动算 ...
- 一起来写2048(160行python代码)
前言: Life is short ,you need python. --Bruce Eckel 我与2048的缘,不是缘于一个玩家,而是一次,一次,重新的ACM比赛.四月份校赛初赛,第一次碰到20 ...
- 一起写2048(160行python代码)
前言: Life is short ,you need python. --Bruce Eckel 我与2048的缘,不是缘于一个玩家.而是一次,一次,重新的ACM比赛.四月份校赛初赛,第一次碰到20 ...
- 【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现
[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...
- python写2048小游戏
#!/usr/bin/env python # coding=utf-8 #******************************************************** # > ...
- 初学者cocos2dx 写2048 为了和大家一起分享
第一个是在头文件 部分的代码是学习不变 大多数写自己. class HelloWorld : public cocos2d::CCLayer { public: virtual bool init( ...
- R语言写2048游戏
2048 是一款益智游戏,只需要用方向键让两两相同的数字碰撞就会诞生一个翻倍的数字,初始数字由 2 或者 4 构成,直到游戏界面全部被填满,游戏结束. 编程时并未查看原作者代码,不喜勿喷. 程序结构如 ...
- js写2048游戏代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
随机推荐
- 一个Interface 继承多个Interface 的总结
我们知道在Java中的继承都是单继承的,就是说一个父类可以被多个子类继承但是一个子类只能有一个父类.但是一个接口可以被不同实现类去实现,这就是我们说的Java中的多态的概念.下面我们再来说一下接口的多 ...
- [翻译] 扩张卷积 (Dilated Convolution)
英文原文: Dilated Convolution 简单来说,扩张卷积只是运用卷积到一个指定间隔的输入.按照这个定义,给定我们的输入是一个2维图片,扩张率 k=1 是通常的卷积,k=2 的意思是每个输 ...
- 2.MyBatis 动态SQL
动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格 ...
- Spring常用注解简单汇总
使用注解之前要开启自动扫描功能,其中base-package为需要扫描的包(含子包). <context:component-scan base-package="cn.test&qu ...
- Entity Framework对同一张表配置一对多关系
在实际的项目开发中,可能会遇到同一张表同时保存自身和上级(或下级)的信息(一般是通过设置一个上级主键[ParentId]的列与主键[Id]关系) 例如:城市库,有国家.省.市...,省的ParentI ...
- 浅析Oracle 12c中Data Guard新特性
浅析Oracle 12c中Data Guard新特性 写在前面 无论是做Oracle运维的小伙伴还是老伙伴,想必对Oracle数据库的数据级灾备核心技术—Data Guard是再熟悉不过了!这项从 ...
- SpringBoot @AutoWired Null
在调用工具类时,若工具类中含有@Autowired注解,这此工具类对象必须同样使用@Autowired注解,否则工具类中的Spring注入的对象都为空值,这里的HadoopTest就是这样 比如MyC ...
- [转] 29个你必须知道的Linux命令
总结: 1. find 查找文件 2. grep 查找某个文件或者文件夹里面文件的内容 29个你必须知道的Linux命令 虽然Linux发行版支持各种各样的GUI(graphical user in ...
- MapReduce实例2(自定义compare、partition)& shuffle机制
MapReduce实例2(自定义compare.partition)& shuffle机制 实例:统计流量 有一份流量数据,结构是:时间戳.手机号.....上行流量.下行流量,需求是统计每个用 ...
- java面向切面编程总结-面向切面的本质
面向切面的本质:定义切面类并将切面类的功能织入到目标类中: 实现方式:将切面应用到目标对象从而创建一个新的代理对象的过程.替换: 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Point ...