建材秒知道
登录
建材号 > 设计 > 正文

C语言程序设计推箱子算法

完美的荔枝
天真的百合
2022-12-28 10:37:36

C语言程序设计推箱子算法

最佳答案
顺利的大炮
哭泣的寒风
2026-05-15 14:21:38

#include"stdio.h"

#include"bios.h"

#define LEFT 75

#define RIGHT 77

#define UPPER 72

#define DOWN 80

#define ESC 27

struct Boxss

{

int x,y

}

union keyboard

{

unsigned int iKeyInfo

char chKeyBit[2]

}

int fnGetKey(void)

{

union keyboard uniKey1

while(bioskey(1)==0)

uniKey1.iKeyInfo=bioskey(0)

return(uniKey1.chKeyBit[0]==0?uniKey1.chKeyBit[1]:uniKey1.chKeyBit[0])

}

void main()

{

int iKey,x=11,y=6,tx=11,ty=6

struct Boxss Box[4]

int chMap[10][10]={

{0,0,0,0,0,0,0,0,0,0},

{0,1,0,0,0,0,1,1,1,0},

{0,1,0,2,0,0,1,0,1,0},

{0,1,0,1,0,0,1,0,1,0},

{0,1,1,1,0,0,1,0,1,0},

{0,1,0,0,0,0,1,0,1,0},

{0,1,1,1,1,1,1,0,1,0},

{0,1,0,1,0,0,0,0,2,0},

{0,2,0,1,1,1,1,2,0,0},

{0,0,0,0,0,0,0,0,0,0},

}

int i,j

Box[0].x=13

Box[1].x=11

Box[2].x=14

Box[3].x=18

Box[0].y=8

Box[1].y=7

Box[2].y=13

Box[3].y=7

while(1)

{

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

{

gotoxy(10,5+i)

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

{

if(chMap[i][j]==0)

printf("#")

if(chMap[i][j]==1)

printf(" ")

if(chMap[i][j]==2)

printf("X")

}

}

j=0

for(i=0i<4i++)

if(chMap[Box[i].y-5][Box[i].x-10]==2)

j++

if(j==4)

{

clrscr()

printf("You Win!")

break

}

for(i=0i<4i++)

{

gotoxy(Box[i].x,Box[i].y)

printf("0")

}

gotoxy(x,y)

printf("*\b")

tx=x

ty=y

iKey=fnGetKey()

if(iKey==LEFT&&chMap[y-5][x-1-10]!=0)

x--

if(iKey==RIGHT&&chMap[y-5][x+1-10]!=0)

x++

if(iKey==UPPER&&chMap[y-1-5][x-10]!=0)

y--

if(iKey==DOWN&&chMap[y+1-5][x-10]!=0)

y++

if(iKey==ESC)

{

clrscr()

printf("You Lost")

break

}

for(i=0i<4i++)

if(Box[i].x==x&&Box[i].y==y)

{

Box[i].x+=(x-tx)

Box[i].y+=(y-ty)

if(chMap[Box[i].y-5][Box[i].x-10]==0)

{

Box[i].x-=(x-tx)

Box[i].y-=(y-ty)

x=tx

y=ty

}

break

}

clrscr()

}

getch()

}

最新回答
标致的泥猴桃
舒适的火
2026-05-15 14:21:38

我的回答仅作参考,因为是文曲星编程上学的一点东西。

我当时做地图时用到一些语句:

data 1//表示关卡关数

data 00000000000000//地图第一行

data 00011111111100//地图第二行

data 00012223222100

data 00012224222100

data 00012225222100

data 00011111111100

data 00000000000000

(数字是随便编的)作为地图时这样理解:

0表示墙外空地,1表示墙,2表示墙内空地,3表示箱子指定地,4表示箱子,5表示小人初始位置。

那么当你设计好地图时,只需在data内对应的写好地图信息编号,那么就能直接读出地图来了,我想文本文档应该是同样的道理,你可以改成:

map 1

line 00000000000000 line

line 00011111111100 line

line 00012223222100 line

line 00012224222100 line

line 00012225222100 line

line 00011111111100 line

line 00000000000000 line

读取关键字进行讨论。

或者用xml之类的语言解析下就好了。

希望对你有帮助。

