5_23_贪吃蛇(成功)

修复上一篇中的bug

1.蛇的尾巴删除后,更新地图

2.设计链表使得蛇链接起来,从而在尾部释放并更新最后一个节点

function.h

#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<Windows.h>
#include<conio.h>
#include<iostream>
#include<map>
#include<string>
using namespace std;
#define WIDTH 80
#define HEIGHT 25//地图的宽和高
#define SPEED 100

typedef enum {
	WALL,
	EMPTY,
	SNAKE_BODY,
	FOOD
}Mapelement;//定义一个枚举类型Mapelement

typedef struct {
public:
	Mapelement **elements;
}Map;//Map的结构体成员是一个Mapelement数组

typedef struct Snake{
	int x, y;//记录蛇的位置
	int flag;//记录蛇是否死亡
	struct Snake* next;//记录蛇的节点
	int len;//记录得分
	char way;//记录蛇的移动方向
}Snake;

void initmap(Map*& map);//初始化地图

void mapdisplay(Map*& map);//地图打印函数

void drawFood(Map*& map);//生成食物

void initSnake(Snake*& head,Snake*& tail); //初始化蛇身

void updateSnake(Map*& map,Snake*& head,Snake*& tail); //更新绘制地图上的蛇

void ctrlSnake(Snake*& head);//控制蛇移动

function.cpp

#include"function.h"

void initmap(Map*& map)
{
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++)
        {
            if (i == 0 || j == 0 || i == HEIGHT - 1 || j == WIDTH - 1)
            {
                map->elements[i][j] = WALL;

            }
            else
            {
                map->elements[i][j] = EMPTY;
            }
        }
    }
    map->elements[1][1] = SNAKE_BODY;
    map->elements[1][2] = SNAKE_BODY;
}

void mapdisplay(Map*& map)
{
    system("cls");
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            switch (map->elements[i][j]) {
            case EMPTY:
                printf(" ");
                break;
            case SNAKE_BODY:
                printf("*");
                break;
            case FOOD:
                printf("#");
                break;
            case WALL:
                printf("+");
            }
        }
        printf("\n");
    }
}

void drawFood(Map*& map)
{
    int res = 1;
    srand((unsigned)time(NULL));
    
    while (res)
    {
        int x, y;
        x = rand() % (HEIGHT - 3) + 1;
        y = rand() % (WIDTH - 3) + 1;
        if (map->elements[x][y] != SNAKE_BODY)
        {
            map->elements[x][y] = FOOD;
            res = 0;
        }
    }
    
}

void initSnake(Snake*& head,Snake*& tail)
{
    head->x = 1;
    head->y = 2;
    tail->flag = head->flag = 1;
    head->way = 'd';
    tail->next = head;


    tail->len = head->len = 2;
    head->next = NULL;
    tail->x = 1;
    tail->y = 1;
    tail->way = 'd';
}

void updateSnake(Map*& map, Snake*& head, Snake*& tail)
{
    Snake* snake = (Snake*)malloc(sizeof(Snake));
    switch (head->way) {
    case 'a':
        snake->y = head->y - 1;
        snake->x = head->x;
        break;
    case 'd':
        snake->y = head->y + 1;
        snake->x = head->x;
        break;
    case 's':
        snake->y = head->y;
        snake->x = head->x + 1;
        break;
    case'w':
        snake->y = head->y;
        snake->x = head->x - 1;
        break;
    }
    snake->way = head->way;
    snake->len = head->len;
    head->next = snake;
    head = snake;
    head->next = NULL;
    if (head->y >= WIDTH || head->x >= HEIGHT || head->x <= 0 || head->y <= 0)
    {
        head->flag = 0;
        return;
    }
    if (map->elements[head->x][head->y] == WALL || map->elements[head->x][head->y] == SNAKE_BODY)
    {
        head->flag = 0;
        return;
    }
    if (map->elements[head->x][head->y] == FOOD)
    {
        map->elements[head->x][head->y] = SNAKE_BODY;
        head->len++;
        drawFood(map);
    }
    else {
        map->elements[head->x][head->y] = SNAKE_BODY;
        map->elements[tail->x][tail->y] = EMPTY;
        Snake* a = tail;
        tail = tail->next;
        free(a);
    }
}

void ctrlSnake(Snake*& head)
{
    char key = 0;
    if (_kbhit())
    {
        key = _getch();
    }
    switch (key) {
    case 'a':
        if (head->way == 'd')
        {
            break;
        }
        head->way = 'a';
        break;
    case 'd':
        if (head->way == 'a')
        {
            break;
        }
        head->way = 'd';
        break;
    case 's':
        if (head->way == 'w')
        {
            break;
        }
        head->way = 's';
        break;
    case'w':
        if (head->way == 's')
        {
            break;
        }
        head->way = 'w';
        break;
    }
}


main.cpp

#include"function.h"

int main()
{
	printf("欢迎来到贪吃蛇小游戏,请输入用户名\n");
	string users;
	cin >> users;
	map<int, string>bangdan;
	bangdan.insert(pair<int, string>(1000, "wanglingxiao"));
	printf("请输入1开始游戏\n");
	int res;
	scanf_s("%d", &res);
	if (res != 1) { return 0; }
	while (1)
	{
		Snake* head = (Snake*)malloc(sizeof(Snake));
		Snake* tail = (Snake*)malloc(sizeof(Snake));
		Map* map = (Map*)malloc(sizeof(Map));
		map->elements = (Mapelement**)malloc(HEIGHT * sizeof(Mapelement*));
		if (map->elements == NULL) {
			// 内存分配失败的处理
			free(map); // 释放先前分配的内存
			return 1;
		}
		for (int i = 0; i < HEIGHT; i++) {
			map->elements[i] = (Mapelement*)malloc(WIDTH * sizeof(Mapelement));
			if (map->elements[i] == NULL) {
				// 内存分配失败的处理
				// 释放先前分配的内存
				for (int j = 0; j < i; j++) {
					free(map->elements[j]);
				}
				free(map);
				return 1;
			}
		}
		initSnake(head, tail);
		initmap(map);
		drawFood(map);
		while (head->flag)
		{
			mapdisplay(map);
			Sleep(SPEED);
			ctrlSnake(head);
			updateSnake(map, head, tail);
		}

		// 现在 a->elements 可以正常使用了
		
		// 释放内存
		for (int i = 0; i < HEIGHT; i++) {
			free(map->elements[i]);
		}
		free(map);

		system("cls");
		std::cout << "本次得分:" << head->len - 2 << std::endl;
		bangdan.insert(pair<int, string>(head->len - 2, users));
		cout << "按a查看得分榜:" << endl;
		char a;
		cin >> a;
		if (a == 'a')
		{
			for (const auto& pair : bangdan) {
				std::cout << "姓名: " << pair.second << "得分: " << pair.first << std::endl;
			}
		}
		Sleep(3000);
		char yes;
		printf("还想继续玩吗?,输入y或者n\n");
		std::cin >> yes;
		if (yes == 'n')break;
	}
	return 0;
}
posted @ 2023-05-24 01:16  aallofitisst  阅读(38)  评论(0)    收藏  举报