一月前写的贪吃蛇。不解释,注释很清楚了。主要处理那几个制表符弄了好长时间。还看不懂的话,可以一起交流。
由于不懂链表,就硬是用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.没有积分的可以直接找我要。
欢迎交流。