c++贪吃蛇代码

这是一个使用C++实现的单机版贪吃蛇游戏,包括游戏窗口设置、蛇的移动、碰撞检测、食物生成等功能。游戏有两版,分别展示了不同风格的蛇和界面。

单机版1

#include<iostream>
#include<windows.h>
#include<conio.h>
#include<ctime>
using namespace std;

const int COLS = 22;//游戏窗口列数 
const int ROWS = 22;//游戏窗口行数 
const string S_WALL = "∷";//围墙元素 
const string S_SPACE = " ";//空白元素 
const string S_HEAD = "●";//蛇头 
const string S_BODY = "⊙";//蛇身 
const string S_FOOD = "★";//苹果

int snake [COLS * ROWS][2];
int food_x, food_y;//苹果的坐标 
int Score = 5;
bool gameOver = false;
bool isPosInSnake( int x , int y );
char ch = 'd';

HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord;

void p_wall();
void p_snake();
void p_food();
void move( char ch );
void locate( int x, int y )
{
    coord.X = x * 2;
    coord.Y = y;
    SetConsoleCursorPosition(hout, coord);
}

double random( double start , double end )//生成一个start到end之间的随机数 
{
    return start + ( end - start ) * rand() / ( RAND_MAX + 1.0 );
}

int main()
{
    
    system("pause");
    
    system ( "cls" );
    
    //初始化屏幕的一些参数,隐藏光标
    CONSOLE_CURSOR_INFO cursor_info = {1, 0};
    SetConsoleCursorInfo(hout, &cursor_info);
    
    snake [0][0] = 6;//蛇头的坐标 
    snake [0][1] = 2;
    snake [1][0] = 5;//蛇的第二个关节 
    snake [1][1] = 2;
    snake [2][0] = 4;//蛇的第二个关节 
    snake [2][1] = 2;
    snake [3][0] = 3;//蛇的第三个关节 
    snake [3][1] = 2;
    snake [4][0] = 2;//蛇的第四个关节 
    snake [4][1] = 2;
    
    //初始化苹果位置
    do
    {
        food_x = random( 3 , COLS - 2 );
        food_y = random( 2 , ROWS - 2 );
    }
    while ( isPosInSnake( food_x , food_y ) );
    p_wall();//调用绘制墙面
    clock_t a , b;
    while( true )//死循环 
    {    
        //初始化屏幕的一些参数,隐藏光标
        CONSOLE_CURSOR_INFO cursor_info = {1, 0};
        SetConsoleCursorInfo(hout, &cursor_info);
        
        if( gameOver )
        {
            system ( "cls" );
            cout << "Game Over!" << endl;
            cout << "You lose!" << endl;
            cout << "Score : " << Score << endl;
            system("pause");
            return 0;
        }
        p_snake();//调用绘制蛇头
        p_food();//调用绘制苹果 
        a = clock();
        while ( 1 )
        {
            b = clock();
            if( b - a >= 230 )
            {
                break;
            }
        }
        if( kbhit() )
        { 
            char next_ch = getch();//死循环获取用户按下的字符 
            if( next_ch >= 'A' && next_ch <= 'Z' )
            {
                next_ch += 'a' - 'A';
            }
            if( ( 'd' == ch || 'a' == ch ) && ( next_ch == 'w' || next_ch == 's' ) )
            {
                ch = next_ch;
            }
            else if( ( 'w' == ch || 's' == ch ) && ( next_ch == 'a' || next_ch == 'd' ) )
            {
                ch = next_ch;
            }
        }
        move( ch );//调整坐标的x,y位置
        locate( 0 , COLS + 1 );
        cout << "Now Score : " << Score; 
    }
}

bool isPosInSnake( int x , int y )
{
    for( int i = 0; i < COLS * ROWS; i++ )
    {
        if( snake [i][0] == x && snake [i][1] == y )
        {
            return true;
        }
    }
    return false;
}

