本帖最后由 wujunkai 于 2020-9-20 11:49 编辑
回复 3# Gin_Q
断断续续优化了2年,C++的- /* 贪吃蛇 3.40.0 */
- #include<cstdio>
- #include<windows.h>
- #define HIT
- #define UP 1
- #define LEFT 2
- #define DOWN 3
- #define RIGHT 4
- #define HEAD 5
- #define WALL 22
- #define Handle GetStdHandle(STD_OUTPUT_HANDLE)
- #define Pempty(a) Psame(a,' ')
- #define Key(a) GetAsyncKeyState(a)
- #define elif else if
- struct botton{
- int x ,y ;
- int length ;
- };
- struct bearing:POINT{
- void walk(int Flag);
- };
- struct Snake{
- int Sum ;
- int Flag ;
- int Grade ;
- int Color ;
- int Speed ;
- bool Life ;
- bool Active ;
- bearing End ;
- bearing Head ;
- Snake(int color,int speed,bool life) ;
- void Move() ;
- void Smarter() ;
- void Re(int flag,POINT pos) ;
- void Go(bool iiSmart,bool iiSmarter,int faster) ;
- void Direction(int up,int left,int down,int right) ;
- };
- bool Pcolor(int,int) ;
- bool Hit(botton,int) ;
- char*Psame(int,char) ;
- bool Pposition(int,int) ;
- void Dead() ;
- void Menu() ;
- void Foods() ;
- void Levels() ;
- void GradeIn() ;
- void Prepare() ;
- void Setting() ;
- void GradeInput() ;
- void Pedge(botton) ;
- void GradeOutput(int) ;
- void Walk(int,long&,long&) ;
- POINT Food = {} ;
- // 第一个人 第二个人 电脑
- Snake Frst(10,1,true) ,Scnd(14,1,false) ,Auto( 1,1,false) ;
- int Level = 1 ;
- int Score[4] = {} ;
- int Map[WALL][WALL] = {} ;
- // 开始 菜单 死亡
- bool iBegin = true ,iMenu = false ,iDead = true ;
- // 加速 循环地图 竞技模式
- bool iFast = true ,iFor = true ,iRace = false ;
- // 迷宫模式 额外奖励 帮助
- bool iMaze = false ,iPrize = false ,iHelp = false ;
- // 调试模式
- bool iDebug = false ;
- const char wLevel[5][5] ={"简单","普通","困难","炼狱","调试"} ;
- /* 初始化蛇 */
- Snake::Snake(int color,int speed,bool life)
- {
- Color=color ;
- Speed=speed ;
- Life=life ;
- }
- /* 数据导入 */
- void GradeIn()
- {
- if(fopen("score.log","rb"))
- fscanf(fopen("score.log","rb"),"%d%d%d",Score,Score+1,Score+2) ;
- }
- /* 检测击键 */
- bool Hit(botton bot,int key)
- {
- #ifdef HIT
- RECT rect={} ;
- POINT pos={} ;
- GetCursorPos(&pos) ;
- GetWindowRect(GetConsoleWindow(),&rect) ;
- int x=(pos.x-rect.left-6)/8 , y=(pos.y-rect.top-32)/16 ;
- return(x>=bot.x&&x<bot.x+bot.length&&y>=bot.y&&y<=bot.y+2)&&Key(key) ;
- #endif
- return false;
- }
- /* 选择菜单 */
- void Menu()
- {
- int place=0 ;
- void (*function[])()={Prepare,Levels,GradeInput,Setting} ;
- botton bot[5]={{16,7,12},{13,10,18},{13,13,10},{23,13,8},{16,16,12}} ;
- Print:
- system("cls") ;
- printf("\n\n\n%s贪%s吃%s蛇\n\n\n\n",Pempty(17),Pempty(2),Pempty(2),Pcolor(15,3)) ;
- printf("\n%s开始游戏\n\n",Pempty(18)) ;
- printf("\n%s游戏难度 :%s\n\n",Pempty(15),wLevel[Level]) ;
- printf("\n%s排行榜%s设置\n\n",Pempty(15),Pempty(4)) ;
- printf("\n%s退出游戏",Pempty(18)) ;
- Pedge(bot[place]);
- Scan:
- Sleep(125) ;
- if (Key(' ')||Key(VK_RETURN)){
- if(place<4)
- function[place]() ;
- if(place==0||place==4){
- iBegin=(place==0);
- return ;
- }
- place=0 ;
- }
- elif ((Key('S')||Key(VK_DOWN)) && place!=4)
- place+=(place==2)?2:1 ;
- elif ((Key('W')||Key(VK_UP)) && place!=0)
- place-=(place==3)?2:1 ;
- elif ((Key('D')||Key(VK_RIGHT)) && place==2)
- place++ ;
- elif ((Key('A')||Key(VK_LEFT)) && place==3)
- place-- ;
- else
- goto Scan ;
- goto Print ;
- }
- /* 难度选择 */
- void Levels()
- {
- Print:
- system("cls") ;
- printf("\n\n\n%s困 难 度 选 择\n\n\n\n",Pempty(15)) ;
- for(int i=0 ;i<4+iDebug ;i++)
- printf("%s%s\n\n\n",Pempty(20),wLevel[i]) ;
- Pedge({18,(Level+2)*3,8});
- Scan:
- Sleep(125) ;
- if ((Key('S')||Key(VK_DOWN)) && Level != 3+iDebug)
- Level++ ;
- elif((Key('W')||Key(VK_UP)) && Level != 0)
- Level-- ;
- elif(Key(' ')||Key(VK_RETURN))
- return ;
- else
- goto Scan ;
- goto Print ;
- }
- /* 排行数据 */
- void GradeInput()
- {
- system("cls") ;
- printf("\n\n\n%s排 行 榜\n\n",Pempty(18)) ;
- for(int i=0 ;i<3 ;i++)
- printf("%s第%d名: %d\n\n",Pempty(17) ,i+1,Score[i]) ;
- printf("\n\n\n%s知道了\n\n",Pempty(19)) ;
- Pedge({17,13,10});
- for(Sleep(125) ; !(Key(' ') ||Key(VK_RETURN)) ;Sleep(125)) ;
- }
- /* 游戏设置 */
- void Setting()
- {
- bool iClear = false ;
- bool *str[10] = {&iDead ,&iFor ,&iHelp ,&iMaze ,&iPrize ,&iRace ,&Auto.Life ,&Scnd.Life ,&iClear ,&iDebug } ;
- char name[10][9] = {"死亡判定" ,"循环地图" ,"智能辅助" ,"迷宫地图" ,"额外奖励" ,"淘汰模式" ,"人机模式" ,"双人模式" ,"分数清理" ,"调试模式" } ;
- int place = 0 ;
- Print:
- system("cls") ;
- printf("\n\n%s设%s置\n\n\n",Pempty(18),Pempty(4)) ;
- for(int i=0;i<10;i+=2){
- printf("%s%s%s%s\n\n\n",Pempty(4),name[i],Pempty(11),name[i+1],Pposition(0,i/2*3+5),Pcolor(15,3));
- printf("%s",(*str[i] )?" 开":"关",Pposition(16,i/2*3+5),Pcolor((*str[i] )?3:15,(*str[i])?15:3));
- printf("%s",(*str[i+1])?" 开":"关",Pposition(36,i/2*3+5),Pcolor((*str[i+1])?3:15,(*str[i+1])?15:3));
- }
- printf("\n\n\n%s退%s出",Pempty(16),Pempty(5),Pcolor(15,3));
- if(place<10)
- Pedge({(place%2)?34:14,place/2*3+4,8}) ;
- else
- Pedge({14,19,13}) ;
- Scan:
- if ((iFast||!iDead)&&!iDebug)
- iDead=true;
- Sleep(125) ;
- if ( (Key('S')||Key(VK_DOWN)) && place < 10)
- place+=2 ;
- elif( (Key('W')||Key(VK_UP)) && place > 1)
- place-=2 ;
- elif( (Key('A')||Key(VK_LEFT)) && place%2 == 1)
- place-- ;
- elif( (Key('D')||Key(VK_RIGHT)) && place%2 == 0)
- place++ ;
- elif(Key(' ')||Key(VK_RETURN)){
- if(place>=10)
- return ;
- *str[place]=!(*str[place]);
- }
- else
- goto Scan ;
- if(iClear)
- Score[0] = Score[1] = Score[2] = Score[3]= 0 ;
- goto Print ;
- }
- /* 主函数 */
- int main()
- {
- system("color 3f&mode con cols=44 lines=24&title 贪吃蛇") ;
- GradeIn() ;
- Menu:
- Menu() ;
- while( iBegin ){
- Frst.Direction('W','A','S','D' );
- Scnd.Direction(VK_UP,VK_LEFT,VK_DOWN,VK_RIGHT) ;
- if( !Scnd.Life )
- Frst.Direction(VK_UP,VK_LEFT,VK_DOWN,VK_RIGHT) ;
- Frst.Go(iHelp ,false ,'R' ) ;
- Scnd.Go(iHelp ,false ,VK_NUMPAD0 ) ;
- Auto.Go(true ,true ,-1 ) ;
- if(iDead&&(Frst.Active&& Map[Frst.Head.y][Frst.Head.x] != HEAD)||
- (Auto.Active&& Map[Auto.Head.y][Auto.Head.x] != HEAD)||
- (Scnd.Active&& Map[Scnd.Head.y][Scnd.Head.x] != HEAD))
- Dead() ;
- if(iMenu){
- GradeOutput(Frst.Grade+Scnd.Grade) ;
- goto Menu ;
- }
- Sleep((iDebug&&Level==4)?0 : ( Level < 3)?(150 -(Level * 50)) :(rand() % 80)) ;
- }
- return 0 ;
- }
- /* 运动处理 */
- void Snake::Go(bool iiSmart,bool iiSmarter,int faster)
- {
- for(int i=0;((iFast&&Key(faster))||i<Speed)&&Active;i++){
- iMenu = Key(VK_ESCAPE) ;
- if(iiSmarter)
- Smarter() ;
- if(iiSmart)
- for(int i=0 ;i<16 ;i++)
- if((Flag==LEFT && Map[Head.y] [Head.x-1])||
- (Flag==DOWN && Map[Head.y+1][Head.x] )||
- (Flag==RIGHT && Map[Head.y] [Head.x+1])||
- (Flag==UP && Map[Head.y-1][Head.x] ))
- Flag=rand()%4+1 ;
- Move() ;
- }
- }
- /* 智能方向 */
- void Snake::Smarter()
- {
- Map[Food.y][Food.x]=-2 ;
- for(int nem=0 ;nem<50&&Map[Head.y-1][Head.x]!=-2&&Map[Head.y+1][Head.x]!=-2&&Map[Head.y][Head.x-1]!=-2&&Map[Head.y][Head.x+1]!=-2 ;nem++){
- for(int i=1 ;i<WALL-1 ;i++){
- for(int j=1 ;j<WALL-1 ;j++){
- if(Map[i][j]==-2){
- if(Map[i-1][j]==0)
- Map[i-1][j]=-1 ;
- if(Map[i+1][j]==0)
- Map[i+1][j]=-1 ;
- if(Map[i][j-1]==0)
- Map[i][j-1]=-1 ;
- if(Map[i][j+1]==0)
- Map[i][j+1]=-1 ;
- }
- }
- }
- if(iFor){
- for(int i=0 ;i<WALL ;i++){
- for(int j=0 ;j<WALL ;j+=(i==0||i==WALL-1)?1:WALL-1){
- if(Map[i][j]==-1){
- Map[(i==0||i==WALL-1)?abs(i-WALL+1):i][(j==0||j==WALL-1)?abs(j-WALL+1):j] = (Map[(i==0||i==WALL-1)?abs(i-WALL+1):i][(j==0||j==WALL-1)?abs(j-WALL+1):j]==0)?-2:Map[(i==0||i==WALL-1)?abs(i-WALL+1):i][(j==0||j==WALL-1)?abs(j-WALL+1):j] ;
- Map[(i==0||i==WALL-1)?abs(i-WALL+2):i][(j==0||j==WALL-1)?abs(j-WALL+2):j] = (Map[(i==0||i==WALL-1)?abs(i-WALL+2):i][(j==0||j==WALL-1)?abs(j-WALL+2):j]==0)?-2:Map[(i==0||i==WALL-1)?abs(i-WALL+2):i][(j==0||j==WALL-1)?abs(j-WALL+2):j] ;
- }
- }
- }
- }
- for(int i=0 ;i<WALL ;i++)
- for(int j=0 ;j<WALL ;j++)
- Map[i][j]=(Map[i][j]==-1)?-2:Map[i][j] ;
- }
- if (Map[Head.y-1][Head.x]==-2)
- Flag=UP ;
- elif(Map[Head.y+1][Head.x]==-2)
- Flag=DOWN ;
- elif(Map[Head.y][Head.x-1]==-2)
- Flag=LEFT ;
- elif(Map[Head.y][Head.x+1]==-2)
- Flag=RIGHT ;
- for(int i=0 ;i<WALL ;i++)
- for(int j=0 ;j<WALL ;j++)
- if(Map[i][j]==-2)
- Map[i][j]=0 ;
- }
- /* 定位打印 */
- bool Pposition(int x ,int y)
- {
- CONSOLE_CURSOR_INFO CurSor ={};
- SetConsoleCursorPosition(Handle, { x,y }) ;
- GetConsoleCursorInfo(Handle,&CurSor) ;
- CurSor.bVisible = false ;
- SetConsoleCursorInfo(Handle,&CurSor) ;
- }
- /* 字体颜色 */
- bool Pcolor( int a ,int b)
- {
- SetConsoleTextAttribute(Handle, a + b * 0x10) ;
- }
- /* 批量打印 */
- char*Psame (int n,char word)
- {
- char * turn=new char [n+1] ;
- memset(turn,word,n);
- turn[n]=0;
- return turn ;
- }
- /* 边框打印 */
- void Pedge(botton the)
- {
- for(int i=0;i<2;i++){
- printf("%s",Psame(the.length,'-'),Pposition(the.x,the.y+i*2),Pcolor(15,3));
- printf("#" ,Pposition(the.x+i*(the.length-1),the.y+1));
- }
- }
- /* 运行准备 */
- void Prepare()
- {
- Frst.Re(RIGHT,{3,10}) ;
- if(Auto.Life)
- Scnd.Re(DOWN,{11,3});
- else
- Scnd.Re(LEFT,{18,10}) ;
- Auto.Re(LEFT,{18,10}) ;
- iMenu = false ;
- system("cls") ;
- for(int i = 0 ; i < WALL ; i++){
- for(int j = 0 ; j < WALL ; j++){
- Map[i][j] = 0;
- if ( i == 0 || i == WALL -1 || j == 0 || j == WALL -1){
- Map[i][j] = (iFor)?0:WALL;
- printf("■",Pcolor( 15,3)) ;
- }
- else
- printf("%s",Pempty(2),Pcolor( 3 , 3)) ;
- }
- }
- Foods() ;
- }
- /* 蛇的重置 */
- void Snake::Re(int flag,POINT pos)
- {
- Sum = -3 ;
- Grade = 0 ;
- Flag = flag ;
- Active = Life ;
- End.x = Head.x = pos.x ;
- End.y = Head.y = pos.y ;
- }
- /* 蛇皮走位 */
- void bearing::walk(int Flag)
- {
- switch(Flag){
- case LEFT:{
- x-=(iFor&&x==1)?-19:1 ;
- }return ;
- case RIGHT:{
- x+=(iFor&&x==20)?-19:1 ;
- }return ;
- case UP:{
- y-=(iFor&&y==1)?-19:1 ;
- }return ;
- case DOWN:{
- y+=(iFor&&y==20)?-19:1 ;
- }return ;
- }
- }
- /* 方向判断 */
- void Snake::Direction(int up,int left,int down,int right)
- {
- Flag = ((Key(left)) && Flag!=RIGHT )? LEFT :Flag ;
- Flag = ((Key(right))&& Flag!=LEFT )? RIGHT :Flag ;
- Flag = ((Key(up)) && Flag!=DOWN )? UP :Flag ;
- Flag = ((Key(down)) && Flag!=UP )? DOWN :Flag ;
- }
- /* 蛇的移动 */
- void Snake::Move()
- {
- printf("●",Pcolor(Color,3) ,Pposition(End.x*2,End.y) ) ;
- Map[Head.y][Head.x] = Flag ;
- Head.walk(Flag) ;
- printf("●",Pcolor( Color ,3),Pposition( Head.x * 2 ,Head.y)) ;
- Map[Head.y][Head.x] += HEAD ;
- if (Head.y==Food.y&& Head.x==Food.x){
- Grade++ ;
- Foods() ;
- }
- if (Sum==Grade){
- int Temp = Map[End.y][End.x] ;
- Map[End.y][End.x] = 0 ;
- printf("%s",Pempty(2),Pcolor( 3 ,3), Pposition( End.x * 2 ,End.y) ) ;
- End.walk(Temp) ;
- }
- else
- Sum++ ;
- }
- /* 死亡判断 */
- void Dead()
- {
- if(iRace&&(Frst.Active||Scnd.Active||Auto.Active)){
- Snake*they[3]={&Frst,&Scnd,&Auto} ;
- for(int i=0;i<3;i++)
- if(Map[they[i]->Head.y][they[i]->Head.x] != HEAD){
- they[i]->Active = false ;
- Map[they[i]->Head.y][they[i]->Head.x] -= HEAD ;
- }
- return ;
- }
- GradeOutput(Frst.Grade+Scnd.Grade) ;
- printf(" Game Over !",Pcolor( 15, 3) ,Pposition( 16 , 9)) ;
- Sleep(1500) ;
- char wDead[3][9] ={"重新开始","返回菜单","退出游戏"} ;
- int place = iBegin = false ;
- Print:
- system("cls") ;
- printf("\n\n\n\n%s游 戏 结 束\n",Pempty(16)) ;
- if (Scnd.Life&&Frst.Grade!=Scnd.Grade)
- printf("%s%s 赢 了",Pempty(16),(Frst.Grade>Scnd.Grade)?"左 边":"右 边");
- printf("\n%s分数 : %d\n\n\n\n" ,Pempty(17),Frst.Grade+Scnd.Grade) ;
- for( int i = 0 ; i < 3 ; i++)
- printf("%s%s\n\n\n",Pempty(18),wDead[i]) ;
- Pedge({16,place*3+9,12}) ;
- Scan:
- Sleep(125) ;
- if ((Key('W')||Key(VK_UP)) && place != 0)
- place-- ;
- elif((Key('S')||Key(VK_DOWN)) && place != 2)
- place++ ;
- elif(Key(' ')||Key(VK_RETURN)){
- iBegin = (place==0||place==1) ;
- if (place==0)
- Prepare() ;
- elif(place==1)
- iBegin = iMenu = true ;
- return ;
- }
- else
- goto Scan ;
- goto Print ;
- }
- /* 随机果实 */
- void Foods()
- {
- do{
- Food.x = rand() %(WALL - 2) +1 ,Food.y = rand() %(WALL - 2) +1 ;
- }while( Map[Food.y][Food.x]!=0 ) ;
- printf("★",Pcolor(4,3),Pposition( Food.x * 2 ,Food.y)) ;
- }
- /* 分数保存 */
- void GradeOutput(int grade)
- {
- for(int i=2 ;i>=0 ;i--)
- if(Score[i]<grade){
- Score[i+1] = Score[i] ;
- Score[i] = grade ;
- }
- fprintf(fopen("score.log","w+"),"%d\n%d\n%d",Score[0],Score[1],Score[2]) ;
- }
复制代码
|