PhoenixRiser 2023-10-21 14:06 采纳率: 0%
浏览 1
已结题

代码解释,代码的工作原理

下面代码的原理


#include<stdlib.h>
#include<iostream>
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#define random(x) (rand()%x)
using namespace std;

int **map;
char c = 0;
int sign = 0;        //全局变量声明,判断游戏是否结束
void print_regulation()
{
    cout<<"一、贪吃蛇游戏规则:"<<endl;
    cout<<"1.分别通过w/s/a/d按键来控制撒上/下/左/右方向"<<endl;
    cout<<"2.撞到边界或者地图部分则游戏结束"<<endl;
    cout<<"3.通过数字按键(1/2/3)来选择不同的地图和难度"<<endl;
}
int choice_map()
{
    int k;
    cout<<"二、请选择您需要的地图(1/2/3/4)"<<endl;
    cout<<"1.基础模型地图"<<endl;
    cout<<"2.“仙”字地图"<<endl;
    cout<<"3.“中”字地图"<<endl;
    cout<<"4.“帅”字地图"<<endl;
    cin>>k;
    return k;
}
int print_difficulty()
{
    int n;
    cout<<"三、请输入您想要的困难程度(1/2/3)"<<endl;
    cout<<"*****1.入门"<<endl<<"*****2.简单"<<endl<<"*****3.困难"<<endl;
    cin>>n;
    return n;
}

char check_snake(char c);

struct snake{    
    int i;
    int j;
    struct snake *next;
    };

struct snake *generateSnake()        //定义一个表示当前蛇位置的函数,并返回指向当前蛇类(结构体)的的指针
{
    struct snake *s;
    s = (struct snake*)malloc(sizeof(struct snake));
    struct snake *p = s;
    int x[6] = {2, 3, 4, 5, 5, 5};
    int y[6] = {2, 2, 2, 2, 3, 4};
    for(int i = 0; i < 6; i++){
        struct snake *node; //节点
        node = (struct snake*)malloc(sizeof(struct snake));
        p->next = node;        
        p = p->next;
        p->i = x[i];
        p->j = y[i];
    }
    p->next = NULL;//系统自定义的一个特殊的0,防野指针 
    return s;
}  // 设置蛇的长度和初始位置

void gotoxy(int x, int y)
{
    COORD Position;
    Position.X = x;
    Position.Y = y;
    //调用API改变字体位置
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Position);
}

// 绘制地图
void draw_map(int **map, int height, int weight,int k){

    for(int i = 0; i < height ; ++i){
        for(int j = 0; j < weight ; ++j){
            if(i == 0  || i == height - 1  ){  // 表示在第一层和最后一层  
                map[i][j] = 1;    // 四边形的四边作为墙,强我们用1表示,表示位置已占
            }
            else if ( j == 0 ||  j == weight - 1 ){ // 表示在最左层和最右层
                map[i][j] = 1;
            }
            else{
                map[i][j] = 0 ; // 除墙以外其他位置为0 表示该位置为空
            }
        }
        for(int i = 0; i < height ; ++i){
        for(int j = 0; j < weight ; ++j)
        {
            if(k==2){
                if(((i==4||i==5)&&j==5)||(i==6&&j==4)||(i==7&&j==3)            //“仙”字地图绘制k=2
                ||(i==8&&j==2)||(j==4&&(i<=15&&i>=7)))
                {map[i][j]=1;
                map[10][5]=0;}
                else if(((j==7&&i>=7&&i<=15)||(j==15&&i>=7&&i<=15)||
                (j==11&&i>=4&&i<=15)||(i==15&&j>=7&&j<=15)))
                {map[i][j]=1;
                 map[10][8]=0;
                 map[10][9]=0;
                 map[10][10]=0;
                 map[10][16]=0;
                 map[10][17]=0;
                 map[10][18]=0;
                 map[4][12]=0;
                 map[5][12]=0;}}
            else if(k==1){
                if((j==weight-8 && (i==height-15 || i==height-16 ||            //基础地图绘制k = 1
                i==height-17 || i==height-18 || i==height-19)))
                {map[i][j]=1;}
                else if((i==height-15)&& (j==weight-2 || j==weight-3
                ||j==weight-4))
                {map[i][j]=1;}
                else if((i==height-10)&&(j<=5||j>=13||(j<=11&&j>=7)))
                {map[i][j]=1;}
            }
            else if(k==3){                                                    //“中”字绘制地图k = 3
                if((j==4&&(i>=6&&i<=10))||(j==16&&(i>=6&&i<=10))||(i==11&&j>=4&&j<=16)
                    ||(i==6&&j>=5&&j<=15)||(j==10&&i>=3&&i<=16))
                {map[i][j]=1;
                map[9][4]=0;
                map[6][9]=0;
                map[6][11]=0;
                map[9][16]=0;}
            }
            else if(k=4){
                if((j==3&&i>=7&&i<=11)||(j==6&&i>=4&&i<=13)||(j==9&&i>=6&&i<=12)||//“帅”字地图绘制k = 4 
                    (j==17&&i>=6&&i<=12)||(i==6&&j>=10&&j<=16)||(j==13&&i>=4&&i<=16))
                {map[i][j]=1;
                 map[14][5]=1;
                 map[15][4]=1;}
            }
        }}
        cout << "\n";
    }
    return;
}
// 图形形状
void draw(int **map,int *star, int height, int weight){
    system("cls");//清空屏幕
    gotoxy(0, 0);
    for(int i = 0; i < height; ++i){
        for(int j = 0; j < weight; ++j){
            if(map[i][j] == 1){
             cout << "■";
            }
            else if (map[i][j] == 2)
            {
                cout << "●";
            }
            else if ( i == star[0] && j == star[1])
            {
                cout << "★";
            }
            else{
             cout << "  ";
            }
        }
        cout << '\n';
    }
    return;
}

