C语言游戏之贪吃蛇--链表实现

早自习时突然想到怎么写贪吃蛇,话不多说,代码如下:


开发环境:vs2015


虽然开始还是出了很多指针问题。。。(很烦C语言指针)调试了很久也大概是可以畅快的玩了。

C语言新手,有很多写得不好的地方望大神提出


当然,我也不介意把我代码拿去学习(这样就说明我的代码有学习价值偷笑


头文件:snake.h

/**
*By Liu Yuchuan
*2017.3.30
*/

#ifndef SNAKE_H_INCLUDED
#define SNAKE_H_INCLUDED
#include<stdio.h>

//游戏中各种符号
#define CHOOSE_LOGO "->"
#define SNAKE_NODE '*'
#define WALL '#'
#define FOOD '$'

//地图大小
#define mapWidth 50
#define mapHeight 25

//蛇状态
#define LIVE 1
#define DEAD 0

//移动方向
enum Direction{UP, DOWN, RIGHT, LEFT};
typedef enum Direction Direction;

struct Node;
typedef struct Node  Node;
typedef Node* SnakeHead;
typedef Node* PtrToNode;

//蛇的链表节点
struct Node{
	int x;
	int y;
	PtrToNode next;
};


//蛇的结构体
typedef struct Snake{
	SnakeHead snakeHead;
	int lenth;
	int state;
	Direction dir;
} *Snake;

//食物的结构体
typedef struct Food {
	int x;
	int y;
	int isEat;
} *Food;

//移动键
char key_down = 's';
char key_up = 'w';
char key_right = 'd';
char key_left = 'a';

//移动间隔时间
int moveTime = 100;

//得分
int score = 0;

Food food = NULL;
Snake snake = NULL;

void menu();
void pos(int x, int y);
void startGame();
void initMap();
Snake initSnake(Snake snake);
void printSnake(Snake snake);
void clearSnake(Snake snake);
void move(Snake snake);
Snake getLonger(Snake snake);
void createFood();
int isLocationOK(int x, int y);

#endif // SNAKE_H_INCLUDED


源码:Snake.c

#include"Snake.h"
#include<windows.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>

int main(){
	menu:menu();
	system("cls");
	startGame();
	goto menu;
}

void menu(){
	pos(18, 2);
	printf("欢迎来到贪吃蛇!");

	//打印菜单
	pos(18, 6);
	printf("%s", CHOOSE_LOGO);
	printf("开始游戏");
	pos(20, 10);
	printf("退出游戏");

	//控制菜单
	int option = 0;
	char ch = 1;

	//键入回车退出循环
	while(1){
		ch = _getch();

		//下移
		if(ch == key_down){
			if(option == 0){
				pos(18, 6+option);
				printf("  ");
				option += 4;
				pos(18, 6+option);
				printf("%s", CHOOSE_LOGO);
			}
		}

		//上移
		else if(ch == key_up){
			if(option == 4){
				pos(18, 6+option);
				printf("  ");
				option -= 4;
				pos(18, 6+option);
				printf("%s", CHOOSE_LOGO);
			}
		}

		else if(ch == 13){
			switch(option){
				case 0:
					return;
				case 4:
					exit(0);
			}
		}
	}
}

//定位光标
void pos(int x, int y){
	COORD position;
	position.X = x;
	position.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);
}

void startGame(){
	char ch = 1;
	score = 0;
	snake = initSnake(snake);
	initMap();
	food = (Food)malloc(sizeof(struct Food));
	food->x = 0;
	food->y = 0;
	food->isEat = 1;
	printSnake(snake);
	while (snake->state){
		createFood(food);
		//监听键盘输入
		if (_kbhit()) {
			ch = _getch();
			if (snake->dir != UP && ch == key_down) {
				snake->dir = DOWN;
			}
			else if (snake->dir != DOWN && ch == key_up) {
				snake->dir = UP;
			}
			else if (snake->dir != LEFT && ch == key_right) {
				snake->dir = RIGHT;
			}
			else if (snake->dir != RIGHT && ch == key_left) {
				snake->dir = LEFT;
			}
		}

		move(snake);
	}

	pos(mapWidth + 2, mapHeight / 2 - 1);
	printf("                                       ");
	pos(mapWidth + 2, mapHeight / 2);
	printf("                                       ");
	pos(mapWidth + 2, mapHeight / 2 + 1);
	printf("                                       ");
	pos(mapWidth + 2, mapHeight / 2 + 2);
	printf("                                       ");
	pos(mapWidth + 2, mapHeight / 2 - 1);
	printf("游戏结束");
	pos(mapWidth + 2, mapHeight / 2);
	printf("最终长度: %d", snake->lenth);
	pos(mapWidth + 2, mapHeight / 2 + 1);
	printf("您的得分: %d", score);
	pos(mapWidth + 2, mapHeight / 2 + 2);
	printf("Enter键返回主菜单");

	while(ch != 13)
		ch = _getch();
	system("cls");
}

