空余时间写了贪吃蛇,基于microsoft windows console和c++标准库。
Snake.h
#pragma once
// coded by ciderpark
// ciderpark@163.com
#include <iostream>
#include <string>
#include <cstdlib>
#include <windows.h>
#include <ctime>
#include <conio.h>
#include <cstdio>
#include <vector>
using namespace std;
struct Pos
{
int x;
int y;
bool operator==(Pos& cmp_tgt) const {
return(x == cmp_tgt.x&&y == cmp_tgt.y);
}
};
Pos pos0{ 20,10 };
Pos pos1{ 20,11 };
Pos pos2{ 20,12 };
class Snake
{
public:
/** \brief Empty constructor. */
Snake();
//: diffculty () //Empty constructor, all 0 by default
//, score()
//{
//}
/** \brief Empty destructor */
~Snake(){}
void Welcome();
void DrawMap();
void SetColor(int);
void Run();
bool Judge(Pos);
void Updata(int);
Pos Pea();
void Pause();
void SetPos(Pos pos) //control cursor position, column, line
{
COORD posi = { pos.x,pos.y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), posi);
}
private:
int difficulty;
vector<Pos> snake_v;
int map[21][26]{ 0 };
Pos pea_p;
int dir;
int score;
bool kbhited_flag;
};
#include <Snake.hpp>
Snake.hpp
#pragma once
// coded by ciderpark
// ciderpark@163.com
#ifndef SNAKE_H_
#define SNAKE_H_
#include <Snake.h>
Snake::Snake()
{
difficulty = 1;
snake_v.push_back(pos0);
snake_v.push_back(pos1);
snake_v.push_back(pos2);
//map[pos0.x / 2][pos0.y] = 1;
map[pos1.x / 2][pos1.y] = 1;
map[pos2.x / 2][pos2.y] = 1;
dir = 72;
kbhited_flag = 0;
}
void Snake::Welcome()
{
SetColor(3);
int key;
system("cls");
cout << "★■■■■■■■■■★■■■■■■■■■★" << endl;
cout << " 贪吃蛇 " << endl;
cout << "★■■■■■■■■■★■■■■■■■■■★" << endl;
cout << " 操作方式:" << endl;
cout << " ↑ - 上移" << endl;
cout << " ↓ - 下移" << endl;
cout << " ← - 左移" << endl;
cout << " → - 右移" << endl;
cout << " 空格 - 暂停" << endl;
cout << " ESC - 退出" << endl;
cout << "★■■■■■■■■■★■■■■■■■■■★" << endl;
cout << " ★ 按1—3选择难度 ★" << endl;
Pos pos{ 31,11 };
SetPos(pos);
//char x;
while (1)
{
/*x = getchar();
if (x <= '3' && x >= '1')
{
difficulty = x - '0';
break;
}*/
key = _getch();
if (key <= 51 && key >= 49)
{
difficulty = key - 48;
break;
}
else if (key == 27)
exit(1);
}
}
void Snake::DrawMap()
{
int i;
SetColor(0);
Pos pos;
for (i = 0; i < 21; i++) //width: 21 grids
{
/*pos.x = i * 2;
pos.y = 0;*/
pos = { i * 2,0 };
SetPos(pos);
cout << "■";
pos.y = 25;
SetPos(pos);
cout << "■";
}
for (i = 0; i < 26; i++) //height: 26 grids
{
pos = { 0,i };
SetPos(pos);
cout << "■";
pos.x = 40;
SetPos(pos);
cout << "■";
}
/*SetPos(snake_v[0]);
cout << "■";
SetPos(snake_v[1]);
cout << "■";*/
SetColor(2);
for (int i = 0; i < snake_v.size(); i++)
{
SetPos(snake_v[i]);
cout << "■";
}
}
void Snake::SetColor(int color_num)
{
int n;
switch (color_num)
{
case 0: n = 0x08; break;
case 1: n = 0x0A; break;
case 2: n = 0x0B; break;
case 3: n = 0x0C; break;
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n);
}
void Snake::Run()
{
srand((int)time(0));
int i = 0;
int count;
if (difficulty == 1)
count = 300; //150
else if (difficulty == 2)
count = 150; //100
else if (difficulty == 3)
count = 75; //50
else
count = 5;
pea_p = Pea();
SetPos(pea_p);
SetColor(1);
cout << "■";
SetColor(2);
while (1)
{
if (!(i < count))
{
i = 0;
Updata(dir);
kbhited_flag = 0;
/*if (Judge(snake_v[0]))
{
system("cls");
score = snake_v.size() - 3;
cout << "Game Over! Score: " << score << endl;
break;
}
else
{
Updata(dir, pea_p);
}*/
}
if (Judge(snake_v[0]))
{
system("cls");
score = snake_v.size() - 3;
cout << "Game Over! Score: " << score << endl;
break;
}
if (_kbhit())
{
int key, key2;
key = _getch();
if (key == 224)
{
key2 = _getch();
if (key2 == 72) //up
{
if (dir != 80 && !kbhited_flag)
{
dir = 72;
kbhited_flag = 1;
}
}
if (key2 == 80) //down
{
if (dir != 72 && !kbhited_flag)
{
dir = 80;
kbhited_flag = 1;
}
}
else if (key2 == 75) //left
{
if (dir != 77 && !kbhited_flag)
{
dir = 75;
kbhited_flag = 1;
}
}
else if (key2 == 77) //right
{
if (dir != 75 && !kbhited_flag)
{
dir = 77;
kbhited_flag = 1;
}
}
}
else if (key == 32)
Pause();
else if (key == 27)
{
system("cls");
exit(1);
}
}
Sleep(1);
i++;
}
}
bool Snake::Judge(Pos pos)
{
if (!(pos.x < 40 && pos.x > 0 && pos.y < 25 && pos.y > 0 && !map[pos.x / 2][pos.y]))
return true;
return false;
}
void Snake::Updata(int dir)
{
Pos temp;
Pos next_pea_p;
switch (dir)
{
case 72:
temp = snake_v.back();
for (int i = snake_v.size() - 1; i > 0; i--)
{
snake_v[i] = snake_v[i - 1];
map[snake_v[i].x / 2][snake_v[i].y] = 1;
}
snake_v[0].y -= 1;
if (!(snake_v[0] == pea_p))
{
map[temp.x / 2][temp.y] = 0;
SetPos(temp);
cout << " ";
}
else
{
snake_v.push_back(temp);
next_pea_p = Pea();
pea_p = next_pea_p;
SetPos(next_pea_p);
SetColor(1);
cout << "■";
SetColor(2);
}
SetPos(snake_v[0]);
cout << "■";
break;
case 80:
temp = snake_v.back();
for (int i = snake_v.size() - 1; i > 0; i--)
{
snake_v[i] = snake_v[i - 1];
map[snake_v[i].x / 2][snake_v[i].y] = 1;
}
snake_v[0].y += 1;
if (!(snake_v[0] == pea_p))
{
map[temp.x / 2][temp.y] = 0;
SetPos(temp);
cout << " ";
}
else
{
snake_v.push_back(temp);
next_pea_p = Pea();
pea_p = next_pea_p;
SetPos(next_pea_p);
SetColor(1);
cout << "■";
SetColor(2);
}
SetPos(snake_v[0]);
cout << "■";
break;
case 75:
temp = snake_v.back();
for (int i = snake_v.size() - 1; i > 0; i--)
{
snake_v[i] = snake_v[i - 1];
map[snake_v[i].x / 2][snake_v[i].y] = 1;
}
snake_v[0].x -= 2;
if (!(snake_v[0] == pea_p))
{
map[temp.x / 2][temp.y] = 0;
SetPos(temp);
cout << " ";
}
else
{
snake_v.push_back(temp);
next_pea_p = Pea();
pea_p = next_pea_p;
SetPos(next_pea_p);
SetColor(1);
cout << "■";
SetColor(2);
}
SetPos(snake_v[0]);
cout << "■";
break;
case 77:
temp = snake_v.back();
for (int i = snake_v.size() - 1; i > 0; i--)
{
snake_v[i] = snake_v[i - 1];
map[snake_v[i].x / 2][snake_v[i].y] = 1;
}
snake_v[0].x += 2;
if (!(snake_v[0] == pea_p))
{
map[temp.x / 2][temp.y] = 0;
SetPos(temp);
cout << " ";
}
else
{
snake_v.push_back(temp);
next_pea_p = Pea();
pea_p = next_pea_p;
SetPos(next_pea_p);
SetColor(1);
cout << "■";
SetColor(2);
}
SetPos(snake_v[0]);
cout << "■";
break;
default:
break;
}
}
Pos Snake::Pea()
{
Pos temp;
int r_x = rand() % 19 * 2 + 2;
int r_y = rand() % 24 + 1;
while (map[r_x / 2][r_y])
{
r_x = rand() % 19 * 2 + 2;
r_y = rand() % 24 + 1;
}
temp = { r_x,r_y };
return temp;
}
void Snake::Pause()
{
char temp;
while (1)
{
while (1)
{
if (_kbhit())
{
temp = _getch();
break;
}
}
if (temp == 32)
break;
else if (temp == 27)
exit(1);
}
}
#endif // !SNAKE_H_
main.cpp
#include <iostream>
#include <windows.h>
#include <Snake.h>
using namespace std;
int main(int argc, char** argv)
{
system("mode con cols=42 lines=26");
Snake game;
game.Welcome();
system("cls");
game.DrawMap();
game.Run();
system("pause");
return (0);
}
效果:
如有不妥之处,望指正。
ciderpark@163.com