C语言实现Sōkoban推箱子游戏

彩舟载得离愁动,无端更借樵风送

Posted by 张振 on March 24, 2019

实现功能

  • 给定地图内推箱子的所有操作

未实现功能

  • 地图的自动生成

源代码

PushBox.cpp


#include"PushBox.h"

#include<iostream>

using namespace std;

//1坑  ¥
//4箱子○
//2墙壁■
//8玩家RR
//9入坑的箱子U

int main(void)
{  

	printf("*****************************************************\n");
	printf("**                WELCOME TO SOKOBAN               **\n");
	printf("**   GAME STAET PRESS 'A' 'W' 'S' 'D' to control   **\n");
	printf("*****************************************************\n");
	system("pause");
	system("cls");


	while (1)
	{
		mapInitialization(map);//数组传参不需要带方括号
		char ch = _getch();
		switch (ch)
		{
		case 'A':
			PlayerLeft();
			break;
		case 'D':
			PlayerRight();
			break;
		case 'W':
			PlayerUp();
			break;
		case 'S':
			PlayerDown();
			break;
		default:
			break;
		}
		system("cls");
		if (boxNum == 0)
		{
			system("cls");

			printf("*****************************************************\n");
			printf("**           congratuilations  well done !         **\n");    
			printf("*****************************************************\n");

			break;
		}
		/*if (gameOver() == 1)
		{
			break;
		}*/
	}
	return 0;
}
void mapInitialization(int map[][14])
{
	for (int i=0;i<13;i++)
	{
		for (int j=0;j<14;j++)
		{

			switch (map[i][j])
			{
				case 0:
					printf("  ");  
					break;
				case 1:
					printf("¥");  
					break;
				case 2:
					printf("■");  
					break;
				case 4:
					printf("○");
					break;
				case 8:
					printf("RR");
					//获取小人的位置信息
					Playerx = i;
					Playery = j;
					break;
				default:
					break;
			}

		}
		printf("\n");
	}

}

void PlayerLeft()
{

	if (map[Playerx][Playery - 1] != 1 && map[Playerx][Playery-1]!=2&& map[Playerx][Playery - 1] != 4)//不撞墙不推箱子
	{
		map[Playerx][Playery] = 0;
		map[Playerx][Playery - 1] = 8;
		//更新位置信息
		Playerx = Playerx;
		Playery = Playery - 1;
	}
	else if (map[Playerx][Playery - 1] == 4)//若推箱子
	{
		printf("前方有箱子\n");
		SokobanLeft( Playerx, Playery);
	}
	else if (map[Playerx][Playery - 1]==1)//若前方是坑
	{
		printf("前方是坑\n");
		gameOver();
	}
	else//若撞墙
	{
		JustWait();
	}

}
void PlayerRight()
{
	if (map[Playerx][Playery + 1] != 1 && map[Playerx][Playery + 1] != 2 && map[Playerx][Playery +1] != 4)//不撞墙不推箱子
	{
		map[Playerx][Playery] = 0;
		map[Playerx][Playery + 1] = 8;
		//更新位置信息
		Playerx = Playerx;
		Playery = Playery + 1;
	}
	else if (map[Playerx][Playery + 1] == 4)//若推箱子
	{
		printf("前方有箱子\n");
		SokobanRight(Playerx, Playery);
	}
	else if (map[Playerx][Playery + 1] == 1)//若前方是坑
	{
		printf("前方是坑\n");
		gameOver();
	}
	else//若撞墙
	{
		JustWait();
	}

}
void PlayerDown()
{
	if (map[Playerx+1][Playery ] != 1 && map[Playerx+1][Playery ] != 2 && map[Playerx+1][Playery ] != 4)//不撞墙不推箱子
	{
		map[Playerx][Playery] = 0;
		map[Playerx + 1][Playery] = 8;
		//更新位置信息
		Playerx = Playerx+1;
		Playery = Playery ;
	}
	else if (map[Playerx+1][Playery ] == 4)//若推箱子
	{
		printf("前方有箱子\n");
		SokobanDown(Playerx, Playery);
	}
	else if (map[Playerx+1][Playery ] == 1)//若前方是坑
	{
		printf("前方是坑\n");
		gameOver();
	}
	else//若撞墙
	{
		JustWait();
	}
}
void PlayerUp()
{
	if (map[Playerx-1][Playery ] != 1 && map[Playerx-1][Playery ] != 2 && map[Playerx-1][Playery ] != 4)//不撞墙不推箱子
	{
		map[Playerx][Playery] = 0;
		map[Playerx - 1][Playery] = 8;
		//更新位置信息
		Playerx = Playerx-1;
		Playery = Playery;
	}
	else if (map[Playerx - 1][Playery] == 4)//若推箱子
	{
		printf("前方有箱子\n");
		SokobanUp(Playerx, Playery);
	}
	else if (map[Playerx-1][Playery] == 1)//若前方是坑
	{
		printf("前方是坑\n");
		gameOver();
	}
	else//若撞墙
	{
		JustWait();
	}
}

