Small game of pushing box -- c/c + + implementation

Push box must be a classic game in many people's childhood. We still remember the scene of holding an old man's machine for entertainment. Today, I'd like to use c/c + + to implement a simple push box game with the blogger.

Before writing the code, we must consider how to write the whole idea of the game, such as how to build a map, how to let people walk up and down, when to go, when not to go, how to represent the characters, space, wall in the game Wait a moment, etc. in order not to make the program appear disorderly and improve the readability of the code, we'd better write some functions to realize various functions in the game. So let's analyze.

If the map is like this:
We can use a two-dimensional array to store the map.

int map[8][8]={
	{1,1,1,1,1,1,1,1},//0 open space 
	{1,0,0,0,1,0,0,1},//1 walls 
	{1,0,1,0,1,4,3,1},//3 destination 
	{1,0,0,0,0,4,3,1},//4 boxes 
    {1,0,1,0,1,4,3,1},//5 person 
	{1,0,0,0,1,0,0,1},//7 box and destination overlap 
	{1,1,1,1,1,5,0,1},//8 people and destination 
	{0,0,0,0,1,1,1,1}};

It can be seen that the figure is 8 * 8 in size. We use 0.1.3.4.5.7.8 to represent each element in the figure respectively. Here we leave a foreshadowing. 7 is exactly equal to 3 + 4, which is the destination + box, 8 is exactly 5 + 3, which is + person and destination. In a moment, we can directly use the addition and subtraction method on the relative position when we judge the character movement.
But it's not easy to recognize the map. We are using two for loop traversal arrays and a switch statement to output the corresponding pictures respectively

 for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			switch(map[i][j])
			{
				case 0:printf("  ");break;
				case 1:printf("■");break;
				case 3:printf("☆");break;
				case 4:printf("□");break;
				case 5:printf("♀");break;
				case 7:printf("★");break;
				case 8:printf("♀");break;
			} 
		}
		cout<<endl; 
	} 

Let's see the effect

If you want to play different levels, you only need to change the size of the array or the number in the array!

How do we control the movement of characters? First of all, we need to find the location of the current character. We still only need to traverse the array once to find it, and store its subscript for the convenience of the next move judgment.

	int r,c;//Subscript subscript
	int flag=0;
	for(r=0;r<8;r++)
	 {
	 	for(c=0;c<8;c++)
	    {if(map[r][c]==5||map[r][c]==8)
	    	{
	     	flag=1;
	  	    break;
	    	}
		}
	 if(flag)
	 break;
     }

The purpose of using flag here is that if we find a person, we can exit the cycle without unnecessary operations to avoid wasting resources.
Here we use getch() to accept the direction control on the keyboard

After finding people, we use the up as an example to judge. We only need to write code when we can move, and we don't need to do anything when we can't move. There are several situations that can be moved:
1. It's open space
2. Above is the destination
3. It's a box, and it's a destination or an empty space
4. Above is the box + destination, and above the box + destination is the destination or open space

We use the if statement to judge

     	if(map[r-1][c]==0)//1. Corresponding to the empty space above
     	{map[r-1][c]=5;//Generate a person on it
     	 map[r][c]=0;}//The original man was replaced with a vacant lot
     	 
     	else if(map[r-1][c]==3)//2. Corresponding destination above
     	{map[r-1][c]=8;//Destination becomes destination + person
     	 map[r][c]=0;}//The original man was replaced by a vacant lot
     	 
     	else if(map[r-1][c]==4)//3. Corresponding to the box above
     	{	if(map[r-2][c]==3)//On top of the box is the destination 
			  {
			  	map[r-2][c]=7;//Box + destination on top of box
			  	map[r-1][c]=5;//Replace the box with an adult
			  	map[r][c]=0;//Replace people with empty space
			  } 
			if(map[r-2][c]==0)//There is an open space on the box
			  { map[r-2][c]=3;//The top of the box becomes a box
			  	map[r-1][c]=5;//Replace the box with an adult
			  	map[r][c]=0;//Replace people with empty space
			  }
     	}
       else if(map[r-1][c]==7)//4. Corresponding box + destination
       ...//We can change the numbers just like 3

In this way, although we can summarize all the upward situations, it is too complicated.
Do you remember the foreshadowing we left when we began to list the numbers?
Now it can be used, so we can directly give the original number + 5 for people to come, give the original number - 5 for people to go, give the original number + 4 for more boxes, give the original number - 4 for people to go, so give the original formula + 5-4 for people to come and boxes to go. And whether it's a destination or an open space, this conclusion applies, because we intentionally set this value. This can greatly reduce the amount of code, on the modified code!

	if(map[r-1][c]==0||map[r-1][c]==3)//In front of people is an open space or a destination 
		 { map[r-1][c]+=5; //People come to +5
		   map[r][c]-=5;//People walk -5 
		    }  
	    else if(map[r-1][c]==4||map[r-1][c]==7)//In front of people is the box or box plus destination
		{
		  	if(map[r-2][c]==0||map[r-2][c]==3)//In front of people is an open space or a destination 
			  {
			  	map[r-2][c]+=4;//Here comes the box.
			  	map[r-1][c]+=1;//People come, boxes go
			  	map[r][c]-=5;//People are gone.
			  } 
		} 		