void move( char ch )
{
    int x = snake [0][0] , y = snake [0][1];
    switch( ch )
    {
        case 'W' ://按下W,向上 
        case 'w' ://按下w,向上 
            y--;
            break;
        case 'S' ://按下S,向下 
        case 's' ://按下s,向下 
            y++;
            break;
        case 'A' ://按下A,向左 
        case 'a' ://按下a,向左 
            x--;
            break;
        case 'D' ://按下D,向右 
        case 'd' ://按下d,向右 
            x++;
            break;
        default :
            return;
    }
    if( x < 2 || x > COLS - 1 || y < 2 || y > ROWS - 1 )//检测是否撞墙 
    {
        gameOver = true;
        return;
    }
    if( isPosInSnake( x , y ) )
    {
        gameOver = true;
        return;
    }
    for( int i = COLS * ROWS - 1; i >= 1; i-- )//身体所有部位向前移 
    {
        snake [i][0] = snake [i - 1][0];
        snake [i][1] = snake [i - 1][1];
    }
    snake [0][0] = x; snake [0][1] = y;
    if( x == food_x && y == food_y )//检测是否吃掉苹果
    {
        Score+=1;
        //吃了苹果,分数加1 
        do
        {
            food_x = random( 3 , COLS - 2 );
            food_y = random( 2 , ROWS - 2 );
        }
        while ( isPosInSnake( food_x , food_y ) );
    }
    else
    {
        for( int i = COLS * ROWS - 1; i >= 1; i-- )//删除尾巴节点 
        {
            if( snake [i][0] > 0 )
            {
                locate( snake [i][0] , snake [i][1] );
                cout << S_SPACE;
                snake [i][0] = 0;
                snake [i][1] = 0;
                break;
            }
        }
    }
}

void p_snake()//绘制蛇头+蛇身 
{
    for( int i = 0; i < COLS * ROWS; i++ )
    {
        if( snake [i][0] <= 0 )
        {
            break;
        }
        if( i == 0 )//绘制蛇头 
        {
            locate( snake [i][0] , snake [i][1] );
            cout << S_HEAD;
        }
        else//绘制蛇身 
        {
            locate( snake [i][0] , snake [i][1] );
            cout << S_BODY;
        }
    }
}

void p_wall()//绘制围墙 
{
    locate( 0 , 0 );
    cout << endl;
    for( int i = 1; i <= ROWS; i++ )
    {
        cout << " ";
        for( int j = 1; j <= COLS; j++ )
        {
            if( i == 1 || i == ROWS || j == 1 || j == COLS )
            {
                cout << S_WALL; 
            }
            else
            {
                cout << S_SPACE;
            }
        }
        cout << endl; 
    }
    cout << endl;
}

void p_food()//绘制苹果 
{
    locate( food_x , food_y );
    cout << S_FOOD;
}

单机版2

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <cmath>
#include <windows.h>
using namespace std;
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord;

void locate(int x, int y) {
    coord.X = y*2;//因为使用的是全角符号,所以需要在x坐标*2 
    coord.Y = x;
    SetConsoleCursorPosition(hout, coord);
};

void hide() {
    CONSOLE_CURSOR_INFO cursor_info = {1, 0};
    SetConsoleCursorInfo(hout, &cursor_info);
}

double random(double start, double end) {
    return start + (end - start) * rand() / (RAND_MAX + 1.0);
}
int m, n;

struct node {
    int x, y;
} snake[1000];

