HJ07 发表于 2022-3-11 11:37

C++控制台贪吃蛇

本帖最后由 HJ07 于 2022-3-12 09:56 编辑

以前写的C++控制台贪吃蛇游戏,现在发到论坛上来。

(按↑↓←→键控制方向,按住空格暂停)



```
/*
* Snake.cpp
* Coco07
* 2020.8.28
*/

#include <Windows.h>
#include <stdio.h>
#include "Snake.h"
#include "Canvas.h"

#define SNAKE_INIT_X 10
#define SNAKE_INIT_Y 10

using namespace std;

Snake snake(SNAKE_INIT_X, SNAKE_INIT_Y);

int Get_Message(){
      if(GetAsyncKeyState(VK_SPACE)) return -1;
      else if(GetAsyncKeyState(VK_LEFT)) return 1;
      else if(GetAsyncKeyState(VK_RIGHT)) return 2;
      else if(GetAsyncKeyState(VK_UP)) return 3;
      else if(GetAsyncKeyState(VK_DOWN)) return 4;
      return 0;
}

const int PATH_X = {0, 0, -1, 1}, PATH_Y = {-1, 1, 0, 0};
bool mirr(int msg){
      if(msg < 1) goto ret;
      
      snake.next = snake.body.back();
      snake.next.first += PATH_X;
      snake.next.second += PATH_Y;
      
ret:return snake.move();
}

void SetConsoleCursor(const bool bo){
      HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
      CONSOLE_CURSOR_INFO CursorInfo;
      GetConsoleCursorInfo(handle, &CursorInfo);
      CursorInfo.bVisible = bo;
      SetConsoleCursorInfo(handle, &CursorInfo);
}

void welcome(){
      system("cls");
      system("mode con:cols=50 lines=25");
      system("title Snake1.1");
      system("color 0f");
      
      printf("Copyright Coco07\n");
      printf("https://www.coco07.com/\n\n");
      for(int i = 0; i < 50; ++i){
                putchar('.');
                Sleep(20);
      }
      Sleep(500);
      putchar('\n');
      system("pause");
      system("cls");
      
      SetConsoleCursor(0);
}

void game_over(){
      system("color 0c");
      Sleep(2000);
      system("cls");
      SetConsoleCursor(1);
      Set_Cursor(0, 0);
      printf("GAME OVER\n\n");
      Sleep(500);
}

void DEBUG(){
      Set_Cursor(0, 24);
      printf("%d %d %d", snake.body.front().first, snake.body.front().second, snake.body.size());
}

int main(){
      welcome();
      while(1){
                DEBUG();
                int msg = Get_Message();
                if(msg == -1){      //wait
                        system("color 0a");
                        while(Get_Message() == -1){}
                        system("color 0f");
                }
                else if(!mirr(msg)){
                        game_over();
                        goto program_exit;
                }
                snake.canvas.draw();
                Sleep(120);
      }
      
program_exit:
      system("pause");
      return 0;
}
```

```
/*
* Snake.h
* Coco07
* 2020.8.27
*/

#ifndef SNAKE_H
#define SNAKE_H

#include <queue>
#include <utility>

#include "Canvas.h"

#define SNAKE_CHAR '*'
#define WALL_CHAR '#'
#define SPACE_CHAR ' '
#define SUPRISE_CHAR_L '1'
#define SUPRISE_CHAR_H '5'

using std::pair;
using std::queue;

class Snake{
public:
         queue<pair<int, int> > body;
         pair<int, int> next;
         Canvas canvas;
         
         Snake(const int x, const int y);
      bool move();
      char Make_Suprise();
      
private:
      int tail_size;
};

Snake::Snake(const int x, const int y){
         while(!body.empty()) body.pop();
      body.push((pair<int, int>){x, y});
      next = (pair<int, int>){x, y};
      tail_size = 0;
      canvas.init();
      canvas = SNAKE_CHAR;
      Make_Suprise();
}

bool Snake::move(){
      int nextX = next.first, nextY = next.second,
                headX = body.back().first, headY = body.back().second,
                tailX = body.front().first, tailY = body.front().second;
      
      if(canvas >= SUPRISE_CHAR_L && canvas <= SUPRISE_CHAR_H){
                tail_size += (int)canvas-'0';
                Make_Suprise();
      }
      else if(canvas != SPACE_CHAR && next != body.back()){
                return 0; //game over
      }
      
      body.push(next);
      canvas = SNAKE_CHAR;
      
      if(tail_size){
                --tail_size;
      }
      else{
                body.pop();
                canvas = SPACE_CHAR;
      }
      
      if(nextX == headX){
                next.first = nextX;
                if(headY > nextY) next.second = nextY-1;
                else next.second = nextY+1;
      }
      else{
                if(headX > nextX) next.first = nextX-1;
                else next.first = nextX+1;
                next.second = nextY;
      }
      
      return 1;
}

pair<int, int> random(){return (pair<int, int>){rand()%(MAP_X+1), rand()%(MAP_Y+1)};}

char Snake::Make_Suprise(){
con:pair<int, int> where = random();
      if(canvas != SPACE_CHAR) goto con; //maybe bug
      char p = SUPRISE_CHAR_L+rand()%(SUPRISE_CHAR_H-SUPRISE_CHAR_L+1);
      canvas = p;
      return p;
}

#endif
```

```
/*
* Canvas.h
* Coco07
* 2020.8.27
*/

#ifndef CANVAS_H
#define CANVAS_H

#include <windows.h>
#include <ctime>
#include <stdio.h>

#define MAP_X 20
#define MAP_Y 40
#define SNAKE_CHAR '*'
#define WALL_CHAR '#'
#define SPACE_CHAR ' '
#define SUPRISE_CHAR_L '1'
#define SUPRISE_CHAR_H '5'

class Canvas{
public:
         char page;
         
         bool draw();
         void init();
         char *operator[] (const int i) {return page;}
         
private:
      char pageOUT;
};

bool Set_Cursor(const int x, const int y);

void Canvas::init(){
      srand(time(NULL));
      for(int i = 0; i < MAP_X; ++i){
                for(int j = 0; j < MAP_Y; ++j){
                        if(i == 0 || j == 0 || i == MAP_X-1 || j == MAP_Y-1) page = WALL_CHAR;
                        else page = SPACE_CHAR;
                }
      }
}

bool Canvas::draw(){
      for(int i = 0; i < MAP_X; ++i){
                for(int j = 0; j < MAP_Y; ++j){
                        if(pageOUT != page){
                              pageOUT = page;
                              Set_Cursor(j, i);
                              putchar(pageOUT);
                        }
                }
      }
}

COORD coord;
bool Set_Cursor(const int x, const int y){
      coord.X = x; coord.Y = y;
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

#endif
```

HJ07 发表于 2022-3-12 09:47

源码在压缩文件里

666888tzq 发表于 2022-3-11 12:31

厉害了,感谢分享。

xz91168 发表于 2022-3-12 15:15

厉害了,谢谢分享{:1_921:}

cnjlzhe 发表于 2022-3-18 16:03

感谢分享,试试能不能运行

weidadi 发表于 2023-3-15 21:20

新手学习

fzydsz 发表于 2023-3-15 21:25

学习学习

MISTIS 发表于 2023-3-17 14:51

有意思,这个需要写key down动作吗?

shenji5 发表于 2023-3-17 17:01

厉害下来玩玩

hcbkevin 发表于 2023-3-26 20:21

最近正在写通讯录,准备写一个贪吃蛇,下来学习
页: [1] 2
查看完整版本: C++控制台贪吃蛇