C语言贪吃蛇经典小游戏

一、贪吃蛇小游戏简介:

用上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,也不能咬到自己的身体,等到了一定的分数,就能过关。

二、函数框架

三、数据结构

typedef struct Snake
{
  size_t x; //行
  size_t y; //列
  struct Snake* next;
}Snake, *pSnake;

定义蛇的结构体,利用单链表来表示蛇,每个结点为蛇身体的一部分。

四、代码实现(vs2010  c语言)

1.Snake.h

#ifndef __SNAKE_H__
#define __SNAKE_H__ 

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <time.h>
#include <malloc.h>
#include <assert.h>
//标识地图大小
#define ROW_MAP 10  //地图的行
#define COL_MAP 20  //地图的列
#define SUCCESS_SCORE 10//通关分数
enum Direction //蛇行走的方向
{
  R, //右
  L, //左
  U, //上
  D //下
}Direction; 

enum State
{
  ERROR_SELF, //咬到自己
  ERROR_WALL, //撞到墙
  NORMAL,   //正常状态
  SUCCESS   //通关
}State; 

typedef struct Snake
{
  size_t x; //行
  size_t y; //列
  struct Snake* next;
}Snake, *pSnake; 

void StartGame();
void RunGame();
void EndGame(); 

#endif

2.Snake.c

#include "Snake.h" 

pSnake head = NULL; //定义蛇头指针
pSnake Food = NULL; //定义食物指针 

int sleeptime = 500;//间隔时间,用来控制速度
int Score = 0; //总分
int everyScore = 1; //每步得分 

//定义游戏中用到的符号
const char food = '#';
const char snake = '*'; 

void Pos(int x, int y)  //控制输出光标
{
  COORD pos; //pos为结构体
  pos.X = x; //控制列
  pos.Y = y; //控制行
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);//读取标准输出句柄来控制光标为pos
} 

void Face()
{
  system("color 0C");
  printf("*******************************************************\n");
  printf("*        Welcome to Snake Game!        *\n");
  printf("*                           *\n");
  printf("*       ->开始游戏请按 enter键         *\n");
  printf("*       ->退出游戏请按 esc键          *\n");
  printf("*       ->暂停游戏请按 space键         *\n");
  printf("*       ->通过上下左右键来控制蛇的移动     *\n");
  printf("*       ->通过F1键减速    F2键加速     *\n");
  printf("*******************************************************\n");
}
void Map()  //初始化地图
{
  int i = 0;
  for(i = 0; i<COL_MAP; i+=2)  //打印上下边框(每个■占用两列)
  {
    Pos(i, 0);
    printf("■");
    Pos(i, ROW_MAP-1);
    printf("■");
  }
  for(i = 0; i<ROW_MAP; i++)  //打印左右边框
  {
    Pos(0, i);
    printf("■");
    Pos(COL_MAP-2, i);
    printf("■");
  }
}
void PrintSnake() //打印蛇
{
  pSnake cur = head;
  while(cur)
  {
    Pos(cur->y, cur->x);
    printf("%c", snake);
    cur = cur->next;
  }
}
void InitSnake()  //初始化蛇身
{
  int initNum = 3;
  int i = 0;
  pSnake cur;
  head = (pSnake)malloc(sizeof(Snake));
  head->x = 5;
  head->y = 10;
  head->next = NULL; 

  cur = head;
  for(i = 1; i < initNum; i++)
  {
    pSnake newNode = (pSnake)malloc(sizeof(Snake));
    newNode->x = 5+i;
    newNode->y = 10;
    newNode->next = NULL;
    cur->next = newNode;
    cur = cur->next;
  } 

  PrintSnake();
} 

void CreateFood() //在地图上随机产生一个食物
{
  pSnake cur = head;
  Food = (pSnake)malloc(sizeof(Snake)); 

  //产生x~y的随机数 k=rand()%(Y-X+1)+X;
  srand((unsigned)time(NULL));
  Food->x = rand()%(ROW_MAP-2 - 1 + 1)+1;
  Food->y = rand()%(COL_MAP-3 - 2 + 1)+2;
  Food->next = NULL;
  while(cur)  //检查食物是否与蛇身重合
  {
    if(cur->x == Food->x && cur->y == Food->y)
    {
      free(Food);
      Food = NULL;
      CreateFood();
      return;
    }
    cur = cur->next;
  }
  Pos(Food->y, Food->x);
  printf("%c", food);
} 

