console下纯字符实现的俄罗斯方块
忙里偷闲,消遣一下,先上一张寒酸的效果图:
废话不多说,直接上代码,win7 64 code blocks编译通过。
吐槽一下cb的watch功能实在不够友好,不过免费的也不能要求太高。
【按键说明】
A:向左
D:向右
S:向下
Space:变化
#include "stdio.h"
#include "stdlib.h"
#include "windows.h"
#include "time.h" // ----------------------------------------------------------------------------
// local define
// ---------------------------------------------------------------------------- #define _KEY_DOWN 's'
#define _KEY_LEFT 'a'
#define _KEY_RIGHT 'd' #define _KEY_CHANGE ' ' #define _BLOCK_X_MAX 20
#define _BLOCK_Y_MAX 20
#define _BLOCK_UNIT_NONE ' '
#define _BLOCK_UNIT_TETRIS '@'
#define _BLOCK_UNIT_EDGE '*' #define _TETRIS_BUF_SIZE 4
#define _TETRIS_TYPE_NUM 7 #define _TETRIS_SPEED 600 #define _CHANGE_TIME_MAX 4 // ----------------------------------------------------------------------------
// local type
// ---------------------------------------------------------------------------- typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD; typedef unsigned char * PBYTE;
typedef unsigned short * PWORD;
typedef unsigned long * PDWORD; typedef enum
{
_E_KT_NONE, _E_KT_DOWN,
_E_KT_LEFT,
_E_KT_RIGHT,
_E_KT_CHANGE, _E_KT_SIZE
}E_KEY_TYPE; typedef struct
{
int i_x;
int i_y;
}T_Tetris_Unit_Pos; // ----------------------------------------------------------------------------
// local vars
// ----------------------------------------------------------------------------
const T_Tetris_Unit_Pos __DB[_TETRIS_TYPE_NUM][_TETRIS_BUF_SIZE] =
{
/*
@@
@@
*/
{{_BLOCK_X_MAX/2, 0},{_BLOCK_X_MAX/2+1, 0},{_BLOCK_X_MAX/2+1, 1},{_BLOCK_X_MAX/2+2, 1}},
/*
@@
@@
*/
{{_BLOCK_X_MAX/2+1, 0},{_BLOCK_X_MAX/2+2, 0},{_BLOCK_X_MAX/2, 1},{_BLOCK_X_MAX/2+1, 1}},
/*
@
@@@
*/
{{_BLOCK_X_MAX/2, 0},{_BLOCK_X_MAX/2-1, 1},{_BLOCK_X_MAX/2, 1},{_BLOCK_X_MAX/2+1, 1}},
/*
@
@@@
*/
{{_BLOCK_X_MAX/2, 0},{_BLOCK_X_MAX/2-2, 1},{_BLOCK_X_MAX/2-1, 1},{_BLOCK_X_MAX/2, 1}},
/*
@
@@@
*/
{{_BLOCK_X_MAX/2, 0},{_BLOCK_X_MAX/2, 1},{_BLOCK_X_MAX/2+1, 1},{_BLOCK_X_MAX/2+2, 1}},
/*
@@
@@
*/
{{_BLOCK_X_MAX/2, 0},{_BLOCK_X_MAX/2+1, 0},{_BLOCK_X_MAX/2, 1},{_BLOCK_X_MAX/2+1, 1}},
/*
@@@@
*/
{{_BLOCK_X_MAX/2, 1},{_BLOCK_X_MAX/2+1, 1},{_BLOCK_X_MAX/2+2, 1},{_BLOCK_X_MAX/2+3, 1}},
}; const DWORD __OFFSET[_TETRIS_TYPE_NUM][_CHANGE_TIME_MAX] =
{
/*
@@
@@
*/
{0x00101121, 0x10110102, 0x00101121, 0x10110102},
/*
@@
@@
*/
{0x10200111, 0x01001211, 0x10200111, 0x01001211},
/*
@
@@@
*/
{0x10011121, 0x21101112, 0x12211101, 0x01121110},
/*
@
@@@
*/
{0x20011121, 0x22101112, 0x02211101, 0x00121110},
/*
@
@@@
*/
{0x00011121, 0x10000102, 0x21201000, 0x02121110},
/*
@@
@@
*/
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
/*
@@@@
*/
{0x01112131, 0x00010203, 0x01112131, 0x00010203},
}; T_Tetris_Unit_Pos l_at_cur_tetris[_TETRIS_BUF_SIZE];
BYTE l_by_offset_index = 0;
BYTE l_by_db_index = 0;
BYTE l_aby_block[_BLOCK_Y_MAX][_BLOCK_X_MAX]; // ----------------------------------------------------------------------------
// funcs part
// ---------------------------------------------------------------------------- void Pos_Jump(int x, int y)
{
COORD pos = {x, y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
} void Pos_Jump_In_Block(int x, int y)
{
Pos_Jump(x+1, y+1);
} E_KEY_TYPE Key_Detect()
{
BYTE by_key_value;
E_KEY_TYPE e_kt; if(0 == kbhit())
{
return _E_KT_NONE;
} by_key_value = (BYTE)(getch()); /*
if(l_b_key_lock)
{
return _E_KT_NONE;
}
*/
switch(by_key_value)
{
case _KEY_DOWN:
e_kt = _E_KT_DOWN;
break; case _KEY_LEFT:
e_kt = _E_KT_LEFT;
break; case _KEY_RIGHT:
e_kt = _E_KT_RIGHT;
break; case _KEY_CHANGE:
e_kt = _E_KT_CHANGE;
break; default:
e_kt = _E_KT_NONE;
break;
} return e_kt;
} void Show_Block()
{
int i, j; // set default value -----
for(i=0 ; i<_BLOCK_Y_MAX ; i++)
{
for(j=0 ; j<_BLOCK_X_MAX ; j++)
{
l_aby_block[i][j] = _BLOCK_UNIT_NONE;
}
} // show frame -------
// top
Pos_Jump(0, 0);
for(i=0 ; i<_BLOCK_X_MAX+2 ; i++)
{
printf("%c", _BLOCK_UNIT_EDGE);
} // bottom
Pos_Jump(0, _BLOCK_Y_MAX+1);
for(i=0 ; i<_BLOCK_X_MAX+2 ; i++)
{
printf("%c", _BLOCK_UNIT_EDGE);
} // side
for(j=1 ; j<_BLOCK_Y_MAX+1 ; j++)
{
Pos_Jump(0, j);
printf("%c", _BLOCK_UNIT_EDGE);
Pos_Jump(_BLOCK_X_MAX+1, j);
printf("%c", _BLOCK_UNIT_EDGE);
}
} BOOL Get_New()
{
int i_type_num;
int i; srand(time(0));
i_type_num = rand()%(_TETRIS_TYPE_NUM); for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
l_at_cur_tetris[i] = __DB[i_type_num][i];
}
l_by_offset_index = 0;
l_by_db_index = i_type_num; for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
if(_BLOCK_UNIT_TETRIS == l_aby_block[l_at_cur_tetris[i].i_y][l_at_cur_tetris[i].i_x])
{
return FALSE;
}
} return TRUE;
} void Clear_Cur_Tetris()
{
int i;
// draw new ----------
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
Pos_Jump_In_Block(l_at_cur_tetris[i].i_x, l_at_cur_tetris[i].i_y);
printf(" ");
}
} void Show_Cur_Tetris()
{
int i;
// draw new ----------
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
Pos_Jump_In_Block(l_at_cur_tetris[i].i_x, l_at_cur_tetris[i].i_y);
printf("@");
}
} void Move_Left()
{
int i;
T_Tetris_Unit_Pos at_next[_TETRIS_BUF_SIZE]; // calc next ---
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
at_next[i] = l_at_cur_tetris[i];
if(0 == at_next[i].i_x)
{
return;
}
at_next[i].i_x--;
} // clear old ---------
Clear_Cur_Tetris();
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
l_at_cur_tetris[i] = at_next[i];
}
Show_Cur_Tetris();
} void Move_Right()
{
int i;
T_Tetris_Unit_Pos at_next[_TETRIS_BUF_SIZE]; // calc next ---
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
at_next[i] = l_at_cur_tetris[i];
at_next[i].i_x++;
if(_BLOCK_X_MAX == at_next[i].i_x)
{
return;
}
} // clear old ---------
Clear_Cur_Tetris();
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
l_at_cur_tetris[i] = at_next[i];
}
Show_Cur_Tetris();
} BOOL Move_Down()
{
int i;
T_Tetris_Unit_Pos at_next[_TETRIS_BUF_SIZE];
BOOL b_can_down = FALSE; // calc next ---
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
at_next[i] = l_at_cur_tetris[i];
at_next[i].i_y++;
} // check if next is ok ---
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
if( _BLOCK_UNIT_TETRIS == l_aby_block[at_next[i].i_y][at_next[i].i_x]
||_BLOCK_Y_MAX == at_next[i].i_y)
{
b_can_down = FALSE;
return b_can_down;
}
} // clear old ---------
Clear_Cur_Tetris();
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
l_at_cur_tetris[i] = at_next[i];
}
Show_Cur_Tetris(); b_can_down = TRUE;
return b_can_down;
} void On_Change()
{
int i;
DWORD dw_cur, dw_next;
int i_x_offset, i_y_offset;
int i_x_min, i_x_max;
T_Tetris_Unit_Pos at_next[_TETRIS_BUF_SIZE]; if(_CHANGE_TIME_MAX-1 != l_by_offset_index)
{
dw_cur = __OFFSET[l_by_db_index][l_by_offset_index];
dw_next = __OFFSET[l_by_db_index][l_by_offset_index+1];
}
else
{
dw_cur = __OFFSET[l_by_db_index][_CHANGE_TIME_MAX-1];
dw_next = __OFFSET[l_by_db_index][0];
} for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
i_x_offset = (int)(((dw_next>>8*(4-i-1))&0xF0)>>4) - (int)(((dw_cur>>8*(4-i-1))&0xF0)>>4);
i_y_offset = (int)((dw_next>>8*(4-i-1))&0x0F) - (int)((dw_cur>>8*(4-i-1))&0x0F); at_next[i] = l_at_cur_tetris[i]; at_next[i].i_x += i_x_offset;
at_next[i].i_y += i_y_offset;
} // check ------
i_x_min = at_next[0].i_x;
i_x_max = at_next[0].i_x;
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
if(i_x_min > at_next[i].i_x)
{
i_x_min = at_next[i].i_x;
} if(i_x_max < at_next[i].i_x)
{
i_x_max = at_next[i].i_x;
}
} if(i_x_min < 0)
{
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
at_next[i].i_x -= i_x_min;
}
} if(i_x_max > _BLOCK_X_MAX-1)
{
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
at_next[i].i_x -= i_x_max - (_BLOCK_X_MAX-1);
}
} for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
if(_BLOCK_UNIT_TETRIS == l_aby_block[at_next[i].i_x][at_next[i].i_y])
{
// can not change -------
return;
}
} // ----------------
l_by_offset_index++;
l_by_offset_index = l_by_offset_index % _CHANGE_TIME_MAX; Clear_Cur_Tetris();
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
l_at_cur_tetris[i] = at_next[i];
}
Show_Cur_Tetris();
} void On_Key_Detecting()
{
E_KEY_TYPE e_type; e_type = Key_Detect(); if(_E_KT_NONE == e_type)
{
return;
} if(_E_KT_CHANGE == e_type)
{
On_Change();
} if(_E_KT_LEFT == e_type)
{
Move_Left();
} if(_E_KT_RIGHT == e_type)
{
Move_Right();
} if(_E_KT_DOWN == e_type)
{
Move_Down();
}
} void Show_Game_Over()
{
Pos_Jump(0, _BLOCK_Y_MAX+2);
printf("Game Over!!!");
} BOOL On_Timer()
{
static DWORD dw_time_cur = 0;
static DWORD dw_time_last = 0;
int i; // check speed
dw_time_cur = GetTickCount();
if(dw_time_cur < dw_time_last + _TETRIS_SPEED)
{
return FALSE;
}
dw_time_last = dw_time_cur; if(FALSE == Move_Down())
{
for(i=0 ; i<_TETRIS_BUF_SIZE ; i++)
{
l_aby_block[l_at_cur_tetris[i].i_y][l_at_cur_tetris[i].i_x] = _BLOCK_UNIT_TETRIS;
} if(FALSE == Get_New())
{
Show_Cur_Tetris();
return TRUE;
}
} return FALSE;
} void Line_Blink(int y, BOOL b_show)
{
int i;
// draw new ----------
Pos_Jump_In_Block(0, y);
for(i=0 ; i<_BLOCK_X_MAX ; i++)
{
if(b_show)
{
printf("%c", _BLOCK_UNIT_TETRIS);
}
else
{
printf("%c", _BLOCK_UNIT_NONE);
}
}
} void Eliminate()
{
int i, j, k;
int i_blink_times;
BOOL ab_eliminate_flag[_BLOCK_Y_MAX], b_need_blink = FALSE;
DWORD dw_blink_time = 200;
DWORD dw_time_cur; // check which line need to eliminate ------
for(j=0 ; j<_BLOCK_Y_MAX ; j++)
{
ab_eliminate_flag[j] = TRUE;
for(i=0 ; i<_BLOCK_X_MAX ; i++)
{
if('@' != l_aby_block[j][i])
{
ab_eliminate_flag[j] = FALSE;
break;
}
} if(ab_eliminate_flag[j])
{
b_need_blink = TRUE;
}
} if(FALSE == b_need_blink)
{
return;
} // blink -----------
i_blink_times = 3;
for(i=0 ; i<i_blink_times ; i++)
{
dw_time_cur = GetTickCount();
while(TRUE)
{
if((dw_time_cur + dw_blink_time) < GetTickCount())
{
break;
}
} for(j=0 ; j<_BLOCK_Y_MAX ; j++)
{
if(ab_eliminate_flag[j])
{
Line_Blink(j, FALSE);
}
} dw_time_cur = GetTickCount();
while(TRUE)
{
if((dw_time_cur + dw_blink_time) < GetTickCount())
{
break;
}
} for(j=0 ; j<_BLOCK_Y_MAX ; j++)
{
if(ab_eliminate_flag[j])
{
Line_Blink(j, TRUE);
}
}
} // remove ----------
for(j=0 ; j<_BLOCK_Y_MAX ; j++)
{
if(ab_eliminate_flag[j])
{
for(i=0 ; i<_BLOCK_X_MAX ; i++)
{
l_aby_block[j][i] = ' ';
} for(k=j ; k>0 ; k--)
{
for(i=0 ; i<_BLOCK_X_MAX ; i++)
{
l_aby_block[k][i] = l_aby_block[k-1][i];
}
}
}
} for(j=0 ; j<_BLOCK_Y_MAX ; j++)
{
Pos_Jump_In_Block(0, j);
for(i=0 ; i<_BLOCK_X_MAX ; i++)
{
printf("%c", l_aby_block[j][i]);
}
} } int main()
{
BOOL b_game_over; Show_Block();
Get_New();
Show_Cur_Tetris(); while(TRUE)
{
On_Key_Detecting(); b_game_over = On_Timer();
if(b_game_over)
{
Show_Game_Over();
break;
} Eliminate();
} getch(); return 0;
}
console下纯字符实现的俄罗斯方块的更多相关文章
- console下纯字符实现的贪吃蛇
最近简直超级无聊-- code blocks win7 64编译运行无问题,应该其他编译器也不会有问题. w:上 s:下 a:左 d:右 CS标准方向控制,AK47和M4这种高级货是没有滴-- 废话不 ...
- Ubuntu纯字符界面的一些设置
由于Ubuntu的纯字符界面不支持中文显示,所以进行了一些配置,为了更好的显示 1. 把环境语言配置为英文 在用户目录下的".bashrc"文件的结尾处添加以下内容,然后重新登录 ...
- Linux 纯字符界面的玩法
Linux 纯字符界面的用途 装逼必备 省资源,服务器一般不安装图形界面 图形界面崩溃后紧急救援 进入字符界面的正确方式 目前新的 Linux 发行版基本上都使用 Systemd 作为 init 程序 ...
- 配置 .vimrc 解决 Vim / gVim 在中文 Windows 下的字符编码问题
转载自:-杨博的日志 - 网易博客 Vim / gVim 在中文 Windows 下的字符编码有两个问题: 默认没有编码检测功能 如果一个文件本身采用的字符集比 GBK 大(如 UTF-8.UTF-1 ...
- .Net Core Web/Console 下使用Nlog
.Net Core Console 下使用Nlog 官方介绍: https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-C ...
- linux下的字符界面和图形界面转换
linux下的字符界面和图形界面转换 linux下有六个虚拟终端按键ctrl+alt+F1-F6可以进入相应的虚拟终端永久的话修改/etc/inittab将id:5:initdefault:中的5改成 ...
- linux纯字符界面不支持中文
[2017-01-17] linux纯字符界面不支持中文
- Linux下中文字符乱码的问题
来源:Linux社区 作者:frankfellow Linux下中文经常会出现乱码,有的是浏览网页出现乱码:有的是文本模式下显示中文出现乱码.下图显示的是我遇到的问题.我安装的是CentOS,x-w ...
- 关于 MySQL UTF8 编码下生僻字符插入失败/假死问题的分析
原文:http://my.oschina.net/leejun2005/blog/343353 目录[-] 1.问题:mysql 遇到某些中文插入异常 2.原因:此 utf8 非彼 utf8 3.解决 ...
随机推荐
- MSP430x1_4_6x之问题总结
01:MSP430端口上电复位的初始值是不确定的:所以使用是都要初始化:比如加下面的语句或者加你使用的端口就行了: /*下面六行程序关闭所有的IO口*/ P1DIR = 0XFF;P1OUT ...
- IOS UITableView的分隔线多出问题
如题,有时显示UITableView多出部分在页面时,下面会显示处多出的行, 此时应该在UITableView初始化时设置为Group if (_tableView == nil) { _tableV ...
- 【django入门教程】Django的安装和入门
很多初学django的朋友,都不知道如何安装django开发以及django的入门,今天小编就给大家讲讲django入门教程. 注明:python版本为3.3.1.Django版本为1.5.1,操作系 ...
- Oracle的DDL、DML、DCL
DDL (Data Definition Language 数据定义语言) create table 创建表 alter table 修改表 drop table 删除表 truncate table ...
- 2016-1-7第一个完整APP 私人通讯录的实现 5:保存数据
一:登陆界面 1):用户点击登陆按钮并成功登陆后,根据此时的开关情况选择是否保存数据,代码如下: "]) { [self performSegueWithIdentifier:@" ...
- type safe printf
在书里看到的,摘录如下: #include <iostream> #include <stdexcept> template<class T> struct is_ ...
- Makefile总结和反序字符数组,整体右移数组,杨辉三角!
2015.1.23今天我值日 继续接着昨天Makefile的目标开始记录:第一种:有 .PHNOY声明,但是冒号后面没有依赖文件.PHNOY:clean clean://没有依赖文件 rm *.0 t ...
- vs中附加IIS进程的调试方法
项目运行以管理员的身份进行运行否则附加不进去:
- 钉子和小球_DP
Description 有一个三角形木板,竖直立放,上面钉着n(n+1)/2颗钉子,还有(n+1)个格子(当n=5时如图1).每颗钉子和周围的钉子的距离都等于d,每个格子的宽度也都等于d,且除了最左端 ...
- Java 集合深入理解(7):ArrayList
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情有点美丽,学学 ArrayList 放松下吧! 什么是 ArrayList ArrayList 是 Java 集合 ...