初试linux编译(ubuntu+vim)+玩转智能蛇

一.初试linux编译(ubuntu+vim)

步骤:
①下载vmware15+ubuntu桌面版映像
②安装ubuntu
③下载vim+gcc
在ubuntu终端输入:

sudo apt-get install vim-gtk
sudo apt-get install gcc

④安装完毕后进行编译测试
1)新建helloworld.c

vim helloworld.c
在这里插入图片描述

2)进入界面按 i 即可输入代码
在这里插入图片描述

3)按ESC再按ZZ(大写)即可保存并退出

4)再在终端输入以下代码进行编译

gcc helloworld.c

5)输入以下代码运行

./a.out

在这里插入图片描述
在这里插入图片描述

二.运行sin-demo(一个好玩的正弦函数动态展示)

在这里插入图片描述

三.简单贪吃蛇(字符版)——不可使用getch()和清屏等操作

①程序头部(生成初始地图 礼物 蛇)
程序实现思想已经在我的注释里面啦~~
我想大家应该能很快理解的

/* 
	snake_move.c
	
	2018.11.30
	Created by sysu-18342026
	
	Use 'w'(up),'s'(down),'a'(left),'d'(right) to move and eat the gold.
	Be careful not to hit yourseld as well as the wall(*)!
	
	Happy playing!
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SNAKE_MAX_LENGTH 10
#define SNAKE_HEAD 'H'
#define SNAKE_BODY 'X'
#define BLANK_CELL ' '
#define SNAKE_FOOD '$'
#define WALL_CELL '*'

//output the initial map,food and snake.
void output();
void creatrandomfood();

//use 'w'(up),'s'(down),'a'(left),'d'(right) and 'Enter' to move.
void snakemove();

//When the snake hits itself or hits the wall,the game will be over.
int gameover();


//the begining
char map[12][12] = {

					"***********",
    				"*XXXXH    *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"***********",
					
					};

//the initial position and length	        
int snake_length = 5;
int snake_x[SNAKE_MAX_LENGTH] = {5, 4, 3, 2, 1};
int snake_y[SNAKE_MAX_LENGTH] = {1, 1, 1, 1, 1};
int food_x;
int food_y;

②让蛇动起来
先参考TA的伪代码如下
在这里插入图片描述

再简单地转成c语言(实际上磕磕绊绊弄了好久,哭了~~)

/* 
	snake_eat.c
	
	2018.11.30
	Created by sysu-18342026
	
	Use 'w'(up),'s'(down),'a'(left),'d'(right) to move and eat the gold.
	Be careful not to hit yourseld as well as the wall(*)!
	
	Happy playing!
*/

int main() {
	
	output();				//output the initial map and snake.
    creatrandomfood();		//output the random food.
    
    char direction;
    int flag=1;
    
    while (flag==1) {
    	
        scanf(" %c", &direction);		//input the moving direction
        
        snakemove();					//use 'w'(up),'s'(down),'a'(left),'d'(right) and 'Enter' to move.
        
        if (direction == 'w') {
            snake_y[0] -= 1;
            map[snake_y[0]][snake_x[0]] = SNAKE_HEAD;
        }
        
        if (direction == 's') {
            snake_y[0] += 1;
            map[snake_y[0]][snake_x[0]] = SNAKE_HEAD;
        }
        
        if (direction == 'a') {
            snake_x[0] -= 1;
            map[snake_y[0]][snake_x[0]] = SNAKE_HEAD;
        }
        
        if (direction == 'd') {
            snake_x[0] += 1;
            map[snake_y[0]][snake_x[0]] = SNAKE_HEAD;
        }
        
        if (snake_x[0] == food_x && snake_y[0] == food_y) {
            creatrandomfood();
            
            snake_length++;
            
            snake_x[snake_length - 1] = snake_x[snake_length - 2];
            snake_y[snake_length - 1] = snake_y[snake_length - 2];
            
            map[snake_y[snake_length - 1]][snake_x[snake_length - 1]] = SNAKE_BODY;
        }
        
        if (gameover()!=1) {			//When the snake hits itself or hits the wall,
                                        //the game will be over.

            printf("GAMEOVER!\n\nTHANKS FOR PLAYING!\n");
            flag=0;
        } 
		
		else {
            output();
        }
    }
    
    return 0;
}



//output the initial map and snake.
void output() {
	int i,j;
	
    for (i = 0; i <= 11; i++) {
    	
        for (j = 0; j <= 11; j++) {
            printf("%c", map[i][j]);
        }
        	printf("\n");
    }
}