void StartGame() //游戏开始的所有设置
{
  Face();
  system("pause"); 

  if(GetAsyncKeyState(VK_RETURN))
  {
    system("cls");
    Pos(COL_MAP+5, 1);
    printf("当前分数/通关分数:");
    Pos(COL_MAP+20, 1);
    printf("%d/%d", Score, SUCCESS_SCORE);
    Pos(COL_MAP+5, 2);
    printf("当前分每步得分:");
    Pos(COL_MAP+20, 2);
    printf("%d", everyScore);
    Pos(COL_MAP+5, 3);
    printf("\n");
    Pos(COL_MAP+5, 4);
    printf("速度越快 得分越高哦!!\n"); 

    Map();
    InitSnake();
    CreateFood();
  }
  else if(GetAsyncKeyState(VK_ESCAPE))
  {
    exit(0);
  }
} 

int IsCrossWall()       //判断是否碰到墙
{
  if(head->x <= 0 || head->x >= ROW_MAP-1
    ||head->y <= 1 || head->y >= COL_MAP-2)
  {
    State = ERROR_WALL;
    return 0;
  }
  return 1;
} 

int IsEatSelf(pSnake newHead) //判断是否咬到自己
{
  pSnake cur = head;
  assert(newHead);
  while(cur)
  {
    if(cur->x == newHead->x && cur->y == newHead->y)
    {
      State = ERROR_SELF;
      return 0;
    }
    cur = cur->next;
  }
  return 1;
} 

int IsFood(pSnake pos) //判断该位置是不是食物
{
  assert(pos);
  if(pos->x == Food->x && pos->y == Food->y)
  {
    return 1;
  }
  return 0;
} 

void SnakeMove()  //蛇移动一次
{
  pSnake newHead = NULL;
  newHead = (pSnake)malloc(sizeof(Snake)); 

  if(Direction == R)
  {
    newHead->x = head->x;
    newHead->y = head->y+1;
    newHead->next = head;
  }
  else if(Direction == L)
  {
    newHead->x = head->x;
    newHead->y = head->y-1;
    newHead->next = head;
  }
  else if(Direction == U)
  {
    newHead->x = head->x-1;
    newHead->y = head->y;
    newHead->next = head; 

  }
  else if(Direction == D)
  {
    newHead->x = head->x+1;
    newHead->y = head->y;
    newHead->next = head;
  } 

  if(IsFood(newHead))
  {
    head = newHead;
    PrintSnake();
    CreateFood();
    Score += everyScore;
    Pos(COL_MAP+20, 1);
    printf("%d/%d", Score, SUCCESS_SCORE);
    if(Score >= SUCCESS_SCORE)
    {
      State = SUCCESS;
    }
  }
  else
    {
      if(IsCrossWall() && IsEatSelf(newHead))
      {
        pSnake cur = NULL;
        head = newHead;
        cur = head;
        //删除蛇尾并打印
        while(cur->next->next != NULL)
        {
          Pos(cur->y, cur->x);
          printf("%c", snake);
          cur = cur->next;
        } 

        Pos(cur->y, cur->x);
        printf("%c", snake);
        Pos(cur->next->y, cur->next->x);
        printf(" "); //打印空格来覆盖频幕上的蛇尾
        free(cur->next);
        cur->next = NULL;
      }
      else
      {
        free(newHead);
        newHead = NULL;
      }
  }
} 

void Pause()
{
  while(1)
  {
    Sleep(sleeptime);
    if(GetAsyncKeyState(VK_SPACE))
    {
      break;
    }
  }
} 

