源.cpp
#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;
}