C语言学习笔记(7)——C总结与贪吃蛇小游戏实现

C语言学习笔记(7)——C总结与图形化贪吃蛇小游戏实现

知识点总结:

内存管理:

​ 最小单位:bit

​ 最小管理单位:byte

main函数开始,一条一条语句从上往下执行

进制转换:数据本身就是数,不同进制只是表现形式不同

数据类型:int char float double unsigned signed short long

​ 数据占内存段大小 数据存储方式

运算符,表达式,标示符,返回值,值,左值,右值,左操作数,右操作数

流程控制语句:

​ 条件判断: if else switch case

​ 跳转:goto

​ 循环: for while dowhile continue break return

函数: 形参 实参 函数声明 函数定义 函数调用 返回值

指针:值传递 地址传递

​ 地址:首地址 指针 指针变量 解引用* 指针变量的数学运算

数组:定义 访问(下标)

​ const:常量指针 指针常量

字符串:字符串字面量 字符串指针 字符数组

二维数组,二级指针

动态内存分配

动态数组

队列&栈

结构:结构和结构体 结构体的对齐补齐 typedef

链表

联合&枚举 大小端系统 bool类型

文件操作

预处理

贪吃蛇小游戏:

需求分析:

//贪吃蛇
1.蛇(动态数组,链表)
    选择用链表
    	1.吃食物是插入插足,显示蛇是遍历操作。链表插入效率高,数组查找效率高
    	2.数组是连续内存段,如果蛇比较长,开辟内存失败风险高
2.食物
    变量	数组
3.map地图
    二维数组描述;空白:墙:蛇:食物
4.控制
    整体:
    while1{
    打印地图
    接收用户输入
    按照用户输入去改变
}
// 图形界面程序.cpp : 定义控制台应用程序的入口点。
//编译环境:Visual studio 2015
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<windows.h>
#include<conio.h>		//调用 _getch函数
#include<graphics.h>	//需安装easyx,百度搜索即可

//MAP
#define	ROW 20
#define COL 40
#define Space 20	//宏定义格式大小

enum map {//空白,墙,蛇,食物
	space, wall, snake, food
};

IMAGE jpgs[4];

enum direction {//蛇移动方向,上0,下1,左5,右6
	up, down, left = 5, right
};
int g_snake_dir = right;//默认移动方向
						//初始化地图
int* pMap = NULL;
void InitMap();
void Initsnake();
//点类型
typedef struct MyPoint
{
	int row;
	int col;
}Point;

//用链表来描述蛇
typedef struct SnakeNode {
	Point pos;
	struct SnakeNode* next;
}snakeNode;

snakeNode* list = NULL;

//头插法插入结点到蛇链表中
void InsertNode(int row, int col);

//初始化游戏
void InitGame();
//显示游戏
void ShowGame();
//控制游戏
void ctolGame();
//判断某个点是不是蛇,食物,空白,墙
enum map isWhat(int row, int col);
//食物
Point Food[5] = { 0 };
//排除掉墙壁,蛇,食物后的数组
Point* pBuff = NULL;
int index = 0;
//初始化用作排除的函数
//void InitBuff();
//初始化食物
void InitFood();
//更新地图
void UpdateMap();
//蛇移动
void snake_move(int row, int col);
//蛇是否存活
bool isAlive = true;//全局变量
//图形界面蛇
void DrawGame();

int main()
{
	InitGame();

	while (isAlive) {
		ShowGame();
		DrawGame();
		ctolGame();//有操作跟操作,无操作自动
	}
	system("cls");
	printf("人生自古谁无死,少侠请重新来过!\n");

	while (1);
	return 0;
}

//图形界面蛇
void DrawGame() {
	//system("cls");
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {
			putimage(j*Space, i*Space, &jpgs[*(pMap + (i*COL) + j)]);
		}
		//printf("\n");
	}
}

