忙里偷闲,消遣一下,先上一张寒酸的效果图:

废话不多说,直接上代码,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下纯字符实现的俄罗斯方块的更多相关文章

  1. console下纯字符实现的贪吃蛇

    最近简直超级无聊-- code blocks win7 64编译运行无问题,应该其他编译器也不会有问题. w:上 s:下 a:左 d:右 CS标准方向控制,AK47和M4这种高级货是没有滴-- 废话不 ...

  2. Ubuntu纯字符界面的一些设置

    由于Ubuntu的纯字符界面不支持中文显示,所以进行了一些配置,为了更好的显示 1. 把环境语言配置为英文 在用户目录下的".bashrc"文件的结尾处添加以下内容,然后重新登录 ...

  3. Linux 纯字符界面的玩法

    Linux 纯字符界面的用途 装逼必备 省资源,服务器一般不安装图形界面 图形界面崩溃后紧急救援 进入字符界面的正确方式 目前新的 Linux 发行版基本上都使用 Systemd 作为 init 程序 ...

  4. 配置 .vimrc 解决 Vim / gVim 在中文 Windows 下的字符编码问题

    转载自:-杨博的日志 - 网易博客 Vim / gVim 在中文 Windows 下的字符编码有两个问题: 默认没有编码检测功能 如果一个文件本身采用的字符集比 GBK 大(如 UTF-8.UTF-1 ...

  5. .Net Core Web/Console 下使用Nlog

    .Net Core Console 下使用Nlog 官方介绍: https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-C ...

  6. linux下的字符界面和图形界面转换

    linux下的字符界面和图形界面转换 linux下有六个虚拟终端按键ctrl+alt+F1-F6可以进入相应的虚拟终端永久的话修改/etc/inittab将id:5:initdefault:中的5改成 ...

  7. linux纯字符界面不支持中文

    [2017-01-17] linux纯字符界面不支持中文

  8. Linux下中文字符乱码的问题

    来源:Linux社区  作者:frankfellow Linux下中文经常会出现乱码,有的是浏览网页出现乱码:有的是文本模式下显示中文出现乱码.下图显示的是我遇到的问题.我安装的是CentOS,x-w ...

  9. 关于 MySQL UTF8 编码下生僻字符插入失败/假死问题的分析

    原文:http://my.oschina.net/leejun2005/blog/343353 目录[-] 1.问题:mysql 遇到某些中文插入异常 2.原因:此 utf8 非彼 utf8 3.解决 ...

随机推荐

  1. OpenCV之响应鼠标(四):在图像上绘制出矩形并标出起点的坐标

    涉及到两方面的内容:1. 用鼠标画出矩形.2.在图像上绘制出点的坐标 用鼠标绘制矩形,涉及到鼠标的操作,opencv中有鼠标事件的介绍.需要用到两个函数:回调函数CvMouseCallback和注册回 ...

  2. 在T-SQL中访问远程数据库(openrowset、opendatasource、openquery)

    1.  启用Ad Hoc Distributed Queries 在使用openrowset/opendatasource前要先启用Ad Hoc Distributed Queries服务,因为这个服 ...

  3. (转)面向移动设备的HTML5开发框架

    (原)http://www.cnblogs.com/itech/archive/2013/07/27/3220352.html 面向移动设备的HTML5开发框架   转自:http://blogrea ...

  4. Android MotionEvent getX() getY() getRawX() getRawY() and View getTop() getLeft()

    getRowX:触摸点相对于屏幕的坐标getX: 触摸点相对于按钮的坐标getTop: 按钮左上角相对于父view(LinerLayout)的y坐标getLeft: 按钮左上角相对于父view(Lin ...

  5. hdu 2076

    ps:WA了三次...第一次头脑有点乱,很麻烦的分几种情况讨论,第二次发现,只要分别算出时针和分针的角度,然后一减就行,却忽略了哪个大的问题,第三次加上了绝对值,就好了..就是以后double型比较最 ...

  6. 顺序表(C++)

    以下为数据结构中的顺序表实现代码,已测试能够运行.虽然说是C++版的,但是其实应该是C语言班的.C++应该是面向对象,用抽象方法实现,而以下代码是面向过程的,只是把C语言中的输入(scanf)和输出( ...

  7. linux下的定时任务

    cronb命令 在Linux中,周期执行的任务一般由cron这个守护进程来处理.ps -ef | grep cron.cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间. cron ...

  8. Fish入门

    安装以及配置 Linux和OS X基本都可以通过源来安装,实在不行就下载源码编译,不难的. 安装好第一步是修改OS默认shell: chsh -s /usr/bin/fish 然后就可以直接使用了,就 ...

  9. 利用WPF绘图

    C#入门经典 25章的一个例子,利用WPF绘图. XAML: <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/p ...

  10. Excel文件的导出操作

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...