MCU Snake Program Lcd12864 Display

Publisher:数据之翼Latest update time:2020-01-09 Source: 51heiKeywords:MCU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The MCU source program of the snake is as follows:

/***************************************************************

Function description: Greedy Snake

Compilation environment: keil4

MCU: STC89C52RC

Clock frequency: 22.1184MHz


Note: The "pass" in this routine cannot be displayed normally in the keil4 compilation environment

****************************************************************/

/********************************************************************

                    /^/^

                  _|__| O|

         / /~ _/

          ____|__________/ 

                 _______     

                         `                      

                           | |                 

                          //                   

                         // \

                       //                         

                      //                             

                    //_----_               

                   / / _-~ ~-_ | |

                 ( ( _-~ _--_ ~-_ _/ |

                         ~-____-~ _-~ ~-_ ~-_-~ /

                     ~-_ _-~ ~-_ _-~   

                        ~--______-~ ~-___-~  

*********************************************************************/

#include "stc.h"

#include "Lcd12864.h"

#include "Key.h"

#define uchar unsigned char

#define uint unsigned int


static unsigned long Seed = 1;

#define A 48271L

#define M 2147483647L

#define Q (M / A)

#define R (M % A)

/************************************

Pseudo-random number generator

*************************************/

double Random(void)

{

        long TmpSeed;

        TmpSeed=A*(Seed%Q)-R*(Seed/Q);

        if(TmpSeed>=0)

                Seed=TmpSeed;

        else

                Seed=TmpSeed+M;

        return (double)Seed/M;

}


/**************************************

Seeding the pseudo-random number generator

*******************************************/

void InitRandom(unsigned long InitVal)

{

        Seed=InitVal;

}


//Delay subroutine

void delay(unsigned int t)

{  

        unsigned int i,j;

        for(i=0;i                for(j=0;j<10;j++);    

}


/*************************************

Initialize MPU

**********************************/

void InitCpu(void)

{

        TMOD=0x01;

        TH0=0;

        TL0=0;

        TR0=1;

        ET0=1;

        EA=1;

}


#define N 25

struct Food

{

        unsigned char x;

        unsigned char y;

        unsigned char yes;

}food; //food structure

struct Snake

{

        unsigned char x[N];

        unsigned char y[N];

        unsigned char node;

        unsigned char direction;

        unsigned char life;

}snake; //Snake structure


unsigned char Flag=0;

unsigned char Score=0;

unsigned char Speed=5; //The larger the speed, the slower the speed

unsigned char KeyBuffer=0;

#define FUNC 1 //(P3^1) indicates level

#define UP 2 //(P3^3) indicates left

#define DOWN 3 //(P3^5) indicates right

#define LEFT 4 //(P3^4) means down

#define RIGHT 5 //(P3^2) indicates up

#define PASSSCORE 20 //Predefined pass score

void Timer0Int(void) interrupt 1

{

        switch(OSReadKey())

        {

                case 5:

                                KeyBuffer=FUNC; // indicates the level

                                /*if(++Speed>=10)

                                        Speed=1;

                                   Flag|=1<<1; //speed change flag set to 1*/

                                break;

                case 21:

                                KeyBuffer=DOWN; //Indicates right

                                /*if(snake.direction!=2)

                                        snake.direction=1;*/

                                break;

                case 13:

                                KeyBuffer=UP; //Indicates left

                                /*if(snake.direction!=1)

                                        snake.direction=2;*/

                                break;

                case 9:

                                KeyBuffer=RIGHT; // indicates up

                                /*if(snake.direction!=4)

                                        snake.direction=3;*/

                                break;

                   case 17:

                                KeyBuffer=LEFT; // means next

                                /*if(snake.direction!=3)

                                        snake.direction=4;*/

                                break;

                default:

                                break;

        }

}


/**********************************

Draw the wall and initialize the interface

*******************************/

void DrawBoard(void)

{

        unsigned char n;

        for(n=0;n<31;n++)

        {

                Lcd_Rectangle(3*n,0,3*n+2,2,1);

                Lcd_Rectangle(3*n,60,3*n+2,62,1);

        }

        for(n=0;n<21;n++)

        {

                Lcd_Rectangle(0,3*n,2,3*n+2,1);

                Lcd_Rectangle(90,3*n,92,3*n+2,1);                

        }

        Lcd_HoriLine(93,31,35,1);

        Lcd_HoriLine(93,63,35,1);

}


/*******************************

Printing results

****************************/

void PrintScore(void)

{

        unsigned char Str[3];

        Lcd_WriteStr(6,0,"Results");

        Str[0]=(Score/10)|0x30;//ten digit

        Str[1]=(Score%10)|0x30;//unit digit

        Str[2]=0;

        Lcd_WriteStr(7,1,Str);

}


/********************************

Print speed class

*********************************/

void PrintSpeed(void)

{

        unsigned char Str[2];

        Lcd_WriteStr(6,2,"Level");

        Str[0]=Speed|0x30;

        Str[1]=0;

        Lcd_WriteStr(7,3,Str);

}


/***********************************

Game over processing

************************************/

void GameOver(void)

{

        unsigned char n;

        Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,0); //Eliminate the food

        for(n=1;n        {

                Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,0); //Eliminate the food. The snake head has already reached the wall, so it does not need to be eliminated.                

        }

        if(snake.life==0) //If the snake is still alive

                Lcd_WriteStr(2,1,"pass");

        else //If the snake is dead

                Lcd_WriteStr(2,1,"Lost");

        Lcd_WriteStr(1,2,"Game over");

}