眯眯眼的衬衫
眼睛大的水杯
2026-05-15 14:21:38
推箱子游戏是一款很有趣味的游戏,其开发过程有一定的技巧和方法,其中涉及到软中断、二维数组、键盘操作以及图形化函数等方面的知识。本游戏的开发者需要基本掌握显示器中断寄存器的设置。二维数组及结构体的定义、键盘上键值的获取、图形方式下光标的显示各定位,以及部分图形函数的使用。

具体架构我不说了,直接上代码:

1、程序预处理

程序预处理部分包括加载头文件、定义全局变量和定义数据结构,并对它们进行初始化工作。其中加载头文件的代码如下:

#include <dos.h>

#include <stdio.h>

#include <ctype.h>

#include <conio.h>

#include <bios.h>

#include <alloc.h>

2、初始化模块

该模块主要用于对屏幕和关卡的初始化,初始化关卡时是调用画图模块中画图函数。该模块包括以下几个函数。

(1) void init(),初始化屏幕的大小、显示方式、显示操作提示信息和版权信息。

(2) winer *initStep1(),初始化游戏的第一关。

(3) winer *initStep2(),初始化游戏的第二关。

(4) winer *initStep3(),初始化游戏的第三关。

(5) winer *initStep4(),初始化游戏的第四关。

其中初始化屏幕函数的详细代码如下:

void init()

{

int i,j

for(i=0i<20i++)

for(j=0j<20j++)

status[i][j]=0

_AL=3

_AH=0

geninterrupt(0x10)

gotoxy(41,4)

printf(" --------- up")

gotoxy(41,6)

printf(" --------- down")

gotoxy(41,8)

printf(" --------- left")

gotoxy(41,10)

printf(" --------- right")

gotoxy(40,12)

printf("Space ----- reset")

gotoxy(40,14)

printf("Esc ------- quit")

gotoxy(18,24)

printf("CopyRight: 2008 LuoFuxing")

gotoxy(40,4)

_CX=01

_AH=0xa

_AL=24

geninterrupt(0x10)

gotoxy(40,6)

_CX=01

_AH=0xa

_AL=25

geninterrupt(0x10)

gotoxy(40,8)

_CX=01

_AH=0xa

_AL=27

geninterrupt(0x10)

gotoxy(40,10)

_CX=01

_AH=0xa

_AL=26

geninterrupt(0x10)

}

3、 画图模块

该模块主要用于画图操作,包括画墙、画箱子、画目的地和画小人等。该模块包括以下几个函数。

(1) void printWall(int x,int y),用于画墙。

(2) void printBox(int x,int y),在空白地(非目的地)画箱子。

(3) void printBoxDes(int x,int y),在目的地画箱子。

(4) void printDestination(int x,int y),画目的地函数。

(5) void printDestination1(int x,int y,winer **win,winer **pw),画目的地函数,并记录每个目的地的位置。

(6) void printMan(int x,int y),画小人函数。

其中画墙函数的代码如下:

void printWall(int x,int y)

{

putoutChar(y-1,x-1,219,GREEN,BLACK)

status[x][y]='w'

}

4、 移动箱子模块

该模块是实现箱子的移动。根据游戏规则,箱子可以在空地之间、目的地之间、空地和目的地之间来回移动,因此,实现本模块共有以下4个函数。

(1) void moveBoxSpacetoSpace(int x,int y,char a),把箱子从空地移动到空地。

(2) void moveBoxDestoSpace(int x,int y,char a),把箱子从目的地移动到空地。

(3) void moveBoxSpacetoDes(int x,int y,char a),把箱子从空地移动到目的地。

(4) void moveBoxDestoDes(int x,int y,char a),把箱子从目的地移动到目的地。

其中从空地移动箱子到空地函数的详细代码如下:

void moveBoxSpacetoSpace(int x,int y,char a)

{

switch(a)

{

case 'u':

status[x-1][y]=0

printf(" ")

printBox(x-2,y)

printMan(x-1,y)

status[x-2][y]='b'

break

case 'd':

status[x+1][y]=0

printf(" ")

printBox(x+2,y)

printMan(x+1,y)

status[x+2][y]='b'

break

case 'l':

status[x][y-1]=0

printf(" ")

printBox(x,y-2)

printMan(x,y-1)

status[x][y-2]='b'

break

case 'r':

status[x][y+1]=0

printf(" ")

printBox(x,y+2)

printMan(x,y+1)

status[x][y+2]='b'

break

default:

break

}

}

5、 移动小人模块

