俄罗斯方块linux服务器,基与Linux环境下 C 俄罗斯方块
俄罗斯方块
一、设置控制台
1、更改屏幕的背景色,字体颜色
printf("\33[%dm", i);
30<= i <=37 设置字体颜色
30黑,31红,32绿,33黄,34蓝,35紫,36深绿,37白
40<= i <=47 设置背景颜色
40黑,41红,42绿,43黄,44蓝,45紫,46深绿,47白
2、任意指定屏幕的输出坐标
printf("\33[x;yH"); 将输出坐标定位在第x行,第y列
printf("\33[%d;%dH", x,y); 将输出坐标定位在第x行,第y列
二、菜单
1、边框
游戏区宽48,高31;辅助区宽27,高31
游戏区起始坐标(2,3);辅助区起始坐标(2,53)(18,53)
2、开始
用空格和[]描出一个fight单词
3、结束
用空格和[]描出一个game over单词
三、绘制方块
1、一个小方格
由于一个字符在屏幕上占的空间是一个长方形,所以用[]来表示一个方格
2、俄罗斯方块
总共有7个类型的方块,每个方块有4种摆放的方式(可以旋转)
一个方块最多占用4个小方格
用4x4的矩阵来表示一个俄罗斯方块,矩阵中为1的地方,绘制[]
{0, 0, 0, 0}
{0, 0, 1, 0} -----> []
{0, 0, 1, 1} [][]
{0, 0, 1, 0} []
3、用一个三位数组表示所有的俄罗斯方块
int shape[i][j][k]
i表示方块的类型,j表示方块摆放的方式,k将4x4矩阵变为一维数组
将上面的二维数组变成一维的{0,0,0,0, 0,0,1,0, 0,0,1,0, 0,0,1,0}
4、起始坐标
绘制方块从4x4矩阵的左下角开始,制定其坐标为row、col
俄罗斯方块中小方格的坐标rrow = row + j/4-3 ccol = ccol + (i%4)*2
四、 自动下落
1、内核定时器
setitimer(int which, const struct itimerval *val, struct itimerval *oldval)
参数which:
ITIMER_REAL 用系统实时的时间计算,时间减1,减到0发送SIGALRM信号
ITIMER_VIRTUAL 当前进程用户态计数, 计数完成发送SIGVTALRM信号
ITIMER_PROF 用户态和内核态同时计数,计数完成发送SIGPROF信号
参数val:
struct itimerval{
struct timeval it_interval; //定时时间
struct timeval it_value; //定时器开始执行的时间
}
struct timeval{
long second; //秒
long usec; //微妙
}
参数oldval:
保存旧的状态
struct itimerval val = {
{0,500000}, //0.5秒的定时时间
{1,0} //1s后开启定时器
};
setitimer{ITIMER_REAL, &val, NULL};
2、信号捕捉
sigaction(int signo, struct sigaction *act, struct sigaction *oldact);
参数signo:
要捕捉的信号
参数act:
为信号设置动作
参数oldact:
保存旧的状态,NULL就是不保存
struct sigaction{
void (*sa_handler)(int); //信号执行的函数
sigset_t mask; //信号执行过程中要屏蔽的其他信号
}
struct sigaction act;
act.sa_handler = self_down;
sigaction(SIGALRM, &act, NULL);
五、 响应键盘
1、设置终端,键盘可以输入,但是不能在屏幕上显示输入的字符,否则影响游戏画面。
struct termios old, new;
tcgetattr(0, &old); //保存旧的状态
tcgetattr(0, &new); //获取旧的状态
new.c_lflag = new.c_lflag & ~(ICANON|ECHO); //设置屏幕不显示输入的字符
new.c_cc[VTIME] = 0;
new.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &new); //修改终端的属性,立即生效
2、响应键盘输入
判断输入字符
while(1)
{
c = getchar();
switch(c)
{
case 'a':
left(); //左移,列-2,因为一个小方格占2列
break;
case 'd':
right(); //右移,列+2
break;x
case 'w':
change(); //逆时针旋转
break;
case 's':
self_down(1); //自由下落 row+1
break;
default:
break;
}
}
3、设置标志位
方块降落到最后,需要用以个二维数组来标志,数组中为1的地方证明有方格
int flag[30][24];
void set_flag()
{
int i;
int row, col;
for(i=0; i<16; i++)
{
if(shape[box.sh][box.num][i] == 1)
{
row = box.row + i/4 -3 -2;
col = (box.col + (i%4)*2 + 1)/2-2;
flag[row][col] = 1;
}
}
}
4、边界判断
1)、下落判断
//判断能有下落,当对应方格的下一行位置有东西,那么就不能下落来了
//比如现在方格在8行9列,那么如果9行9列有东西(判断标志位),那么
//方格就不能在下落了
int is_down()
{
int err = 1;
int i;
if(box.row >= 31) //第一次超过31行就不能下落,那是最低的边界
{
err = 0;
return err;
}
for(i = 0; i < 16; i++)
{
if(shape[box.sh][box.num][i] == 1)
{
if(flag[box.row + i/4 -3 -2 + 1][(box.col+i%4*2+1)/2-2] == 1)
{
err = 0;
return err;
}
}
}
return err;
}
2)、左移判断
//首先要获取大方块中的最左边的列
int get_left()
{
int col[4];
int i, j, temp;
for(i=0, j=0; i<16; i++)
{
if(shape[box.sh][box.num][i] == 1) //获取方块中小方格占的列
{
col[j] = box.col + (i%4)*2;
j++;
}
}
for(i=1; i<4; i++)
{
if(col[0] > col[i]) //求出列中最小的,也就是最左边的列
{
temp = col[0];
col[0] = col[i];
col[i] = temp;
}
}
return col[0];
}
int is_left() //判断能否左移
{
int err = 1;
int i;
int col = get_left();
if(col == 3) //最左边的列是第3列,移动到第3列就不能左移了
return 0;
//如果左边有方格,也不能左移,通过标志位来判断
for(i = 0; i < 16; i++)
{
if(shape[box.sh][box.num][i] == 1)
{
if(flag[box.row + i/4 -3 -2][(box.col+i%4*2+1)/2-2-1] == 1)
{
err = 0;
return err;
}
}
}
return err;
}
3)、右移判断
//首先要获取大方块中的最右边的列
int get_right()
{
int col[4];
int i, j, temp;
for(i=0, j=0; i<16; i++)
{
if(shape[box.sh][box.num][i] == 1) //获取方块中小方格占的列
{
col[j] = box.col + (i%4)*2;
j++;
}
}
for(i=1; i<4; i++)
{
if(col[0] < col[i]) //求出列中最大的,也就是最右边的列
{
temp = col[0];
col[0] = col[i];
col[i] = temp;
}
}
return col[0];
}
int is_right() //判断能否右移
{
int err = 1;
int i;
int col = get_right();
if(col == 3) //最右边的列是第49列,移动到第49列就不能右移了
return 0;
//如果右边有方格,也不能右移,通过标志位来判断
for(i = 0; i < 16; i++)
{
if(shape[box.sh][box.num][i] == 1)
{
if(flag[box.row + i/4 -3 -2][(box.col+i%4*2+1)/2-2+1] == 1)
{
err = 0;
return err;
}
}
}
return err;
}
4)、旋转判断
旋转依赖4x4大方格,在4x4大方格内有东西到地方都不能旋转
int is_change()
{
int err=1;
int i;
for(i=0; i<16; i++)
{
if(flag[box.row+i/4-3-2+1][(box.col+1+i%4*2)/2-2] == 1)
{
err = 0;
return err;
}
if(box.col<3)
{
err = 0;
return err;
}
}
return err;
}
六、消行
1、判断是否需要消行,获取需要消的行号
在flag数组中,如果有一行全部为1,那么就需要消行了
int is_clean()
{
int err=0, fg=1;
int num=0;
int i,j;
for(i=0; i<30; i++)
{
fg = 1; //假设这一行能消去
for(j=0; j<24; j++)
{
if(flag[i][j]==0) //如果这一行中有一个0,那么就不能消去
{
fg = 0;
break;
}
}
if(fg == 1)
{
clean_row[num] = i; //如果能消行,那么需要记录行号
num++;
err = 1;
}
}
return err;
}
2、记录以前的状态,设值新的状态
void swap()
{
int i,j,k; //old_flag记录以前的状态
for(i=0; i<30; i++)
for(j=0; j<24; j++)
old_flag[i][j] = flag[i][j];
for(k=0; k<4; k++) //更新flag,消行后,上面的行要掉下来
for(i=0; i
for(j=0; j<24; j++)
{
flag[i+1][j] = old_flag[i][j];
}
}
3、重新画图
void redraw()
{
int i,j;
//将以前的图形全部擦掉
for(i=0; i<30; i++)
{
for(j=0; j<24; j++)
{
if(old_flag[i][j]==1)
single_box(i+2, (j+1)*2+1, 0);
}
}
//绘制新的图形
for(i=0; i<30; i++)
{
for(j=0; j<24; j++)
{
if(flag[i][j]==1)
single_box(i+2, (j+1)*2+1, 1);
}
}
}
七、右侧指示下一个
1、一开始就产生两个图形,box、next_box
使用box下落,next_box显示在右侧
box.sh = 1;
box.num = 1;
box.row = 1;
box.col = 13;
big_box(box, 1);
next();
display_next( 1);
void next()
{
next_box.sh = rand_num(7);
next_box.num = rand_num(4);
next_box.row = 1;
next_box.col = 13;
}
void display_next(int mode)
{
struct box_info nbox;
memcpy(&nbox, &next_box, sizeof(struct box_info));
nbox.row = 10;
nbox.col = 60;
big_box(nbox, mode);
}
2、当下落结束的时候,需要使用next_box下落,然后接着产生另一个next_box
if(new_flag == 1)
{
new_flag = 0;
display_next(0); //将右侧的提示去掉
memcpy(&box, &next_box, sizeof(struct box_info));//将next_box拷贝到box
next(); //产生新的next_box
display_next( 1); //在右侧提示next_box
}
八、判断游戏是否结束
//判断是否结束游戏
int is_gameover()
{
int err = 0;
int i,j;
for(j=0; j<24; j++)
{
//flag第0行有1就是结束游戏
if(flag[0][j] == 1)
{
err = 1;
break;
}
}
return err;
}
//产生下一个box的时候判断是否游戏结束
void next()
{
if(is_gameover()==1)
{
flag_over = 1;
return;
}
next_box.sh = rand_num(7);
next_box.num = rand_num(4);
next_box.row = 1;
next_box.col = 13;
}
九、修改菜单,完善游戏
增加游戏的灵活性,进入游戏后,按1是开始,按2是选关,按3是退出。
选关的时候+是增加难度,-是减少难度,1是开始,3是退出
最后未完成的双人版,日后补上,有源代码
压缩文件中有:els.c els.h main.c Makefile
运行方式:1 make
2 ./main
俄罗斯方块linux服务器,基与Linux环境下 C 俄罗斯方块相关推荐
- linux服务器历险之linux性能监控
linux服务器历险之linux性能监控 1.uptime uptime命令用于查看服务器运行了多长时间以及有多少个用户登录,快速获知服务器的负荷情况. uptime的输出包含一项内容是load av ...
- linux服务器关机日期,linux服务器last查看关机记录
1.查看重启记录 last reboot命令 [root@test ~]# last reboot reboot system boot 2.6.-.el6.x Mon May : - : (+:) ...
- 红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理)丨epoll丨c/c++linux服务器开发丨linux后台开发
红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理) 视频讲解如下: 红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理)丨epoll丨c/c++linux服务器开 ...
- 全面了解C++后端开发技能树,C++后端开发面试技术点丨C/C++linux服务器开发丨linux后台开发
C++后端开发技能树,C++后端开发面试技术点 视频讲解如下: 全面了解C++后端开发技能树,C++后端开发面试技术点丨C/C++linux服务器开发丨linux后台开发丨网络编程丨面试经验 C/C+ ...
- 解析Linux内核源码中数据同步问题丨C++后端开发丨Linux服务器开发丨Linux内核开发丨驱动开发丨嵌入式开发丨内核操作系统
剖析Linux内核源码数据同步 1.pdflush机制原理 2.超级块同步/inode同步 3.拥塞及强制回写技术 视频讲解如下,点击观看: 解析Linux内核源码中数据同步问题丨C++后端开发丨Li ...
- 详解5种红黑树的场景,从Linux内核谈到Nginx源码,听完醍醐灌顶丨Linux服务器开发丨Linux后端开发
5种红黑树的场景,从Linux内核谈到Nginx源码,听完醍醐灌顶 1. 进程调度CFS的红黑树场景 2. 虚拟内存管理的红黑树场景 3. 共享内存slab的红黑树场景 视频讲解如下,点击观看: [干 ...
- linux 服务器(CentOS7)搭建PHP环境+SSH配置+服务器文件上传配置
Linux服务器搭建PHP环境 一.配置SSH(Xshell) 1. 公钥私钥配置(普通用户登录) 2. root用户密码登录 二.配置可视化文件上传工具(WinSCP) 1. 公钥私钥配置(普通用户 ...
- 硬盘克隆带linux系统,一种Windows环境下基于DiskGenius克隆Linux系统的方法及系统与流程...
本发明涉及服务器操作系统技术领域,特别是一种windows环境下基于diskgenius克隆linux系统的方法及系统. 背景技术: 服务器在测试过程中需要反复安装linux操作系统用于服务器的各种测 ...
- 基于Linux服务器的JAVA开发环境搭建
Linux服务器开发环境搭建 Linux安装Java 一.使用yum查询JDK 二.执行安装命令 三.验证java是否安装成功 四.安装开发环境 Linux安装Nginx 一.安装前环境检查 二.下载 ...
最新文章
- 阿里云centos配置nginx和nodejs
- ArcGIS 10 五大飞跃
- 端口扫描器——ZenmapKail Linux渗透测
- H3C SecPath防火墙GRE+IPSEC+OSPF典型配置举例
- P4198-楼房重建【线段树】
- 怎么让车辆gps定位失效_如何更有效地检测车辆gps定位器?
- LeetCode--265. 粉刷房子Ⅱ(动态规划)
- 【IT】使用gdb调试code
- ELK官方文档:在Kibana加密通讯
- js检查身份证号是否正确
- AutoCAD Civil 3D 2015-2020
- php网页抓取浏览者手机号码_php 获取 手机浏览器的信息 获取手机号
- [教学]基于crnn的中文汉字识别_pyqt界面交互界面python含代码
- 大数据主要应用于哪些行业,应用价值是什么?
- Ubuntu16.04安装以及在 TitanX 下搭建 caffe框架(cuda8.0 + cudnn5.1)
- 基于WEB快速开发平台的轻量ERP
- 找不到com.sun.beans.introspect.PropertyInfo的类文件问题
- QGIS插件grass使用出现“This algorithm cannot be run:”问题
- 有源电力滤波器并联三相apf matlab simulink仿真 谐波检测谐波补偿
- 爬取猫眼《长津湖》影评,分析观影群众信息,还进行了明日票房预测,好玩!...
热门文章
- 查询rssi指令_RSSI测量方法及网络设备、终端设备与流程
- img预加载获取图片大小方法
- 日历节气显示不正常2015年1月6号是小寒,而现在是显示2015年1月5号是小寒
- 让开源按键组件MultiButton支持菜单操作(事件驱动型)
- 高楼火灾的时候如何利用逃生缓降器进行逃生?
- 《增强现实:原理、算法与应用》读书笔记(1)基础矩阵、本质矩阵与单应性矩阵
- Promise in ES6
- oracle 启动crs进程,由于CRS磁盘dismount造成的CRS进程无法启动问题
- 《Sony Vegas Pro 12标准教程》——1.3 Vegas Pro安装与设置
- 在PlatEMO v2.9中增加多模态多目标算法(1)