C++控制臺循環(huán)鏈表實現(xiàn)貪吃蛇
本文實例為大家分享了C++控制臺循環(huán)鏈表實現(xiàn)貪吃蛇的具體代碼,供大家參考,具體內(nèi)容如下
-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 // =============結(jié)束?============== #define OVER false #define RUN true #endif
-SnakeUI.h
主要是初始化UI,初始化蛇,還有生產(chǎn)食物,判斷食物和蛇有沒有相撞,還有對界面的一些操作
#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
蛇類,蛇的移動和狀態(tài)
#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() {
// 狀態(tài):向右
state = RIGHT;
// 創(chuàng)建循環(huán)鏈表
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;
}
關(guān)于C++小游戲的更多精彩內(nèi)容請點擊專題: 《C++經(jīng)典小游戲》 學(xué)習(xí)了解
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++的靜態(tài)成員變量和靜態(tài)成員函數(shù)詳解
這篇文章主要為大家介紹了C++的靜態(tài)成員變量和靜態(tài)成員函數(shù),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-12-12
VSstudio中scanf返回值被忽略的原因及解決方法(推薦)
這篇文章主要介紹了VSstudio中scanf返回值被忽略的原因及其解決方法,scanf返回值被忽略,接下來我就告訴大家該如何解決這個問題,需要的朋友可以參考下2022-09-09
C++實現(xiàn)查找二叉樹中和為某一值的所有路徑的示例
這篇文章主要介紹了C++實現(xiàn)查找二叉樹中和為某一值的所有路徑的示例,文中的方法是根據(jù)數(shù)組生成二叉排序樹并進行遍歷,需要的朋友可以參考下2016-02-02
C語言實現(xiàn)直角坐標轉(zhuǎn)換為極坐標的方法
這篇文章主要介紹了C語言實現(xiàn)直角坐標轉(zhuǎn)換為極坐標的方法,涉及C語言進行三角函數(shù)與數(shù)值運算相關(guān)操作技巧,需要的朋友可以參考下2017-09-09