/********************************

The specific process of the game is also the key part of the snake algorithm

*********************************/

void GamePlay(void)

{

        unsigned char n;

        InitRandom(TL0);

        food.yes=1; //1 means new things need to appear, 0 means food already exists but has not been eaten

        snake.life=0; // means the snake is still alive

        snake.direction=DOWN;

        snake.x[0]=6;snake.y[0]=6;

        snake.x[1]=3;snake.y[1]=6;

        snake.node=2;

        PrintScore();

        PrintSpeed();

        while(1)

        {

                if(food.yes==1)

                {

                        while(1)

                        {

                                food.x=Random()*85+3;

                                food.y=Random()*55+3; //Get a random number

        

                                while(food.x%3!=0)

                                        food.x++;

                                while(food.y%3!=0)

                                        food.y++;

                            for(n=0;n                                {

                                        if ((food.x == snake.x[n]) && (food.y == snake.y[n]))

                                                break;

                                }

                                if(n==snake.node)

                                {

                                        food.yes=0;

                                        break; //Generate valid food coordinates

                                }

                        }

                }

                if(food.yes==0)

                {

                        Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,1);

                }        

                for(n=snake.node-1;n>0;n--)

                {

                        snake.x[n]=snake.x[n-1];

                        snake.y[n]=snake.y[n-1];

                }

                switch(snake.direction)

                {

                        case DOWN:snake.x[0]+=3;break;

                        case UP: snake.x[0]-=3;break;

                        case RIGHT:snake.y[0]-=3;break;

                        case LEFT: snake.y[0]+=3;break;

                        default:break;

                }

                for(n=3;n                {

                        if (snake.x[n]==snake.x[0]&&snake.y[n]==snake.y[0])

                        {

                                GameOver();

                                snake.life=1;

                                break;

                        }

                }

                if(snake.x[0]<3||snake.x[0]>=90||snake.y[0]<3||snake.y[0]>=60)//Judge whether the snake head hits the wall

                {

                        GameOver();

                        snake.life=1;

                }

                if(snake.life==1)

                        break; //If the snake dies, it will jump out of the while(1) loop

                if(snake.x[0]==food.x&&snake.y[0]==food.y)//Judge whether the snake has eaten food

                {

                        Lcd_Rectangle(food.x,food.y,food.x+2,food.y+2,0); //Hide food

                        snake.x[snake.node]=200;

                        snake.y[snake.node]=200; //Generate new node coordinates of snake and place them in invisible position first

                        snake.node++; //Snake node number plus 1

                        food.yes=1; //food flag set to 1

                        if(++Score>=PASSSCORE)

                        {

                                PrintScore();

                                GameOver();

                                break;

                        }

                        PrintScore();

                }

                for(n=0;n                {

                        Lcd_Rectangle(snake.x[n],snake.y[n],snake.x[n]+2,snake.y[n]+2,1);

[1] [2]
Keywords:MCU Reference address:MCU Snake Program Lcd12864 Display

Previous article:51 MCU + ULN2003 drive 5V deceleration stepper motor program
Next article:DHT11 temperature and humidity acquisition system based on single chip microcomputer

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号