C++控制台循环链表实现贪吃蛇

本文实例为大家分享了C++控制台循环链表实现贪吃蛇的具体代码,供大家参考,具体内容如下

-stdafx.h 为了简化程序定义一些宏和全局变量

#ifndef __STDAFX_H__
#define __STDAFX_H__

// ============上下左右=============
const int UP = 72;
const int DOWN = 80;
const int LEFT = 75;
const int RIGHT = 77;

// ==============宽高===============
#define HEIGHT 20
#define WIDTH 39

// ==============输出===============
#define cout_food std::cout<<"*"
#define cout_snake std::cout<<"■"
#define cout_space std::cout << " "
#define cout_snake_xy(x,y) SnakeUI::gotoXY(x,y);cout_snake
#define cout_food_xy(x,y) SnakeUI::gotoXY(x,y);cout_food
#define cout_space_xy(x,y) SnakeUI::gotoXY(x,y);cout_space

// =============结束?==============
#define OVER false
#define RUN true

#endif

-SnakeUI.h

主要是初始化UI,初始化蛇,还有生产食物,判断食物和蛇有没有相撞,还有对界面的一些操作

#ifndef __SNAKE_UI_H__
#define __SNAKE_UI_H__

#include <iostream>
#include <Windows.h>
#include "Snake.h"

struct Food {
 int x;
 int y;
};

class SnakeUI {
public:
 static void initUI();
 static void initSnake();
 static void gotoXY(int x, int y);

 static void productFood(Snake& snake);
 static bool meetWithFood(int x, int y);

private:
 static Food food;

};

#endif

-SnakeUI.cpp

#include "stdafx.h"
#include "SnakeUI.h"
#include <ctime>
using namespace std;

Food SnakeUI::food = { 0, 0 };

// init UI
void SnakeUI::initUI() {
 cout << "┏";
 for (int i = 1; i < WIDTH; ++i) cout << "━";
 cout << "┓";
 gotoXY(0, HEIGHT);
 cout << "┗";
 for (int i = 1; i < WIDTH; ++i) cout << "━";
 cout << "┛";
 for (int y = 1; y < HEIGHT; ++y) {
 gotoXY(0, y); cout << "┃";
 gotoXY(WIDTH, y); cout << "┃";
 }
}

// init snake: three points
void SnakeUI::initSnake() {
 gotoXY(2, 10); cout_snake;
 gotoXY(3, 10); cout_snake;
 gotoXY(4, 10); cout_snake;
}

// goto point(x, y) in console
void SnakeUI::gotoXY(int x, int y) {
 COORD coord = { x * 2, y };
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

// random product food
void SnakeUI::productFood(Snake& snake) {
 srand((unsigned)time(NULL));
 int x, y; // x from 1 to 38, y from 1 to 19
 bool productOK;
 for (;;) {
 productOK = true;
 x = rand() % 38 + 1;
 y = rand() % 19 + 1;
 // 不和蛇身碰撞1->检查身体和尾部
 for (SnakeNode* sn = snake.last; sn != snake.first; sn = sn->prev) {
  if (sn->x == x && sn->y == y) {
  productOK = false;
  break;
  }
 }
 // 不和蛇身碰撞2->检查头部
 if (x == snake.first->x && y == snake.first->y)
  productOK = false;

 if (productOK)
  break;
 }
 food.x = x;
 food.y = y;
 cout_food_xy(food.x, food.y);
}

// is snake's head meet with food?
bool SnakeUI::meetWithFood(int x, int y) {
 return (food.x == x && food.y == y);
}

-Snake.h
蛇类,蛇的移动和状态

#ifndef __SNAKE_H__
#define __SNAKE_H__

struct SnakeNode {
 int x;
 int y;
 SnakeNode* prev;
 SnakeNode(int x_t, int y_t){ x = x_t; y = y_t; }
 SnakeNode(){}
};

class Snake {
 friend class SnakeUI;

public:
 Snake();
 ~Snake();
 bool snakeMove(char& dir);

private:
 void getKey(char& dir);

private:
 SnakeNode* first;
 SnakeNode* last;
 char state;
};

#endif

-Snake.cpp

#include "stdafx.h"
#include "Snake.h"
#include "SnakeUI.h"

Snake::Snake() {
 // 状态:向右
 state = RIGHT;
 // 创建循环链表
 first = new SnakeNode(4, 10);
 last = new SnakeNode(2, 10);
 last->prev = new SnakeNode(3, 10);
 last->prev->prev = first;
 first->prev = last;
 // UI
 SnakeUI::initSnake();
 SnakeUI::productFood(*this);
}

Snake::~Snake() {
 SnakeNode* tmp = last;
 while (last != last) {
 last = last->prev;
 delete tmp;
 tmp = last;
 }
 delete last;
}

bool Snake::snakeMove(char& dir) {
 int x = first->x;
 int y = first->y;
 getKey(dir);
 // 撞墙->Game Over
 switch (state)
 {
 case UP: --y; if (y == 0) return OVER; break;
 case DOWN: ++y; if (y == HEIGHT) return OVER; break;
 case LEFT: --x; if (x == 0) return OVER; break;
 case RIGHT: ++x; if (x == WIDTH) return OVER; break;
 }

 // 撞到了自己
 SnakeNode* tmp = last;
 for (; tmp != first; tmp = tmp->prev) {
 if (first->x == tmp->x && first->y == tmp->y)
  return OVER;
 }

 // 吃食物
 if (SnakeUI::meetWithFood(x, y)) {
 SnakeNode* newHead = new SnakeNode(x, y);
 first->prev = newHead;
 newHead->prev = last;
 first = newHead;
 cout_snake_xy(x, y);
 SnakeUI::productFood(*this);
 }
 else {
 cout_space_xy(last->x, last->y);
 last->x = x;
 last->y = y;
 first = last;
 last = last->prev;
 cout_snake_xy(x, y);
 }

 return RUN;
}

void Snake::getKey(char& dir) {
 switch (dir)
 {
 case UP: if (state == LEFT || state == RIGHT) state = UP; return;
 case DOWN: if (state == LEFT || state == RIGHT) state = DOWN; return;
 case LEFT: if (state == UP || state == DOWN) state = LEFT; return;
 case RIGHT: if (state == UP || state == DOWN) state = RIGHT; return;
 }
}

-main.cpp

#include "stdafx.h"
#include "SnakeUI.h"
#include "Snake.h"
#include <iostream>
#include <conio.h>
using namespace std;

DWORD WINAPI ThreadProc1(LPVOID lpParameter);

char dir = RIGHT;

int main()
{
 SnakeUI::initUI();
 Snake snake;

 CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
 while (snake.snakeMove(dir)) Sleep(100);

 system("pause");
 return 0;
}

DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
 for (;;) {
 dir = _getch();
 }
 return 1;

}

