/*
  
 /*
  头尾平移的方法实现
  By black4yl
  原理:
  在大小为100的数组中,利用head,rear标记的头,尾坐标值,定位当前头和尾巴。
  在行走时,擦去尾巴,按方向标记新头,擦去旧头, 实现蛇行走。
  当吃到食物时,只变化头,不变化

*/
#include"windows.h"
#include"conio.h"
#include"iostream"
#include<time.h>
using namespace std;

#define up      72
#define down    80
#define left    75
#define right   77

void GotoXY(int x,int y)
{
    COORD c;
    c.X=x-1; c.Y=y-1;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}

void Display(char img[][22],int score,int speed)   //0为空 1为身子 2为头 3为食物
{
    system("cls");
    int i,j;
    GotoXY(1,1);
    for(i=0;i<24;i++)  cout<<"□";
    cout<<endl;
    for(i=0;i<22;i++)
    {
        cout<<"□";
        for(j=0;j<22;j++)
        {
                if(img[i][j]==0)
                    cout<<"  ";
                if(img[i][j]==1)
                    cout<<"○";
                if(img[i][j]==2)
                    cout<<"○";
                if(img[i][j]==3)
                    cout<<"○";
        }
        
        cout<<"□"<<endl;
    }
    for(i=0;i<24;i++)  cout<<"□";
        GotoXY(50,10); printf("Score:  %d 分",score);
        GotoXY(50,11); printf("speed=  %d ms",speed);
}
void Welcome()
{
    long time=clock();

    GotoXY(3,8);
    cout<<"欢迎进入贪吃蛇游戏"<<endl;
    while(clock()-time<2000);
    system("cls");
    GotoXY(3,8);
    time=clock();
    cout<<"操作方法: 按 上 下 左 右 键控制蛇,以便吃到更多的食物,不要饿死哦~ "<<endl;
    GotoXY(6,13);
    int i=4;
    do
    {
        time=clock();
        while(clock()-time<1000);    
        GotoXY(6,13);
        cout<<"游戏将在--"<<i<<"--秒"<<"后开始";
    }while(i--);
    system("cls");
}
int main()
{
    int x, y;
    int fx,fy;  //食物
    srand(time(0));
    fx=rand()%20+1;
    fy=rand()%20+1;
    int len=0;
    int i,j;
    int tcspos[2][150];
    char img[22][22]={0};
    char arr=77;
    long time;//时间
    int timeover;
    int speed=500,score=0;
    int head,rear;
    head=3;
    rear=0;
    for(i=0; i<4; i++){        //初始化蛇身
        tcspos[0][i] = 1;
        tcspos[1][i] = i + 1;
    }
     img[fy][fx]=3;      
    Welcome();
    Display(img,score,speed);
    while(1)
    {    
        timeover=1;
        time=clock();
        while((timeover=clock()-time<=speed)&&!kbhit());
        if(timeover)  //timeover 非0,说明是按键中断循环
        {
            getch();
            arr=getch();
        }
        switch(arr)
        {                //完成操作
            case up: y=tcspos[1][head]-1; x=tcspos[0][head]; break;                            //上
            case down: y=tcspos[1][head]+1; x=tcspos[0][head];  break;                        //下
            case left: y=tcspos[1][head]; x=tcspos[0][head]-1;  break;                        //左
            case right: y=tcspos[1][head]; x=tcspos[0][head]+1; break;                        //右
        }
        if(img[y][x]!=0&&!((x==fx)&&(y==fy)))  //冲突
        {    
             break; //结束
        }
        if(x<0||x>21||y<0||y>21)
        {
                break; //结束
        }
        if((x==fx)&&(y==fy))  //吃到
        {    
            len++;
            score+=2;   //每吃一个加2分
            if(len>9)  //蛇长大于10,
            {
                len%=9;  //重新计算
                speed-=20;  //每次速度增加20ms
                score+=10;  //没完成一个10,则多加10分
            }

        img[tcspos[1][head]][tcspos[0][head]]=2; //标记行走后的头
        head=(head+1)%150; //head 移到第二位;
        tcspos[0][head]=x;  //设置蛇头坐标
        tcspos[1][head]=y;
        do                        //生产食物
        {
            fx=rand()%21+1;
            fy=rand()%21+1;
        }while(img[fy][fx]!=0);
        img[fy][fx]=3;
        Display(img,score,speed);
        }
        else   //没吃到
        {    
            img[tcspos[1][head]][tcspos[0][head]]=1; //头变为身子
            head=(head+1)%150;            //头前移
            img[tcspos[1][rear]][tcspos[0][rear]]=0; //消去尾巴
            rear=(rear+1)%150;          //尾巴前移
            tcspos[1][head]=y;
            tcspos[0][head]=x;
            img[tcspos[1][head]][tcspos[0][head]]=2;  //标记新头
            Display(img,score,speed);
        }

    }  //while()
            system("cls");
            GotoXY(20,12);
            cout<<"score:"<<score<<endl;
            GotoXY(20,13);
            cout<<"---Game Over---"<<endl;
            GotoXY(20,14);
            cout<<"请输入您的姓名:";
            getchar();
}