C从零开始实现贪吃蛇大作战

 

 个人主页:星纭-CSDN博客

系列文章专栏 : C语言

踏上取经路,比抵达灵山更重要!一起努力一起进步!

有关Win32API的知识点在上一篇文章:

目录

一.地图

1.控制台基本介绍

2.宽字符

1.本地化

2.类项

3.setlocale函数

4.打印宽字符 

3.地图坐标

 二.游戏的结构设计

1.基础结构

2.游戏流程(未完成)

3.核心逻辑实现

1.游戏开始

1.控制台设置 

2.欢迎界面 

3.创建地图

 4.初始化蛇

5.创建食物

4.游戏运行

 1.打印信息

2.判断按键 

 3.蛇的移动

5.游戏结束 


一.地图

这个游戏中,我们是通过控制台来完成的。首先就是需要完成这个地图。

1.控制台基本介绍

接下来介绍有关控制台窗口的一些知识点,当运行程序,需要在控制台上输出信息,打印的时候,第一个字符是在控制台最左上角打印的。我们将这个位置的坐标当作(0,0).

横向的坐标轴称为x轴,从左向右依次增长,纵向的坐标轴是y轴,从上到下依次增长。

2.宽字符

 普通的字符是占一个字节的,宽字符是占用两个字节的。

打印字符,不难发现,两个英文字符的宽度是等于一个中文字符的宽度的。 而且一个英文字符的高大概是其宽的两倍。

1.<locale.h>本地化

<locale.h>提供的函数用于控制C标准库中对于不同的地区会产生不一样行为的部分。

在标准中,以来地区的部分有以下几项:

  1. 数字量的格式
  2. 货币量的格式
  3. 字符集
  4. 日期和时间的表示形式

2.类项

通过修改地区,程序可以改变它的⾏为来适应世界的不同区域。但地区的改变可能会影响库的许多部 分,其中⼀部分可能是我们不希望修改的。所以C语⾔⽀持针对不同的类项进⾏修改,下⾯的⼀个宏, 指定⼀个类项:

  1. • LC_COLLATE:影响字符串⽐较函数 strcoll() 和 strxfrm() 。
  2. • LC_CTYPE:影响字符处理函数的⾏为。
  3. • LC_MONETARY:影响货币格式。
  4. • LC_NUMERIC:影响 printf() 的数字格式。
  5. • LC_TIME:影响时间格式 strftime() 和 wcsftime() 。
  6. • LC_ALL-针对所有类项修改,将以上所有类别设置为给定的语⾔环境。

参考:setlocale,_wsetlocale | Microsoft Learn 

3.setlocale函数

char *setlocale(int category,const char *locale
);

这个函数用于修改当前地区,可针对一个类项修改,也可以针对所有类型。

第一个参数是前面说明的类项目中的一个,那么每次都只会影响一个类项,如果第一个参数是LC_ALL就会影响所有的类项。

C标准给第二个参数仅仅定义了两种取值:“C”正常模式和“”本地模式

在任意程序开始执行之前,都会隐藏执行调用:

    setlocale(LC_ALL, "C");

 当地区设置为"C"时,库函数按正常⽅式执⾏,⼩数点是⼀个点。 当程序运⾏起来后想改变地区,就只能显⽰调⽤setlocale函数。⽤""作为第2个参数,调⽤setlocale 函数就可以切换到本地模式,这种模式下程序会适应本地环境。 ⽐如:切换到我们的本地模式后就⽀持宽字符(汉字)的输出等。

setlocale(LC_ALL, " ");//切换到本地环境

4.打印宽字符 

如果想要在屏幕上打印宽字符,那么该如何打印呢?

为了区分宽字符与普通字符,宽字符的字面量前面必须加上前缀 L ,否则C语言会把字面量当作窄字符类型来处理。

同时还需要另一个函数wprintf函数来打印宽字符,用法与printf一样。宽字符的占位符为%lc,宽字符串的占位符为%ls.

	setlocale(LC_ALL, "");wprintf(L"%lc\n", L'□');wprintf(L"%lc\n", L'●');wprintf(L"%lc\n", L'★');