移动小人模块是本程序的核心模块,仅由move()函数来实现。Move()函数控制小人的移动,并调用画图模块、移动箱子模块中的函数来实现箱子的重画、移动等操作。其操作流程可参见图(三)。部分代码如下:

void move(int x,int y,char a)

{

switch(a)

{

case 'u':

if(!judge(x-1,y))

{

gotoxy(y,x)

break

}

else if(judge(x-1,y)==1||judge(x-1,y)==3)

{

if(judge(x,y)==3)

{

printDestination(x,y)

printMan(x-1,y)

break

}

else

{

printf(" ")

printMan(x-1,y)

break

}

}

else if(judge(x-1,y)==2)

{

if(judge(x-2,y)==1)

{

moveBoxSpacetoSpace(x,y,'u')

if(judge(x,y)==3)

printDestination(x,y)

gotoxy(y,x-1)

}

else if(judge(x-2,y)==3)

{

moveBoxSpacetoDes(x,y,'u')

if(judge(x,y)==3)

printDestination(x,y)

gotoxy(y,x-1)

}

else

gotoxy(y,x)

break

}

……

……

6、 功能控制模块

功能控制模块包括屏幕输出功能、关卡重置功能和坐标位置状态的判断功能。该模块包括以下几个函数。

(1) void putoutChar(int y,int x,char fc,char bc),在屏幕上指定的位置输出指定的字符。

(2) int judge(int x,int y),判断位置(x,y)处的状态,状态值可参见“数据结构设计”部分。

(3) void reset (int i),重置关卡。

其中在屏幕上的指定位置输出指定的字符函数的代码如下:

void putoutChar(int y,int x,char ch,char fc,char bc)

{

printScreen[(x*160)+(y<<1)+0]=ch

printScreen[(x*160)+(y<<1)+1]=(bc*16)+fc

}

7、 主函数

主函数实现整个程序的控制,其游戏操作流程可参见图(二)。详细代码如下:

void main()

{

int key

int x

int y

int s

int i=0

winer *win

winer *pw

_AL=3

_AH=0

geninterrupt(0x10)

init()

win=initStep1()

do{

_AH=3

geninterrupt(0x10)

x=_DH+1

y=_DL+1

while(bioskey(1)==0)

key=bioskey(0)

switch(key)

{

case 0x4800:

move(x,y,'u')

break

case 0x5000:

move(x,y,'d')

break

case 0x4b00:

move(x,y,'l')

break

case 0x4d00:

move(x,y,'r')

break

case 0x3920:

reset(i)

break

default:

break

}

s=0

pw=win

while(pw)

{

if(status[pw->x][pw->y]=='m')

s++

pw=pw->p

}

if(s==0)

{

free(win)

gotoxy(15,20)

printf("congratulate! You have done this step!")

getch()

i++

switch(i)

{

case 1:

init()

win=initStep2()

break

case 2:

init()

win=initStep3()

break

case 3:

init()

win=initStep4()

break

case 4:

gotoxy(15,21)

printf("Congratulation! \n")

gotoxy(15,22)

printf("You have done all the steps, You are very clever!")

key=0x011b

getch()

break

default:

break

}

}

}while(key!=0x011b)

_AL=3

_AH=0

geninterrupt(0x10)

}

阳光的樱桃
拉长的柚子
2026-05-15 14:21:38
推箱子是日本人今林宏行于1981年发明并且编写程序实现的,1982年由 Thinking Rabbit 公司在日本发行。日文原名《仓库番》, 英语音译为 Sokoban,中文目前最通用的叫法是推箱子。

犹豫的飞机
发嗲的黑裤
2026-05-15 14:21:38

写箱子的java 的been

写小人的java been

设置画板,第一关的map(包括过关时箱子的位置,也可以写成been单元)

画出小人和箱子的初始位置

用键盘中的点击事件(上下左右)控制画板中的两个been的xy轴位置的增减,事项箱子的移动。

移动的同时写好判定条,如是否满足过关条件,是否碰壁等

勤恳的西装
自觉的小蜜蜂
2026-05-15 14:21:38
你可以这么理解 推箱子的地图为一个MXN的二维数组(地图大小决定M N的大小) 可以走的地方为1 墙置为0

推箱子的过程就是 在二维数组中 通过1的路径 一个点到另一个点 这类题C语言的数据结构里面前几章就有讲