// 蛇
void drawSnake(int **map, struct snake *s){
    struct snake *p = s->next;
    map[p->i][p->j] = 2;    // 蛇头
    p = p->next;
    while(p){
        map[p->i][p->j] = 1;
        p = p->next;
    }
    return;
}


void draw_star(int **map,int *star, int height, int weight){
    int sum = 0; // 空格子的个数
    int index = 0; // 剩下的格子

    // 算出空格子的个数
    for(int i = 0; i < height ; ++i){
        for(int j = 0; j < weight; ++j){
            if(map[i][j] == 0)
            {
                sum += 1;
            }
        }
    }
    index = random(sum) + 1; // 在1到sum 中随机的位置生成星星
    //生成星星
    for(i = 0; i < height; ++i){
        for(int j = 0; j < weight; ++j){
            if(map[i][j] == 0){
                index -= 1;
            }
            if(index == 0){
                star[0] = i;
                star[1] = j;
                return ;
            }
        }
    }
    return;
}

void update_snake(char c,struct snake *s,int *star)
{
    snake *newsnake;
    newsnake = (snake*)malloc(sizeof(snake));
    if(c == 'w'){
        // 相当于在s 头插一个新节点
        newsnake->i = s->next->i - 1;
        newsnake->j = s->next->j; 

        if(map[newsnake->i][newsnake->j] == 1){
            // 头插的节点的位置 原本 map[i][j] == 1 表示该位置是墙或者是蛇身了
             sign = 3;  
        }
        else if(newsnake->i == star[0] && newsnake->j == star[1]){
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s; 
                while(q->next->next != NULL){
                    gotoxy(q->i, q->j);
                    printf("■");  // 恢复蛇身
                    q = q->next;
                }
            sign = 2;
        }
        else{
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;   
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            gotoxy(q->i, q->j);
            printf("■");
            map[q->next->i][q->next->j] = 0; 
            free(q->next);        
            q->next = NULL;
        }
    }
    else if( c == 's'){
        newsnake->i = s->next->i + 1;
        newsnake->j = s->next->j;
        if(map[newsnake->i][newsnake->j] == 1){
            sign = 3;  
        }
        if(newsnake->i == star[0] && newsnake->j == star[1]){
            newsnake->next = s->next; 
            s->next = newsnake;
            struct  snake *q = s; 
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            sign = 2;
        }
        else{
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;   
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            gotoxy(q->i, q->j);
            printf("■");
            map[q->next->i][q->next->j] = 0; 
            free(q->next);        
            q->next = NULL;
        }
    }
    else if( c == 'a'){
        newsnake->i = s->next->i;
        newsnake->j = s->next->j - 1;
        if(map[newsnake->i][newsnake->j] == 1){
            sign = 3;  
        }        
        if(newsnake->i == star[0] && newsnake->j == star[1]){
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            sign = 2;
        }
        else{
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;   
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            gotoxy(q->i, q->j);
            printf("■");
            map[q->next->i][q->next->j] = 0;
            free(q->next);         
            q->next = NULL;
        } 
    }       
    else{
        newsnake->i = s->next->i;
        newsnake->j = s->next->j + 1;
        if(map[newsnake->i][newsnake->j] == 1){
            sign = 3; 
        }        
        if(newsnake->i == star[0] && newsnake->j == star[1]){
            newsnake->next = s->next; 
            s->next = newsnake;
            struct  snake *q = s;
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            sign = 2;
        }
        else{
            newsnake->next = s->next; 
            s->next = newsnake; 
            struct  snake *q = s;   
            while(q->next->next != NULL){
                gotoxy(q->i, q->j);
                printf("■"); 
                q = q->next;
            }
            gotoxy(q->i, q->j);
            printf("■");
            map[q->next->i][q->next->j] = 0; 
            free(q->next);           
            q->next = NULL;
        }  
    }            
}

