个人练习程序,使用Windows.h库简单制作了一个传统的贪吃蛇游戏。
直接复制到Dev-C++中,就可以运行了。
效果如下:

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <cstdio>
#include <ctime>
using std::cout;
using std::cin;
#define MaxWidth 30
#define MaxHeight 30
#define MaxLenght MaxHeight*MaxWidth
enum mapSize
{
Small=0,
Middle,
Big
};
enum deriction
{
Left=0,
Right,
Up,
Down
};
struct Position
{
int x;
int y;
};
void gotoxy(short x,short y)
{
COORD pos={x,y};
HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout,pos);
}
char getScrChar(short x,short y)
{
char out[2]={0};
DWORD num=0;
HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE);
COORD cod={x,y};
ReadConsoleOutputCharacterA(hout,out,1,cod,&num);
return out[0];
}
class Snake {
Position pos;
Position body[MaxLenght];
int lenght;
int mlen;
deriction MoveDerict;
int mode;
public:
Snake(){};
~Snake(){cout<<"snake deleted";};
void Init();
void ModeChoose(int m);
void MaxlenSet(int &n);
void Move();
int Getlen();
Position getPos(int n);
void Eat(Position);
Position getHeadPos();
bool HitSelf();
};
void Snake::Init()
{
pos={2,2};
body[0]={1,1};
body[1]={2,1};
body[2]={2,2};
body[3]={2,3};
body[4]={3,3};
lenght=5;
mlen=5;
MoveDerict=Right;
mode=0;
}
void Snake::ModeChoose(int m){mode=m;}
void Snake::MaxlenSet(int &n){mlen=n;}
int Snake::Getlen(){return lenght;}
Position Snake::getPos(int n){return body[n];}
Position Snake::getHeadPos(){Position p=pos;return p;}
bool Snake::HitSelf()
{
for(int i=0;i<lenght-1;i++){
if((body[i].x==pos.x)&&(body[i].y==pos.y)){
return true;
}
}
return false;
}
void Snake::Move(){
char mv;
if(kbhit()){
mv=getch();
switch (mv) {
case 'w':
if(MoveDerict!=Down){
MoveDerict=Up;
}
break;
case 's':
if(MoveDerict!=Up){
MoveDerict=Down;}
break;
case 'a':
if(MoveDerict!=Right){
MoveDerict=Left;}
break;
case 'd':
if(MoveDerict!=Left){
MoveDerict=Right;}
break;
default:
break;
}
}
}
void Snake::Eat(Position p)
{
switch (MoveDerict) {
case Left:
if(p.x==(pos.x-1)&&p.y==(pos.y)){
pos.x--;
body[lenght]=pos;
lenght++;
}
else{
for(int i=0;i<lenght-1;i++){
body[i]=body[i+1];
}
pos.x--;
body[lenght-1]=pos;
}
break;
case Right:
if(p.x==(pos.x+1)&&p.y==pos.y){
pos.x++;
body[lenght]=pos;
lenght++;
}
else{
for(int i=0;i<lenght-1;i++){
body[i]=body[i+1];
}
pos.x++;
body[lenght-1]=pos;
}
break;
case Up:
if(p.x==pos.x&&p.y==(pos.y-1)){
pos.y--;
body[lenght]=pos;
lenght++;
}
else{
for(int i=0;i<lenght-1;i++){
body[i]=body[i+1];
}
pos.y--;
body[lenght-1]=pos;
}
break;
default:
if(p.x==pos.x&&p.y==(pos.y+1)){
pos.y++;
body[lenght]=pos;
lenght++;
}
else{
for(int i=0;i<lenght-1;i++){
body[i]=body[i+1];
}
pos.y++;
body[lenght-1]=pos;
}
break;
}
}
class Map {
int width,height;
int blankNum;
mapSize size;
Position foodPos;
Snake *snake;
bool initFirst;
int mode;
public:
Map();
~Map();
void Init();
void Choose();
void Draw();
void Scores();
void FoodMv(int);
bool LoseCheck();
int flash();
};
Map::Map()
{
snake=new Snake();
Init();
snake->Init();
}
Map::~Map(){
delete snake;
cout<<"Map deleted";
}
void Map::Init()
{
width=20;
height=20;
blankNum=0;
size=Small;
foodPos={0,0};
initFirst=false;
}
void Map::Choose(){
cout<<"请输入要选择的地图尺寸:"<<"\n";
cout<<"小型地图:1"<<"\n";
cout<<"中型地图:2"<<"\n";
cout<<"大型地图:2"<<"\n";
int choice=0;
bool exitLoop=false;
while(!exitLoop){
cin>>choice;
switch (choice) {
case 1:
size=Small;
exitLoop=true;
break;
case 2:
size=Middle;
exitLoop=true;
break;
case 3:
size=Big;
exitLoop=true;
break;
default:
cout<<"输出有误请重试!";
break;
}
}
system("cls");
cout<<"地图尺寸选择为:"<<size<<"\n";
cout<<"请输入要难度:"<<"\n";
cout<<"简单:1"<<"\n";
cout<<"一般:2"<<"\n";
cout<<"困难:3"<<"\n";
choice=0;
exitLoop=false;
while(!exitLoop){
cin>>choice;
switch (choice) {
case 1:
mode=3;
exitLoop=true;
break;
case 2:
mode=2;
exitLoop=true;
break;
case 3:
mode=1;
exitLoop=true;
break;
default:
cout<<"输出有误请重试!";
break;
}
}
}
void Map::FoodMv(int lenRecord)
{
if(lenRecord<snake->Getlen()||!initFirst){
srand(time(NULL));
short x,y;
bool foodputed=false;
while(!foodputed){
x=rand()%width+1;
y=rand()%height+1;
if(getScrChar(x,y)==' '){
foodPos.x=x;
foodPos.y=y;
foodputed=true;
}
}
initFirst=true;
}
gotoxy(foodPos.x,foodPos.y);
cout<<"0";
}
void Map::Draw()
{
//system("cls");
switch (size) {
case Small:
width=20;
height=15;
break;
case Middle:
width=25;
height=20;
break;
default:
width=30;
height=25;
break;
}
blankNum=width*height;
snake->MaxlenSet(blankNum);
//SetConsoleOutputCP(437);
gotoxy(0,1);
for(int i=0;i<height;i++){
cout<<"|";
for(int j=0;j<width;j++){
//cout<<static_cast<char>(197);
cout<<" ";
}
cout<<"|"<<"\n";
}
int lenRecord=snake->Getlen();
snake->Move();
snake->Eat(foodPos);
for(int k;k<snake->Getlen();k++){
Position lp=snake->getPos(k);
gotoxy(lp.x,lp.y);
cout<<'8';
}
FoodMv(lenRecord);
Scores();
}
void Map::Scores()
{
gotoxy(0,height+1);
cout<<"当前分数:"<<snake->Getlen()<<"\n";
//cout<<"Food位置:"<<foodPos.x<<","<<foodPos.y<<"\n";
//cout<<"Head 位置:"<<snake->getHeadPos().x<<","<<snake->getHeadPos().y<<"\n";
}
int Map::flash()
{
int m;
m=mode;
return m;
}
bool Map::LoseCheck()
{
Position p=snake->getHeadPos();
gotoxy(0,0);
//cout<<"kaishi"<<"\n";
if((p.x<=0||p.x>width)||(p.y<=0||p.y>height)) {
return true;
}
else if(snake->HitSelf()){
return true;
}
return false;
}
int main()
{
//Map *mymap= new Map;
Map mymap;
mymap.Choose();
system("cls");
while(1){
mymap.Draw();
Sleep(100*mymap.flash());
if(mymap.LoseCheck()){
break;
}
}
gotoxy(0,25+2);
cout<<"游戏结束"<<"\n";
//delete mymap;
return 0;
}
1345

被折叠的 条评论
为什么被折叠?