打印一个宽字符选哟占用两个字符的位置,那么我们在贪吃蛇中使用宽字符,就需要处理好地图上坐标的位置的计算。

3.地图坐标

我们假设实现一个三十行六十列的地图,在围绕地图画出墙。

#define WALL L'□'   //墙
#define BODY L'●'   //蛇身
#define FOOD L'★'  //食物

需要打印的东西总共有三个分别是墙,蛇身,食物。为了方便,我们define。

1.蛇身与食物

初始化状态,假设蛇的其实长度是5,蛇的每一个节点都是BODY.并且在一个固定的位置开始生成。

从该图不难发现,蛇与食物的每一个节点的坐标都应该是偶数,不能是技术,否则就就不对其了,而且会出现身体一半在墙体之内,一半在墙体之外的现象。

 二.游戏的结构设计

1.基础结构

在游戏运行过程中,蛇每次吃一个食物,蛇的身体就会变长一节,如果我们使用链表来储存蛇的信息,那么蛇的每一个节点其实就是链表的每一个节点,每一个节点就需要记录好蛇身节点的位置,以及下一个节点的位置。

typedef struct SnakeNode {int x;int y;struct SnakeNode* next;
}SnakeNode,*pSnakeNode;

为了方便管理这个游戏,我们在封装一个Snake的结构来维护整个贪吃蛇。

//蛇的运动方向:上下左右
enum DIRECTION { UP = 1, DOWN, RIGHT, LEFT };
//游戏运行状态:正常运行,撞墙,撞自己,非正常结束。
//非正常结束:比如按Esc退出游戏。
enum GAME_STATUS { OK, KILL_BY_WALL, KILL_BY_SELF, END_NORMAL };typedef struct GreedySnake {pSnakeNode _pSnake;pSnakeNode _pFood;enum DIRECTION _Dir;enum GAME_STATUS _Status;int _Score;int _FoodWeight;int _SleepTime;//可以理解为蛇的运行速度。
}GSnake,*pGSnake;

2.游戏流程(未完成)

3.核心逻辑实现

程序开始就设置程序⽀持本地模式,然后进⼊游戏的主逻辑。 主逻辑分为3个过程:

  1.  • 游戏开始(GameStart)完成游戏的初始化
  2. • 游戏运⾏(GameRun)完成游戏运⾏逻辑的实现
  3.  • 游戏结束(GameEnd)完成游戏结束的说明,实现资源释放

1.游戏开始

 这个模块需要完成游戏的初始化任务。

  1. 控制台的设置
  2. 欢迎界面

1.控制台设置 
	//一.设置控制台以及光标//设置控制台窗口的大小system("mode con cols=100 lines=30");//设置控制台窗口的名字system("title 贪吃蛇");//获得标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定义一个光标信息的结构体CONSOLE_CURSOR_INFO cursor_info = { 0 };//获取和houput句柄相关的控制台上的光标的信息,存放在cursor_info中GetConsoleCursorInfo(houtput, &cursor_info);//修改光标信息cursor_info.bVisible = false;//可见度//设置和houtput句柄相关的控制台上的光标的信息SetConsoleCursorInfo(houtput, &cursor_info);

在这里需要更改控制台窗口的名字,以及将光标不可见。

2.欢迎界面 

1.首先需要完成坐标定位函数,这样方便我们在特定的位置打印信息

void SetPos(int x, int y) {HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x, y };SetConsoleCursorPosition(houtput, pos);}

2.然后就是欢迎界面以及游戏规则的讲解

void WelcomeToGame() {SetPos(36,13);printf("欢迎来到星纭的贪吃蛇小游戏");SetPos(40,25);system("pause");system("cls");SetPos(15,10);printf("游戏规则介绍:");SetPos(24,13);wprintf(L"用 ↑. ↓ . ← . → 来控制蛇的移动,按F3加速,F4减速\n");SetPos(36,16);printf("加速可以获得更更高的分数");SetPos(40,25);system("pause");system("cls");
}

 