//人前方至少有一个箱子的情况下
void SokobanLeft(int Playerx,int Playery)
{

	if (map[Playerx][Playery - 2] != 2 && map[Playerx][Playery - 2] != 1&& map[Playerx][Playery - 2] != 4)//若箱子前方无墙无坑无箱子
	{

			printf("箱子前方无墙无坑\n");
			//更新玩家位置信息
			map[Playerx][Playery] = 0;
			map[Playerx][Playery - 1] = 8;
			Playerx = Playerx;
			Playery = Playery - 1;
			//更新箱子位置信息
			map[Playerx][Playery - 1] = 4;

	}
	else if (map[Playerx][Playery - 2] == 1)//若箱子前方有坑
	{
		printf("箱子前方有坑\n");
		//更新玩家位置信息
		map[Playerx][Playery] = 0;
		map[Playerx][Playery - 1] = 8;

		Playerx = Playerx;
		Playery = Playery - 1;
		//更新箱子位置信息
		map[Playerx][Playery - 1] = 0;
		boxNum--;

	}
	else if(map[Playerx][Playery - 1] == 4&& map[Playerx][Playery - 2]==4)//若前方有两个箱子
	{
		printf("前方有两个箱子");
		JustWait();
	}
	else//若箱子前方有墙
	{
		printf("箱子前方有墙\n");
		JustWait();
	}
}
void SokobanRight(int Playerx, int Playery)
{

	if (map[Playerx][Playery + 2] != 2 && map[Playerx][Playery + 2] != 1 && map[Playerx][Playery +2] != 4)//若箱子前方无墙无坑无箱子
	{

		printf("箱子前方无墙无坑\n");
		//更新玩家位置信息
		map[Playerx][Playery] = 0;
		map[Playerx][Playery +1] = 8;

		Playerx = Playerx;
		Playery = Playery + 1;
		//更新箱子位置信息
		map[Playerx][Playery + 1] = 4;


	}
	else if (map[Playerx][Playery + 2] == 1)//若箱子前方有坑
	{
		printf("箱子前方有坑\n");
		//更新玩家位置信息
		map[Playerx][Playery] = 0;
		map[Playerx][Playery + 1] = 8;

		Playerx = Playerx;
		Playery = Playery + 1;
		//更新箱子位置信息
		map[Playerx][Playery + 1] = 0;
		boxNum--;

	}
	else if (map[Playerx][Playery + 1] == 4 && map[Playerx][Playery + 2] == 4)//若前方有两个箱子
	{
		printf("前方有两个箱子");
		JustWait();
	}
	else//若箱子前方有墙
	{
		printf("箱子前方有墙\n");
		JustWait();
	}
}
void SokobanUp(int Playerx, int Playery)
{

	if (map[Playerx-2][Playery ] != 2 && map[Playerx-2][Playery ] != 1 && map[Playerx-2][Playery ] != 4)//若箱子前方无墙无坑无箱子
	{

		printf("箱子前方无墙无坑\n");
		//更新玩家位置信息
		map[Playerx][Playery] = 0;
		map[Playerx-1][Playery ] = 8;

		Playerx = Playerx-1;
		Playery = Playery ;
		//更新箱子位置信息
		map[Playerx-1][Playery ] = 4;


	}
	else if (map[Playerx-2][Playery ] == 1)//若箱子前方有坑
	{
		printf("箱子前方有坑\n");
		//更新玩家位置信息
		map[Playerx][Playery] = 0;
		map[Playerx-1][Playery ] = 8;

		Playerx = Playerx-1;
		Playery = Playery ;
		//更新箱子位置信息
		map[Playerx-1][Playery ] = 0;
		boxNum--;

	}
	else if (map[Playerx-1][Playery]  == 4 && map[Playerx-2][Playery ] == 4 )//若前方有两个箱子
	{
		printf("前方有两个箱子");
		JustWait();
	}
	else//若箱子前方有墙
	{
		printf("箱子前方有墙\n");
		JustWait();
	}
}
void SokobanDown(int Playerx, int Playery)
{

	if (map[Playerx + 2][Playery] != 2 && map[Playerx +2][Playery] != 1 && map[Playerx + 2][Playery] != 4)//若箱子前方无墙无坑无箱子
	{

		printf("箱子前方无墙无坑\n");
		//更新玩家位置信息
		map[Playerx][Playery] = 0;
		map[Playerx + 1][Playery] = 8;

		Playerx = Playerx + 1;
		Playery = Playery;
		//更新箱子位置信息
		map[Playerx + 1][Playery] = 4;


	}
	else if (map[Playerx + 2][Playery] == 1)//若箱子前方有坑
	{
		printf("箱子前方有坑\n");
		//更新玩家位置信息
		map[Playerx][Playery] = 0;
		map[Playerx + 1][Playery] = 8;

		Playerx = Playerx + 1;
		Playery = Playery;
		//更新箱子位置信息
		map[Playerx + 1][Playery] = 0;
		boxNum--;

	}
	else if (map[Playerx + 1][Playery] == 4 && map[Playerx + 2][Playery] == 4)//若前方有两个箱子
	{
		printf("前方有两个箱子");
		JustWait();
	}
	else//若箱子前方有墙
	{
		printf("箱子前方有墙\n");
		JustWait();
	}
}
void JustWait()
{
	Playerx = Playerx ;
	Playery = Playery;
}
int  gameOver()
{
	//system("pause");
	system("cls");
	printf("*******************************\n");
	printf("**           YOU DIE         **\n");
	printf("*******************************\n");

	printf("TRY AGAIN ?(y/n)\n");
	char ans = getchar();
	char enter = getchar();//接收回车
	if (ans == 'y' || ans == 'Y')
	{
		//刷新当前地图
		for (int i = 0; i < 13; i++)
		{
			for (int j = 0; j < 14; j++)
			{
				map[i][j] = mapInit[i][j];
			}
		}
		boxNum = 4;
		return 0;
	}
	else if( ans == 'n' || ans == 'N')
	{
		exit(true);
	}
	else
	{
		printf("INPUT ERROR!!!");
		system("pause");
		gameOver();
	}

}
//1坑D
//2墙壁I
//4箱子S
//8玩家R