//output the random food.
void creatrandomfood() {
    srand((unsigned)(time(NULL)));
    
    food_x = rand() % 7;
    food_y = rand() % 7;
    
    while (map[food_y][food_x] != BLANK_CELL) {
        food_x = rand() % 7;
        food_y = rand() % 7;
        
    }
    map[food_y][food_x] = SNAKE_FOOD ;
}

//use 'w'(up),'s'(down),'a'(left),'d'(right) and 'Enter' to move.
void snakemove() {
    int i;
    
    map[snake_y[snake_length - 1]][snake_x[snake_length - 1]] = BLANK_CELL;
    
    for (i = snake_length - 1; i > 0; i--) {
        snake_x[i] = snake_x[i - 1];
        snake_y[i] = snake_y[i - 1];
        map[snake_y[i]][snake_x[i]] = SNAKE_BODY;
    }
}


//When the snake hits itself or hits the wall,the game will be over.
int gameover() {
	int i; 
	
    if (snake_x[0] == SNAKE_MAX_LENGTH || snake_x[0] == 0) {
        return 0;
    }
    
    if (snake_y[0] == SNAKE_MAX_LENGTH || snake_y[0] == 0) {
        return 0;
    }
    
    for (i = 1; i < snake_length; i++) {
        if (snake_x[0] == snake_x[i] && snake_y[0] == snake_y[i]) {
            return 0;
        }
    }
    
    return 1;
}

③简单的贪吃蛇的效果图(由于不能用getch()函数,所以比较简陋= =)
在这里插入图片描述

④在ubuntu内运行效果图(感觉linux中运行得流畅很多啊!!!)
在这里插入图片描述

⑤用kbhit()函数进一步完善(丑陋的)贪吃蛇——不需要自己按回车了!!

注:需要在linux运行才行
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SNAKE_MAX_LENGTH 10
#define SNAKE_HEAD 'H'
#define SNAKE_BODY 'X'
#define BLANK_CELL ' '
#define SNAKE_FOOD '$'
#define WALL_CELL '*'

#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <termios.h>
#include <unistd.h>

//output the initial map,food and snake.
void output();
void creatrandomfood();

//use 'w'(up),'s'(down),'a'(left),'d'(right) and 'Enter' to move.
void snakemove();

//When the snake hits itself or hits the wall,the game will be over.
int gameover();

static struct termios ori_attr, cur_attr;

static __inline 
int tty_reset(void)
{
        if (tcsetattr(STDIN_FILENO, TCSANOW, &ori_attr) != 0)
                return -1;

        return 0;
}


static __inline
int tty_set(void)
{
        
        if ( tcgetattr(STDIN_FILENO, &ori_attr) )
                return -1;
        
        memcpy(&cur_attr, &ori_attr, sizeof(cur_attr) );
        cur_attr.c_lflag &= ~ICANON;
//        cur_attr.c_lflag |= ECHO;
        cur_attr.c_lflag &= ~ECHO;
        cur_attr.c_cc[VMIN] = 1;
        cur_attr.c_cc[VTIME] = 0;

        if (tcsetattr(STDIN_FILENO, TCSANOW, &cur_attr) != 0)
                return -1;

        return 0;
}

static __inline
int kbhit(void) 
{
                   
        fd_set rfds;
        struct timeval tv;
        int retval;

        /* Watch stdin (fd 0) to see when it has input. */
        FD_ZERO(&rfds);
        FD_SET(0, &rfds);
        /* Wait up to five seconds. */
        tv.tv_sec  = 0;
        tv.tv_usec = 0;

        retval = select(1, &rfds, NULL, NULL, &tv);
        /* Don't rely on the value of tv now! */

        if (retval == -1) {
                perror("select()");
                return 0;
        } else if (retval)
                return 1;
        /* FD_ISSET(0, &rfds) will be true. */
        else
                return 0;
        return 0;
}

//将你的 snake 代码放在这里
char map[12][12] = {
					"***********",
    				"*XXXXH    *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"*         *",
    				"***********",
					};

//the initial position and length	        
int snake_length = 5;
int snake_x[SNAKE_MAX_LENGTH] = {5, 4, 3, 2, 1};
int snake_y[SNAKE_MAX_LENGTH] = {1, 1, 1, 1, 1};
int food_x;
int food_y;


