2021年4月27日 星期二

貪食蛇程式分析

 #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;

}

沒有留言:

張貼留言

標籤