关于C++小游戏的更多精彩内容请点击专题: 《C++经典小游戏》 学习了解

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

(0)

相关推荐

  • C++ vector容器实现贪吃蛇小游戏

    本文实例为大家分享了C++ vector容器 实现贪吃蛇,供大家参考,具体内容如下 使用vector容器实现贪吃蛇简化了很多繁琐操作,且相比之前我的代码已经做到了尽量的简洁 技术环节: 编译环境:windows VS2019 需求: 控制贪吃蛇吃食物,吃到一个食物蛇身变长一节,得分增加,撞墙或撞自己则游戏结束. 思路: 创建一个vector容器,容器内存储蛇的每节身体的结构变量,结构变量中保存蛇身体的xy坐标,通过使用vector成员方法不断添加和删除容器中的数据,实现蛇坐标的规律移动,吃到食物

  • C/C++实现贪吃蛇逐步运动效果

    本文实例为大家分享了C/C++实现贪吃蛇逐步运动效果的代码,供大家参考,具体内容如下 主要使用结构数组和结构指针,再用easyx图形库进行的绘图,以供讨论和学习 #include <conio.h> //建立储存蛇身的结构体 struct snack { int x; int y; }; //决定方向 int fangxiang=3;//w=0,s=1,a=2,d=3 // 按键变量 char anjian=0; //调整坐标关系 int tiaozheng(struct snack *a);

  • C++基于控制台实现的贪吃蛇小游戏

    本文实例讲述了C++基于控制台实现的贪吃蛇小游戏.分享给大家供大家参考.具体实现方法如下: #include <windows.h> #include <time.h> #include <stdio.h> #define MAX 100 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define MOVING 5 #define STOP 0 HANDLE hMain_Out = NULL; H

  • C++通过类实现控制台贪吃蛇

    本文实例为大家分享了C++实现控制台贪吃蛇的具体代码,供大家参考,具体内容如下 初学c++,算刚学完类吧,写个贪吃蛇来玩玩. 现是头文件 #pragma once #ifndef SNACK_H #define SNACK_H #define Frame_X 5//边框起点横坐标 #define Frame_Y 5//边框起点纵坐标 #define Frame_width 50//边框长度 #define Frame_height 25//边框高度 struct point//蛇个点坐标 { i

  • C++控制台实现贪吃蛇游戏

    本文实例为大家分享了C++实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 刚学完了C语言,便尝试的写了贪吃蛇的代码,但是效果不佳,很多的bug,所以,这个学了C++,便重新的写了这个小游戏,用类来封装! 先是头文件: struct Snake { int x, y; }; class snake { public: snake() //构造函数 { length = 3; s[2].x = 10; s[2].y = 10; s[1].x = 9; s[1].y = 10; s[0].x =

  • C++实现简单贪吃蛇游戏

    我大概在一个多月前把自己上学期写的c代码的贪吃蛇游戏push到csdn上,并且说c风格的贪吃蛇写起来有些麻烦(贪吃蛇游戏的c语言实现),准备用面向对象的c++再写一遍.现在我们专业恰好刚教完了c++,学校也布置了一道简单的贪吃蛇的编程题目,实现下来,的确觉得c++的思路清晰很多,所以再次把c++的代码push上来,供大家对比参考:) 直接上代码,c++把整个游戏拆分成几个文件,分开上,有一定的c++基础的同学应该可以很容易看懂. 1.全局头文件(global.hpp) #ifndef _GLOB

  • 贪吃蛇游戏C++命令行版实例代码

    本文实例讲述了贪吃蛇游戏C++命令行版的实现代码,是非常经典的游戏.分享给大家供大家参考.具体实现方法如下: 众所周知,贪吃蛇游戏是经典的计算机游戏. 游戏描述如下: 1. 贪吃蛇可以自动直线前进,或者玩家可以通过方向键操纵贪吃蛇上下左右前进,每次前进一格. 2. 贪吃蛇在规定的区域内活动,当: ①贪吃蛇触碰到墙壁时: ②贪吃蛇的蛇头触碰到蛇身或者蛇尾时: ③玩家的键盘输入不是方向键时: 命令行显示"Game Over!"并且退出游戏. 3. 贪吃蛇活动的区域内每次随机产生一颗&quo

  • 利用C/C++实现较完整贪吃蛇游戏

    记得在大一时刚学习c/c++语言,学到一半突然想用这门语言做一些小游戏出来,首先想到的便是贪吃蛇.于是本人利用空余时间写出了这么一个简单的小游戏. 由于当时的我还没有能力构造出用户界面,故直接使用dos界面运行.那么问题来了,如何让一个字符在dos界面上自由移动???对于这个问题我采用的解决方案是实现gotoxy函数来控制指针位置从而实现字符的移动.那么我们就先来实现这个函数. gotoxy 函数并非系统函数,我将其储存于 gotoxy.h 的头文件中方便调用. gotoxy.h #includ

  • C++结构体数组实现贪吃蛇

    本文实例为大家分享了C++结构体数组实现贪吃蛇的具体代码,供大家参考,具体内容如下 代码: #include<bits/stdc++.h> #include<windows.h> #include<conio.h> using namespace std; const int h=50,w=50,MaxLen=400; void gotoxy(short y,short x)//光标移动函数 { COORD pos={x,y}; SetConsoleCursorPosi

  • C++控制台循环链表实现贪吃蛇

    本文实例为大家分享了C++控制台循环链表实现贪吃蛇的具体代码,供大家参考,具体内容如下 -stdafx.h 为了简化程序定义一些宏和全局变量 #ifndef __STDAFX_H__ #define __STDAFX_H__ // ============上下左右============= const int UP = 72; const int DOWN = 80; const int LEFT = 75; const int RIGHT = 77; // ==============宽高==

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

    本文实例为大家分享了C语言表实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 总体思想 利用循环链表将一条蛇的坐标进行存储,然后利用gotoxy()函数(可以将光标定位到指定的位置),此时根据蛇的坐标进行输出"@",输出多几个既可以产生一条蛇.通过遍历循环链表进行蛇的移动,对循环链表的插入元素,产生蛇变长的效果.下面为各功能实现的函数 1.贪吃蛇地图函数map() 2.蛇的移动move(),up(),left()等函数 3.产生食物food()和吃到食物eat_food() 4.蛇吃

  • C语言实现控制台版贪吃蛇游戏

    用c语言写的期末作业:C语言实现控制台版贪吃蛇游戏的具体代码,供大家参考,具体内容如下 /* { conio.h 阻塞式: getch(): 从无回显的控制台获取字符.无缓冲区,只有当按下一个键才会执行后面的程序. 非阻塞式: kbhit() 检测缓冲区中是否有字符:执行该函数后程序不会停下,而是继续执行下面的代码 由于getch()和kbhit()已弃用, 在编译时会产生警告, 可以用_getch()和_kbhit()替换它们, 或者在包含头文件前加上#pragma warning(disab

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

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

  • JavaScript贪吃蛇小组件实例代码

    1 写在前面 看来<JavsScript高级编程>,想做一个小demo练练自己的手,选择了贪吃蛇游戏.由于以前都是用c#写的,将贪吃蛇写到一个类里面,然后一个一个小方法的拆分,只向外提供需要提供的方法.这样就可以将贪吃蛇作为一个模块,任何地方都可以复用的.然而,用js进行编写的时候,由于不能很好的利用js语言的特性进行模块化编程,所以第一版的实现完全采用面向过程的方式,将函数中所需要的变量全部声明为全局变量.虽然这样也能够实现功能,但是做不到复用,而且定义非常多的最顶层变量,污染了全局变量.写

  • C语言单链表贪吃蛇小游戏

    C语言实现单链表控制台贪吃蛇小游戏 编译环境:vs2019 需求: 统计游戏开始后的时间,控制贪吃蛇:吃到食物蛇身加长,得分加一:碰墙或蛇头碰到身体减一条生命:生命消耗完则结束游戏. 思路: 使用wasd键控制蛇的移动方向,蛇头碰到食物得分加一,并在地图上随机产生一个食物,累加得分,碰墙或碰自己减一条生命,并初始化整条蛇,生命值为0时结束游戏. 做法: 使用单链表控制贪吃蛇移动的核心思想就是:链表存储贪吃蛇所有坐标,每次循环贪吃蛇不断向一个方向插入一个新的结点作为新的蛇头,按下按键控制新蛇头产生

随机推荐