Isn't it amazing, just three if statements will cover all of the above!!!
With one direction, other directions are easy to follow, for example:
To go down, just change r-1 in the array to r+1.
To the left, you only need to restore r, and modify c to c-1.
To the right, just change c to c+1.
The rest of the code remains the same.

Let's take a look at the overall effect!

#include<iostream>
#include<stdlib.h>
#include<conio.h>
using namespace std;

int map[8][8]={
	{1,1,1,1,1,1,1,1},//0 open space 
	{1,0,0,0,1,0,0,1},//1 walls 
	{1,0,1,0,1,4,3,1},//3 destination 
	{1,0,0,0,0,4,3,1},//4 boxes 
    {1,0,1,0,1,4,3,1},//5 person 
	{1,0,0,0,1,0,0,1},//7 box and destination overlap 
	{1,1,1,1,1,5,0,1},//8 people and destination 
	{0,0,0,0,1,1,1,1}};

void GamePaint()
{
	//output
    for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			switch(map[i][j])
			{
				case 0:printf("  ");break;
				case 1:printf("■");break;
				case 3:printf("☆");break;
				case 4:printf("□");break;
				case 5:printf("♀");break;
				case 7:printf("★");break;
				case 8:printf("♀");break;
			} 
		}
		cout<<endl; 
	} 
}

void GamePlay()
{
	int r,c;//Subscript subscript
	int flag=0;
	for(r=0;r<8;r++)
	 {
	 	for(c=0;c<8;c++)
	    {if(map[r][c]==5||map[r][c]==8)
	    	{
	     	flag=1;
	  	    break;
	    	}
		}
	 if(flag)
	 break;
     }
     cout<<"Subscript subscript:"<<r<<" "<<c;
     char key;
     key=getch();
     switch(key)
     {
     	case 'w': 
     	if(map[r-1][c]==0||map[r-1][c]==3)//In front of people is an open space or a destination 
		 { map[r-1][c]+=5; //People come to +5
		   map[r][c]-=5;//People walk -5 
		    }  
	    else if(map[r-1][c]==4||map[r-1][c]==7)//In front of people is the box or box plus destination
		{
		  	if(map[r-2][c]==0||map[r-2][c]==3)//In front of people is an open space or a destination 
			  {
			  	map[r-2][c]+=4;
			  	map[r-1][c]+=1;
			  	map[r][c]-=5;
			  } 
		} 		
			
			 break;
     	case 's':
     		if(map[r+1][c]==0||map[r+1][c]==3)//The back of a person is an open space or a destination 
		 { map[r+1][c]+=5; //People come to +5
		   map[r][c]-=5;//People walk -5 
		    }  
	    else if(map[r+1][c]==4||map[r+1][c]==7)//Behind people are boxes or boxes plus destinations
		{
		  	if(map[r+2][c]==0||map[r+2][c]==3)//The front of the back of a person is an open space or a destination 
			  {
			  	map[r+2][c]+=4;
			  	map[r+1][c]+=1;
			  	map[r][c]-=5;
			  } 
		} 		
		      break;
     	case 'a':
     		if(map[r][c-1]==0||map[r][c-1]==3)//On the left side of a person is an open space or a destination 
		 { map[r][c-1]+=5; //People come to +5
		   map[r][c]-=5;//People walk -5 
		    }  
	    else if(map[r][c-1]==4||map[r][c-1]==7)//On the left is the box or box plus destination
		{
		  	if(map[r][c-2]==0||map[r][c-2]==3)//To the left of a person is an open space or a destination 
			  {
			  	map[r][c-2]+=4;
			  	map[r][c-1]+=1;
			  	map[r][c]-=5;
			  } 
		} 
		  break;
		  
     	case 'd': 
		 	if(map[r][c+1]==0||map[r][c+1]==3)//To the right of a person is an open space or a destination 
		 { map[r][c+1]+=5; //People come to +5
		   map[r][c]-=5;//People walk -5 
		    }  
	    else if(map[r][c+1]==4||map[r][c+1]==7)//On the right is the box or box plus destination
		{
		  	if(map[r][c+2]==0||map[r][c+2]==3)//To the right of a person is an open space or a destination 
			  {
			  	map[r][c+2]+=4;
			  	map[r][c+1]+=1;
			  	map[r][c]-=5;
			  } 
		} 	 
		 break;
     }
}


int main()
{   while(1)//Keep the following statements running
    {system("cls");//Clear screen function
    GamePaint();
    GamePlay();
	}
	return 0;
}

Where to improve this Code:

1. Lack of output display and stop function after success.
2. Lack of prompt game operation function
3. Lack of "regret chess" function
The first two are not difficult to realize. For example, we can judge whether it is successful by judging whether there are independent boxes in the original array instead of boxes plus destinations, or whether all three destinations have become destinations + boxes.
And the game operation prompt can be output directly in GamePlay(), and the third function interested little friends can try it!!!

Try to play:

As long as you go wild like a blogger, it's quite easy to do so~

Published 6 original articles, won praise 6, visited 162
Private letter follow

Keywords: REST

Added by richardjh on Mon, 27 Jan 2020 13:30:29 +0200