void ControlSnake() //用键盘控制游戏
{
  if(GetAsyncKeyState(VK_UP) && Direction!=D)
  {
    Direction = U;
  }
  else if(GetAsyncKeyState(VK_DOWN) && Direction!=U)
  {
    Direction = D;
  }
  else if(GetAsyncKeyState(VK_LEFT) && Direction!=R)
  {
    Direction = L;
  }
  else if(GetAsyncKeyState(VK_RIGHT) && Direction!=L)
  {
    Direction = R;
  }
  else if(GetAsyncKeyState(VK_F1))
  {
    if(sleeptime != 500)
    {
      sleeptime = 500;
      everyScore = 1;
      Pos(COL_MAP+20, 2);
      printf("%d", everyScore);
    }
  }
  else if(GetAsyncKeyState(VK_F2))
  {
    if(sleeptime != 300)
    {
      sleeptime = 300;
      everyScore = 2;
      Pos(COL_MAP+20, 2);
      printf("%d", everyScore);
    }
  }
  else if(GetAsyncKeyState(VK_SPACE))
  {
    Pause();
  }
  else if(GetAsyncKeyState(VK_ESCAPE))
  {
    exit(0);
  }
} 

void StateGame() //判断游戏失败或成功
{
  if(State == ERROR_SELF)
  {
    system("cls");
    printf("很遗憾,蛇咬到自己,游戏失败!\n");
  }
  else if(State == ERROR_WALL)
  {
    system("cls");
    printf("很遗憾,蛇碰到墙壁,游戏失败!\n");
  }
  else if(State == SUCCESS)
  {
    system("cls");
    printf("恭喜您,已通关!!!\n");
  } 

}
void RunGame()
{
  Direction = R; //蛇初始行走方向为右
  State = NORMAL;//游戏初始为正常状态
  while(1)
  {
    ControlSnake();
    SnakeMove();
    if(State != NORMAL)
    {
      StateGame();
      break;
    }
    Sleep(sleeptime);
  }
} 

void EndGame() //释放链表并恢复默认值
{
  pSnake cur = head;
  while(cur)
  {
    pSnake del = cur;
    cur = cur->next;
    free(del);
    del = NULL;
  }
  head = NULL;
  if(Food != NULL)
  {
    free(Food);
    Food = NULL;
  }
  Score = 0;
  everyScore = 1;
  sleeptime = 500;
}

3.Test.c

#include "Snake.h" 

int main()
{
  while(1)
  {
    StartGame();
    RunGame();
    EndGame();
  }
  system("pause");
  return 0;
}

五、运行界面展示

1.欢迎界面

2.游戏界面

小小的c语言项目,用来练手,仅供参考哦!!
谢谢阅读,如有问题,欢迎提出。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • C语言手把手教你实现贪吃蛇AI(中)
  • 贪吃蛇C语言代码实现(难度可选)
  • C语言手把手教你实现贪吃蛇AI(上)
  • C语言链表实现贪吃蛇游戏
  • C语言结构数组实现贪吃蛇小游戏
  • 基于C语言实现的贪吃蛇游戏完整实例代码
  • C语言手把手教你实现贪吃蛇AI(下)
(0)