3.创建地图

 创建地图就是将地图打印出来,因为是宽字符打印,所以使用wprintf函数进行打印。

void CreateMap() {int i = 0;//上面的墙for (i = 0; i < 60; i += 2) {wprintf(L"%lc",WALL);}//左边的墙for (i = 1; i <= 30; i++) {SetPos(0,i);wprintf(L"%lc", WALL);}//右边的墙for (i = 1; i <= 30; i++) {SetPos(58,i);wprintf(L"%lc", WALL);}//下面的墙for (i = 2; i < 57; i += 2) {SetPos(i,30);wprintf(L"%lc", WALL);}SetPos(0, 33);
}
 4.初始化蛇

蛇最开始⻓度为5节,每节对应链表的⼀个节点,蛇⾝的每⼀个节点都有⾃⼰的坐标。 创建5个节点,然后将每个节点存放在链表中进⾏管理。创建完蛇⾝后,将蛇的每⼀节打印在屏幕上。

  1.  • 蛇的初始位置从(10,5)开始。 再设置当前游戏的状态,蛇移动的速度,默认的⽅向,初始成绩,每个⻝物的分数。
  2. • 游戏状态是:OK
  3. • 蛇的移动速度:200毫秒
  4.  • 蛇的默认⽅向:RIGHT
  5.  • 初始成绩:0
  6. • 每个⻝物的分数:10
void InitSnake(pGSnake ps) {//创建五个蛇节点,并完成头插pSnakeNode cur = NULL;int i = 0;for (i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));cur->next = NULL;cur->x = POS_X - i * 2;cur->y = POS_Y;if (ps->_pSnake == NULL) {ps->_pSnake = cur;}else {cur->next = ps->_pSnake;ps->_pSnake = cur;}}//打印蛇cur = ps->_pSnake;while (cur) {SetPos(cur->x,cur->y);wprintf(L"%lc",BODY);cur = cur->next;}//初始化游戏ps->_SleepTime = 200;ps->_Score = 0;ps->_Dir = RIGHT;ps->_Status = OK;ps->_FoodWeight = 10;
}
5.创建食物
void CreateFood(pGSnake ps) {int x = 0;int y = 0;again:do {x = rand() % 55 + 2;y = rand() % 29 + 1;} while (x % 2 != 0);pSnakeNode cur = ps->_pSnake;while (cur) {if (cur->x == x && cur->y == y) {goto again;}cur = cur->next;}pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));pFood->x = x;pFood->y = y;SetPos(x, y);wprintf(L"%lc",FOOD);ps->_pFood = pFood;
};

4.游戏运行

游戏运行期间,右侧打印帮助信息,提示玩家,坐标开始位置(64,15) 

根据游戏状态检测游戏是否继续,如果状态时OK,游戏继续,其他状态游戏结束。

并且根据游戏的过程中,按键的情况来确定蛇的下一步方向,或者是否加速减速,暂停或者退出游戏。

  1. • 上:VK_UP
  2.  • 下:VK_DOWN
  3. • 左:VK_LEFT
  4. • 右:VK_RIGHT
  5. • 空格:VK_SPACE
  6. • ESC:VK_ESCAPE
  7. • F3:VK_F3
  8. • F4:VK_F4

这是所需的虚拟按键

 1.打印信息
void PrintHelpInfo()
{SetPos(60,10);wprintf(L"用 ↑. ↓ . ← . → 来控制蛇的移动方向");SetPos(70,12);wprintf(L"按F3加速,F4减速");SetPos(66,14);printf("加速可以获得更更高的分数");
}

在控制台窗口中,打印游戏规则以及分数。

2.判断按键 
#define KEY_PRESS(vk) ((GetAsyncKeyState(vk) & 1) ? 1 : 0)
 3.蛇的移动

