贪吃蛇

源.cpp


//贪吃蛇
//Author:wzh190015
//Date:2015/12/29

#include<iostream>
#include<Windows.h>
#include<conio.h>
#include<thread>
#include<ctime>

#include"snake.h"

using namespace std;
void drawmap ();
void moveon ( snake* s );

int main ( void )
{
    drawmap ();
    snake s;
    thread t1 ( moveon , &s );
    while ( 1 )
    {
        if ( _kbhit () )
        {
            switch ( _getch () )
            {
                case 'w':
                    s.change_direction ( UP );
                    break;
                case 'a':
                    s.change_direction ( LEFT );
                    break;
                case 'd':
                    s.change_direction ( RIGHT );
                    break;
                case 's':
                    s.change_direction ( DOWN );
                    break;
            }
        }
    }

    system ( "pause" );
    return 0;
}

void moveon ( snake* s )
{
    while ( 1 )
    {
        Sleep ( 300 );
        s->move_forward ();
    }
}

void drawmap ()
{
    wcout.imbue ( locale ( "chs" ) );
    wchar_t ch = L'█';

    for ( int i = 0; i < 25; i++ )
    {
        SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , { 0 , i } );
        wcout << ch;
        SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , { i * 2 , 0 } );
        wcout << ch;
        SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , { 48 , i } );
        wcout << ch;
        SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , { i * 2 , 24 } );
        wcout << ch;
    }
}

snake.h


#ifndef SNAKE_H
#define SNAKE_H

#include<Windows.h>
#include<conio.h>
#include<deque>
#include"food.h"

using namespace std;

enum direction
{
    UP , DOWN , LEFT , RIGHT
};

class snake
{
public:
    friend class food;
    snake ();
    void move_forward ();
    void change_direction ( direction );
    void updatescore ();
    void gameover ();
    void handle ( COORD& );
private:
    int lenth = 0;
    deque<COORD> body;
    direction dir = UP;
    food f;
};

bool operator==( const COORD , const COORD );
bool outofrange ( COORD& );

#endif

snake.cpp


#include"snake.h"
#include<iostream>

using namespace std;

wchar_t ch = L'●';

snake::snake ()
{
    body.push_back ( { 12 , 11 } );
    body.push_back ( { 12 , 12 } );
    body.push_back ( { 12 , 13 } );
    for ( auto &i : body )
    {
        wcout.imbue ( locale ( "chs" ) );
        SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , i );
        wcout << ch;
    }
    while ( count ( body.begin () , body.end () , f.coor ) )
    {
        f.reset ();
    }
}

void snake::move_forward ()
{
    wcout.imbue ( locale ( "chs" ) );
    COORD coor1 = { body.front ().X , body.front ().Y - 1 };
    COORD coor2 = { body.front ().X , body.front ().Y + 1 };
    COORD coor3 = { body.front ().X - 2 , body.front ().Y };
    COORD coor4 = { body.front ().X + 2 , body.front ().Y };
    bool    deletetail = true;
    switch ( dir )
    {
        case UP:
            handle ( coor1 );
            break;

        case DOWN:
            handle ( coor2 );
            break;

        case LEFT:
            handle ( coor3 );
            break;

        case RIGHT:
            handle ( coor4 );
            break;
    }
}

void snake::change_direction ( direction direct )
{
    if ( ( dir == UP && direct == DOWN ) || ( dir == DOWN && direct == UP ) || ( dir == LEFT && direct == RIGHT ) || ( dir == RIGHT && direct == LEFT ) )
    {
        return;
    }
    this->dir = direct;
}

bool operator==( const COORD coor1 , const COORD coor2 )
{
    return ( coor1.X == coor2.X ) && ( coor1.Y == coor2.Y );
}

bool outofrange ( COORD& coor )
{
    if ( coor.X<1 || coor.X>46 || coor.Y<1 || coor.Y>23 )
    {
        return true;
    }
    return false;
}

void snake::updatescore ()
{
    SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , { 55 , 13 } );
    cout << "Score:" << lenth;
}

void snake::gameover ()
{
    SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , { 50 , 13 } );
    cout << "GAME OVER! YOUR SCORE IS:" << lenth;
    Sleep ( 40000 );
    exit ( 0 );
}

void snake::handle ( COORD& coor)
{
    bool deletetail = true;
    if ( coor == f.coor )
    {
        deletetail = false;
        f.reset ();
        while ( count ( body.begin ( ) , body.end ( ) , f.coor ) )
        {
            f.reset ();
        }
    }
    else if ( count ( body.begin ( ) , body.end ( ) , coor ) || outofrange ( coor ) )
    {
        gameover ( );
    }
    body.push_front ( coor );
    SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , body.front ( ) );
    wcout << ch;
    if ( deletetail )
    {
        SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , body.back ( ) );
        cout << " ";
        body.pop_back ( );
    }
    else
    {
        lenth++;
    }
    updatescore ( );
}

food.h


#ifndef FOOD_H
#define FOOD_H

#include<Windows.h>
#include<conio.h>
#include<iostream>

class food
{
    friend class snake;
public:
    food ( );
    void reset ();
private:
    COORD coor;
};

#endif

food.cpp


#include"food.h"
#include"snake.h"
#include<random>
#include<iostream>
#include<ctime>

using namespace std;

food::food ()
{
    uniform_int_distribution<unsigned short> x ( 1 , 23 );
    uniform_int_distribution<unsigned short> y ( 1 , 23 );
    default_random_engine e ( time ( 0 ) );
    coor = { x ( e ) * 2 , y ( e ) };
    SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , coor );
    wcout.imbue ( locale ( "chs" ) );
    wchar_t ch = L'○';
    wcout << ch;
}

void food::reset ()
{
    uniform_int_distribution<unsigned short> x ( 1 , 23 );
    uniform_int_distribution<unsigned short> y ( 1 , 23 );
    default_random_engine e ( time ( 0 ) );
    coor = { x ( e ) * 2 , y ( e ) };
    SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ) , coor );
    wcout.imbue ( locale ( "chs" ) );
    wchar_t ch = L'○';
    wcout << ch;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值