PushBox.h


#include<stdio.h>

#include<conio.h>

#include<stdlib.h>
//1坑  ¥
//4箱子○
//2墙壁■
//8玩家RR
//9入坑的箱子U
int mapInit[13][14] =
{
	{2,2,2,2,2,2,2,2,2,2,2,2,2,2},
	{2,0,0,0,2,0,0,0,2,0,0,2,0,2},
	{2,0,2,0,0,0,2,0,0,0,1,2,0,2},
	{2,0,0,0,0,2,0,2,0,0,0,2,0,2},
	{2,0,0,0,2,2,0,0,0,0,4,0,0,2},
	{2,0,1,0,0,2,0,0,0,0,0,0,0,2},
	{2,0,0,2,0,0,0,0,2,0,2,0,0,2},
	{2,0,4,0,0,2,0,0,4,0,8,0,0,2},
	{2,2,0,0,0,0,0,0,0,0,0,0,0,2},
	{2,0,0,0,0,2,0,0,0,2,0,0,0,2},
	{2,0,1,0,4,0,2,0,0,2,0,0,0,2},
	{2,0,0,0,0,0,2,0,0,0,0,1,0,2},
	{2,2,2,2,2,2,2,2,2,2,2,2,2,2}
};
int map[13][14] =
{
	{2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,0,0,0,2,0,0,0,2,0,0,2,0,2},
	{2,0,2,0,0,0,2,0,0,0,1,2,0,2},
	{2,0,0,0,0,2,0,2,0,0,0,2,0,2},
	{2,0,0,0,2,2,0,0,0,0,4,0,0,2},
	{2,0,1,0,0,2,0,0,0,0,0,0,0,2},
	{2,0,0,2,0,0,0,0,2,0,2,0,0,2},
	{2,0,4,0,0,2,0,0,4,0,8,0,0,2},
	{2,2,0,0,0,0,0,0,0,0,0,0,0,2},
	{2,0,0,0,0,2,0,0,0,2,0,0,0,2},
	{2,0,1,0,4,0,2,0,0,2,0,0,0,2},
	{2,0,0,0,0,0,2,0,0,0,0,1,0,2},
	{2,2,2,2,2,2,2,2,2,2,2,2,2,2}
};
void mapInitialization(int map[][14]);
//人的前方没有箱子
void PlayerUp();
void PlayerDown();
void PlayerRight();
void PlayerLeft();
//人的前方至少有一个箱子
void SokobanLeft(int Playerx, int Playery);
void SokobanRight(int Playerx, int Playery);
void SokobanUp(int Playerx, int Playery);
void SokobanDown(int Playerx, int Playery);
void JustWait();
int gameOver();

int Playerx=0;
int Playery=0;

int boxNum=4;