2.6 Snake applet
According to the test plan, complete the Snake applet and run it on the GD32E503V-EVAL development board.
2.6.1 Snake requirements
The snake requirements are as follows:
(1) The touch screen displays the snake body, snake head, food, etc.
(2) The snake body and tongue control the cursor movement direction through the touch screen
(3) Food can be generated randomly and will be eaten when it encounters the snake head
(4) When the snake eats the food, the snake body will increase the length of the food
(5) The snake's movement speed can be set and other settings are available.
2.6.2 Snake design instructions
1) Display interface
Set a two-dimensional map and define (x, y). The two-dimensional array displays the image location information.
Define the display mode of the snake body, snake head, food, and wall. The snake body is displayed as "X", the snake head is displayed as "H", the wall is displayed as "#", and the food is displayed as "*".
/****************************************************** *******************************
* Function: map creation
* void creatmap(char map[MAP_ROW][MAP_COLUMN])
*** *************************************************** *************************/
void creatmap(char map[6][20])
{
for (int i = 0; i < MAP_COLUMN; ++i) /* Wall created in bottom and top site*/
{
map[0] = wall;
map[MAP_ROW-1] = wall;
}
for (int i = 1; i < MAP_ROW- 1; ++i) /* Wall created in left and right site*/
{
map[0] = wall;
map[MAP_COLUMN-1] = wall;
}
for (int i = 1; i < MAP_ROW-1; ++i) /* Blank area used to display snake and food*/
{
for (int j = 1; j < MAP_COLUMN-1; ++j)
map[j] = ' ';
}
}
/****************************************************** *******************************
* Function: snake body creation
* void createsnake(int snake[MAP_ROW][MAP_COLUMN])
** *************************************************** ****************************/
void createsnake(int snake[6][20])
{
for (int i = 1; i < snake_initiallength ; ++i)
{
snake[1] = body;
++body;
}
}
/****************************** *************************************************** *
* Function: image displayed
* void displaymap(char map[MAP_ROW][MAP_COLUMN],int snake[MAP_ROW][MAP_COLUMN])
********************** *************************************************** ******/
void displaymap(char map[6][20],int snake[6][20])
{
/*In snake, 0 represents free position, -1 represents food, positive number represents snake*/
for (int i = 1; i < MAP_ROW-1; ++i)
{
for (int j = 1; j < MAP_COLUMN- 1; ++j)
{
if (snake[j] == 0)map[j] = ' ';
else map[j] = snake_body;
}
}
map[head_x][head_y ] = snake_head;
map[food_x][food_y] = food;
for (uint16_t i = 0; i < MAP_ROW; i++)
{
for (uint16_t j = 0; j < MAP_COLUMN; j++)
{
lcd_char_display((a1+8*j ), b3+i*16, map[j], char_format);
}
}
}
2) Control the movement of the snake
The movement of the snake is achieved by using the virtual buttons "↑", "↓", "←", and "→" on the touch screen. The snake moves according to inertia.
int a;
switch(button_id){
case 0: direction = FLAG_UP;break;
case 1: direction = FLAG_DOWN;break;
case 2: direction = FLAG_LEFT;break;
case 3: direction = FLAG_RIGHT;break;
default:
break;
}
switch (direction){
case 0:snake[head_x][head_y] = body; body++; head_x--; break;
case 1:snake[head_x][head_y] = body; body++; head_x++; break;
case 2:snake[head_x ][head_y] = body; body++; head_y--; break;
case 3: snake[head_x][head_y] = body; body++; head_y++; break;
default:
break;
}
if (snake[head_x][head_y] != -1)
{
a = snake[tail_x][tail_y];
snake[tail_x][tail_y] = 0;
if (tail_x + 1 < MAP_ROW - 1 && snake[tail_x + 1][tail_y] == a+1)
tail_x = tail_x + 1;
else
if (tail_x - 1 > 0 && snake[tail_x - 1][tail_y] == a + 1)
tail_x = tail_x - 1;
else
if (tail_y + 1 < MAP_COLUMN - 1 && snake[tail_x][tail_y + 1] == a + 1)
tail_y = tail_y + 1;
else
if (tail_y - 1 > 0 && snake[tail_x][tail_y - 1] == a + 1)
tail_y = tail_y - 1;
}
else
{
creatfood(snake);
}
num[0]=num[1 ]=num[2]=num[3]=0;
count=0;
}
b = judge(map);
3) Food placement
Use the random number function to place the coordinates of the food. If the food is not eaten, do not call the random number function; otherwise, regenerate it.
/**********************************************************************************
* Function: food creation
* void creatfood(int snake[MAP_ROW][MAP_COLUMN])
******************************************************************************/
void creatfood(int snake[6][20])
{
while (snake[food_x][food_y] != 0)
{
food_x = rand() % 6 ;
food_y = rand() % 20 ;
}
snake[food_x][food_y] = -1; /* The food is displayed with "-1" */
}
4) Changes when the snake eats food
The snake's head "eats" the food, the old food disappears, and the new food is displayed;
the snake's body grows.
5) Set the menu
Control button display
2.6.3 Snake program writing
For development speed, develop based on the GD32E503V-EVAL development board demo program "16_EXMC_TouchScreen".
1) Debug and test the "16_EXMC_TouchScreen" program
Shot JP12 (2, 3) for SPI0 function
The "16_EXMC_TouchScreen" program controls the touch screen through the "External momory controller (EXMC)"
interface 2) Program body
#include <stdlib.h>
#include <time.h>
uint16_t MAP_ROW = 6; /* map row*/
uint16_t MAP_COLUMN = 20; /* map COLUMN*/
char snake_head = 'H';
char snake_body = 'X';
char wall = '#';
char food = '*';
char map_string[6][20]={"###################",
"# #",
"# XH #",
"# * #",
"# #",
"###################"};
char gameover_string[1][10]={"GAME OVER!"};
uint16_t snake_initiallength = 5;
uint16_t body = 1;
uint8_t direction = 3; // snake movement direction
int tail_x = 1, tail_y = 1; // snake tail coordinates
int head_x = 1, head_y = 5; // initial snake head position
int food_x = 1, food_y = 1; // food position
void snake_init(void); /* snake app initiation */
void creatmap(char map[6][20]);
void creatsnake(int snake[6][20]);
void creatfood(int snake[6][20] );
void displaymap(char map[6][20],int snake[6][20]);
int judge(char map[6][20]);
/* main*/
uint8_t led_string[4][4]={"UPPE","DOWN","LEFT","RGHT"};
uint8_t button_id = 3;
enum eFLAG{
FLAG_UP = 0,
FLAG_DOWN = 1,
FLAG_LEFT = 2,
FLAG_RIGHT = 3
}direction;
snake_init();
char map[6][20]={0};
int snake[6][20]={0};
creatmap(map);
delay_1ms(100);
creatsnake(snake);
delay_1ms(100);
creatfood(snake);
delay_1ms(100);
while(1){
displaymap(map,snake);
/* get the position of touch on LCD screen */
if(SUCCESS == touch_scan()){
count++;
if(0x8989 == device_code){
/* SSD1289 */
get_touch_area (touch_coordinate_x_get(touch_ad_x),(LCD_Y - touch_coordinate_y_get(touch_ad_y)),num);
}else if((0x9320 == device_code) || (0x9300 == device_code)){
/* ILI9320 */
get_touch_area(LCD_X - touch_coordinate_x_get(touch_ad_x ),(LCD_Y - touch_coordinate_y_get(touch_ad_y)),num);
}
}
/* generate response to the touch(turn on LED and change picture)*/
if(count==20){
button_id = find_max(num);
turn_on_led(button_id);
//change_picture(button_id);
int a;
switch(button_id){
case 0: direction = FLAG_UP;break;
case 1: direction = FLAG_DOWN;break;
case 2: direction = FLAG_LEFT; break;
case 3: direction = FLAG_RIGHT;break;
default:
break;
}
switch(direction){
case 0:snake[head_x][head_y] = body; body++; head_x--; break;
case 1:snake[head_x][ head_y] = body; body++; head_x++; break;
case 2: snake[head_x][head_y] = body; body++; head_y--; break;
case 3: snake[head_x][head_y] = body; body++; head_y++; break ;
default:
break;
}
if (snake[head_x][head_y] != -1)
{
a = snake[tail_x][tail_y];
snake[tail_x][tail_y] = 0;
if (tail_x + 1 < MAP_ROW - 1 && snake[tail_x + 1] [tail_y] == a+1)
tail_x = tail_x + 1;
else
if (tail_x - 1 > 0 && snake[tail_x - 1][tail_y] == a + 1)
tail_x = tail_x - 1;
else
if (tail_y + 1 < MAP_COLUMN - 1 && snake[tail_x][tail_y + 1] == a + 1)
tail_y = tail_y + 1;
else
if (tail_y - 1 > 0 && snake[tail_x][tail_y - 1] == a + 1 )
tail_y = tail_y - 1;
}
else
{
creatfood(snake);
}
num[0]=num[1]=num[2]=num[3]=0;
count=0;
}
b = judge(map);
}
2.6.4 Snake Program Running
The program is running normally now! The wall-hitting program needs to be adjusted. Other operations are normal
|