void initMap(){
	for(int i = 0; i < mapWidth; i++){
		for(int j = 0; j < mapHeight; j++){
			if(i == 0 || j == 0 || i == mapWidth - 1 || j == mapHeight - 1){
				pos(i, j);
				printf("%c", WALL);
			}
		}
	}

	pos(mapWidth + 2, mapHeight/2 - 1);
	printf("当前长度(越长吃一次食物得分越高哦):");
	pos(mapWidth + 2, mapHeight/2);
	printf("%d", snake->lenth);
	pos(mapWidth + 2, mapHeight / 2 + 1);
	printf("当前得分:");
	pos(mapWidth + 2, mapHeight / 2+2);
	printf("%d", score);
}

Snake initSnake(Snake snake){
	snake = (Snake)malloc(sizeof(struct Snake));
	snake->snakeHead = (SnakeHead)malloc(sizeof(Node));
	SnakeHead snakeHead = snake->snakeHead;
	snakeHead->x = 4;
	snakeHead->y = 3;
	snakeHead->next = (PtrToNode)malloc(sizeof(Node));
	snakeHead->next->x = 4;
	snakeHead->next->y = 2;
	snakeHead->next->next = (PtrToNode)malloc(sizeof(Node));
	snakeHead->next->next->x = 4;
	snakeHead->next->next->y = 1;
	snakeHead->next->next->next = NULL;
	snake->lenth = 3;
	snake->dir = DOWN;
	snake->state = LIVE;
	return snake;
}

void printSnake(Snake snake) {
	PtrToNode position = snake->snakeHead;
	while (position) {
		pos(position->x, position->y);
		printf("%c", SNAKE_NODE);
		position = position->next;
	}
}

void clearSnake(Snake snake){
	PtrToNode position = snake->snakeHead;
	while (position) {
		pos(position->x, position->y);
		printf(" ");
		position = position->next;
	}
}

void move(Snake snake) {

	//判断是否会撞墙
	if ((snake->snakeHead->x == mapWidth - 2 && snake->dir == RIGHT)
		|| snake->snakeHead->x == 1 && snake->dir == LEFT
		|| snake->snakeHead->y == 1 && snake->dir == UP
		|| snake->snakeHead->y == mapHeight - 2 && snake->dir == DOWN) {
		snake->state = DEAD;
		return;
	}

	clearSnake(snake);
	SnakeHead head = snake->snakeHead;
	int x = head->x;
	int y = head->y;
	int tmpX, tmpY;
	switch (snake->dir) {
	case UP:
		head->y--;
		break;
	case DOWN:
		head->y++;
		break;
	case LEFT:
		head->x--;
		break;
	case RIGHT:
		head->x++;
		break;
	default:
		break;
	}

	while (head->next) {
		tmpX = head->next->x;
		tmpY = head->next->y;
		head->next->x = x;
		head->next->y = y;
		x = tmpX;
		y = tmpY;
		head = head->next;

		//判断是否咬到自己
		if (head->x == snake->snakeHead->x
			&& head->y == snake->snakeHead->y)
			snake->state = DEAD;
	}

	if (snake->snakeHead->x == food->x
		&& snake->snakeHead->y == food->y && snake->state) {
		score += snake->lenth / 10 + 1;
		food->isEat = 1;
		pos(food->x, food->y);
		printf(" ");
		snake = getLonger(snake);
		pos(mapWidth + 2, mapHeight / 2 + 2);
		printf("%d", score);
		pos(mapWidth + 2, mapHeight / 2 );
		printf("%d", snake->lenth);
	}

	printSnake(snake);
	Sleep(moveTime);
}

Snake getLonger(Snake snake){
	PtrToNode position = snake->snakeHead;
	while (position->next->next) {
		position = position->next;
	}
	int x1 = position->x;
	int y1 = position->y;
	position = position->next;
	int x2 = position->x;
	int y2 = position->y;
	position->next = (PtrToNode)malloc(sizeof(Node));
	position->next->next = NULL;
	if (x1 == x2) {
		position->next->x = x1;
		position->next->y = y2 + y2 - y1;
	}
	else{
		position->next->y = y1;
		position->next->x = x2 + x2 - x1;
	}

	snake->lenth++;

	return snake;
}

//生成食物
void createFood(){
	if (food->isEat) {

		//获取系统时间作为产生随机数的种子
		srand((unsigned)time(0));
		while (1) {
			food->x = rand() % (mapWidth - 2) + 1;
			food->y = rand() % (mapHeight - 2) + 1;
			if (isLocationOK(food->x, food->y)) {
				pos(food->x, food->y);
				printf("%c", FOOD);
				food->isEat = 0;
				break;
			}
		}
	}
}

//判断位置是否合理
int isLocationOK(int x, int y){
	PtrToNode position = snake->snakeHead;

	while (position) {
		if (x == position->x && y == position->y) {
			position = position->next;
			return 0;
		}
	}

	return x > 0 && x < mapWidth - 1
		&& y > 0 && y < mapHeight - 1;
}


  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值