//头插法插入结点到蛇链表中
void InsertNode(int row, int col) {
	snakeNode* pNew = (snakeNode*)malloc(sizeof(snakeNode));
	pNew->pos.row = row;
	pNew->pos.col = col;
	pNew->next = list;
	list = pNew;
	/*if(list){
	pNew -> next = list;
	list = pNew;
	}
	else{
	pNew -> next = list;
	list = pNew;
	}*/
}

//初始化地图
void InitMap() {
	pMap = (int*)malloc(sizeof(int)*ROW*COL);
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {
			//判断这个点是不是蛇
			*(pMap + i*COL + j) = isWhat(i, j);
		}
		//printf("\n");
	}
}
//初始化游戏
void InitGame() {
	//0 初始化图形界面
	//0.1 创建窗口
	initgraph(COL * Space, ROW * Space, SHOWCONSOLE);
	//0.2加载图片
	//加载空白,墙,蛇,食物
	loadimage(&jpgs[0], L"space.jpg", Space, Space, true);
	loadimage(&jpgs[1], L"wall.jpg", Space, Space, true);
	loadimage(&jpgs[2], L"snake.jpg", Space, Space, true);
	loadimage(&jpgs[3], L"food.jpg", Space, Space, true);
	//1.初始化蛇
	Initsnake();
	//2.初始化食物
	//2.1初始化buff
	pBuff = (Point*)malloc(sizeof(Point)*ROW*COL - 2 * ROW - 2 * (COL - 2) - 3);//开辟食物空间
	InitFood();
	/*
	for (int i = 0; i<ROW; i++) {
	for (int j = 0;j<COL; j++) {
	if (isWhat(i, j) == space) {
	pBuff[index].row = i;
	pBuff[index].col = j;
	index++;
	}
	}
	}
	//2.2初始化food
	int sui_ji = rand()%index;
	Food[0].row = pBuff[sui_ji].row;
	Food[0].col = pBuff[sui_ji].col;
	//Food[0].row = pBuff[30].row;
	//Food[0].col = pBuff[30].col;*/
	//3.初始化地图
	InitMap();
}
//初始化蛇
//插入三个结点到链表中:分别是(2,2)(2,3)(2,4)->头
void Initsnake() {
	for (int i = 0; i<3; i++) {
		InsertNode(2, 2 + i);
	}
}

//显示游戏
void ShowGame() {
	system("cls");
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {
			switch (*(pMap + (i*COL) + j)) {
			case wall:printf("#"); break;
			case snake:printf("*"); break;
			case food:printf("@"); break;
			case space:printf(" "); break;
			}
		}
		printf("\n");
	}
}

//控制游戏
void ctolGame() {
	char n;
	int snakeDir = g_snake_dir;
	//scanf_s("%c", &n);
	if (_kbhit()) {
		n = _getch();
		switch (n) {
		case 'w':snakeDir = up; break;
		case 'a':snakeDir = left; break;
		case 's':snakeDir = down; break;
		case 'd':snakeDir = right; break;
		}
	}
	Sleep(300);
	if ((snakeDir + g_snake_dir) % 10 == 1) {//用户自杀
		isAlive = false;
		return;
	}
	int row;
	int col;
	switch (g_snake_dir = snakeDir) {
	case up: row = (list->pos.row) - 1; col = (list->pos.col); break;
	case left: row = (list->pos.row); col = (list->pos.col) - 1; break;
	case down: row = (list->pos.row) + 1; col = (list->pos.col); break;
	case right: row = (list->pos.row); col = (list->pos.col) + 1; break;
	}
	switch (isWhat(row, col)) {
	case food:
		InsertNode(Food[0].row, Food[0].col);
		InitFood();
		snake_move(row, col); break;
	case wall:
	case snake:
		isAlive = false; return;
	case space:
		snake_move(row, col); break;
	}
	/*g_snake_dir = snakeDir;
	snake_move(g_snake_dir);//蛇移动
	//如果碰到了食物,刷新地图
	if (list->pos.row == Food[0].row && list->pos.col == Food[0].col) {
	InsertNode(Food[0].row, Food[0].col);
	InitFood();}*/
	UpdateMap();//更新地图
}

