#include <iostream>
#include <list>
#include <cstdio>
#include <string>
#include <vector>
#include <ctime>
#include <algorithm>
#include <conio.h>
#include <windows.h>
using namespace std;
class Node {
public:
int x, y;
Node(int x1, int y1);
};
class UserData {
public:
string name;
long long score;
int gt;
int gr;
UserData(string s, long long sc,int gametime,int grade);
friend bool operator < (UserData a, UserData b);
};
#define RIGHT 0x4d
#define LEFT 0x4b
#define UP 0x48
#define DOWN 0x50
#define YELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define CYAN FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define ORANGE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define PURPLE FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY
#define RED FOREGROUND_RED | FOREGROUND_INTENSITY
const int STARTX = 8;
const int STARTY = 4;
const int RANGEX = 60;
const int RANGEY = 20;
int point=10;
const int ENDX = STARTX + RANGEX;
const int ENDY = STARTY + RANGEY;
bool isSnake[RANGEY + 10 ][RANGEX + 10];
int speed;
int sysj;
int gametime;
list<Node> snake;
int curDiraction; //Éߵĵ±Ç°Ç°½ø·½Ïò, 1ÉÏ, 2ÏÂ, 3×ó, 4ÓÒ
int score; //µ±Ç°·ÖÊý
int grade;
int snakeLen; //Éߵij¤¶È
int foodx, foody; //ʳÎï×ø±ê
int gox, goy; //ÉßÍ·×ø±ê
int mj;
void GoTo(short x, short y); //¶¨Î»¹â±ê
void DrawBoard(); //»æÖƱ߿ò
void ShowInformation(); //չʾÓÎÏ·ÐÅÏ¢
void Init(); //³õʼ»¯ÓÎÏ·
void RunSnake(int x, int y); //»æÖÆÉßÉí
void Try(int& x, int& y); //ÊÔ×ß
bool IsGoodCoord(int x, int y); //Ç°½ø×ø±êÊÇ·ñºÏ·¨
void AddFood();
void EartFood();
void InitSnake();
bool EndGame();
bool StartGame();
bool GameMenu(); //ÓÎÏ·²Ëµ¥
void ShowRanking(); //ÅÅÐаñ
void ShowAbout(); //Ïà¹ØÐÅÏ¢
void InputData(); //ÊäÈëÍæ¼ÒÃû×Ö
int main() {
system("title Ì°³ÔÉßСÓÎÏ·v.1.5.5.3 by ÀµÒÔ·²");
while (true) {
if (!GameMenu()) return 0;
}
return 0;
}
Node::Node(int x1, int y1) { //¹¹ÔìNode¶ÔÏó
x = x1; y = y1;
}
int SuiJi()
{
srand((unsigned)time(NULL));
return (rand()*rand()+rand()*rand())%14;
}
bool operator < (UserData a, UserData b) { //ÖØÔØÔËËã·û£¬°´·ÖÊýÓÉ´óµ½Ð¡ÅÅÁÐ
if(a.score != b.score)
return a.score > b.score;
if(a.gt !=b.gt)
return a.gt > b.gt;
else
return a.gr > b.gr;
}
UserData::UserData(string s, long long sc,int gametime_,int _grade) { //¹¹ÔìUserData¶ÔÏó
name = s; score = sc; gt=gametime_; gr=_grade;
}
void color(WORD A)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), A);
}
void Color(int a)
{
switch (a%4)
{
case 0:color(RED);break;
case 1:color(CYAN);break;
case 2:color(YELLOW);break;
case 3:color(PURPLE);break;
}
}
void GoTo(short x, short y) { //¶¨Î»¹â±ê
COORD coord = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void ShowInformation() { //Êä³öÓÎÏ·ÐÅÏ¢
color(YELLOW);
GoTo(78, 5);
printf("Ì°³ÔÉßÓÎÏ·");
GoTo(78,18);
gametime=(clock()-mj)/1000;
grade=snakeLen-3;
printf("Éú´æʱ¼ä£º%3d Ãë",(clock()-mj)/1000);
GoTo(78, 8);
printf("ÓÎÏ·¹æÔò£º");
GoTo(78, 10);
printf("Çë°´ ¡ü ¡ý ¡û ¡ú À´¿ØÖÆÄúµÄÉß³Ô¶«Î÷");
GoTo(78, 12);
printf("³ÔµÄÔ½¶à£¬Éß¾ÍÔ½³¤£¬ÄúµÄµÈ¼¶Ò²½«Ô½¸ß");
GoTo(78, 14);
printf("µ±Éß³Ôµ½×Ô¼º»òײÉÏǽʱ£¬ÓÎÏ·½áÊø¡£");
GoTo(78,16);
printf("×Ô¶¯Ç°½øʱ¼ä£º%3dms",speed);
GoTo(78, 20);
printf("µ±Ç°µÈ¼¶£º %8d", snakeLen-3);
GoTo(78, 23);
printf("ÄúµÄ·ÖÊý£º %d", score);
color(CYAN);
printf("+%d=%d",score/3,score*3/2);
color(YELLOW);
GoTo(78,25);
printf("Ê£Óàʱ¼ä£º%dÃë",20+(snakeLen-3)*5-gametime);
sysj=20+(snakeLen-3)*5-gametime;
}
void DrawBoard() { //»æÖÆǽÌå
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //»ñµÃÊä³ö¾ä±ú
CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; //¹â±êÐÅÏ¢
SetConsoleCursorInfo(hOut, &cursor_info); //Òþ²Ø¹â±ê
COORD size = { 120, 30 };
SetConsoleScreenBufferSize(hOut, size); //ÖØÉ軺³åÇø´óС
SMALL_RECT rc = { 0 , 0, 120, 30 };
SetConsoleWindowInfo(hOut, true, &rc); //ÖØÉè´°¿Ú´óС
SetConsoleTextAttribute(hOut, CYAN);
for (int i = STARTX - 2; i <= ENDX + 2; i += 2) { //ºáÏòǽÌå
GoTo(i, STARTY - 1);
printf("¡ö");
GoTo(i, ENDY + 1);
printf("¡ö");
}
for (int i = STARTY - 1; i <= ENDY + 1; ++i) { //ÊúÏòǽÌå
GoTo(STARTX - 2, i);
printf("¡ö");
GoTo(ENDX + 2, i);
printf("¡ö");
}
}
void draw()
{
char m=snakeLen+62;
Color(score);
cout<<m;
}
void Init() { //³õʼ»¯ÓÎÏ·
system("cls");
memset(isSnake, 0, sizeof(isSnake));
speed = 200;
curDiraction = 4;
score = 0;
DrawBoard();
InitSnake();
ShowInformation();
AddFood();
mj=clock();
point=20;
sysj=20;
}
void RunSnake(int x, int y) { //»æÖÆÉßÉí
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
score += snakeLen + 1;
if (x == foodx && y == foody) {
EartFood();
AddFood();
return;
}
DrawBoard();
snake.push_front(Node(x, y));
isSnake[y][x] = true;
GoTo(x, y);
draw();
Node back = snake.back();
snake.pop_back();
isSnake[back.y][back.x] = false;
GoTo(back.x, back.y);
printf(" ");
}
void Try(int& x, int& y) { //ÊÔ×ß
int key, cnt = 100;
while (cnt--) { //¶à´Î¼ì²â¼üÅÌ״̬
if (_kbhit()) {
key = getch();
switch (key) {
case UP:
// if (curDiraction == 1 || curDiraction == 2) break;
--y; curDiraction = 1; return;
case DOWN:
// if (curDiraction == 1 || curDiraction == 2) break;
++y; curDiraction = 2; return;
case LEFT:
// if (curDiraction == 3 || curDiraction == 4) break;
x -= 2; curDiraction = 3; return;
case RIGHT:
// if (curDiraction == 3 || curDiraction == 4) break;
x += 2; curDiraction = 4; return;
}
}
}
if (curDiraction == 1) --y; //Óû§Ã»ÓÐÊäÈëʱ
else if (curDiraction == 2) ++y;
else if (curDiraction == 3) x -= 2;
else x += 2;
}
bool IsGoodCoord(int x, int y) { //ÅжϹâ±êÊÇ·ñºÏ·¨
if (x <= ENDX && y <= ENDY && x >= STARTX && y >= STARTY)
return true;
else
return false;
}
void AddFood() { //Ôö¼ÓʳÎï
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), PURPLE);
srand((unsigned)time(NULL));
while (true) {
foodx = (rand()%ENDX) + 1;
foody = (rand()%ENDY) + 1;
if (foodx&1) foodx++;
if (!isSnake[foody][foodx] && IsGoodCoord(foodx, foody)) break;
}
GoTo(foodx, foody);
int a=rand()%5;
if(a>=4)
printf("¡ï");
else if(a<=1)
printf("¡ð");
else
printf("¡ø");
}
void EartFood() { //³Ô¶«Î÷
point+=4;
int sb=gametime=(clock()-mj)/1000;
sysj=point-sb;
score+=score/2;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
snake.push_front(Node(foodx, foody));
isSnake[foody][foodx] = true;
++snakeLen;
if (speed >= 55) speed -= 5;
GoTo(foodx, foody);
draw();
AddFood();
}
void InitSnake() { //³õʼ»¯ÉßÉí
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
snakeLen = 3, gox = 18, goy = 14;
snake.clear();
snake.push_front(Node(12, 14));
snake.push_front(Node(14, 14));
snake.push_front(Node(16, 14));
for (int i = 12; i <= 16; i += 2) {
GoTo(i, 14);
draw();
isSnake[14][i] = true;
}
}
bool EndGame() { //½áÊøÓÎÏ·
system("cls");
DrawBoard();
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
GoTo(28, 10);
printf("ÄúµÄ±¾¾ÖÓÎÏ·µÃ·Ö£º %d·Ö", score);
GoTo(32, 18);
printf("....Äã¹ÒÁË....");
GoTo(27, 20);
printf("ÊÇ·ñ¼ÌÐøÓÎÏ·: ÊÇ(1), ·ñ(0)");
GoTo(27, 22);
char key = getch();
while (true) {
if (key == '1') return false;
else if (key == '0')
{GoTo(ENDX+1,ENDY+2);
exit(0);return true;
}
else key = getch();
}
}
bool StartGame() { //Æô¶¯ÓÎÏ·
Init();
while (sysj>0) { //¿ª¹Ò
RunSnake(gox, goy);
ShowInformation();
Try(gox, goy);
Sleep(speed);
}
InputData();
return true;
}
bool GameMenu() { //ÓÎÏ·²Ëµ¥
system("cls");
DrawBoard();
GoTo(STARTX + 22, STARTY + 4);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
printf("»¶Ó½øÈëÌ°³ÔÉßÓÎÏ·!");
GoTo(STARTX + 24, STARTY + 10);
printf("1: ÐÂÓÎÏ·");
GoTo(STARTX + 24, STARTY + 12);
printf("2: ÅÅÐаñ");
GoTo(STARTX + 24, STARTY + 14);
printf("3: ¹ØÓÚÓÎÏ·");
GoTo(STARTX + 24, STARTY + 16);
printf("4: Í˳öÓÎÏ·");
while (true) {
if (_kbhit()) {
char key = getch();
switch (key) {
case '1':
if (!StartGame()) return false;
else return true;
case '2':
ShowRanking(); return true;
case '3':
ShowAbout(); return true;
case '4':
GoTo(1,ENDY+2);
return false;
default:
return true;
}
}
}
}
void ShowRanking() { //չʾÅÅÐаñ
vector<UserData> vu;
FILE *fp = fopen("Gamedata2.txt", "r");
if (fp == NULL) fp = fopen("Gamedata2.txt", "w+");
char name[20];
int len = 0;
while (fscanf(fp, "%s", name) != EOF) {
++len;
int score,g=grade;
fscanf(fp, "%d%d%d%*c", &score,&gametime,&g);
vu.push_back(UserData(string(name), score,gametime,g));
}
fclose(fp);
sort(vu.begin(), vu.end()); //¶ÔµÃ·Ö½øÐÐÅÅÃû
system("cls");
DrawBoard();
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
GoTo(STARTX + 8, STARTY + 2);
printf("Óû§");
GoTo(STARTX + 20, STARTY + 2);
printf("·ÖÊý");
GoTo(STARTX + 32, STARTY + 2);
printf("Éú´æʱ¼ä");
GoTo(STARTX + 44, STARTY + 2);
printf("ÅÅÐÐ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
for (int i = 0; i < len && i < 10; ++i) { //´òÓ¡Ç°Ê®ÃûÓû§Êý¾Ý
char const *p = vu[i].name.c_str();
Color(score);
GoTo(STARTX + 8, STARTY + 4 + i);
printf("%s", p);
GoTo(STARTX + 20, STARTY + 4 + i);
printf("%d·Ö", vu[i].score);
GoTo(STARTX + 32, STARTY + 4 + i);
printf("%dÃë", vu[i].gt);
GoTo(STARTX + 44, STARTY + 4 + i);
printf(" %d", i + 1);
}
GoTo(STARTX + 4, ENDY - 2);
printf("----------------- °´'1'·µ»ØÓÎÏ·²Ëµ¥ ---------------");
while (true) {
if (_kbhit()) {
char key = getch();
if (key == '1') break;
}
}
}
void ShowAbout() { //չʾÓÎÏ·Ïà¹Ø
system("cls");
DrawBoard();
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
GoTo(STARTX + 4, STARTY + 2);
printf("------------------- Ì°³ÔÉßÓÎÏ· -------------------");
GoTo(STARTX + 10, STARTY + 4);
printf("ÖÆ×÷ÈË: ");
GoTo(STARTX + 10, STARTY + 6);
printf("Àî¿êÅ");
GoTo(STARTX + 10,STARTY + 8);
printf("Ì°³ÔÉßÓÎÏ·");
GoTo(STARTX + 10,STARTY + 10);
printf("ÓÎÏ·¹æÔò£º");
GoTo(STARTX + 10,STARTY + 12);
printf("Çë°´ ¡ü ¡ý ¡û ¡ú À´¿ØÖÆÄúµÄÉß³Ô¶«Î÷");
GoTo(STARTX + 10,STARTY + 14);
printf("³ÔµÄÔ½¶à£¬Éß¾ÍÔ½³¤£¬ÄúµÄµÈ¼¶Ò²½«Ô½¸ß");
GoTo(STARTX + 10,STARTY + 16);
printf("µ±Éß³Ôµ½×Ô¼º»òײÉÏǽʱ£¬ÓÎÏ·½áÊø¡£");
GoTo(STARTX + 4, ENDY - 2);
printf("----------------- °´'1'·µ»ØÓÎÏ·²Ëµ¥ ---------------");
while (true) {
if (_kbhit()) {
char key = getch();
if (key == '1') break;
}
}
}
void InputData() { //Óû§ÊäÈëÃû×Ö
char name[20];
if(score>=1000)
{
GoTo(STARTX + 10, STARTY + 10);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), RED);
printf("ÇëÊäÈëÄãµÄÃû×Ö: ");
COORD coord = { STARTX + 10, STARTY + 12 };
SetConsoleCursorPosition(GetStdHandle(STD_INPUT_HANDLE), coord);
while (true) { //ºöÂÔ·Ç·¨×Ö·û
scanf("%s", name);
if (name[0] != 0 && name[0] != ' ') break;
}FILE *fp = fopen("Gamedata2.txt", "a");
if (fp == NULL) fp = fopen("Gamedata2.txt", "w+");
fprintf(fp, "%s %d %d \n", name, score,gametime);
fclose(fp);
}
else
{
GoTo(STARTX + 20, STARTY + 10);
cout<<"Ó´£¡Õâ·ÖÊýÒ²ÄÜÉÏ°ñ£¿£¿"<<endl;
Sleep(1000);
}
EndGame();
}