c++貪喫蛇

空餘時間寫了貪喫蛇,基於microsoft windows console和c++標準庫。
Snake.h

#pragma once
// coded by ciderpark
// [email protected]
#include <iostream>
#include <string>
#include <cstdlib>
#include <windows.h>
#include <ctime>
#include <conio.h>
#include <cstdio>
#include <vector>

using namespace std;
struct Pos
{
 int x;
 int y;
 bool operator==(Pos& cmp_tgt) const {
  return(x == cmp_tgt.x&&y == cmp_tgt.y);
 }
};
Pos pos0{ 20,10 };
Pos pos1{ 20,11 };
Pos pos2{ 20,12 };

class Snake
{
public:
 /** \brief Empty constructor. */
 Snake();
  //: diffculty ()  //Empty constructor, all 0 by default
  //, score()
  //{
  //}
 /** \brief Empty destructor */
 ~Snake(){}
 void Welcome();
 void DrawMap();
 void SetColor(int);
 void Run();
 bool Judge(Pos);
 void Updata(int);
 Pos Pea();
 void Pause();

 void SetPos(Pos pos)  //control cursor position, column, line
 {
  COORD posi = { pos.x,pos.y };
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), posi);
 }
private:
 int difficulty;
 vector<Pos> snake_v;
 int map[21][26]{ 0 };
 Pos pea_p;
 int dir;
 int score;
 bool kbhited_flag;
};

#include <Snake.hpp>

Snake.hpp

#pragma once
// coded by ciderpark
// [email protected]
#ifndef SNAKE_H_
#define SNAKE_H_

#include <Snake.h>