//判断某个点是不是蛇,食物,空白,墙
enum map isWhat(int row, int col) {
	if (row == 0 || col == 0 || row == (ROW - 1) || col == (COL - 1))
		return wall;
	//检查是否是蛇
	snakeNode* temp = list;
	while (temp) {
		if (temp->pos.row == row && temp->pos.col == col) return snake;
		temp = temp->next;
	}
	//检查是否是食物
	for (int i = 0; i < 5; i++) {
		if (Food[i].row == row && Food[i].col == col)
			return food;
	}
	return space;
}
//初始化食物
void InitFood() {
	//获取当前空白格子数目
	index = 0;
	for (int i = 0; i<ROW; i++) {
		for (int j = 0; j<COL; j++) {
			if (isWhat(i, j) == space) {
				pBuff[index].row = i;
				pBuff[index].col = j;
				index++;
			}
		}
	}
	//2.2初始化food
	int sui_ji = rand() % index;
	Food[0].row = pBuff[sui_ji].row;
	Food[0].col = pBuff[sui_ji].col;
}
//更新地图
void UpdateMap() {
	pMap = (int*)malloc(sizeof(int)*ROW*COL);
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {
			//判断这个点是不是蛇
			*(pMap + i*COL + j) = isWhat(i, j);
		}
	}
}

//蛇移动
void snake_move(int row, int col) {
	//1.去尾
	snakeNode* pTemp = list;
	//1.1找到倒数第二个节点
	while (pTemp->next->next != NULL)
		pTemp = pTemp->next;
	//1.2释放最后一个节点内存
	free(pTemp->next);
	//1.3倒数第二个结点next指向NULL
	pTemp->next = NULL;
	/*//2.加头(更新到控制函数中)
	int row;
	int col;
	switch (dir) {
	case up: row = (list->pos.row) - 1; col = (list->pos.col); break;
	case left: row = (list->pos.row); col = (list->pos.col) - 1; break;
	case down: row = (list->pos.row) + 1; col = (list->pos.col); break;
	case right: row = (list->pos.row); col = (list->pos.col) + 1; break;
	}*/
	InsertNode(row, col);
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言实训心得总结.doc C语言实训心得 10903090113 李新程 在初学C语言的一个学期后,我们进行了C语言实训阶段,尝试编写一个比较复杂的程序系统。在为期两周的时间中,我们同组的同学共同的感受是:C语言实训和平时上课所接触的程序是有很大不同的,所经受的考验和克服的困难是平时所无法比拟的。好在同组的搭档们精诚合作,分工明确,有问题共同解决,攻克了C语言实训的复杂程序。在这里,我作为其中的参与者,感触良多。 在这次实训中,我对对C语言有了一个更深的了解认识,也对这个学期学的知识得到巩固,还尝试运行编程,每次运行程序成功,让我对下面的项目就充满信心。通过自己与同学合作编写程序,最终把最初的理论知识转化基本技能。这次的实训,使我对C语言学习产生浓厚的兴趣。 还是这次实训,最令人激动的就是合作做项目,虽然那只是一个很小很小的项目。每天大家来得很早,大家在一起学习,取长补短,我们很好的在实训中长知识,提高我们的学习热情。实训中深切体会到了老师认真负责的伟大的精神和热情为同学指导的促学方式,虽然对有些时候老师没给我们指出解决问题的方法有些小抱怨,但是到了结束时才知道,这种教学让我们自己学会了自学,学会了去看懂别人的代码。更多是老师给的感动,每天在我们来之前就到了教室,在讲课中海给我们分享他在公司上班的一些心得和体会,还有那些我们应该注意的事项,这些是平时上课时无法学到的,是更深层次的巨大收获。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值