实验四 二维数组基本操作的编程实现
一、实验目的
掌握二维数组的建立、读取数据、压缩存储等基本操作的编程实现,存储结构可以在顺序结构或链接结构中任选,也可以全部实现。也鼓励学生利用基本操作进行一些应用的程序设计。
二、实验要求
1. 修改程序:补充推箱子游戏的遗缺的部分,使之能正常运行,逻辑结果正确。之后增加至少一关自己的关数,墙体,箱子的最初位置,人的最初位置由自己设定,要求必须有解,而且有一定的破解难度。主要的问题是部分移动方向的代码没有给出,另外计数器的整体工作不正常,更完善的修改包括启用栈结构实现后悔的机制。
2.运行程序了解二维结构:稀疏矩阵的压缩和解压缩、生命繁衍模型、迷宫问题等,通过这些程序的运行过程或结果体会二维结构在程序设计中的重要性和实用性。
原始数据构建方式最简模式为:键盘输入。其他的方式也在鼓励之中:数据内置,计算机自动生成,文件读入。
三、程序说明 程序中用于建立栈的类
//节点 class Reback{ public:
int re_key_up; int re_key_down; int re_key_left; int re_key_right; int re_count; int re_movex; int re_movey; int re_movexold; int re_moveyold; int re_peopleflag; int re_Maptemp[11][11]; Reback *next; Reback *before;
1
};
Reback *headp=new Reback;//头指针 Reback *tailp=new Reback;//尾指针
说明:此类用于存储每一步的游戏临时数据,用于回退
程序中的功能函数
void myDraw(HWND hWnd,HDC &dc);//界面的绘制
void Key_D(HWND &hWnd,HDC &dc,int key_value);//响应键盘 void init();//初始化函数
void CueatMap(int AimMap[][11]);//创建地图 void rememberbefore();//保存数据(入栈) void returnbefore();//还原数据(出栈) void delrecord();//删除数据(清空栈)
功能的实现:
1.游戏中的鼠标操作的实现:
case WM_LBUTTONDOWN://鼠标左键点击消息
{
int x,y,i=0,j=0,count=0;
x=LOWORD(lParam);//相对于窗口的位置 y=HIWORD(lParam); if(x>=775&&y<=35){ }
else if(x>=0&&x<=774&&y<35){ }
else if(x>600&&y>120&&x<720&&y<160){//上一关 }
else if(x>600&&y>200&&x<720&&y<240){//下一关
if(Mapdatacounnt+1 Mapdatacounnt++; if(Mapdatacounnt-1>=0){ } CueatMap(Mapdata[Mapdatacounnt]); InvalidateRect(hWnd, NULL, true); Mapdatacounnt--; delrecord(); SendMessage(hWnd,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0);//发送消息 delrecord();//释放资源 PostQuitMessage(0);//发送窗口销毁消息用于关闭窗口 2 } } } delrecord(); CueatMap(Mapdata[Mapdatacounnt]); InvalidateRect(hWnd, NULL, true); else if(x>600&&y>280&&x<720&&y<320){//后退一步 } else if(x>600&&y>410&&x<720&&y<450){ } ShellExecute(hWnd,\,\,\,\, SW_SHOW ); returnbefore(); InvalidateRect(hWnd, NULL, true); 说明:此处的设计方法为,先获取鼠标在窗口中的点击坐标,然后判断该坐标点是否在设定的区域,如果是,则执行相应的操作 2.游戏中键盘操作的实现: /*键盘消息处理函数*/ void Key_D(HWND &hWnd,HDC &hdc,int key_value){//用于响应键盘消息的处理 //限定区域 if(count!=4){ rememberbefore(); switch(key_value){ case 38: {//在key_up-40之前进行判断看执行此计算后是否还在游戏区域内其他方向相同 if((key_up-40+key_down+40)/40>0){ } key_up-=40; }break; if((key_left+key_right+40+40)/40<=9) { } }break; key_right+=40; case 39:{ case 40:{ if((key_up+key_down+40+40)/40<=9) { } }break; key_down+=40; case 37:{ if((key_left-40+key_right+40)/40>0) 3 } } { } }break; key_left-=40; keyflag=key_value; InvalidateRect(hWnd, NULL, true); 说明:获取发生键盘消息时对应的键值,判断此时是否游戏过关,如果没过关就记录当前的游戏数据,响应方向键,如果过关就响应回车键,进入下一关,同时调用屏幕刷新函数。 3.推箱子的逻辑功能实现: 由于对四个方向的处理大致相同,此处仅对向上移动进行说明 …… /*运动方向及相应的处理*/ } else if(Map[(movex)/40][(movey)/40]==3)//前面是箱子接下来判断箱子的前面的情况 { //1 箱子前面是路 if(Map[(movex)/40-1][(movey)/40]==0){ Map[(movex)/40-1][(movey)/40]=3;//把箱子的前面换成箱子 Map[(movex)/40][(movey)/40]=4;//,当前的箱子位置换成人, movexold=movex;//之前路过 moveyold=movey; /*下面的判断都是即将到达的地方*/ /* 向上运动*/ if(keyflag==38) {//上 if(Map[movex/40][movey/40]==0) {//前面是路 Map[(movex)/40][(movey)/40]=4; if(peopleflag==1){ } peopleflag=0; Map[(movexold)/40][(moveyold)/40]=0; Map[(movexold)/40][(moveyold)/40]=2; //在之前已经经过了限制此时不会越界 movey=key_left+key_right+40;//即将要到达的地方 movex=key_up+key_down+40;// 二维数组中x控制行y控制列 }else{ 4 } } if(peopleflag==1){//之前人已经到了位置上 } else{ } movexold=movex; moveyold=movey; peopleflag=0;//人离开了位置 Map[(movexold)/40][(moveyold)/40]=2;//当前人的位置换成位置 Map[(movexold)/40][(moveyold)/40]=0;//当前人的位置换成位置 //2 箱子前面是放置位置 else if(Map[(movex)/40-1][(movey)/40]==2){ } else{ } key_up+=40; PlaySound (TEXT (\), NULL, SND_FILENAME | SND_ASYNC) ; Map[(movex)/40-1][(movey)/40]=5;//把箱子的前面换成“完成”, Map[(movex)/40][(movey)/40]=4;//当前的箱子位置换成人 Map[(movexold)/40][(moveyold)/40]=0; count++; movexold=movex; moveyold=movey; else if(Map[(movex)/40][(movey)/40]==5){//前面是放置完成表示箱子已经推到位置 //放置完成的状态下前面的情况 //1 放置完成的前面是路 把箱子推出去 if(Map[(movex)/40-1][(movey)/40]==0){//路 } Map[(movex)/40-1][(movey)/40]=3;//把放置完成的的前面换成箱子 Map[(movex)/40][(movey)/40]=2;//,当前的完成换成位置 if(peopleflag==0){//之前人的位置不是放置位置为:路 } else{//之前人的位置是放置位置 } count--; movexold=movex; moveyold=movey; Map[(movexold)/40][(moveyold)/40]=2;//之前人的位置换成\放置位置\Map[(movexold)/40][(moveyold)/40]=0;//之前人的位置换成路 peopleflag=1;//人已经到了位置上 5