下午在刷题过程中,忽然想写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的更多相关文章

  1. 用python实现一个无界面的2048

    转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5519453.html 以前游戏2048火的时候,正好用其他的语言编写了一个,现在学习python,正好想起来,便决定 ...

  2. js280行代码写2048

    2048 原作者就是用Js写的,一直想尝试.但久久未动手. 昨天教学生学习JS代码.最好还是就做个有趣的游戏好了.2048这么火,是一个不错的选择. 思路: 1. 数组 ,2维数组4x4 2. 移动算 ...

  3. 一起来写2048(160行python代码)

    前言: Life is short ,you need python. --Bruce Eckel 我与2048的缘,不是缘于一个玩家,而是一次,一次,重新的ACM比赛.四月份校赛初赛,第一次碰到20 ...

  4. 一起写2048(160行python代码)

    前言: Life is short ,you need python. --Bruce Eckel 我与2048的缘,不是缘于一个玩家.而是一次,一次,重新的ACM比赛.四月份校赛初赛,第一次碰到20 ...

  5. 【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现

    [实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...

  6. python写2048小游戏

    #!/usr/bin/env python # coding=utf-8 #******************************************************** # > ...

  7. 初学者cocos2dx 写2048 为了和大家一起分享

    第一个是在头文件 部分的代码是学习不变  大多数写自己. class HelloWorld : public cocos2d::CCLayer { public: virtual bool init( ...

  8. R语言写2048游戏

    2048 是一款益智游戏,只需要用方向键让两两相同的数字碰撞就会诞生一个翻倍的数字,初始数字由 2 或者 4 构成,直到游戏界面全部被填满,游戏结束. 编程时并未查看原作者代码,不喜勿喷. 程序结构如 ...

  9. js写2048游戏代码

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

随机推荐

  1. Pig的使用场景

    数据转换加载(ETL)数据流:读取原始数据(比如用户日志),进行数据清洗,进行简单的预计算后导入到数据仓库,比如join连接数据库里的用户信息.

  2. 五、vue常用UI组件

    下面简单的总结下vue常用的一些UI 组件,有一些我也没怎么用过,这里先罗列出来,便于自己后面使用的时候查找方便,大家有更好的可以给我推荐哦~ vuex: vux github ui demo:htt ...

  3. HBase RegionServer宕机处理恢复

    本文分析RegionServer宕机后这个region server上的region是如何在其他region server上恢复的. region server宕机后发生了什么   HMaster有一 ...

  4. TreeView控件概述、属性与方法

    1.作用:用于显示Node结点的分层列表.2.添加到控件箱菜单命令:工程 | 部件,在部件对话框中选择:Microsoft Windows Common Controls 6.03.TreeView控 ...

  5. python基础_类型_str

    #python不用考虑变量,可随时变换,自动分配内存,比如a = 'jjj'后a = 123是可以的 #str 文本 字符串 #常用函数 a = ' abcefg \n' a.strip() #去掉前 ...

  6. WinPE ISO制作

    1.安装ADK,然后导出winPE镜像文件和启动文件: 打开 部署和映像工具环境,cd "Windows Preinstallation Environment",运行 copyp ...

  7. mysqlDOS命令

    MySQL : 1.安装mysql服务:mysqld install 2.删除mysql服务:sc delete mysql 3.启动mysql服务:net start mysql 4.初始化设置密码 ...

  8. ES(ElasticSearch)学习总结

    基本概念 一个分布式多用户能力的全文搜索引擎,基于RESTful web接口. Elasticsearch和MongoDB/Redis/Memcache一样,是非关系型数据库.是一个接近实时的搜索平台 ...

  9. 前端统计利器:Sentry & Matomo

    今天主要说下两款前端统计工具的使用,Sentry & Matomo.以下主要是统计代码接入方式,因此使用前提是你已经在自己的服务器上搭建好了Sentry和Matomo的服务器 Sentry统计 ...

  10. ijcai statistics