先创建下⼀个节点,根据移动⽅向和蛇头的坐标,蛇移动到下⼀个位置的坐标。 确定了下⼀个位置后,看下⼀个位置是否是⻝物(NextIsFood),是⻝物就做吃⻝物处理 (EatFood),如果不是⻝物则做前进⼀步的处理(NoFood)。 蛇⾝移动后,判断此次移动是否会造成撞墙(KillByWall)或者撞上⾃⼰蛇⾝(KillBySelf),从⽽影 响游戏的状态。

int NextisFood(pSnakeNode pNextNode, pGSnake ps) {if (ps->_pFood->x == pNextNode->x && ps->_pFood->y == pNextNode->y) {return 1;}return 0;
}
void EatFood(pSnakeNode pNextNode, pGSnake ps) {ps->_pFood->next = ps->_pSnake;ps->_pSnake = ps->_pFood;free(pNextNode);pSnakeNode cur = ps->_pSnake;while (cur) {SetPos(cur->x, cur->y);wprintf(L"%lc", L'●');cur = cur->next;}ps->_Score += ps->_FoodWeight;CreateFood(ps);}
void NoFood(pSnakeNode pNextNode, pGSnake ps) {pNextNode->next = ps->_pSnake;ps->_pSnake = pNextNode;pSnakeNode cur = ps->_pSnake;while (cur->next->next){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}SetPos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;
}void KillByWall(pGSnake ps) {if ((ps->_pSnake->x == 0) ||(ps->_pSnake->x == 58) ||(ps->_pSnake->y == 0) ||(ps->_pSnake->y == 29)) {ps->_Status = KILL_BY_WALL;return 1;}return 0;
}
void KillBySelf(pGSnake ps) {pSnakeNode cur = ps->_pSnake->next;while (cur) {if (cur->x == ps->_pSnake->x && cur->y == ps->_pSnake->y) {ps->_pSnake = KILL_BY_SELF;break;}cur = cur->next;}}
void SnakeMove(pGSnake ps) {pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));switch (ps->_Dir) {case UP:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y - 1;break;case DOWN:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y + 1;break;case LEFT:pNextNode->x = ps->_pSnake->x - 2;pNextNode->y = ps->_pSnake->y;break;case RIGHT:pNextNode->x = ps->_pSnake->x + 2;pNextNode->y = ps->_pSnake->y;break;}if (NextisFood(pNextNode,ps)) {EatFood(pNextNode, ps);}else {NoFood(pNextNode, ps);}KillByWall(ps);KillBySelf(ps);
}

5.游戏结束 

游戏状态不再是OK(游戏继续)的时候,要告知游戏结束的原因,并且释放蛇⾝节点。

void GameEnd(pGSnake ps) {system("cls");SetPos(32, 12);switch (ps->_Status) {case END_NORMAL:printf("游戏已结束。");break;case KILL_BY_WALL:printf("蛇撞墙!游戏结束。");break;case KILL_BY_SELF:printf("蛇撞到自己!游戏结束。");break;}printf("总得分:%d", ps->_Score);//pSnakeNode cur = ps->_pSnake;while (cur) {pSnakeNode del = cur;cur = cur->next;free(del);}SetPos(0, 26);}

三.代码

greedysnake.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<stdbool.h>
#include<locale.h>
#include<time.h>
#define WALL L'□'   //墙
#define BODY L'●'   //蛇
#define FOOD L'★'  //食物typedef struct SnakeNode {int x;int y;struct SnakeNode* next;
}SnakeNode, * pSnakeNode;
//蛇的运动方向:上下左右
enum DIRECTION { UP = 1, DOWN, RIGHT, LEFT };
//游戏运行状态:正常运行,撞墙,撞自己,非正常结束。
//非正常结束:比如按Esc退出游戏。
enum GAME_STATUS { OK, KILL_BY_WALL, KILL_BY_SELF, END_NORMAL };typedef struct GreedySnake {pSnakeNode _pSnake;pSnakeNode _pFood;enum DIRECTION _Dir;enum GAME_STATUS _Status;int _Score;int _FoodWeight;int _SleepTime;//可以理解为蛇的运行速度。
}GSnake,*pGSnake;#define POS_X 10 //起始位置x
#define POS_Y 5  //起始位置y//游戏开始
void GameStart(pGSnake ps);void WelcomeToGame();
void CreateMap();
void InitSnake(pGSnake ps);
void CreateFood(pGSnake ps);//游戏运行
void GameRun(pGSnake ps); void PrintHelpInfo();
#define KEY_PRESS(vk) ((GetAsyncKeyState(vk) & 1) ? 1 : 0)
void SnakeMove(pGSnake ps);
int NextisFood(pSnakeNode pNextNode, pGSnake ps);
void EatFood(pSnakeNode pNextNode, pGSnake ps);
void NoFood(pSnakeNode pNextNode, pGSnake ps);
void KillByWall(pGSnake ps);
void KillBySelf(pGSnake ps);void GameEnd(pGSnake ps);