// 蛇 移动方向
// 上 119 wd
// 下 115 s
// 左 97  a
// 右 100 d
void action_snake(struct snake *s,int *star){
        switch(c)
        {
            //向上
            case 'w':
            update_snake(c, s,star);
            break;
            //向下
            case 's':
            update_snake(c, s,star);
            break;
            //向左
            case 'a':
            update_snake(c, s,star);
            break;
            //向右
            case 'd':
            update_snake(c, s,star);
            break;
        }
}

void check_snake(int n){
    DWORD time = n; // 1表示一毫秒 1000表示一秒  要改变速度可以修改time的时间
    DWORD time_start = GetTickCount();  // 获取当前时间
    char t;
    while(true){
        if(_kbhit()){
            char ch = _getch(); // 当前键位
            if(ch == 97 || ch == 100 || ch == 115 || ch == 119){
                t = ch;  
                if( t == 97 && c == 'd')
                {
                    c = 'd';
                }
                else if( t == 100 && c =='a'){
                    c ='a';
                }
                else if(t == 115 && c == 'w'){
                    c = 'w';
                }
                else if(t == 119 && c == 's'){
                    c = 's';
                }
                else{
                    c = ch;
                }
            }
        }
        DWORD time_end = GetTickCount(); // 获取键位后的时间
        if(time_end - time_start > time){
            time_start = time_end; 
            break;
        }
    }
    return;
}

int main()
{
    int n,k;
    print_regulation();
    cout<<'\n';
    k=choice_map();
    switch(print_difficulty())
    {
    case 1:n=500;break;
    case 2:n=300;break;
    case 3:n=200;break;
    }
    int height = 20; // 地图高度  map.height = 20
    int weight = 20; // 地图宽度  map.weight = 20

    struct snake *s = generateSnake();     //声明一个指向蛇类(结构体)指针s,并访问表示当前蛇位置的函数,将表示蛇坐标的结构体地址赋给s
    map = (int **) malloc(sizeof(int*)*height);//申请一个动态空间用来保存地图参数(高)
    for(int i = 0; i < height; ++i)
    {
        map[i] = (int *) malloc(sizeof(int)*weight);//循环申请动态内存来保存地图的宽
    }    
    draw_map(map,height,weight,k); //调用绘制地图的函数,并传递地图参数
    drawSnake(map,s);             //绘制蛇,并传递蛇的位置
    int star[2] = {0,0};
    draw_star(map,star,height,weight);//随机生成星星的位置
    draw(map,star,height,weight);
    while(1)                    //循环操作AWSD来控制蛇的移动,循环生成地图
    {
        if( sign == 3)            //如果撞到墙,或蛇身全局变量sign会被置为3,此时则结束循环
        {
            break;
        }
        check_snake(n);
        action_snake(s,star);

        draw_map(map,height,weight,k);
        drawSnake(map,s);
        if(sign == 2)            //若没有撞到墙和蛇身,则循环继续生成地图和蛇
        {
            draw_star(map,star,height,weight);
            sign = 0;
        }
        draw(map,star,height,weight);
        gotoxy(0, 0);
    }

    system("cls");
    gotoxy(height/2,weight/2);
    cout << "游戏结束 " ;
    system("pause");
    return 0;
}
  • 写回答

1条回答 默认 最新

  • threenewbee 2023-10-21 14:07
    关注

    哈哈哈,这看上去是贪吃蛇呀。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月21日
  • 创建了问题 10月21日

悬赏问题

  • ¥50 有没有适合匹配类似图中的运动规律的图像处理算法
  • ¥15 dnat基础问题,本机发出,别人返回的包,不能命中
  • ¥15 请各位帮我看看是哪里出了问题
  • ¥15 vs2019的js智能提示
  • ¥15 关于#开发语言#的问题:FDTD建模问题图中代码没有报错,但是模型却变透明了
  • ¥15 uniapp的h5项目写一个抽奖动画
  • ¥15 hadoop中启动hive报错如下怎么解决
  • ¥15 如何优化QWebEngineView 加载url的速度
  • ¥15 关于#hadoop#的问题,请各位专家解答!
  • ¥15 如何批量抓取网站信息