In the LINUX environment, the terminal uses C language to realize the push box game

First of all, to play this game, you have to get the key value of the keyboard to determine the direction

Get the function of the direction key: use the header file getch gech function in H
The code is as follows:

#ifndef GETCH_H
#define GETCH_H

#include <termios.h>
#include <unistd.h>

//Modify the control mode of the terminal, 1 cancel echo and confirm, 2 obtain data and 3 restore
static int getch(void)
{
    // Record the configuration information of the terminal
    struct termios old;
    // Obtain the configuration information of the terminal
    tcgetattr(STDIN_FILENO,&old);
    // Set new terminal configuration   
    struct termios new = old;
    // Cancel confirmation and echo
    new.c_lflag &= ~(ICANON|ECHO);
    // Setting terminal configuration information
    tcsetattr(STDIN_FILENO,TCSANOW,&new);

    // Get data in new mode   
    int key_val = 0; 
    do{
    	key_val += getchar();
    }while(stdin->_IO_read_end - stdin->_IO_read_ptr);

    // Restore configuration information
    tcsetattr(STDIN_FILENO,TCSANOW,&old); 
    return key_val; 
}

#endif//GETCH_H

After creating the header file, the steps from the computer to the virtual LINUX environment are as follows:

1,stay windows Middle handle getch.h Put header file in shared folder

2,The terminal enters the contribution folder:
    cd /media/sf_Share
    
3,Copy header file to shared library
    sudo cp getch.h /usr/include/
    
4,Add read permission:
    sudo chmod +r /usr/include/gerch.h 

Test the upper, lower, left and right key values respectively

 #include <stdio.h>
 #include<getch.h>
 int main(int argc,const char*argv[])
 {
    for(int i=0;i<4;i++)
         printf("%d ",getch());
  }

The obtained direction and key values are as follows:

Up: 183 down: 184 right: 185 left: 186

Then roughly analyze the overall outline of the code
1. Determine various corresponding relationships, and what are the walls and roads represented by
2. Draw a map
3. Move rules
4. Judgment rules

When you're ready, you can write code

1. First analyze the situation
The push box game consists of roads, walls, people, boxes and targets
Therefore, we can consider using different numbers to represent these scenarios, combined with a two-dimensional array to form a basic map
My settings here are as follows: the numbers 0, 1, 2, 3 and 4 represent the road, wall, person, box and target respectively
2. The map is defined as follows:

	int arry[8][8]={
		{1,1,1,1,1,1,1,1},
		{1,1,1,4,4,1,1,1},
		{1,1,1,0,4,1,1,1},
		{1,1,0,0,3,4,1,1},
		{1,1,0,3,0,0,1,1},
		{1,0,0,1,3,3,0,1},
		{1,2,0,0,0,0,0,1},
		{1,1,1,1,1,1,1,1}
		};//0 Road 1 wall 2 people 3 boxes 4 targets

The printing effect is as follows

		for(i=0;i<8;i++)
		{
			for(j=0;j<8;j++)
			{
				switch(arry[i][j])
				{
					case 1:
						printf(" * ");break;
					case 0:
						printf("   ");break;
					case 2:
						printf(" @ ");break;
					case 3:
						printf(" # ");break;
					case 4:
						printf(" o ");break;
				}
			}
			printf("\n");
		}

You can see that there is already a basic outline

3. Then let's analyze the movement rules:
(1) If the moving direction is the road ahead, you can move forward
The moving direction is ahead, and the target can move forward
In the past, if the front is a box, and the front of the box is a target or road, you can push forward

4. Judgment of victory rule: since the target point is set by itself, the value on the target point can be directly judged when the coordinates are known,
For example, here is (1,3) (1,4) (2,4) (3,5)
If the values on these coordinates are equal to 3, the boxes are home

Based on the two-dimensional array and easy to understand, indix1 and indix2 are defined as human row and column subscripts respectively
Then the person's:

Up direction  arry [indix1-1] [indix2]
Down direction  arry [indix1+1] [indix2]
Left direction  arry [indix1] [indix2-1]
Right direction  arry [indix1] [indix2+1]

The code example of moving up is as follows:

switch(getch())//Get key value
{
	case 183:   //Moving direction up
		if(arry[indix1-1][indix2]==0||arry[indix1-1][indix2]==4)//Line coordinate - 1. If it is judged that there is a road or target above, it can move upward,
		{	
		    arry[indix1-1][indix2]=2;      //Reassign and update the position of people on the map			
			if((indix1==1&&(indix2==3||indix2==4))||(indix1==2&&indix2==4)||(indix1==3&&indix2==5))
				arry[indix1][indix2]=4;          //The exit position is the target point and mark back to the target    
			else
				arry[indix1][indix2]=0;        //Otherwise, the transformer circuit
			indix1=indix1-1;        //Update the human subscript to facilitate the next judgment
			cnt++;         //Record steps
		}
		else if(arry[indix1-1][indix2]==3)       //If there is a box above
		{
			if(arry[indix1-2][indix2]==0||arry[indix1-2][indix2]==4)   //If there is a road or target in front of the box, you can push it
			{
				arry[indix1-2][indix2]=3;      //Box location update
				arry[indix1-1][indix2]=2;      //Human location update
				if((indix1==1&&(indix2==3||indix2==4))||(indix1==2&&indix2==4)||(indix1==3&&indix2==5))
					arry[indix1][indix2]=4;     //The exit position is the target point and mark back to the target    
				else
					arry[indix1][indix2]=0;     //Otherwise, the transformer circuit
				indix1=indix1-1;          //Update the human subscript to facilitate the next judgment
				cnt++;
			}
		}
		break;

The principles of the following directions are similar. Just copy the code and change the direction. For space reasons, it is not posted here

There are many similarities between the codes in several directions. You can consider summarizing the optimized code

As mentioned earlier, this is a representation of direction:
Up direction  arry [indix1-1] [indix2]
Down direction  arry [indix1+1] [indix2]
Left direction  arry [indix1] [indix2-1]
Right direction  arry [indix1] [indix2+1]

  The up-down direction and left-right direction can be represented by a variable respectively. After obtaining the corresponding key values, the different variables can be changed
 Quantity is used here up Indicates up and down on Left and right
 direction  arry [indix1+up] [indix2+on]about(up,on)=(-1,0)/(1,0)/(0,-1)/(0,1)It can indicate all directions

  For the update after moving and pushing boxes, another assignment relationship can be considered, so the coordinate judgment method is not used to judge the access target value and success
 It is defined as follows:
1,If the person moves to a new location or target, the coordinates there are+=2,That is, add the value corresponding to the person and leave-=2
   In this way, if the moving direction is road 0+2=2,If it's goal 4+2=6,So 6 it's also people
   Leave the original position 2-2=0,Reduction path; six-2=4 Restore target
2,The same is true for pushing the box. If you can push, the value of the coordinate to which the box should be moved+=3,People move to the position of the box-=1;Leave the original position-=2
   In this way, if the moving direction is road 0+4=2,Move to box position 3-1=2(Printed or human), leave the original position 2-2=0,Restore path
	
	If it's goal 4+3=7,So 7 the printed box is also the box that has reached the target!!

That's the basic principle

Optimized code


		cnt=0;    //Record the number of boxes entering the target, and it is determined that all boxes enter successfully
		up=0;	   //Clear last direction
		on=0;	   //Clear last direction
		
		switch(getch())    //Gets the key value and determines the direction of movement
		{
			case 183:
				up--;
				break;
			case 184:
				up++;
				break;
			case 185:
				on++;
				break;
			case 186:
				on--;
				break;
		}
		if(0==arry[indix1+up][indix2+on]||4==arry[indix1+up][indix2+on])	//Is it a road or a goal
		{
			arry[indix1+up][indix2+on] +=2;    //New location
			arry[indix1][indix2]  -=2;		  //Old location
			indix1 +=up;      //Update person's coordinates
			indix2 +=on;
			step++;				//Record steps
		}
		else if(3==arry[indix1+up][indix2+on]||7==arry[indix1+up][indix2+on])	//It's a box
		{
			if(arry[indix1+up*2][indix2+on*2]==0||arry[indix1+up*2][indix2+on*2]==4) 
			//The direction of the box to move is the road or target
			{
				arry[indix1+up*2][indix2+on*2] +=3;		//New location of the box
				arry[indix1+up][indix2+on]  -=1;    	//People go to the original position of the box
				arry[indix1][indix2] -=2;				//Man's original position
				indix1 +=up;							//Subscript of Updater
				indix2 +=on;
				step++;        //Record steps
			}
		}

The total code is as follows:

#include <stdio.h>
#include<getch.h>
#include<stdlib.h>
int main(int argc,const char*argv[])
{
	
	int arry[8][8]={
		{0,0,0,1,1,1,0,0},
		{0,0,1,4,4,1,0,0},
		{0,0,1,0,4,1,1,0},
		{1,1,0,0,3,4,1,0},
		{1,1,0,3,0,0,1,1},
		{1,0,0,0,3,3,0,1},
		{1,2,0,0,0,0,0,1},
		{1,1,1,1,1,1,1,1}
		};//1 wall 2 people 3 box 4 target
		  //3 + 4 = 7 boxes
		  //2 + 4 = 6 persons
	
	int up,on,i,j,cnt=0,step=0,indix1=6,indix2=1;

	while(1)
	{
		system("clear");         //Clear screen
		cnt=0;
		up=0;
		on=0;

		for(i=0;i<8;i++)
		{
			for(j=0;j<8;j++)
			{
				switch(arry[i][j])
				{
					case 1:
						printf(" * ");break;
					case 0:
						printf("   ");break;
					case 2:
						printf(" @ ");break;
					case 3:
						printf(" # ");break;
					case 4:
						printf(" o ");break;
					case 6:
						printf(" @ ");break;
					case 7:
						cnt++;             //Count the number of superimposed targets and boxes
						printf(" # ");break;
				}
			}
			printf("\n");
		}

		if(cnt==4)         //If all four boxes are at the target position, you have succeeded
		{
			printf("be gone:%d Number of steps",step);
			return 0;
		}

		cnt=0;
		up=0;
		on=0;
		
		switch(getch())
		{
			case 183:
				up--;
				break;
			case 184:
				up++;
				break;
			case 185:
				on++;
				break;
			case 186:
				on--;
				break;
		}

		if(0==arry[indix1+up][indix2+on]||4==arry[indix1+up][indix2+on])	
		{
			arry[indix1+up][indix2+on] +=2;
			arry[indix1][indix2]  -=2;
			indix1 +=up;
			indix2 +=on;
			step++;
		}
		else if(3==arry[indix1+up][indix2+on]||7==arry[indix1+up][indix2+on])
		{
			if(arry[indix1+up*2][indix2+on*2]==0||arry[indix1+up*2][indix2+on*2]==4)
			{
				arry[indix1+up*2][indix2+on*2] +=3;
				arry[indix1+up][indix2+on]  -=1;
				arry[indix1][indix2] -=2;
				indix1 +=up;
				indix2 +=on;
				step++;
			}
		}

	}
}
	

Added by astarmathsandphysics on Sun, 16 Jan 2022 15:02:49 +0200