相关推荐

  • 基于C语言实现的贪吃蛇游戏完整实例代码

    本文以实例的形式讲述了基于C语言实现的贪吃蛇游戏代码,这是一个比较常见的游戏,代码备有比较详细的注释,对于读者理解有一定的帮助. 贪吃蛇完整实现代码如下: #include <graphics.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #define NULL 0 #define UP 18432 #define DOWN 20480 #define LEFT 19200 #defi

  • C语言手把手教你实现贪吃蛇AI(上)

    本文实例为大家分享了手把手教你实现贪吃蛇AI的具体步骤,供大家参考,具体内容如下 1. 目标 编写一个贪吃蛇AI,也就是自动绕过障碍,去寻找最优路径吃食物. 2. 问题分析 为了达到这一目的,其实很容易,总共只需要两步,第一步抓一条蛇,第二步给蛇装一个脑子.具体来说就是,首先我们需要有一条普通的贪吃蛇,也就是我们常玩儿的,手动控制去吃食物的贪吃蛇:然后给这条蛇加入AI,也就是通过算法控制,告诉蛇怎么最方便的绕开障碍去吃食物.为了讲清楚这个问题,文章将分为三部分:上,写一个贪吃蛇程序:中,算法基础

  • C语言手把手教你实现贪吃蛇AI(下)

    本文实例为大家分享了C语言实现贪吃蛇AI的具体代码,供大家参考,具体内容如下 1. 目标 这一部分的目标是把之前写的贪吃蛇加入AI功能,即自动的去寻找食物并吃掉. 2. 控制策略 为了保证蛇不会走入"死地",所以蛇每前进一步都需要检查,移动到新的位置后,能否找到走到蛇尾的路径,如果可以,才可以走到新的位置:否则在当前的位置寻找走到蛇尾的路径,并按照路径向前走一步,开始循环之前的操作,如下图所示.这个策略可以工作,但是并不高效,也可以尝试其他的控制策略,比如易水寒的贪吃蛇AI 运行效果如

  • C语言手把手教你实现贪吃蛇AI(中)

    手把手教你实现贪吃蛇AI,具体内容如下 1. 目标 这一部分主要是讲解编写贪吃蛇AI所需要用到的算法基础. 2. 问题分析 贪吃蛇AI说白了就是寻找一条从蛇头到食物的一条最短路径,同时这条路径需要避开障碍物,这里仅有的障碍就是蛇身.而A star 算法就是专门针对这一个问题的.在A star 算法中需要用到排序算法,这里采用堆排序(当然其他排序也可以),如果对堆排序不熟悉的朋友,请移步到这里--堆排序,先看看堆排序的内容. 3. A*算法 A star(也称A*)搜寻算法俗称A星算法.这是一种在

  • 贪吃蛇C语言代码实现(难度可选)

    本文实例为大家分享了C语言实现贪吃蛇的具体代码,供大家参考,具体内容如下 /********************************************************* ********************贪吃蛇(难度可选)******************** **************制作者:Xu Lizi 日期:2012/12/31******** ********************部分函数有借鉴************************ ****

  • C语言结构数组实现贪吃蛇小游戏

    一.设计思路 蛇身本质上就是个结构数组,数组里存储了坐标x.y的值,再通过一个循环把它打印出来,蛇的移动则是不断地刷新重新打印.所以撞墙.咬到自己只是数组x.y值的简单比较. 二.用上的知识点 结构数组Windows API函数 三.具体实现 先来实现静态页面,把地图.初始蛇身.食物搞定. 这里需要用到Windows API的知识,也就是对控制台上坐标的修改 //这段代码来自参考1 void Pos(int x, int y) { COORD pos; HANDLE hOutput; pos.X

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

    阅读学习了源代码,并做了简单的注释和修改,里面只用了链表数据结构,非常适合C语言入门者学习阅读. 程序可在VS2013下编译运行. #include<stdio.h> #include<time.h> #include<windows.h> #include<stdlib.h> #define U 1 #define D 2 #define L 3 #define R 4 //蛇的状态,U:上 :D:下:L:左 R:右 typedef struct SNAK

  • C语言贪吃蛇经典小游戏

    一.贪吃蛇小游戏简介: 用上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,也不能咬到自己的身体,等到了一定的分数,就能过关. 二.函数框架 三.数据结构 typedef struct Snake { size_t x; //行 size_t y; //列 struct Snake* next; }Snake, *pSnake; 定义蛇的结构体,利用单链表来表示蛇,每个结点为蛇身体的一部分. 四.代码实现(vs2010  c

  • 基于javascript实现贪吃蛇经典小游戏

    本文实例为大家分享了JS实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta htt

  • js编写“贪吃蛇”的小游戏

    贪吃蛇儿时的回忆,今天刚好学习到这了,就刚好做了一个,也是学习了吧,需要掌握的知识: 1.JS函数的熟练掌握, 2.JS数组的应用, 3.JS小部分AJAX的学习 4.JS中的splice.shift等一些函数的应用, 基本上就这些吧,下面提重点部分: 前端的页面,这里可自行布局,我这边提供一个我自己的布局: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org

  • js编写贪吃蛇的小游戏

    贪吃蛇儿时的回忆,今天刚好学习到这了,就刚好做了一个,也是学习了吧,需要掌握的知识: 1.JS函数的熟练掌握, 2.JS数组的应用, 3.JS小部分AJAX的学习 4.JS中的splice.shift等一些函数的应用, 基本上就这些吧,下面提重点部分: 前端的页面,这里可自行布局,我这边提供一个我自己的布局: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org

  • javascript实现贪吃蛇经典游戏

    js面向对象编程之贪吃蛇,供大家参考,具体内容如下 首先:面向对象编程,我们要找到项目中具体的对象,此处为(食物(food),蛇(snake),游戏本身(game))也可不把游戏本身作为对象,逻辑体现出来即可. 接着分析每个对象的具体的属性及方法: 1)food 对象:属性有:位置,大小,颜色:方法有:渲染在页面,随机不同位置生成: 2)snake对象:属性有:位置,大小,总节数(计分方便),颜色:方法有:渲染在页面,移动(移动过程中判断其它). 3)game对象:游戏逻辑的编写: ok 开敲:

  • js贪吃蛇网页版游戏特效代码分享(挑战十关)

    js贪吃蛇网页版游戏特效,经测试图片切换过程非常酷,相信大家一定都玩过这个经典小游戏吧,但是它是怎么实现的呐,感兴趣的朋友快来学习学习吧 运行效果图:----------------------查看效果----------------------- 小提示:浏览器中如果不能正常运行,可以尝试切换浏览模式. 为大家分享的js贪吃蛇网页版游戏特效代码如下 <body><title>js贪吃蛇网页版游戏特效</title></body> <script>

  • Python实现四个经典小游戏合集

    目录  一.效果展示 1.俄罗斯方块 2.扫雷 3.五子棋 4.贪吃蛇 二.代码展示 1.俄罗斯方块 2.扫雷 3.五子棋 4.贪吃蛇  一.效果展示 1.俄罗斯方块 这个应该是玩起来最最简单的了- 2.扫雷 运气好,点了四下都没踩雷哈哈- 3.五子棋 我是菜鸡,玩不赢电脑人- 4.贪吃蛇 害,这个是最惊心动魄的,为了我的小心脏,不玩了不玩了- 女朋友:你就是借机在玩游戏,逮到了 啊这- 那我不吹牛逼了,我们来敲代码吧~ 二.代码展示 1.俄罗斯方块 方块部分 这部分代码单独保存py文件,这里我

  • C语言简单实现扫雷小游戏

    本文实例为大家分享了C语言简单实现扫雷小游戏 的具体代码,供大家参考,具体内容如下 游戏规则: 以9*9棋盘为例,棋盘上随机分布着10个地雷,玩家在棋盘上进行点击,如果被点击的格子是地雷,则玩家被炸"死",游戏结束:如果被点击的格子上没有地雷,与被点击的格子相邻的格子(被点击格子的上下左右还有斜向,共八个格子)有地雷,则在被点击的格子上显示这些地雷的总数,如果与被点击的格子相邻的八个格子都没有地雷,则棋盘自动展开,直到与展开的格子相邻的格子有地雷才停止.此时最后被展开的格子显示其相邻格

  • C语言实现控制台扫雷小游戏

    C语言实现控制台"扫雷"小游戏 根据以往的游戏经验,我们能首先可以确定扫雷游戏胜利的规则是:翻开所有不是雷的区域才能算是胜利. 接下来我们需要确定整个程序的设计思路: 1.首先,我们定义两个9*9的二维数还是未翻开的状态组.第一个数组用来表示雷区地图的展开情况,即每个素组元素的位置的状态是处于展开状态还是未展开状态,我们命名为showMap().第二个数组我们用来表示地雷的分布情况,素组中的每个元素位置都被标记为是否为地雷,我们命名为minMap(). 2.初始化两个地图,并将地图打印

  • C语言实现数字炸弹小游戏

    本文实例为大家分享了C语言实现数字炸弹小游戏的具体代码,供大家参考,具体内容如下 使用的是C语言 # 内容 #include<stdio.h> #include<stdlib.h> int main(){ //变量 char c_TheRequest = 1;//开始界面的字符 int in_Deltar = 1,in_EnteredNumber,in_Sig;//游戏中输入数字及其判定所需要的数字 int in_GivenNum = 0,in_An = 0,in_Bn = 0;/

随机推荐