#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Point{ // 與位置相關的類別
private: // 宣告私有資料成員
int x;
int y;
public: // 宣告公用資料成員
Point(int a,int b) // 宣告公用成員函數,有傳值時x=a,y=b沒有傳
{
x=a;
y=b;
}
Point() // 宣告公用成員函數,沒有傳值時x=0,y=0
{
x=0;
y=0;
}
void setPoint(int a,int b) // 設定x,y的位置函數
{
x=a;
y=b;
}
int getX() // 取得X方向的位置函數
{
return x;
}
int getY() // 取得y方向的位置函數
{
return y;
}
};
class SnakeGame{ // 與位置相關的類別
private:
char area[10][10]; //定義遊戲範圍為10X10的二維陣列
Point head; //定義"頭"的資料型態為Point
Point body[64]; //定義"身體"
Point tail; //定義"尾巴"
Point food; //定義"食物"
int Length; //定義"長度"為整數
public:
SnakeGame()
{
Length=5;
// 設定蛇與食物的初始位置
head.setPoint(4,3);
body[0].setPoint(4,4);
body[1].setPoint(4,5);
body[2].setPoint(4,6);
body[3].setPoint(4,7);
tail.setPoint(4,7);
food.setPoint(4,1);
for(int i=0;i<10;i++) // 利用二維迴圈劃出遊戲範圍
{
for(int j=0;j<10;j++){
if(i==0||i==9||j==0||j==9)
area[i][j]='#';
else
area[i][j]=' ';
}
}
// 畫出蛇與食物位置
area[head.getX()][head.getY()]='O';
area[body[0].getX()][body[0].getY()]='O';
area[body[1].getX()][body[1].getY()]='O';
area[body[2].getX()][body[2].getY()]='O';
area[tail.getX()][tail.getY()]='O';
area[food.getX()][food.getY()]='*';
}
bool checkSpace(int step){ // 檢查蛇是否撞到牆壁或者回頭吃到自己的函數
if(step==76){ // 往左邊走一步,76是L的ascii碼
return !( area[head.getX() ][head.getY()-1]=='#'||area[head.getX()][head.getY()-1]=='O');
}
else if(step==85){ //往上面走一步,85是U的ascii碼
return !(area[head.getX()-1][head.getY()]=='#'||area[head.getX()-1][head.getY()]=='O');
}
else if(step==82){ //往右邊走一步,82是R的ascii碼
return !(area[head.getX()][head.getY()+1]=='#'||area[head.getX()][head.getY()+1]=='O');
}
else if(step==68){ //往下面走一步,68是D的ascii碼
return !(area[head.getX()+1][head.getY()]=='#'||area[head.getX()+1][head.getY()]=='O');
}
}
void run(int step){ // 蛇移動時的處理函數
tail.setPoint(body[Length-2].getX(),body[Length-2].getY());
int tempX=tail.getX();
int tempY=tail.getY();
area[tail.getX()][tail.getY()]=' '; // 蛇移動後用空白將尾巴消除
// 蛇移動後身體往前移動一格
for(int i =Length-1;i>0;i--)
{body[i].setPoint(body[i-1].getX(),body[i-1].getY());}
body[0].setPoint(head.getX(),head.getY());
// 蛇頭移動後的處理方式
if(step==76){ //蛇頭往左邊移動一格
head.setPoint(head.getX(),head.getY()-1);}
else if(step==85){//蛇頭往上面移動一格
head.setPoint(head.getX()-1,head.getY());}
else if(step==82){//蛇頭往右邊移動一格
head.setPoint(head.getX(),head.getY()+1);}
else if(step==68){//蛇頭往下面移動一格
head.setPoint(head.getX()+1,head.getY());}
for(int i =0;i<Length-2;i++)
{area[body[i].getX()][body[i].getY()]='O';}
area[head.getX()][head.getY()]='O';
Eatfood(tempX,tempY);
}
void printArea(){ // 畫出10X10範圍內的圖像函數
for(int i=0;i<10;i++){
for(int j=0;j<10;j++)
{cout<<area[i][j];}
cout<<endl;
}
}
void Foodset() // 設定食物位置的函數
{
int foodX,foodY;
srand((unsigned)time(NULL));
// 亂數產生新的食物
foodX=(rand()%8)+1;
foodY=(rand()%8)+1;
for(int i =0;i<Length-2;i++) // 檢查亂數產生新的食物是否跟蛇的身體重疊
{
if(foodX != body[i].getX() && foodY != body[i].getY())
{if((foodX != head.getX() && foodY != head.getY()) ||( foodX!=0 && foodY!=0) || (foodX != tail.getX() && foodY != tail.getY()))
{food.setPoint(foodX,foodY);}}
}
area[food.getX()][food.getY()]='*';
}
void Eatfood(int tempX,int tempY){ // 蛇吃到食物的處理函數
if(head.getX()==food.getX()&&head.getY()==food.getY()) // 判斷蛇有沒有吃到食物
{
Length++; // 蛇長度+1
body[Length-1].setPoint(tempX,tempY);
area[body[Length-1].getX()][body[Length-1].getY()]='O';
Foodset(); // 產生新的食物
}
}
};
int main(int argc, char** argv) { // 主程式
SnakeGame sg;
char step;
while(1)
{
sg.printArea();
cout<<"請輸入移動方向(U/D/L/R):";
cin>>step;
if(step==76||step==85||step==82||step==68)
{
if(sg.checkSpace(step)) // 檢查蛇移動後是否違反規則
{sg.run(step); // 蛇移動
}
else{ // 蛇是撞到牆壁或者回頭吃到自己則結束程式
cout<<"GameOver"<<endl;
break;}
}
system("cls");
}
return 0;
}