int snake_length, dir;
node food;
int direct[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

void print_wall() {
    cout << " ";
    for (int i = 1; i <= n; i++)
        cout << "∷";
    cout << endl;
    for (int j = 0; j <= m - 1; j++) {
        cout << "∷";
        for (int i = 1; i <= n; i++)
            cout << " ";
        cout << "∷" << endl;
    }
    cout << " ";
    for (int i = 1; i <= n; i++)
        cout << "∷";
}

void print_snake() {
    locate(snake[0].x, snake[0].y);
    cout << "●";
    for (int i = 1; i <= snake_length - 1; i++) {
        locate(snake[i].x, snake[i].y);
        cout << "⊙";
    }
}

bool is_correct() {
    if (snake[0].x == 0 || snake[0].y == 0 || snake[0].x == m + 1 || snake[0].y == n + 1)
        return false;
    for (int i = 1; i <= snake_length - 1; i++) {
        if (snake[0].x == snake[i].x && snake[0].y == snake[i].y)
            return false;
    }
    return true;
}

bool print_food() {
    srand((unsigned)time(0));
    bool e;
    while (1) {
        e = true;
        int i = (int) random(0, m) + 1, j = (int) random(0, n) + 1;
        food.x = i;
        food.y = j;
        for (int k = 0; k <= snake_length - 1; k++) {
            if (snake[k].x == food.x && snake[k].y == food.y) {
                e = false;
                break;
            }
        }
        if (e)
            break;
    }
    locate(food.x, food.y);
    cout << "★";
    return true;
}

bool go_ahead() {
    node temp;
    bool e = false;
    temp = snake[snake_length - 1];
    for (int i = snake_length - 1; i >= 1; i--)
        snake[i] = snake[i - 1];
    snake[0].x += direct[dir][0];
    snake[0].y += direct[dir][1];
    locate(snake[1].x, snake[1].y);
    cout << "⊙";
    if (snake[0].x == food.x && snake[0].y == food.y) {
        snake_length++;
        e = true;
        snake[snake_length - 1] = temp;
    }
    if (!e) {
        locate(temp.x, temp.y);
        cout << " ";
    } else
        print_food();
    locate(snake[0].x, snake[0].y);
    cout << "●";
    if (!is_correct()) {
        system("cls");
        cout << "You lose!" << endl << "Length: " << snake_length << endl;
        return false;
    }
    return true;
}

int main() {
    cout << "--------------------贪吃蛇---------------------" << endl;
    cout << "请先输入两个数,表示地图大小.要求长宽均不小于10." << endl;
    cout << "请注意窗口大小,以免发生错位.建议将窗口调为最大." << endl;
    cout << "m10~25     n10~40                              " << endl;
    cout << "再选择难度.请在1-10中输入1个数,1最简单,10则最难" << endl;
    cout << "然后进入游戏画面,以方向键控制方向.祝你游戏愉快!" << endl;
    cout << "说明请按0 " << endl;
    cout << "-----------------------------------------------" << endl;

    m = n = 20;
    int hard = 5;
//    cin >> m >> n;
//    if (m < 10 || n < 10 || m > 25 || n > 40) {
//        cout << "ERROR" << endl;
//        system("pause");
//        return 0;
//    }
//    int hard;
//    cin >> hard;
//    if (hard <= 0 || hard > 100) {
//        cout << "ERROR" << endl;
//        system("pause");
//        return 0;
//    }
    snake_length = 5;
    clock_t a, b;
    char ch;
    double hard_len;
    for (int i = 0; i <= 4; i++) {
        snake[i].x = 1;
        snake[i].y = 5 - i;
    }
    dir = 3;

    system("cls");
    hide();
    print_wall();
    print_food();
    print_snake();
    locate(m + 2, 0);
    cout << "Now length: ";
    while (1) {
        
    CONSOLE_CURSOR_INFO cursor_info = {1, 0};
    SetConsoleCursorInfo(hout, &cursor_info);
    
        hard_len = (double)snake_length / (double) (m * n);
        a = clock();
        while (1) {
            b = clock();
            if (b - a >= (int)(400 - 30 * hard) * (1 - sqrt(hard_len)))
                break;
        }
        if (kbhit()) {
            ch = getch();
            if (ch == -32) {
                ch = getch();
                switch (ch) {
                    case 72:
                        if (dir == 2 || dir == 3)
                            dir = 0;
                        break;
                    case 80:
                        if (dir == 2 || dir == 3)
                            dir = 1;
                        break;
                    case 75:
                        if (dir == 0 || dir == 1)
                            dir = 2;
                        break;
                    case 77:
                        if (dir == 0 || dir == 1)
                            dir = 3;
                        break;
                }
            }else {
                switch (ch) {
                    case 'w':
                        if (dir == 2 || dir == 3)
                            dir = 0;
                        break;
                    case 's':
                        if (dir == 2 || dir == 3)
                            dir = 1;
                        break;
                    case 'a':
                        if (dir == 0 || dir == 1)
                            dir = 2;
                        break;
                    case 'd':
                        if (dir == 0 || dir == 1)
                            dir = 3;
                        break;
                }
            }
        }
        if (!go_ahead())
            break;
        locate(m + 2, 12);
        cout << snake_length;
    }
    system("pause");
    return 0;
}

双人版

#include<iostream>
#include<windows.h>
#include<conio.h>
#include<ctime>
using namespace std;
const int COLS = 22;//游戏窗口列数 
const int ROWS = 22;//游戏窗口行数 
const string S_WALL = "∷";//围墙元素 
const string S_SPACE = " ";//空白元素 
const string S_HEAD_1 = "●";//蛇头 
const string S_BODY_1 = "⊙";//蛇身 
const string S_HEAD_2 = "■";//蛇头 
const string S_BODY_2 = "□";//蛇身 
const string S_FOOD = "★";//苹果

int snake [COLS * ROWS][2];
int snake2 [COLS * ROWS][2];
int food_x, food_y;//苹果的坐标 
int Score = 0;
int Score2 = 0;
int oneIsOver = 0;
int twoIsOver = 0;
bool gameOver = false;
char ch = 'd';
char ch2 = 'j';

HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord;

void p_wall();
void p_snake();
void p_food();
int move( int snake[COLS * ROWS][2] , char ch , bool isPlayer1 );
bool isPosInSnake( int x , int y );
void locate( int x, int y )
{
    coord.X = x * 2;
    coord.Y = y;
    SetConsoleCursorPosition(hout, coord);
}

double random( double start , double end )//生成一个start到end之间的随机数 
{
    return start + ( end - start ) * rand() / ( RAND_MAX + 1.0 );
}

int main()
{
    
    system("pause");
    
    system ( "cls" );
    
    snake [0][0] = 6;//蛇头的坐标 
    snake [0][1] = 2;
    snake [1][0] = 5;//蛇的第二个关节 
    snake [1][1] = 2;
    snake [2][0] = 4;//蛇的第二个关节 
    snake [2][1] = 2;
    snake [3][0] = 3;//蛇的第三个关节 
    snake [3][1] = 2;
    snake [4][0] = 2;//蛇的第四个关节 
    snake [4][1] = 2;
    
    snake2 [0][0] = COLS - 5;//蛇头的坐标 
    snake2 [0][1] = ROWS - 1;
    snake2 [1][0] = COLS - 4;//蛇的第二个关节 
    snake2 [1][1] = ROWS - 1;
    snake2 [2][0] = COLS - 3;//蛇的第二个关节 
    snake2 [2][1] = ROWS - 1;
    snake2 [3][0] = COLS - 2;//蛇的第三个关节 
    snake2 [3][1] = ROWS - 1;
    snake2 [4][0] = COLS - 1;//蛇的第四个关节 
    snake2 [4][1] = ROWS - 1;
    
    //初始化苹果位置
    do
    {
        food_x = random( 11 , COLS - 1 );
        food_y = random( 0 , ROWS - 1 );
    }
    while ( isPosInSnake( food_x , food_y ) );
    p_wall();//调用绘制墙面
    clock_t a , b;
    while( true )//死循环 
    {    
    
        //初始化屏幕的一些参数,隐藏光标
        CONSOLE_CURSOR_INFO cursor_info = {1, 0};
        SetConsoleCursorInfo(hout, &cursor_info);
        
        if( oneIsOver )
        {
            Score2 += 1;
        }
        else if( twoIsOver )
        {
            Score += 1;
        }
        if( gameOver )
        {
            system ( "cls" );
            cout << "Game Over!" << endl;
            cout << "player1 : " << Score << endl;
            cout << "player2 : " << Score2 << endl;
            if( oneIsOver )
            {
                cout << "player1 over!" << endl;
            }
            else if( twoIsOver )
            {
                cout << "player2 over!" << endl;
            }
            if( Score > Score2 )
            {
                cout << "player1 win!" << endl;
                cout << "player2 lose!" << endl;
            }
            else if( Score2 > Score )
            {
                cout << "player2 win!" << endl;
                cout << "player1 lose!" << endl;
            }
            else if( Score == Score2 )
            {
                cout << "draw!" << endl;
            }
            system("pause");
            return 0;
        }
        p_snake();//调用绘制蛇头
        p_food();//调用绘制苹果 
        a = clock();
        while ( 1 )//卡时间,每一帧的间隔 
        {
            b = clock();
            if( b - a >= ( 370 + 1 - 1 )  * 1 / 1 + 0 - 0 )
            {
                break;
            }
            if( kbhit() )
            { 
                char next_ch = getch();//死循环获取用户按下的字符 
                if( next_ch >= 'A' && next_ch <= 'Z' )
                {
                    next_ch += 'a' - 'A';
                }
                
                if( ( 'd' == ch || 'a' == ch ) && ( next_ch == 'w' || next_ch == 's' ) )
                {
                    ch = next_ch;
                }
                else if( ( 'w' == ch || 's' == ch ) && ( next_ch == 'a' || next_ch == 'd' ) )
                {
                    ch = next_ch;
                }else if( ( 'j' == ch2 || 'l' == ch2 ) && ( next_ch == 'i' || next_ch == 'k' ) )
                {
                    ch2 = next_ch;
                }
                else if( ( 'i' == ch2 || 'k' == ch2 ) && ( next_ch == 'j' || next_ch == 'l' ) )
                {
                    ch2 = next_ch;
                }
            }
        }
        
        oneIsOver = move( snake , ch , true );//调整坐标的x,y位置
        twoIsOver = move( snake2 , ch2 , false );//调整坐标的x,y位置
        locate( 0 , COLS + 1 );
        cout << "Now Score : " << Score << " / " << Score2; 
    }
}
bool isPosInSnake( int x , int y )
{
    for( int i = 0; i < COLS * ROWS; i++ )
    {
        if( snake [i][0] == x && snake [i][1] == y )
        {
            return true;
        }
        if( snake2 [i][0] == x && snake2 [i][1] == y )
        {
            return true;
        }
    }
    return false;
}
int move( int snake[COLS * ROWS][2] , char ch , bool isPlayer1 )
{
    int x = snake [0][0] , y = snake [0][1];
    switch( ch )
    {
        case 'i' ://按下W,向上 
        case 'w' ://按下w,向上 
            y--;
            break;
        case 'k' ://按下S,向下 
        case 's' ://按下s,向下 
            y++;
            break;
        case 'j' ://按下A,向左 
        case 'a' ://按下a,向左 
            x--;
            break;
        case 'l' ://按下D,向右 
        case 'd' ://按下d,向右 
            x++;
            break;
        default :
            return 0;
    }
    if( x < 2 || x > COLS - 1 || y < 2 || y > ROWS - 1 )//检测是否撞墙 
    {
        gameOver = true;
        return 1;
    }
    if( isPosInSnake( x , y ) )
    {
        gameOver = true;
        return 1;
    }
    for( int i = COLS * ROWS - 1; i >= 1; i-- )//身体所有部位向前移 
    {
        snake [i][0] = snake [i - 1][0];
        snake [i][1] = snake [i - 1][1];
    }
    snake [0][0] = x; snake [0][1] = y;
    if( x == food_x && y == food_y )//检测是否吃掉苹果
    {
        if( isPlayer1 )
        {
            Score+=1;
        }
        else
        {
        Score2+=1;
        }
        //吃了苹果,分数加1 
        do
        {
            food_x = random( 3 , COLS - 2 );
            food_y = random( 2 , ROWS - 2 );
        }
        while ( isPosInSnake( food_x , food_y ) );
    }
    else
    {
        for( int i = COLS * ROWS - 1; i >= 1; i-- )//删除尾巴节点 
        {
            if( snake [i][0] > 0 )
            {
                locate( snake [i][0] , snake [i][1] );
                cout << S_SPACE;
                snake [i][0] = 0;
                snake [i][1] = 0;
                break;
            }
        }
    }
    return 0;
}
void p_snake()//绘制蛇头+蛇身 
{
    for( int i = 0; i < COLS * ROWS; i++ )
    {
        if( snake [i][0] <= 0 )
        {
            break;
        }
        if( i == 0 )//绘制蛇头 
        {
            locate( snake [i][0] , snake [i][1] );
            cout << S_HEAD_1;
        }
        else//绘制蛇身 
        {
            locate( snake [i][0] , snake [i][1] );
            cout << S_BODY_1;
        }
    }
    for( int i = 0; i < COLS * ROWS; i++ )
    {
        if( snake2 [i][0] <= 0 )
        {
            break;
        }
        if( i == 0 )//绘制蛇头 
        {
            locate( snake2 [i][0] , snake2 [i][1] );
            cout << S_HEAD_2;
        }
        else//绘制蛇身 
        {
            locate( snake2 [i][0] , snake2 [i][1] );
            cout << S_BODY_2;
        }
    }
}
void p_wall()//绘制围墙 
{
    locate( 0 , 0 );
    cout << endl;
    for( int i = 1; i <= ROWS; i++ )
    {
        cout << " ";
        for( int j = 1; j <= COLS; j++ )
        {
            if( i == 1 || i == ROWS || j == 1 || j == COLS )
            {
                cout << S_WALL; 
            }
            else
            {
                cout << S_SPACE;
            }
        }
        cout << endl; 
    }
    cout << endl;
}
void p_food()//绘制苹果 
{
    locate( food_x , food_y );
    cout << S_FOOD;
}

关注一下吧,点赞转发也行啊!!!!!!!!!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值