一月前写的贪吃蛇。不解释,注释很清楚了。主要处理那几个制表符弄了好长时间。还看不懂的话,可以一起交流。
由于不懂链表,就硬是用vector实现了。
和基友玩的时候可搞笑,"敢不敢比比" "来木‘" "恩,等下,叫我加个分数,完爆你。" ,然后添加分数的时候,加上了几个歪瓜。比如按键加分数,无障碍。哈
对了,贪吃蛇 有记分数功能,有障碍,有外挂,碰到障碍和墙壁会死,但是咬到自己不会死的。因为贪吃蛇贪吃蛇,不就贪吃了点嘛><咬到自己没事儿阿。
运行中....
暂停: 话说这个功能也花了有总时间的1/5.主要是一秒会刷新很多次,所以按一次键会识别好多次,所以run函数中
if(wasd == ‘p‘){ //shu = !shu; shu=true; }
没有使用注释的这句shu= !shu; 本来这句的功能是,可以暂时取消障碍,可以再按一次p就又有障碍。但是由于按一次识别好多次,就会出现失效的情况,索性要作弊就一直作弊下去。
end.
主程序
//2014-6-25 ~ 2014-6-26 13:44:00 Copyright 2014 onion All rights reserved. email:wsrfssx@yeah.net /* 2014-6-26 19:08:11 添加障碍。 基本操作: w a s d 控制方向 q 退出 l (L)暂停 歪瓜: p 取消障碍的生成,由于run中按键可能会有多次按键的效果,所以多按几次,看分数前的空格成功与否。//已改,不是 shu = !shu; 直接不可逆 zhi=true; / 添加分数 */ #include "tcs.h" #include <conio.h> //getch(); kbhit()检测输入。 #include <windows.h> //Sleep #include <string> #include <ctype.h> //tolower转小写 #include <cstdlib> //rand() #include <ctime> //time()来初始化随机数srand using namespace std; int main(){ Tcs tcs; tcs.show(); tcs.run(); cout<<"nice"<<endl; return 0; } Tcs::Tcs(){ S[0]= "┌──────────────────────┐"; S[sMax-1]="└──────────────────────┘"; for(int j=1;j<sMax-1;++j){ for(int i=0; i<kMax;++i){ if(i==0) S[j]+="│"; else if(i==kMax-1) S[j]+="│"; else S[j]+=' '; } } //S[8][8]='O'; cVec.push_back('+'); // S[8][7]='*'; cVec.push_back('*'); //S[8][6]='*'; cVec.push_back('*'); //S[8][5]='*'; cVec.push_back('*'); //for(int i=0;i<sMax;++i) cout<<S[i]<<endl; cs = R;//初始化为右边前进,go go! x=8; y=8; //x,y先指定下一位置。 8,8 → 8,9 xvec.push_back(8); yvec.push_back(8); xvec.push_back(8); yvec.push_back(7); xvec.push_back(8); yvec.push_back(6); xvec.push_back(8); yvec.push_back(5); score=0; bFood = false; shu=false; return ; } void Tcs::show(){ for(int i=0;i<sMax;++i) cout<<S[i]<<endl; cout<<"w a s d 移动方向\nq 退出"<<endl; if(shu) cout<<" "; cout<<"分数: "<<score<<endl; } void Tcs::run(char wasd){ //由于按了一次键盘会出现重复按键 //要防止按一次键很多次的效果。 while(!kbhit() || (wasd = tolower(getch()) ) != 'q' ){ if(wasd == 'p'){//和基友耍赖 //shu = !shu; shu=true; } else if (wasd =='/') score+=10; else if(wasd == 'l') break; else ; if( wasd == 'w') { if(cs==L || cs==R){ cs = U; //x[0]--; } } else if(wasd == 's'){ if(cs==L || cs==R){ cs = D; //x[0]++; } } else if(wasd == 'a'){ if(cs==U || cs==D){ cs = L; //y[0]--; } } else if(wasd == 'd'){ if(cs==U || cs==D){ cs = R; //y[0]++; } } else ; if(cs==U) x--; else if(cs==D) x++; else if(cs==L) y--; else if(cs==R) y++; else ; food(); bigbang(); for(vector<int>::size_type c =( cVec.size()-1); c <= 1000; c--) { //专用来移动坐标 . 看到条件不要疑惑,本来条件是c>=0,因为size_type 减0后不会取到负数,所以故此 if(c==0){ xvec[0]=x; yvec[0]=y; } else{ if(c == cVec.size()-1) S[xvec[c]][ yvec[c]]=' '; xvec[c]=xvec[c-1]; yvec[c]=yvec[c-1]; } } for(vector<int>::size_type c=0; c < cVec.size(); ++c) { S[xvec[c]][yvec[c]] = cVec[c]; } /* 四角边界 S[1][2]='u'; S[1][kMax-1]='l'; S[sMax-2][2]='u'; S[sMax-2][kMax-1]='r'; */ //if(S[sMax-2][1]!=' ' && S[sMax-2][2]==' ' )cout<<'\a'; show(); Sleep(40); system("cls"); //score+=100; //同耍赖 }//while if(wasd == 'q') gameOver(); else if(wasd == 'l') stop(); //打算保存退出前最后的方向。 else ; }//run void Tcs::food(){ while(!bFood){ srand(time(0)); int i=rand()%20; //0-19 int j=rand()%45; if(S[i][j]==' '){ S[i][j]='@';//食物 bFood = true; } if(!shu){ //障碍添加。每次出现新食物的时候都会新增一个障碍且不会消失。以后得添加食物可食用性的问题。 i=rand()%20; j=rand()%45; if(S[i][j]==' '){ S[i][j]='^';//食物 //bFood = true; } } } } void Tcs::bigbang(){ //先检测墙壁,碰到便game over; if(xvec[0]<1 || xvec[0]>19 || yvec[0]<2 || yvec[0] >45) //碰壁 gameOver(); if(S[x][y]=='@') { //食物 score+=10; cout<<'\a'; cVec.push_back('!'); //末尾添加元素.坐标也要添加 xvec.push_back(xvec[xvec.size()-1]);//x坐标和前一个蛇身坐标一样,y加一或减一 if(S[xvec[xvec.size()-1]] [yvec[yvec.size()-1]+1] == ' '){ yvec.push_back(yvec[yvec.size()-1]+1); } else yvec.push_back(yvec[yvec.size()-1]-1); // S[xvec[xvec.size()-1]][yvec.size()-1]='*'; //cout<<cVec.size(); bFood=false; } if(S[x][y]=='^') gameOver(); } void Tcs::gameOver(){ system("cls"); cout<<"game over!"<<endl; system("pause"); exit(0); } void Tcs::stop(){ cout<<"已暂停。"<<endl; system("pause"); run('X'); //添加无功能字符,否则会调用默认,会改变原有方向。A cs会保存方向的。所以参数添加废弃字符便可 }头文件:tcs.h
#ifndef TCS_H #define TCS_H #include <iostream> #include <vector> using namespace std; class Tcs{ public: Tcs(); void show();//只输出当前的图案 void run(char ='d'); //运行时刻 默认参数 d void turn();//转向 void food();//生成食物,本来参数是bFood,后来去掉了//2014-6-26 18:44:36加障碍 void bigbang();//碰撞检测,两种情况,一种和障碍、墙壁(false),另一种是食物(true)。已去掉参数。 void gameOver(); void stop( );//暂停。参数为退出run前的方向。 /*struct xy{ int x; int y; };*/ private: unsigned x,y; //坐标,保存下一个位置 unsigned score; bool shu; vector<unsigned> xvec,yvec; //保存蛇身的坐标 /* sMax为string高度。kMax为每行长度,主要用蛇身长短控制每个string长度 . 由于坑爹的制表符不是char。所以。边界测验为 x[1~ sMax-2],y[2~kMax-1] . ||-- x[1~19] y[2~45] 即四角边界为 S[1][2]='u'; S[1][kMax-1]='l'; S[sMax-2][2]='u'; S[sMax-2][kMax-1]='r'; 打算用边界控制食物的生成和碰撞检测。不过 if(S[sMax-2][1]!=' ' && S[sMax-2][2]==' ' )cout<<'\a'; 已经测试出来了。边界都不为空格的。所以这就好办了。 制表符大概占用两个char的。 */ static const int sMax=21,kMax=46; string S[sMax]; vector<char> cVec;//保存蛇身,比较容易增长,size计算长度。 //char wasd;//方向 enum A{U,D,L,R} cs;//前进方向ing bool bFood;//此刻食物是否存在 }; #endif
下载地址 //貌似没有必要,代码已经给了
p.s.没有积分的可以直接找我要。
欢迎交流。
原文地址:http://blog.csdn.net/u013542256/article/details/37996219