https://www.luogu.com.cn/team/87742#main

1 条评论

    • @ 2025-8-12 17:01:26

      您是群主了~

    • @ 2025-8-12 17:11:49

      game


      #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; //蛇的长度
      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() {
          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 + 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();
       
      }
      
      
  • 1

信息

ID
218
时间
1000ms
内存
256MiB
难度
7
标签
(无)
递交数
80
已通过
21
上传者