Snake::Snake()
{
 difficulty = 1;
 snake_v.push_back(pos0);
 snake_v.push_back(pos1);
 snake_v.push_back(pos2);
 //map[pos0.x / 2][pos0.y] = 1;
 map[pos1.x / 2][pos1.y] = 1;
 map[pos2.x / 2][pos2.y] = 1;
 dir = 72;
 kbhited_flag = 0;
}
void Snake::Welcome()
{
 SetColor(3);
 int key;
 system("cls");
 cout << "★■■■■■■■■■★■■■■■■■■■★" << endl;
 cout << "    貪喫蛇  " << endl;
 cout << "★■■■■■■■■■★■■■■■■■■■★" << endl;
 cout << "  操作方式:" << endl;
 cout << "  ↑ - 上移" << endl;
 cout << "  ↓ - 下移" << endl;
 cout << "  ← - 左移" << endl;
 cout << "  → - 右移" << endl;
 cout << "  空格 - 暫停" << endl;
 cout << "  ESC - 退出" << endl;
 cout << "★■■■■■■■■■★■■■■■■■■■★" << endl;
 cout << "   ★ 按1—3選擇難度 ★" << endl;
 Pos pos{ 31,11 };
 SetPos(pos);

 //char x;
 while (1)
 {
  /*x = getchar();
  if (x <= '3' && x >= '1')
  {
  difficulty = x - '0';
  break;
  }*/
  key = _getch();
  if (key <= 51 && key >= 49)
  {
   difficulty = key - 48;
   break;
  }
  else if (key == 27)
   exit(1);
 }
}
void Snake::DrawMap()
{
 int i;
 SetColor(0);
 Pos pos;
 for (i = 0; i < 21; i++)  //width: 21 grids
 {
  /*pos.x = i * 2;
  pos.y = 0;*/
  pos = { i * 2,0 };
  SetPos(pos);
  cout << "■";
  pos.y = 25;
  SetPos(pos);
  cout << "■";
 }

for (i = 0; i < 26; i++)  //height: 26 grids
 {
  pos = { 0,i };
  SetPos(pos);
  cout << "■";
  pos.x = 40;
  SetPos(pos);
  cout << "■";
 }
 /*SetPos(snake_v[0]);
 cout << "■";
 SetPos(snake_v[1]);
 cout << "■";*/
 SetColor(2);
 for (int i = 0; i < snake_v.size(); i++)
 {
  SetPos(snake_v[i]);
  cout << "■";
 }
}
void Snake::SetColor(int color_num)
{
 int n;
 switch (color_num)
 {
 case 0: n = 0x08; break;
 case 1: n = 0x0A; break;
 case 2: n = 0x0B; break;
 case 3: n = 0x0C; break;
 }
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n);
}
void Snake::Run()
{
 srand((int)time(0));
 int i = 0;
 int count;
 if (difficulty == 1)
  count = 300;  //150 
 else if (difficulty == 2)
  count = 150;  //100
 else if (difficulty == 3)
  count = 75;  //50
 else
  count = 5;
 pea_p = Pea();
 SetPos(pea_p);
 SetColor(1);
 cout << "■";
 SetColor(2);
 while (1)
 {
  if (!(i < count))
  {
   i = 0;
   Updata(dir);
   kbhited_flag = 0;
   /*if (Judge(snake_v[0]))
   {
    system("cls");
    score = snake_v.size() - 3;
    cout << "Game Over! Score: " << score << endl;
    break;
   }
   else
   {
    Updata(dir, pea_p);
   }*/
  }
  if (Judge(snake_v[0]))
  {
   system("cls");
   score = snake_v.size() - 3;
   cout << "Game Over! Score: " << score << endl;
   break;
  }
  if (_kbhit())
  {
   int key, key2;
   key = _getch();
   if (key == 224)
   {
    key2 = _getch();
    if (key2 == 72)  //up
    {
     if (dir != 80 && !kbhited_flag)
     {
      dir = 72;
      kbhited_flag = 1;
     }
    }
    if (key2 == 80)  //down
    {
     if (dir != 72 && !kbhited_flag)
     {
      dir = 80;
      kbhited_flag = 1;
     }
    }
    else if (key2 == 75)  //left
    {
     if (dir != 77 && !kbhited_flag)
     {
      dir = 75;
      kbhited_flag = 1;
     }
    }
    else if (key2 == 77)  //right
    {
     if (dir != 75 && !kbhited_flag)
     {
      dir = 77;
      kbhited_flag = 1;
     }
    }
   }
   else if (key == 32)
    Pause();
   else if (key == 27)
   {
    system("cls");
    exit(1);
   }
  }
  Sleep(1);
  i++;
 }
}
bool Snake::Judge(Pos pos)
{
 if (!(pos.x < 40 && pos.x > 0 && pos.y < 25 && pos.y > 0 && !map[pos.x / 2][pos.y]))
  return true;
  return false;
}
void Snake::Updata(int dir)
{
 Pos temp;
 Pos next_pea_p;
 switch (dir)
 {
 case 72: 
  temp = snake_v.back();
  for (int i = snake_v.size() - 1; i > 0; i--)
  {
   snake_v[i] = snake_v[i - 1];
   map[snake_v[i].x / 2][snake_v[i].y] = 1;
  }
  snake_v[0].y -= 1;
  if (!(snake_v[0] == pea_p))
  {
   map[temp.x / 2][temp.y] = 0;
   SetPos(temp);
   cout << "  ";
  }
  else
  {
   snake_v.push_back(temp);
   next_pea_p = Pea();
   pea_p = next_pea_p;
   SetPos(next_pea_p);
   SetColor(1);
   cout << "■";
   SetColor(2);
  }
  SetPos(snake_v[0]);
  cout << "■";
  break;
 case 80:
  temp = snake_v.back();
  for (int i = snake_v.size() - 1; i > 0; i--)
  {
   snake_v[i] = snake_v[i - 1];
   map[snake_v[i].x / 2][snake_v[i].y] = 1;
  }
  snake_v[0].y += 1;
  if (!(snake_v[0] == pea_p))
  {
   map[temp.x / 2][temp.y] = 0;
   SetPos(temp);
   cout << "  ";
  }
  else
  {
   snake_v.push_back(temp);
   next_pea_p = Pea();
   pea_p = next_pea_p;
   SetPos(next_pea_p);
   SetColor(1);
   cout << "■";
   SetColor(2);
  }
  SetPos(snake_v[0]);
  cout << "■";
  break;
 case 75:
  temp = snake_v.back();
  for (int i = snake_v.size() - 1; i > 0; i--)
  {
   snake_v[i] = snake_v[i - 1];
   map[snake_v[i].x / 2][snake_v[i].y] = 1;
  }
  snake_v[0].x -= 2;
  if (!(snake_v[0] == pea_p))
  {
   map[temp.x / 2][temp.y] = 0;
   SetPos(temp);
   cout << "  ";
  }
  else
  {
   snake_v.push_back(temp);
   next_pea_p = Pea();
   pea_p = next_pea_p;
   SetPos(next_pea_p);
   SetColor(1);
   cout << "■";
   SetColor(2);
  }
  SetPos(snake_v[0]);
  cout << "■";
  break;
 case 77:
  temp = snake_v.back();
  for (int i = snake_v.size() - 1; i > 0; i--)
  {
   snake_v[i] = snake_v[i - 1];
   map[snake_v[i].x / 2][snake_v[i].y] = 1;
  }
  snake_v[0].x += 2;
  if (!(snake_v[0] == pea_p))
  {
   map[temp.x / 2][temp.y] = 0;
   SetPos(temp);
   cout << "  ";
  }
  else
  {
   snake_v.push_back(temp);
   next_pea_p = Pea();
   pea_p = next_pea_p;
   SetPos(next_pea_p);
   SetColor(1);
   cout << "■";
   SetColor(2);
  }
  SetPos(snake_v[0]);
  cout << "■";
  break;
 default:
  break;
 }
}
Pos Snake::Pea()
{
 Pos temp;
 int r_x = rand() % 19 * 2 + 2;
 int r_y = rand() % 24 + 1;
 while (map[r_x / 2][r_y])
 {
  r_x = rand() % 19 * 2 + 2;
  r_y = rand() % 24 + 1;
 }
 temp = { r_x,r_y };
 return temp;
}
void Snake::Pause()
{
 char temp;
 while (1)
 {
  while (1)
  {
   if (_kbhit())
   {
    temp = _getch();
    break;
   }
  }
  if (temp == 32)
   break;
  else if (temp == 27)
   exit(1);
 }
}
#endif // !SNAKE_H_

main.cpp

#include <iostream>
#include <windows.h>

#include <Snake.h>

using namespace std;

int main(int argc, char** argv)
{
 system("mode con cols=42 lines=26");
 Snake game;
 game.Welcome();
 system("cls");
 game.DrawMap();
 game.Run();
 system("pause");
 return (0);
}

效果:
在這裏插入圖片描述
如有不妥之處,望指正。
[email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章