console下纯字符实现的贪吃蛇
最近简直超级无聊……
code blocks win7 64编译运行无问题,应该其他编译器也不会有问题。
w:上
s:下
a:左
d:右
CS标准方向控制,AK47和M4这种高级货是没有滴……
废话不多说,直接上代码。
#include "stdio.h"
#include "stdlib.h"
#include "windows.h"
#include "time.h"
// ----------------------------------------------------------------------------
// definition
// ---------------------------------------------------------------------------- // basic char node
#define _FOOD "#"
#define _SNAKE_NODE "O"
#define _SNAKE_END "+"
#define _SNAKE_HEAD "@"
#define _MAP_NODE " "
#define _MAP_EDGE "O" // area pos and range
#define _AREA_X_OFFSET 10
#define _AREA_Y_OFFSET 5
#define _AREA_X_LINE_MAX 30 // max line num in x direction
#define _AREA_Y_LINE_MAX 20 // max line num in y direction #define _SNAKE_LENGTH_MAX 30 // key val defintion
#define _KEY_UP 'w'
#define _KEY_DOWN 's'
#define _KEY_LEFT 'a'
#define _KEY_RIGHT 'd' // default snake speed
#define _DEFAULT_SNAKE_SPEED 300 // 1 step per second // ----------------------------------------------------------------------------
// type
// ---------------------------------------------------------------------------- // basic 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; // element type
typedef enum
{
_ET_MAP_NODE,
_ET_MAP_EDGE, _ET_FOOD, _ET_SNAKE_HEAD,
_ET_SNAKE_NODE,
_ET_SNAKE_END
}E_ET; // snake node type
typedef enum
{
_ESNT_HEAD = _ET_SNAKE_HEAD,
_ESNT_NODE = _ET_SNAKE_NODE,
_ESNT_END = _ET_SNAKE_END
}E_SNT; // node pos
typedef struct
{
BYTE by_x;
BYTE by_y;
}T_Pos, *PT_Pos; // snake node
typedef struct
{
E_SNT e_type;
T_Pos t_pos;
//BOOL b_valid;
}T_Snake_Node; // direction
typedef enum
{
_UP,
_DOWN,
_LEFT,
_RIGHT
}E_DRCT; // snake
typedef struct
{
DWORD dw_speed;
E_DRCT e_direction;
BYTE by_node_num;
T_Snake_Node at_node[_SNAKE_LENGTH_MAX];
}T_Snake; // food
typedef struct
{
BOOL b_eaten;
T_Pos t_pos;
}T_Food; // key type
typedef enum
{
_E_KT_NONE, _E_KT_UP,
_E_KT_DOWN,
_E_KT_LEFT,
_E_KT_RIGHT, _E_KT_SIZE
}E_KEY_TYPE; // ----------------------------------------------------------------------------
// local para
// ---------------------------------------------------------------------------- // range buffer
E_ET l_ae_area[_AREA_Y_LINE_MAX][_AREA_X_LINE_MAX]; // snake
T_Snake l_t_snake;
BOOL l_b_key_lock = FALSE;
T_Food l_t_food = {.b_eaten = TRUE}; // ----------------------------------------------------------------------------
// function
// ---------------------------------------------------------------------------- // ------------------------------------
// pos jump
// ------------------------------------
void Pos_Jump(int x, int y)
{
COORD pos = {_AREA_X_OFFSET + x, _AREA_Y_OFFSET + y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
} // ------------------------------------
// draw rect element
// ------------------------------------
void Rect_Elem_Draw(E_ET e_et)
{
switch(e_et)
{
case _ET_FOOD:
printf(_FOOD);
break; case _ET_SNAKE_NODE:
printf(_SNAKE_NODE);
break; case _ET_SNAKE_HEAD:
printf(_SNAKE_HEAD);
break; case _ET_SNAKE_END:
printf(_SNAKE_END);
break; case _ET_MAP_EDGE:
printf(_MAP_EDGE);
break; case _ET_MAP_NODE:
default:
printf(_MAP_NODE);
break;
}
}
// ------------------------------------
// draw map
// ------------------------------------
void Area_Refresh( void )
{
BYTE i, j, k; // make Y offset
for(i=0 ; i<_AREA_Y_OFFSET ; i++)
{
printf("\r\n");
} // refresh rect line by line
for(i=0 ; i<_AREA_Y_LINE_MAX ; i++)
{
// make X offset
for(k=0 ; k<_AREA_X_OFFSET ; k++)
{
printf(" ");
} // draw line
for(j=0 ; j<_AREA_X_LINE_MAX ; j++)
{
Rect_Elem_Draw(l_ae_area[i][j]);
}
printf("\r\n");
}
} // ------------------------------------
// snake init
// ------------------------------------
void Snake_Init()
{
l_t_snake.dw_speed = _DEFAULT_SNAKE_SPEED; l_t_snake.e_direction = _RIGHT; l_t_snake.by_node_num = 3; //l_t_snake.at_node[0].b_valid = TRUE;
l_t_snake.at_node[0].e_type = _ESNT_END;
l_t_snake.at_node[0].t_pos.by_x = 2;
l_t_snake.at_node[0].t_pos.by_y = 1; //l_t_snake.at_node[0].b_valid = TRUE;
l_t_snake.at_node[1].e_type = _ESNT_NODE;
l_t_snake.at_node[1].t_pos.by_x = 2;
l_t_snake.at_node[1].t_pos.by_y = 2; //l_t_snake.at_node[0].b_valid = TRUE;
l_t_snake.at_node[2].e_type = _ESNT_HEAD;
l_t_snake.at_node[2].t_pos.by_x = 2;
l_t_snake.at_node[2].t_pos.by_y = 3;
} // ------------------------------------
// area init
// notice: should be called after snake
// init
// ------------------------------------
void Area_Init()
{
BYTE by_i, by_j; // set area default value
for(by_i=0 ; by_i<_AREA_X_LINE_MAX ; by_i++)
{
for(by_j=0 ; by_j<_AREA_Y_LINE_MAX ; by_j++)
{
l_ae_area[by_i][by_j] = _ET_MAP_NODE;
}
} // set area edge value
for(by_i=0 ; by_i<_AREA_X_LINE_MAX ; by_i++)
{
l_ae_area[0][by_i] = _ET_MAP_EDGE;
l_ae_area[_AREA_Y_LINE_MAX - 1][by_i] = _ET_MAP_EDGE;
} for(by_j=0 ; by_j<_AREA_Y_LINE_MAX ; by_j++)
{
l_ae_area[by_j][0] = _ET_MAP_EDGE;
l_ae_area[by_j][_AREA_X_LINE_MAX - 1] = _ET_MAP_EDGE;
}
} void Show_Game_Over()
{
Pos_Jump(_AREA_X_LINE_MAX/4, _AREA_X_LINE_MAX+1);
printf("Game Over!");
Pos_Jump(_AREA_X_LINE_MAX/4, _AREA_X_LINE_MAX+2);
printf("Press Anykey to Exit...");
} BOOL Snake_Is_Dead()
{
T_Pos t_head_pos = l_t_snake.at_node[l_t_snake.by_node_num-1].t_pos;
BYTE i; // touch area ----------------
if( t_head_pos.by_x == 0
|| t_head_pos.by_x >= _AREA_X_LINE_MAX-1
|| t_head_pos.by_y == 0
|| t_head_pos.by_y >= _AREA_Y_LINE_MAX-1)
{
Show_Game_Over();
return TRUE;
} // touch body --------
for(i=0 ; i<l_t_snake.by_node_num-1 ; i++)
{
if( t_head_pos.by_x == l_t_snake.at_node[i].t_pos.by_x
&&t_head_pos.by_y == l_t_snake.at_node[i].t_pos.by_y)
{
return TRUE;
}
} return FALSE;
} // ------------------------------------
// on snake moving
// ------------------------------------
On_Snake_Moving()
{
static DWORD dw_time_cur = 0;
static DWORD dw_time_last = 0;
BYTE by_i = 0;
T_Pos t_end_pos_before_moving;
BYTE by_neck_index, by_head_index; // check speed
dw_time_cur = GetTickCount();
if(dw_time_cur < dw_time_last + l_t_snake.dw_speed)
{
return;
}
l_b_key_lock = FALSE;
dw_time_last = dw_time_cur; // move
by_head_index = l_t_snake.by_node_num - 1;
by_neck_index = l_t_snake.by_node_num - 2; if( l_t_snake.at_node[by_neck_index].t_pos.by_x != l_t_snake.at_node[by_head_index].t_pos.by_x
||l_t_snake.at_node[by_neck_index].t_pos.by_y != l_t_snake.at_node[by_head_index].t_pos.by_y) // last step not eat food
{
t_end_pos_before_moving = l_t_snake.at_node[0].t_pos;
for(by_i=1 ; by_i<l_t_snake.by_node_num ; by_i++)
{
l_t_snake.at_node[by_i - 1].t_pos = l_t_snake.at_node[by_i].t_pos;
} // refresh snake
Pos_Jump(t_end_pos_before_moving.by_x,
t_end_pos_before_moving.by_y);
Rect_Elem_Draw(_ET_MAP_NODE);
} switch(l_t_snake.e_direction)
{
case _UP:
l_t_snake.at_node[by_head_index].t_pos.by_y--;
break; case _DOWN:
l_t_snake.at_node[by_head_index].t_pos.by_y++;
break; case _LEFT:
l_t_snake.at_node[by_head_index].t_pos.by_x--;
break; case _RIGHT:
l_t_snake.at_node[by_head_index].t_pos.by_x++;
break;
} for(by_i=0 ; by_i<l_t_snake.by_node_num ; by_i++)
{
Pos_Jump(l_t_snake.at_node[by_i].t_pos.by_x,
l_t_snake.at_node[by_i].t_pos.by_y);
Rect_Elem_Draw(l_t_snake.at_node[by_i].e_type);
} // eat food
if( l_t_snake.at_node[by_head_index].t_pos.by_x == l_t_food.t_pos.by_x
&&l_t_snake.at_node[by_head_index].t_pos.by_y == l_t_food.t_pos.by_y)
{
l_t_snake.at_node[by_head_index+1] = l_t_snake.at_node[by_head_index];
l_t_snake.at_node[by_head_index].e_type = _ESNT_NODE;
l_t_snake.by_node_num++;
l_t_food.b_eaten = TRUE;
}
} // ------------------------------------
// key detect
// ------------------------------------
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_UP:
e_kt = _E_KT_UP;
break; 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; default:
e_kt = _E_KT_NONE;
break;
} return e_kt;
} // ------------------------------------
// changing snake direction
// ------------------------------------
void On_Changing_Snake_Drctn(E_KEY_TYPE e_kt)
{
switch(e_kt)
{
case _E_KT_UP:
if( (_LEFT == l_t_snake.e_direction)
||(_RIGHT == l_t_snake.e_direction))
{
l_t_snake.e_direction = _UP;
}
break; case _E_KT_DOWN:
if( (_LEFT == l_t_snake.e_direction)
||(_RIGHT == l_t_snake.e_direction))
{
l_t_snake.e_direction = _DOWN;
}
break; case _E_KT_LEFT:
if( (_UP == l_t_snake.e_direction)
||(_DOWN == l_t_snake.e_direction))
{
l_t_snake.e_direction = _LEFT;
}
break; case _E_KT_RIGHT:
if( (_UP == l_t_snake.e_direction)
||(_DOWN == l_t_snake.e_direction))
{
l_t_snake.e_direction = _RIGHT;
}
break;
}
} // ------------------------------------
// On key down
// ------------------------------------
void On_Key_Down()
{
E_KEY_TYPE e_kt; e_kt = Key_Detect(); if(_E_KT_NONE != e_kt)
{
// lock keyboard
l_b_key_lock = TRUE; // changing snake direction
On_Changing_Snake_Drctn(e_kt); // system operation
} } void Refresh_Food()
{
T_Pos t_food_pos;
if(l_t_food.b_eaten)
{
srand(time(0)); t_food_pos.by_x = rand()%(_AREA_X_LINE_MAX-1-1)+1;
t_food_pos.by_y = rand()%(_AREA_Y_LINE_MAX-1-1)+1; l_t_food.t_pos = t_food_pos;
Pos_Jump(l_t_food.t_pos.by_x, l_t_food.t_pos.by_y);
Rect_Elem_Draw(_ET_FOOD); l_t_food.b_eaten = FALSE;
}
} // ------------------------------------
// main
// ------------------------------------
int main()
{
int i_tmp = 0; Area_Init();
Area_Refresh();
Snake_Init(); while(1)
{
On_Key_Down();
On_Snake_Moving();
Refresh_Food();
if(TRUE == Snake_Is_Dead())
{
break;
}
} getch(); return 0;
}
上张截图
console下纯字符实现的贪吃蛇的更多相关文章
- console下纯字符实现的俄罗斯方块
忙里偷闲,消遣一下,先上一张寒酸的效果图: 废话不多说,直接上代码,win7 64 code blocks编译通过. 吐槽一下cb的watch功能实在不够友好,不过免费的也不能要求太高. [按键说明] ...
- 字符界面的贪吃蛇--链表--C++
前天看了下链表,由于平时对链表的使用不多,所以对链表的应用也没什么了解,所以想来想去,就想用链表实现一下贪吃蛇. 下面言归正传,先看效果图,再看代码,其他没有了! 图1: 图2: 代码: #inclu ...
- 贪吃蛇—C—基于easyx图形库(下):从画图程序到贪吃蛇【自带穿墙术】
上节我们用方向控制函数写了个小画图程序,它虽然简单好玩,但我们不应该止步于此.革命尚未成功,同志还需努力. 开始撸代码之前,我们先理清一下思路.和前面画图程序不同,贪吃蛇可以有很多节,可以用一个足够大 ...
- Linux平台下贪吃蛇游戏的运行
1.参考资料说明: 这是一个在Linux系统下实现的简单的贪吃蛇游戏,同学找帮忙,我就直接在Red Hat中调试了一下,参考的是百度文库中"maosuhan"仁兄的文章,结合自己的 ...
- [010]转+修正---C++的贪吃蛇程序(未用面向对象封装)
在网上看到一段贪吃蛇程序,自己心痒下了下来又稍微做了一点修改. 没有用面向对象的方式来进行封装,下次准备试试. 需要在windows环境下进行编译 #include<iostream> # ...
- 程序游戏推荐(C语言贪吃蛇,python天天酷跑(需要安装pygame),js是狠人就坚持30s)
下面是下载位置,我把他们上传到我的文件下了. C语言贪吃蛇:https://files.cnblogs.com/files/ITXiaoAng/%E8%B4%AA%E5%90%83%E8%9B%87. ...
- ege图形库之简单贪吃蛇(c++)
第二次做动画显示效果的小程序,心血来潮想做下儿时的经典游戏----贪吃蛇.由于时间有限,只是简单地做了基本功能,有时间后再完善更多功能. 由于个人水平有限,可能代码有些地方可以改进.不足之处敬请指出. ...
- C字符贪吃蛇
算法参照Perl字符贪吃蛇,源码: #include <stdio.h> #include <windows.h> #define WIDTH 12 // 宽 #define ...
- 超多经典 canvas 实例,动态离子背景、移动炫彩小球、贪吃蛇、坦克大战、是男人就下100层、心形文字等等等
超多经典 canvas 实例 普及:<canvas> 元素用于在网页上绘制图形.这是一个图形容器,您可以控制其每一像素,必须使用脚本来绘制图形. 注意:IE 8 以及更早的版本不支持 &l ...
随机推荐
- Maven 建立web项目 The import javax.servlet cannot be resolved
右击项目,选择Java Build Path->Libraries->Add External JARs,tomcat的路径lib文件夹下选中"servlet-api.jar&q ...
- Threading in C#
http://www.albahari.com/threading/ PART 1: GETTING STARTED Introduction and Concepts C# supports par ...
- EasyUI 验证框使用方法
使用过程中的一积累,备查. EasyUI 验证框使用方法://***************************missingMessage:未填写时显示的信息validType:验证类型见下示例 ...
- (spring-第10回【IoC基础篇】)InstantiationStrategy--实例化Bean的第三大利器
Bean的实例化整个过程如下图: : 其中,BeanDefinition加入到注册表中,并由BeanFactoryPostProcessor的实现类处理后,需要由InstantiationStrate ...
- @synthesize的使用
利用@synthesize可以给在.m文件中给.h文件中的属性重新定义新的名称如 @synthesize firstname = anothername:firstname是在.h文件中定义的,新定义 ...
- Redis - 事物控制和发布订阅
multi命令后续命令将进入队列,不会马上执行,当执行exec后,一次输出所有结果 事物回滚使用discard命令,放弃之前的输入执行. SUBSCRIBE/PUBLISH SUBSCRIBE KEY ...
- Best Sequence_DFS&&KMp
Description The twenty-first century is a biology-technology developing century. One of the most att ...
- 4、SQL基础整理(规范函数)
规范函数: 绝对值 select abs(-5) print abs(-5) 表中取绝对值的方法: select code,name,abs(chinese)as yuwen from xueshen ...
- 解析nginx负载均衡
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://baidutech.blog.51cto.com/4114344/1033718 ...
- Codis 集群搭建
Codis 集群搭建 1 安装go1.3.1 CentOS 7.0 安装go 1.3.1 1.1 下载go安装包 golang中国上下载 下载到Downloads下 1.2 解压 tar -zxf g ...