用200行C语言代码写出一个贪吃蛇——1.0(基本版)

  • Post author:
  • Post category:其他


1.设计思路


总的来说,贪吃蛇这个小游戏涉及到的东西不多,但是对逻辑思维是比较吃基本功的。


贪吃蛇,

显示给我们看的有三部分:蛇、食物、地图边界



我们可以用一个二维数组来标记这些部分:




例如这里我创建了一个 5*10 的二维数组,

其中 -1 表食物, 1 表蛇头,2、3、4、5表蛇身,0表示空地。



如果我们想要蛇移动起来,只需要将 蛇尾置0 ,其余部分+1 就行了。



另外需要说明的是,我们使用 a s d w 来控制方向,这四个方向对应的整数分别是:3、2、1、0。

2.具体流程


3.源文件(主函数)main.c

#include "head.h"
int main()
{
	int map[SIZE][SIZE] = { 0 };//定义二维数组
	int len = 0;//定义长度
	int state = 0;//定义游戏状态
	int direc = 0;//定义方向
	Init_map(map, &len, &direc);//初始化地图
	while (1)
	{
		direc = get_direc(direc);//键盘读入方向
		state = move(map, direc, &len);//蛇的移动,在函数内部判断蛇头状态并返回值
		if (state == 0)//返回0表游戏结束
			break;
		else//继续游戏
			print(map);//打印
		Sleep(100);
	}
	return 0;
}

4.头文件head.h

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <math.h>

#define SIZE 19

void Init_map(int map[SIZE][SIZE], int* len, int* direc);
int get_direc(int direc);
int move(int map[SIZE][SIZE], int direc, int* len);
void print(int map[SIZE][SIZE]);

5.源文件(函数内部)func.c

void Init_map(int map[SIZE][SIZE], int* len, int* direc)
{
	*len = 3;//初始化长度
	*direc = 2;//初始化方向

	map[5][5] = -1;//初始化食物
	
	//初始化蛇身
	map[3][3] = 3;
	map[4][3] = 2;

	map[5][3] = 1;//初始化蛇头
}

int get_direc(int direc)
{
	int tmp = -1;//定义一个用来接收键盘值的变量
	
	if (_kbhit())//如果键盘被敲击,kbhit()返回一个非0值
	{
		switch (_getch())//从键盘读入
		{
		case 'W':case 'w':tmp = 0; break;
		case 'D':case 'd':tmp = 1; break;
		case 'S':case 's':tmp = 2; break;
		case 'A':case 'a':tmp = 3; break;
		}
		//读入的键盘只能是 w、d、s、a,并且蛇不能掉头
		if (tmp != -1 && abs(direc - tmp) != 2)//abs函数是求绝对值
			direc = tmp;
	}
	return direc;
}

int move(int map[SIZE][SIZE], int direc, int* len)
{
	int i = 0;
	int j = 0;

	//定义蛇头位置
	int head_x = 0;
	int head_y = 0;

	//循环遍历数组
	for (i = 0; i < SIZE; i++)
	{
		for (j = 0; j < SIZE; j++)
		{
			if (map[i][j] == *len)//如果是蛇尾
				map[i][j] = 0;

			if (map[i][j] > 1)//如果是蛇身
				map[i][j] += 1;

			if (map[i][j] == 1)//如果是蛇头
			{
				map[i][j] += 1;

				//此时蛇头+1了,已经没有蛇头了,现在就要找到一个新的蛇头
				// 
				//找到原蛇头的原位置
				head_x = i;
				head_y = j;

				//找到蛇头移动后的位置
				switch (direc)
				{
				case 0:head_x = i - 1; head_y = j; break;
				case 1:head_x = i; head_y = j + 1; break;
				case 2:head_x = i + 1; head_y = j; break;
				case 3:head_x = i; head_y = j - 1; break;
				}
			}
		}
	}

	if (map[head_x][head_y] == -1)//如过蛇头位置是食物
	{
		*len = *len + 1;//吃掉食物,长度+1
		map[head_x][head_y] = 1;//吃掉食物,食物变成蛇头

		//重新生成食物
		while (1)
		{
			i = rand() % SIZE;
			j = rand() % SIZE;
			if (map[i][j] == 0)
			{
				map[i][j] = -1;
				break;
			}
		}
	}
	//如果蛇头碰到自己或墙
	else if (map[head_x][head_y] > 0 || head_x < 0 || head_x == SIZE || head_y < 0 || head_y == SIZE)
		return 0;//返回0
	else
		map[head_x][head_y] = 1;//没碰到食物、墙壁、自己

	return 1;//没碰到食物、墙壁、自己

}

void print(int map[SIZE][SIZE])
{
	//打印边框、食物、蛇用的符号根据自己的喜好来,是自由不受限制的
	system("cls");
	int i = 0;
	int j = 0;

	//打印上边框
	for (i = 0; i <= SIZE; i++)
	{
		if (i == 0)
			printf("┏");
		else if (i == SIZE)
			printf(" ┓");
		else
			printf(" ━");

	}
	printf("\n");

	//打印左、右边框,打印蛇头、蛇身、食物
	for (i = 0; i < SIZE; i++)
	{
		for (j = 0; j < SIZE; j++)
		{
			if (j == 0)
				printf("┃ ");
			else if (map[i][j] == -1)
				printf("★");
			else if (map[i][j] > 0)
				printf("○");
			else if (map[i][j] == 1)
				printf("●");
			else
				printf("  ");
			if (j == SIZE - 1)
				printf("┃");
		}
		printf("\n");
	}

	//打印下边框
	for (i = 0; i <= SIZE; i++)
	{
		if (i == 0)
			printf("┗");
		else if (i == SIZE)
			printf(" ┛");
		else
			printf(" ━");
	}
	printf("\n");
}

6.结束语


可以看到,我们除去无用的换行、注释部分,

真正的代码不到200行

。这只是一个有基本功能的贪吃蛇小游戏。希望大家在这个版本的基础上添加一些花里胡哨的功能。


最后附上游戏效果截图。



版权声明:本文为weixin_59913110原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。