greedysnake.c

#define _CRT_SECURE_NO_WARNINGS 
#include"greedysnake.h"void SetPos(int x, int y) {HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x, y };SetConsoleCursorPosition(houtput, pos);}
void WelcomeToGame() {SetPos(36, 13);printf("欢迎来到星纭的贪吃蛇小游戏");SetPos(40, 25);system("pause");system("cls");SetPos(15, 10);printf("游戏规则介绍:");SetPos(24, 13);wprintf(L"用 ↑. ↓ . ← . → 来控制蛇的移动,按F3加速,F4减速\n");SetPos(36, 16);printf("加速可以获得更更高的分数");SetPos(40, 25);system("pause");system("cls");
}
void CreateMap() {int i = 0;//上面的墙for (i = 0; i < 60; i += 2) {wprintf(L"%lc", WALL);}//左边的墙for (i = 1; i <= 30; i++) {SetPos(0, i);wprintf(L"%lc", WALL);}//右边的墙for (i = 1; i <= 30; i++) {SetPos(58, i);wprintf(L"%lc", WALL);}//下面的墙for (i = 2; i < 57; i += 2) {SetPos(i, 30);wprintf(L"%lc", WALL);}}
void InitSnake(pGSnake ps) {//创建五个蛇节点,并完成头插pSnakeNode cur = NULL;int i = 0;for (i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;if (ps->_pSnake == NULL) {ps->_pSnake = cur;}else {cur->next = ps->_pSnake;ps->_pSnake = cur;}}//打印蛇cur = ps->_pSnake;while (cur) {SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//初始化游戏ps->_SleepTime = 200;ps->_Score = 0;ps->_Dir = RIGHT;ps->_Status = OK;ps->_FoodWeight = 10;
}
void CreateFood(pGSnake ps) {int x = 0;int y = 0;
again:do {x = rand() % 47 + 6;y = rand() % 25 + 3;} while (x % 2 != 0);pSnakeNode cur = ps->_pSnake;while (cur) {if (cur->x == x && cur->y == y) {goto again;}cur = cur->next;}pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));pFood->x = x;pFood->y = y;SetPos(x, y);wprintf(L"%lc", FOOD);ps->_pFood = pFood;
};void GameStart(pGSnake ps) {//一.设置控制台以及光标//设置控制台窗口的大小system("mode con cols=100 lines=36");//设置控制台窗口的名字system("title 贪吃蛇");//获得标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定义一个光标信息的结构体CONSOLE_CURSOR_INFO cursor_info = { 0 };//获取和houput句柄相关的控制台上的光标的信息,存放在cursor_info中GetConsoleCursorInfo(houtput, &cursor_info);//修改光标信息cursor_info.bVisible = false;//可见度//设置和houtput句柄相关的控制台上的光标的信息SetConsoleCursorInfo(houtput, &cursor_info);//二.打印欢迎界面WelcomeToGame();//三.创建地图CreateMap();//四.初始化蛇InitSnake(ps);//五.随机生成食物CreateFood(ps);};void PrintHelpInfo()
{SetPos(60, 10);wprintf(L"用 ↑. ↓ . ← . → 来控制蛇的移动方向");SetPos(70, 12);wprintf(L"按F3加速,F4减速");SetPos(66, 14);printf("加速可以获得更更高的分数");
}
void pause() {while (1) {Sleep(1);if (KEY_PRESS(VK_SPACE)) {break;}}}
int NextisFood(pSnakeNode pNextNode, pGSnake ps) {if (ps->_pFood->x == pNextNode->x && ps->_pFood->y == pNextNode->y) {return 1;}return 0;
}
void EatFood(pSnakeNode pNextNode, pGSnake ps) {ps->_pFood->next = ps->_pSnake;ps->_pSnake = ps->_pFood;free(pNextNode);pSnakeNode cur = ps->_pSnake;while (cur) {SetPos(cur->x, cur->y);wprintf(L"%lc", L'●');cur = cur->next;}ps->_Score += ps->_FoodWeight;CreateFood(ps);}
void NoFood(pSnakeNode pNextNode, pGSnake ps) {pNextNode->next = ps->_pSnake;ps->_pSnake = pNextNode;pSnakeNode cur = ps->_pSnake;while (cur->next->next){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}SetPos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;
}void KillByWall(pGSnake ps) {if ((ps->_pSnake->x == 0) ||(ps->_pSnake->x == 58) ||(ps->_pSnake->y == 0) ||(ps->_pSnake->y == 29)) {ps->_Status = KILL_BY_WALL;return 1;}return 0;
}
void KillBySelf(pGSnake ps) {pSnakeNode cur = ps->_pSnake->next;while (cur) {if (cur->x == ps->_pSnake->x && cur->y == ps->_pSnake->y) {ps->_Status = KILL_BY_SELF;break;}cur = cur->next;}}
void SnakeMove(pGSnake ps) {pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));switch (ps->_Dir) {case UP:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y - 1;break;case DOWN:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y + 1;break;case LEFT:pNextNode->x = ps->_pSnake->x - 2;pNextNode->y = ps->_pSnake->y;break;case RIGHT:pNextNode->x = ps->_pSnake->x + 2;pNextNode->y = ps->_pSnake->y;break;}if (NextisFood(pNextNode, ps)) {EatFood(pNextNode, ps);}else{NoFood(pNextNode, ps);}KillByWall(ps);KillBySelf(ps);
}
void GameRun(pGSnake ps) {//打印帮助信息PrintHelpInfo();//循环do {SetPos(66, 8);printf("游戏得分:%4d", ps->_Score);printf("食物重量:%4d", ps->_FoodWeight);if (KEY_PRESS(VK_UP) && ps->_Dir != DOWN) {ps->_Dir = UP;}else if (KEY_PRESS(VK_DOWN) && ps->_Dir != UP) {ps->_Dir = DOWN;}else if (KEY_PRESS(VK_LEFT) && ps->_Dir != RIGHT) {ps->_Dir = LEFT;}else if (KEY_PRESS(VK_RIGHT) && ps->_Dir != LEFT) {ps->_Dir = RIGHT;}else if (KEY_PRESS(VK_SPACE)) {pause();}else if (KEY_PRESS(VK_ESCAPE)) {ps->_Status = END_NORMAL;break;}else if (KEY_PRESS(VK_F3)) {if (ps->_SleepTime > 80) {ps->_SleepTime -= 30;ps->_FoodWeight += 2;}}else if (KEY_PRESS(VK_F4)) {if (ps->_SleepTime < 320) {ps->_SleepTime += 30;ps->_FoodWeight -= 2;}}Sleep(ps->_SleepTime);SnakeMove(ps);} while (ps->_Status == OK);}void GameEnd(pGSnake ps) {system("cls");SetPos(32, 12);switch (ps->_Status) {case END_NORMAL:printf("游戏已结束。");break;case KILL_BY_WALL:printf("蛇撞墙!游戏结束。");break;case KILL_BY_SELF:printf("蛇撞到自己!游戏结束。");break;}printf("总得分:%d", ps->_Score);pSnakeNode cur = ps->_pSnake;while (cur) {pSnakeNode del = cur;cur = cur->next;free(del);}SetPos(0, 26);}

源.c

#define _CRT_SECURE_NO_WARNINGS 
#include"greedysnake.h"int main()
{srand((unsigned int)time(NULL));setlocale(LC_ALL, "");GSnake snake = { 0 };//游戏初始化GameStart(&snake);//游戏运行中GameRun(&snake);GameEnd(&snake);SetPos(0, 33);system("pause");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/16061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习】第1章

概论: 机器学习是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析,其基础主要是归纳和统计。 深度学习是一种实现机器学习的技术,是机器学习重要的分支。其源于人工神经网络的研究。深度学习的模型结构是一种含多隐层的神经…

关于C的\r回车在不同平台的问题

首先我们需要搞明白\r和\n是两回事 \r是回车&#xff0c;前者使光标到行首&#xff0c;&#xff08;carriage return&#xff09; \n是换行&#xff0c;后者使光标下移一格&#xff0c;&#xff08;line feed&#xff09; Linux平台下 #include <stdio.h> int main()…

神经网络不确定性综述(Part I)——A survey of uncertainty in deep neural networks

相关链接&#xff1a; 神经网络不确定性综述(Part I)——A survey of uncertainty in deep neural networks-CSDN博客 神经网络不确定性综述(Part II)——Uncertainty estimation_Single deterministic methods-CSDN博客 神经网络不确定性综述(Part III)——Uncertainty est…

Python实现xml解析并输出到Excel上

1.编写xml文件 2.使用Python的ElementTree模块来解析XML import xml.etree.ElementTree as ET from openpyxl import Workbook # 解析XML函数 def parse_xml(xml_file):tree ET.parse(xml_file)root tree.getroot() --打开根节点data []for user in root.findall(Users/Us…

1.手动LogisticRegression模型的训练和预测

通过这个示例&#xff0c;可以了解逻辑回归模型的基本原理和训练过程&#xff0c;同时可以通过修改和优化代码来进一步探索机器学习模型的训练和调优方法。 过程: 生成了一个模拟的二分类数据集&#xff1a;通过随机生成包含两个特征的数据data_x&#xff0c;并基于一定规则生…

秋招突击——算法打卡——5/25、5/26——寻找两个正序数组的中位数

题目描述 自我尝试 首先&#xff0c;就是两个有序的数组进行遍历&#xff0c;遍历到一半即可。然后求出均值&#xff0c;下述是我的代码。但这明显是有问题的&#xff0c;具体错误的代码如下。计算复杂度太高了&#xff0c;O&#xff08;n&#xff09;&#xff0c;所以会超时&…

数据结构--《二叉树》

二叉树 1、什么是二叉树 二叉树(Binar Tree)是n(n>0)个结点的优先集合&#xff0c;该集合或者为空集(称为空二叉树)&#xff0c;或者由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树构成。 这里给张图&#xff0c;能更直观的感受二叉树&#xff1…

GDPU JavaWeb mvc模式

搭建一个mvc框架的小实例。 简易计算器 有一个名为inputNumber.jsp的页面提供一个表单&#xff0c;用户可以通过表单输入两个数和运算符号提交给Servlet控制器&#xff1b;由名为ComputerBean.java生成的JavaBean负责存储运算数、运算符号和运算结果&#xff0c;由名为handleCo…

简单好用的文本识别方法--付费的好用,免费的更有性价比-记笔记

文章目录 先说付费的进入真题&#xff0c;免费的来喏&#xff01;PixPin微信 先说付费的 直达网址!!! 进入真题&#xff0c;免费的来喏&#xff01; PixPin 商店里就有 使用示例&#xff1a; 可以看到&#xff1a;贴在桌面上的图片可以复制图片中的文字&#xff0c;真的很…

Springboot+Vue+ElementUI开发前后端分离的员工管理系统01--系统介绍

项目介绍 springboot_vue_emp是一个基于SpringbootVueElementUI实现的前后端分离的员工管理系统 功能涵盖&#xff1a; 系统管理&#xff1a;用户管理、角色管理、菜单管理、字典管理、部门管理出勤管理&#xff1a;请假管理、考勤统计、工资发放、工资统计、离职申请、个人资…

8.Redis之hash类型

1.hash类型的基本介绍 哈希表[之前学过的所有数据结构中,最最重要的] 1.日常开发中,出场频率非常高. 2.面试中,非常重要的考点, Redis 自身已经是键值对结构了Redis 自身的键值对就是通过 哈希 的方式来组织的 把 key 这一层组织完成之后, 到了 value 这一层~~ value 的其中…

最重要的时间表示,柯桥外贸俄语小班课

в第四格 1、与表示“钟点”的数词词组连用 例&#xff1a; в шесть часов утра 在早上六点 в пять тридцать 在五点半 2、与表示“星期”的名词连用 例&#xff1a; в пятницу 在周五 в следующий понедельник …

String类为什么设计成不可变的?

目录 缓存 安全性 线程安全 hashCode缓存 性能 其实这个问题我们可以通过缓存、安全性、线程安全和性能几个维度去解析。 缓存 字符串是Java最常用的数据结构&#xff0c;我们都知道字符串大量创建是非常耗费资源的&#xff0c;所以Java中就将String设计为带有缓存的功能…

【python】python tkinter 计算器GUI版本(模仿windows计算器 源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

17.分类问题

机器学习分类问题详解与实战 介绍 在机器学习中&#xff0c;分类问题是一类常见的监督学习任务&#xff0c;其目标是根据输入特征将数据样本划分为预先定义的类别之一。分类问题广泛应用于各个领域&#xff0c;如图像识别、自然语言处理、金融风险评估等。本文将详细介绍机器…

Spring Cloud 项目中使用 Swagger

Spring Cloud 项目中使用 Swagger 关于方案的选择 在 Spring Cloud 项目中使用 Swagger 有以下 4 种方式&#xff1a; 方式一 &#xff1a;在网关处引入 Swagger &#xff0c;去聚合各个微服务的 Swagger。未来是访问网关的 Swagger 原生界面。 方式二 &#xff1a;在网关处引…

RedHat9 | DNS剖析-配置辅助DNS服务器

一、实验环境 1、辅助域名DNS服务器 DNS通过划分为若干个区域进行管理&#xff0c;每一个区域由1台或多台DNS服务器负责解析&#xff0c;如果仅仅采用1台DNS服务器&#xff0c;在DNS服务器出现故障后&#xff0c;用户将无法完成解析。 辅助DNS服务器的优点 容灾备份&#x…

区间预测 | Matlab实现DNN-KDE深度神经网络结合核密度估计多置信区间多变量回归区间预测

区间预测 | Matlab实现DNN-KDE深度神经网络结合核密度估计多置信区间多变量回归区间预测 目录 区间预测 | Matlab实现DNN-KDE深度神经网络结合核密度估计多置信区间多变量回归区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现DNN-KDE深度神经网络结合…

MySQL数据处理增删改

数据处理增删改DML 由于约束&#xff0c;以下操作都有可能执行失败&#xff08;后面讲约束&#xff09; 插入数据 INSERT 基础添加&#xff1a;VALUES 值的顺序必须和表中字段顺序相同 INSERT INTO class VALUES(1,王小,10); 向指定字段添加&#xff1a; 值的顺序和指定…

MT7628原厂Uboot修改交互串口

工作中&#xff0c;遇到用户用Skylab的SKW92A模组&#xff0c;在参考设计时&#xff0c;将UART接口预留错的情况&#xff0c;对于这种情况&#xff0c;需要将原厂SDK默认的交互串口UART0&#xff0c;改为UART1。在开发过程中&#xff0c;经常需要在Uboot阶段升级固件&#xff0…