int main()
{
        //设置终端进入非缓冲状态
        int tty_set_flag;
        tty_set_flag = tty_set();

        //将你的 snake 代码放在这里
        output();				//output the initial map and snake.
    creatrandomfood();		//output the random food.
    
    char direction;
    int flag=1;
    
    while (flag==1) {
    	
        scanf(" %c", &direction);		//input the moving direction
        
        snakemove();					//use 'w'(up),'s'(down),'a'(left),'d'(right) and 'Enter' to move.
        
        if (direction == 'w') {
            snake_y[0] -= 1;
            map[snake_y[0]][snake_x[0]] = SNAKE_HEAD;
        }
        
        if (direction == 's') {
            snake_y[0] += 1;
            map[snake_y[0]][snake_x[0]] = SNAKE_HEAD;
        }
        
        if (direction == 'a') {
            snake_x[0] -= 1;
            map[snake_y[0]][snake_x[0]] = SNAKE_HEAD;
        }
        
        if (direction == 'd') {
            snake_x[0] += 1;
            map[snake_y[0]][snake_x[0]] = SNAKE_HEAD;
        }
        
        if (snake_x[0] == food_x && snake_y[0] == food_y) {
            creatrandomfood();
            
            snake_length++;
            
            snake_x[snake_length - 1] = snake_x[snake_length - 2];
            snake_y[snake_length - 1] = snake_y[snake_length - 2];
            
            map[snake_y[snake_length - 1]][snake_x[snake_length - 1]] = SNAKE_BODY;
        }
        
        if (gameover()!=1) {								//When the snake hits itself or hits the wall,the game will be over.

            printf("GAMEOVER!\n\nTHANKS FOR PLAYING!\n");
            flag=0;
        } 
		
		else {
            output();
        }
    }
        
        printf("pressed `q` to quit!\n");
        while(1) {

                if( kbhit() ) {
                        const int key = getchar();
                        printf("%c pressed\n", key);
                        if(key == 'q')
                                break;
                } else {
                       ;// fprintf(stderr, "<no key detected>\n");
                }
        }

        //恢复终端设置
        if(tty_set_flag == 0) 
                tty_reset();
        return 0;
}

//output the initial map and snake.
void output() {
	int i,j;
	
    for (i = 0; i <= 11; i++) {
    	
        for (j = 0; j <= 11; j++) {
            printf("%c", map[i][j]);
        }
        	printf("\n");
    }
}

//output the random food.
void creatrandomfood() {
    srand((unsigned)(time(NULL)));
    
    food_x = rand() % 7;
    food_y = rand() % 7;
    
    while (map[food_y][food_x] != BLANK_CELL) {
        food_x = rand() % 7;
        food_y = rand() % 7;
        
    }
    map[food_y][food_x] = SNAKE_FOOD ;
}

//use 'w'(up),'s'(down),'a'(left),'d'(right) and 'Enter' to move.
void snakemove() {
    int i;
    
    map[snake_y[snake_length - 1]][snake_x[snake_length - 1]] = BLANK_CELL;
    
    for (i = snake_length - 1; i > 0; i--) {
        snake_x[i] = snake_x[i - 1];
        snake_y[i] = snake_y[i - 1];
        map[snake_y[i]][snake_x[i]] = SNAKE_BODY;
    }
}


//When the snake hits itself or hits the wall,the game will be over.
int gameover() {
	int i; 
	
    if (snake_x[0] == SNAKE_MAX_LENGTH || snake_x[0] == 0) {
        return 0;
    }
    
    if (snake_y[0] == SNAKE_MAX_LENGTH || snake_y[0] == 0) {
        return 0;
    }
    
    for (i = 1; i < snake_length; i++) {
        if (snake_x[0] == snake_x[i] && snake_y[0] == snake_y[i]) {
            return 0;
        }
    }
    
    return 1;
}

四.玩转智能蛇

①伪代码
在这里插入图片描述

②实现程序(这一步坑略多,以为可以直接在之前的贪吃蛇加一个函数,不过把自己搞崩了= =)
1)障碍效果
在这里插入图片描述

2)自动吃
在这里插入图片描述

3)思考:一个长度为5的障碍物能困死该自动跑的蛇吗?
答:我认为不会困死,设置了最大长度以及最优路线,应该不会困死的。


终于做完了贪吃蛇的学习总结!!!
前前后后踩了很多很多坑,但也学习到了很多东西,这种感觉很充实~~
虽然我的智能蛇还是很(zhizhang)= =
但是它还丑啊(逃)


本次博客到此结束,希望大家也能收获这份乐趣♂

猜你喜欢

转载自blog.csdn.net/weixin_42479092/article/details/84873374