/*

                         \\\|///
                       \\  - -  //
                        (  @ @  )
+---------------------oOOo-(_)-oOOo-------------------------+
|                 智林STM32开发板试验程序                   |
|                 Timer2 PWM 输出方式试验                   |
|                 刘笑然 by Xiaoran Liu                     |
|                        2008.4.16                          |
|                                                           |
|           智林测控技术研究所 ZERO research group          |
|                      www.the0.net                         |
|                             Oooo                          |
+-----------------------oooO--(   )-------------------------+
                       (   )   ) /
                        \ (   (_/
                         \_)     

*/
/*----------------------------------------------------------*\
 |  引入相关芯片的头文件                                    |
\*----------------------------------------------------------*/
#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include  <math.h>
#include  <stdarg.h>
#include  <time.h>

#include <stm32f10x_lib.h>    // STM32F10x Library Definitions
#include "STM32_Init.h"       // STM32 Initialization
#include "TFT018.h"
/*----------------------------------------------------------*\
 | HARDWARE DEFINE                                          |
\*----------------------------------------------------------*/
#define LED             ( 1 << 5 )              // PB5: LED D2

#define BP2             0x2000                     // PC13: BP2
#define BP3             0x0001                     // PA0 : BP3

#define UP              0x0800                     // PB11: UP
#define RIGHT           0x1000                     // PB12: RIGHT
#define LEFT            0x2000                     // PB13: LEFT
#define DOWN            0x4000                     // PB14: DOWN
#define OK              0x8000                     // PB15: OK

#define JOYSTICK        0xF800                     // JOYSTICK ALL KEYS
#define KEY_NONE        0xF800                     // JOYSTICK ALL KEYS
/*----------------------------------------------------------*\
 | SOFTWARE DATA                                            |
\*----------------------------------------------------------*/
#define N 200

int i,key;
int score=0;
int gamespeed=320;

struct Food {
    int x;
    int y;
    int yes;
}food;

struct Snake {
    int x[N];
    int y[N];
    int node;
    int direction;
    int life;
}snake;
/*----------------------------------------------------------*\
 |  Delay                                                   |
 |  延时 Inserts a delay time.                              |
 |  nCount: 延时时间                                        |
 |  nCount: specifies the delay time length.                |
\*----------------------------------------------------------*/
void delay(vu32 nCount) {
  for(; nCount != 0; nCount--) {
    unsigned int j;
	for(j=0;j<5000;j++);
    }
  }
DElAY(char ch) {
    if (ch=='3') {
        delay(gamespeed);
        delay(gamespeed);
    } else if (ch=='2') {
        delay(gamespeed);
    }
}
unsigned short ReadKey(void) {
	unsigned short k;
	k=(unsigned short)(GPIOB->IDR & JOYSTICK);
	return k;
	}
unsigned short getch( void ) {
	unsigned short K;
	while( (K=ReadKey()) == KEY_NONE );
	return K;
	}
void Init(void) {
  stm32_Init ();                                // STM32 setup
  LCD_Init();
  LCD_Clear_Screen(Blue);
  }
void DrawK(void) {
    /*setbkcolor(LIGHTGREEN);*/
    for (i=0;i<=159;i+=3) {
		LCD_Rectangle( i,20,i+2,22,0x07FF );
		LCD_Rectangle( i,125,i+2,127,0x07FF );
    }
    for (i=20;i<=124;i+=3) {
		LCD_Rectangle( 0,i,2,i+2,0x07FF );
		LCD_Rectangle( 156,i,159,i+2,0x07FF );
    }
}
void PrScore(void) {
    char str[10];
    sprintf(str,"score:%d",score);
	LCD_PutString( 10,0,str,0xF800,0x0000 );
}
void GameOver(void) {
	LCD_Clear_Screen( 0x001F );
    PrScore();
	LCD_PutString( 10,50,"GAME OVER",0xF800,0x0000 );
    getch();
}


void Close(void) {
    getch();
}
void GamePlay(char ch) {
    //char str[10];

    //randomize();
	srand(123785);
    food.yes=1;
    snake.life=0;
    snake.direction=1;
    snake.x[0]=78;
    snake.y[0]=56;
    snake.x[1]=81;
    snake.y[1]=56;
    snake.node=2;
    PrScore();
    while (1) {
		while( (key=ReadKey()) == KEY_NONE ) {
            if (food.yes==1) {
                food.x=(rand()%51)*3+3;
                food.y=(rand()%34)*3+20;
                food.yes=0;
            }
            if (food.yes==0) {
				LCD_Rectangle( food.x,food.y-2,food.x+2,food.y,0x07E0 );
            }
            for (i=snake.node-1;i>0;i--) {
                snake.x[i]=snake.x[i-1];
                snake.y[i]=snake.y[i-1];
            }

            switch (snake.direction) {
            case 1:
                snake.x[0]+=3;
                break;
            case 2:
                snake.x[0]-=3;
                break;
            case 3:
                snake.y[0]-=3;
                break;
            case 4:
                snake.y[0]+=3;
                break;
            }
            for (i=3;i<snake.node;i++) {
                if (snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]) {
                    GameOver();
                    snake.life=1;
                    break;
                }
            }
            if (snake.x[0]<3||snake.x[0]>155||snake.y[0]<20||
                    snake.y[0]>125) {
                GameOver();
                snake.life=1;
            }
            if (snake.life==1)
                break;
            if (snake.x[0]==food.x&&snake.y[0]==food.y) {
				LCD_Rectangle( food.x,food.y-2,food.x+2,food.y,0x07E0 );
                snake.x[snake.node]=-3;
                snake.y[snake.node]=-3;

                snake.node++;
                food.yes=1;
                score+=10;
                PrScore();
            }
            for (i=0;i<snake.node;i++)
				LCD_Rectangle( snake.x[i],snake.y[i]-2,snake.x[i]+2,snake.y[i],0xFFE0 );
            delay(gamespeed);
            DElAY(ch);
			LCD_Rectangle( snake.x[snake.node-1],snake.y[snake.node-1]-2,snake.x[snake.node-1]+2,snake.y[snake.node-1],0x0000 );
        } /*endwhile（！kbhit）*/
        if (snake.life==1)
            break;
        if ((key&OK)==0)
            break;
        else
            if ((key&UP)==0&&snake.direction!=4)

                snake.direction=3;
            else
                if ((key&RIGHT)==0&&snake.direction!=2)
                    snake.direction=1;
                else
                    if ((key&LEFT)==0&&snake.direction!=1)
                        snake.direction=2;
                    else
                        if ((key&DOWN)==0&&snake.direction!=3)
                            snake.direction=4;

    //sprintf(str,"%X",key);
	//LCD_PutString( 80,0,str,0xF800,0x0000 );

    }/*endwhile(1)*/
}
/*----------------------------------------------------------*\
 | MIAN ENTRY                                               |
\*----------------------------------------------------------*/
int main (void) {
  int ch='2';
  Init();
    DrawK();
    GamePlay(ch);
    Close();
  for(;;) {
    }
  }
/*----------------------------------------------------------*\
 | END OF FILE                                              |
\*----------------------------------------------------------*/
