贪吃蛇小试牛刀
感谢CSDN和CSDN里的大佬的分享
网上自学写的第一个小游戏。
#define _CRT_SECURE_NO_WARNINGS 1
#include<windows.h>
#include<time.h>//gettimeofday(struct timeval*tv,struct timezone*tz)
#include<stdio.h>
#include<stdlib.h>//rand(),srand()
#include<conio.h>
#define ROW 29
#define COL 89
//全局定义c_time结构类型
typedef struct S_time
{
long long unsigned s;
long long unsigned ms;
char* week;
int year;
}c_time;
//自定义函数P_times在windows环境下获取当前时间并以c_time型返回
c_time P_times()
{
c_time h_time = { 0,0,0,0 };
int a[10] = { 0 }, b[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
//DWORD P_time2;
SYSTEMTIME time;
GetLocalTime(&time);
a[0] = (int)time.wYear; //年
a[1] = (int)time.wMonth; //月
a[2] = (int)time.wDay; //日
a[3] = (int)time.wHour; //小时
a[4] = (int)time.wMinute; //分钟
a[5] = (int)time.wSecond; //秒
a[6] = (int)time.wMilliseconds; //毫秒
a[7] = (int)time.wDayOfWeek; //周
a[8] = 365;
//a[8]本年度的总天数
//a[9]本年度已过时间(天)
//方法一:
if (a[0] % 4 == 0 && a[0] % 100 != 0 || a[0] % 400 == 0)
{
b[2] = 29; a[8] = 366;
}
else
{
a[8] = 0;
}
//方法二:
/*if (a[0] == 0)
printf("公元元年\n");
else if (a[0] % 4 == 0 && a[0] % 100 != 0 || a[0] % 400 == 0)
b[2] = 29, a[8] = 366;
else
b[2] = 28, a[8] = 365;*/
for (int i = 0; i < a[1]; i++)
{
b[0] = a[2];
a[9] = a[9] + b[i];
}
h_time.s = (long long unsigned)a[9] * 86400 + (long long unsigned)a[3] * 60 * 60 + (long long unsigned)a[4] * 60 + (long long unsigned)a[5];//已过时间(秒)
h_time.ms = h_time.s * 1000 + a[6];
if (a[7] == 0)
h_time.week = "星期天";
else if (a[7] == 1)
h_time.week = "星期一";
else if (a[7] == 2)
h_time.week = "星期二";
else if (a[7] == 3)
h_time.week = "星期三";
else if (a[7] == 4)
h_time.week = "星期四";
else if (a[7] == 5)
h_time.week = "星期五";
else if (a[7] == 6)
h_time.week = "星期六";
else h_time.week = "错误";
h_time.year = a[0];
return h_time;
}
//liunx环境下自定义获取系统时间
/*void p_selftime(long long* t)
{ long long p1;
struct timespec timestamp;
clock_gettime(CLOCK_REALTIME, ×tamp);
//获取当前时间,timestamp.tv_sec秒或 timestamp.tv_nsec纳秒
struct timeval tv;
struct timezone tz;
gettimeofday(&tv,&tz);
//tv.tv_sec;获取秒,tv.tv_usec;微秒数,
*t=timestamp.tv_nsec;//获取纳秒
}*/
//void p_start_time(long * t)
//{
// int t;
// SYSTEMTIME P_NOW;
// GetLocalTime(&P_NOW);
// t=(int)P_NOW.wYear
// clock_t c_begin=clock();
//
// *t = (long);//获取纳秒
//}
void modeset()
{
system("mode con cols=90 lines=30");//设置控制台大小,cols为控制台的宽度,lines 则代表控制台的高度
SetWindowLongPtrA(GetConsoleWindow(),GWL_STYLE,GetWindowLongPtrA(GetConsoleWindow(),GWL_STYLE)& ~WS_SIZEBOX & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
//HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
/*COORD size = {100, 20};
SetConsoleScreenBufferSize(hOut,size);
SMALL_RECT rc = {0, 0, 89, 19};
SetConsoleWindowInfo(hOut ,TRUE ,&rc);
//CloseHandle(hOut); //关闭标准输出设备句柄
return; */
}
void P_coord(short x, short y)
{
COORD coord = {x, y};//结构体
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
//称动光标位置
CONSOLE_CURSOR_INFO cci= {1, 0}; // 结构体,第一个值是光标厚度,第二个值为0表示隐藏光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
//隐藏光标
}
void p_colce(int a) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
//任意两数之间的随机数
int p_random(int a,int b)
{
int p2;
if(a<b){p2=a;a=b;b=p2;}//ab换位
return rand()%(a-b+1)+b;//a-b之间随机数
}
int main()
{
modeset();
int a = 77, b = 0, i = 0, m = 5;
//a:方向键键码,b:交换标示符,i:循环标示符,m:体长 ,n:总分
int Xsnake[1350] = { 48,46,44,42,40,0 }, Ysnake[1350] = { 12,12,12,12,12,0 }, e[2] = { 0,0 };
//Xsnake,Ysnake蛇身横纵坐标;e[]坐标计算临时标示符
c_time t;
int food[2] = { 0 };
t=P_times();//获取时间
i = t.ms%10000000;
srand(i);//以系统时间毫秒的8位数做rand的种子
for (i = 0; i < COL; i++)
{
p_colce(7);
b = i % 2;
if (i < ROW && i>1) {
P_coord(0, i);
printf("■");
P_coord(COL - 1, i);
printf("■");
}
i += b;
P_coord(i, 2);
printf("■");
P_coord(i, ROW);
printf("■");
i -= b;
b = 0;
}
p_colce(10);
food[0] = p_random(COL-3, 2);
food[1] = p_random(ROW-1, 3);
food[0] += food[0] % 2;
P_coord(food[0], food[1]);
printf("●");
p_colce(11);
for (i = 0; i < m; i++)
{
if (i ==0) {
P_coord(Xsnake[i], Ysnake[i]);
printf("■");
}
P_coord(Xsnake[i], Ysnake[i]);
printf("□");
}
while (1)
{
P_coord(0, 0);
printf("分数:%d",m-5);
b = a;
if (_kbhit())
{
//a = _getch();
if (a = _getch())
{
a = _getch();
}
}
if (b ==80&& a ==72 || b ==72 && a ==80 || b ==75 && a ==77 || b ==77 && a ==75 || a !=80 && a !=75 && a !=77 && a !=72)
{
a = b;
}
/*while (a == 40 || a ==38 || a ==37 || a ==39) {*/
//dwon 下扫描码80 ASLL码40
//up 上扫描码72 ASLL码38
//left 左扫描码75 ASLL码37
//right 右扫描码77 ASLL码39
if (a ==80)
{
e[0] = Xsnake[0] + 0;
e[1] = Ysnake[0] + 1;//坐标计算规则
if (e[1] > ROW-1)
{
e[1] = 3;
}//穿墙规则
}//dwon下
if (a ==72)
{
e[0] = Xsnake[0] + 0;
e[1] = Ysnake[0] - 1;//坐标计算规则
if (e[1] < 3)
{
e[1] = ROW-1;
}
}//up上
if (a == 75)
{
e[0] = Xsnake[0] - 2;
e[1] = Ysnake[0] + 0;
if (e[0] < 2)
{
e[0] = COL-3;
}
}//Left左
if (a == 77)
{
e[0] = Xsnake[0] + 2;
e[1] = Ysnake[0] - 0;
if (e[0] > COL -3)
{
e[0] = 2;
}
}//Right右
//向指定方向移动时默认向右移动
for (i = m; i >= 0; i--)
{
Xsnake[i] = Xsnake[i - 1];
Ysnake[i] = Ysnake[i - 1];
if (i == 0)
{
Xsnake[0] = e[0]; Ysnake[0] = e[1];
}
}//计算身体点的坐标
if (Xsnake[0] == food[0] && Ysnake[0] == food[1])
{
p_colce(10);
int c = 0;
m += 1;
i = 0;
do
{
food[0] = p_random(COL - 3, 1);
food[1] = p_random(ROW - 1, 3);
food[0] += food[0] % 2;
while (i < m)
{
if (food[0] == Xsnake[i] && food[1] == Ysnake[i])
{
i = m+1 ;
}
i++;
}
} while (i>m);
P_coord(food[0], food[1]);
printf("●");
}//吃子
else
{
P_coord(Xsnake[m], Ysnake[m]);
printf(" ");
P_coord(Xsnake[m] + 1, Ysnake[m]);
printf(" ");
}//未吃子消除尾子
p_colce(11);
P_coord(Xsnake[1], Ysnake[1]);
printf(" ");
P_coord(Xsnake[1], Ysnake[1]);
printf("□");//消除上一次蛇头改成身体
P_coord(Xsnake[0], Ysnake[0]);
printf("■");
//打印蛇头
for (i = 1; i < m; i++)
{
if (Xsnake[i] == Xsnake[0] && Ysnake[i] == Ysnake[0])
{
b = 0;
}
if (b == 0)break;
}
if (b== 0)break;
//撞身体结束
Sleep(200);
}
system("cls");
P_coord(45,12);
printf("game over\n");
P_coord(45, 13);
printf("总分%d\n", m-5);
P_coord(45, 14);
printf("重新开始请按:1\n");
Sleep(1000);
scanf("%d", &i);
if (i == 1)
{
system("cls");
main();
}
else
{
return 0;
}
}
运行结果