高中数学论文 图形计算器应用能力测试活动学生 图形计算器游戏推箱子.docx
《高中数学论文 图形计算器应用能力测试活动学生 图形计算器游戏推箱子.docx》由会员分享,可在线阅读,更多相关《高中数学论文 图形计算器应用能力测试活动学生 图形计算器游戏推箱子.docx(20页珍藏版)》请在冰豆网上搜索。
高中数学论文图形计算器应用能力测试活动学生图形计算器游戏推箱子
2013年高中数学论文图形计算器应用能力测试活动学生图形计算器游戏推箱子
[摘要]
利用图形计算器的编程功能,在CASIOfx-CG20图形计算器平台上实现了推箱子游戏。
本文中的程序利用了图形计算器中的矩阵来储存数据,通过模拟法实现推箱子游戏,提供撤消和恢复操作以及游戏的保存,实现了推箱子的地图编辑,并利用原创的压缩算法压缩储存推箱子游戏地图。
[关键词]
图形计算器;推箱子;
[前言]
观察过以前的获奖论文,大多数的论文只利用到图形计算器的画图功能和小部分的编程功能。
图形计算器编程功能的强大之处并未充分体现出来,而本文正是利用了图形计算器强大的编程功能,并使用了原创的压缩算法,从而在图形计算器上实现了推箱子游戏和推箱子游戏地图的压缩保存。
[研究目的]
利用图形计算器的编程功能,在图形计算器上实现推箱子游戏,从而锻炼编程能力和算法能力,加深对进制转换的理解,同时增强了CASIO图形计算器的娱乐功能,丰富同学们的课余生活。
[程序功能说明]
游戏功能:
玩家可以通过CASIO图形计算器fx-CG20上的按键B、N、!
和$或数学键2、4、6和8控制搬运工(显示为一个手指图案)上下左右移动,将箱子(蓝色方框)推到指定地点。
(如图1)
图1游戏截图
图2编辑地图中
地图编辑功能:
玩家可以将原创的或搜集到的推箱子游戏地图输入到图形计算器中并储存起来。
(如图2)程序提供粘滞功能,按下L键后移动的光标即可拖动出多个与当前位置相同的图案(包括空白)。
本程序用一个包含1000个矩阵元素的矩阵储存地图,经过压缩后,储存上限大约为200幅地图。
游戏保存功能:
玩家可以在游戏途中将游戏保存起来。
按u或l打开游戏菜单(如图3),选择“Save&Exit”即可保存并退出游戏,下次运行程序时,程序将自动读取游戏存档。
(如图4)
图3
图4游戏存档读取中
撤消和恢复功能:
本程序能记录所有箱子发生的移动,玩家按d键即可撤消上一次的箱子移动。
如果想恢复刚才的操作可以按p键,可以通过多次按p键将地图状态恢复到撤消前的状态。
特色:
1.由于图形计算器的主储存空间有限(61KB),所以如果直接将地图的全部信息储存进矩阵的话,储存上限会非常小。
本程序使用原创的压缩算法压缩地图之后,仅用4~7个矩阵元素就能储存一幅地图。
这是整个程序最复杂的部分。
2.提供快捷键7和9,玩家可以立即跳到上一幅图或下一幅图。
提供快捷键w和y,玩家可以读取其他地图和重新载入当前地图。
3.搬运工所指向的方向会根据搬运工移动而改变。
[研究过程]
1.确定程序功能,请参考“程序功能说明”。
2.构思算法:
本程序游戏功能实现方面使用模拟法。
屏幕上的一格对应矩阵中的一个元素。
在矩阵中,不同的数字有不同的含义,请见下表:
数字
0
1
2
3
4
含义
空
箱子
目标位置
在目标位置上的箱子
墙
需要记录的数据:
搬运工的坐标、未完成的目标位置个数(即上面没有箱子的目标位置个数)、当前地图编号
地图保存的实现:
需要压缩储存的原因:
屏幕显示的方格为21×7,共147个方格,而每个矩阵(默认为只储存实数)储存所占用的空间大小为36B+矩阵元素个数×12B(字节),即每个矩阵元素占用12B的空间。
如果采用直接储存的方法,一幅地图所用的空间为:
B。
而CASIOfx-CG20图形计算器的主内存大小为61KB,约为61000B,所以忽略其他数据储存,采用直接储存地图的方法最多只能储存幅地图,亦即实际上只能储存不足30幅地图。
压缩思想一:
忽略空白区域。
考虑到所有地图都是一个封闭的不规则图形(即地图最外侧一定被墙包围),地图外围都是空白的区域,所以用一个最小的矩形覆盖地图,只记录下矩形的信息和矩形中的所有方格的信息即可。
压缩思想二:
一个矩阵元素储存多个方格信息。
由于一个方格的种类只有五种,把每一个方格视为一位的五进制数,将多个方格所对应的五进制数连成一个长五进制数,并转换为十进制数储存在矩阵当中。
因此,一个矩阵元素可以储存多个方格的数据。
CASIOfx-CG20图形计算器中的十进制数能保存十位有效数字,如果多于十位有效数字,多余的有效数字会被去掉。
所以用于记录地图数据的数字不能超过。
5的整数次幂中,514为满足此要求的最大的数,所以矩阵元素最多可以储存一个14位的五进制数,即一个矩阵可以储存14个方格的信息。
而,所以最多只需11个矩阵元素就储存一幅地图。
储存格式:
为了不浪费每个矩阵元素,需要将储存数据连续储存在一个矩阵。
由于不同大小的地图所占的元素个数不同,所以需要记录储存数据的起始位置,也就是数据的地址。
同时又需要记录上面提到的矩形的信息和搬运工的起始位置。
为了节约空间,所以将信息整合起来储存到一个矩阵元素当中,并将这些数据储存到一个矩阵当中,下文称之为“地图索引”数据。
地图索引信息整合方法:
根据模运算的基本理论,对于任意一个整数n,一定存在等式,其中,且。
由模运算的定义可知。
因为如果给定p的话,n的分解是唯一的。
令r为将要整合的信息,p为r的可能的状态总数,k则为之前其他信息整合得出的结果。
P和Q为矩形纵坐标范围,U和V为矩形横坐标范围,X和Y为搬运工的起始位置的坐标,A和B为数据地址。
其中。
只考虑P、Q、U、V、X、Y,这六个信息共有种状态,,也就是说数据地址的状态数可以达到3148种,超出这个范围之后,数据的地址就无法记录了。
最后可以得出这样一个计算公式:
地图读取和保存实现细节:
由于储存和读取时,读取矩阵和编(解)码的方向都是相反的。
本程序保存地图时,从右往左,从下往上编码地图,将五进制转换为十进制,写入到矩阵时,由前往后写入,并记录完成编码时A和B的值,即最后一个地图数据的位置。
读取地图时,解码出A和B的值,从矩阵中(A,B)开始往前读取地图数据,而地图显示时,玩家就可以看到地图是从左往右,从上往下地显示的,这也是地图数据的解码方向。
游戏保存实现:
储存方式与地图保存类似,不同在于地图信息和地图索引储存在一个固定的地方,还要记录存档的关卡数。
游戏的撤消和恢复功能实现:
用一个矩阵储存被推动的箱子的坐标和按下的按键(可以从中获取箱子推动的方向)。
3.使用图形计算器编程实现。
4.进行程序调试。
5.游戏试用。
具体实现步骤如下:
1.打开图形计算器,按1进入“计算·矩阵”模式。
2.按e进入矩阵存储器。
并创建矩阵:
矩阵名
尺寸
用途
MatA
23×9
程序运行时记录地图信息
MatE
100×2
实现撤消和恢复功能时,用于记录箱子移动情况
MatG
200×1
地图索引信息的储存
MatH
79×3
按键判断
MatI
100×10
储存地图
MatH的初始化:
第27行为1,0,2;第28行为0,-1,1;
第37行为0,1,3;第38行为-1,0,4;
第52行为1,1,-1;第53行为1,0,2;第54行为1,-1,-1;
第62行为0,1,3;第64行为0,-1,1;
第72行为-1,1,-1;第73行为-1,0,4;第74行为-1,-1,-1;
其余矩阵元素为0。
3.返回主菜单,进入“程序”模式。
4.创建程序“PUSHBOX”,代码请参考“程序代码分析”或附件。
5.创建程序“P~EDIT”,代码请参考“程序代码分析”或附件。
6.创建程序“P~SAVE”,代码请参考“程序代码分析”或附件。
7.创建程序“P~LOAD”,代码请参考“程序代码分析”或附件。
8.创建程序“NUM~STR”,代码请参考“程序代码分析”或附件。
[程序代码分析]
一、主程序PUSHBOX
'ProgramMode:
RUN
'_Mat_A,E,G,H,I
"■"→Str1:
"
"→Str2
"□"→Str3:
"
"→Str4
"
"→Str5
'Str1记录的是墙的图案,Str2记录的是目标位置的图案,Str3记录的是箱子的图案,Str4记录的是当前搬运工的图案,Str5记录的四个方向的搬运工的图案
MatI[1,3]=>Goto2'如果有游戏存档,则自动读取
Lbl1
IfMatI[1,1]:
Then'判断计算器中是否存有地图
MatI[1,1]→r'矩阵I的(1,1)记录的是总共有多少幅地图
Prog"NUM~STR"'用程序NUM~STR将地图数转换为字符串
"Inputlevel(1~"+Str6+")"?
→L'询问想要读取的关卡,提示关卡数范围
L<=0OrL>MatI[1,1]=>Goto1'输入有误,再次询问
Else
RedLocate8,4,"NomapChar!
"
Stop
IfEnd
Goto3
Lbl2:
0→L:
Lbl3
Prog"P~LOAD"'读取地图
IfMatA[X,Y]=2'显示搬运工
ThenRedLocateX-1,Y-1,Str4
ElseGreenLocateX-1,Y-1,Str4
IfEnd
L→r:
Prog"NUM~STR"
"Level"+Str6→Str6'字符串6用于游戏菜单标题的显示,提示当前关卡数
'P记录最后一次箱子移动信息的储存位置,Q记录的是开始撤消时箱子移动信息的储存位置
0→P:
0→Q
WhileM'M为剩余目标个数,不为0时,执行游戏循环
Do'按键获取循环
Getkey→K
LpWhileK=0
IfMatH[K,3]>=1AndMatH[K,3]<=4:
Then'检测到按下了方向键
StrMid(Str5,MatH[K,3],1)→Str4'改变搬运工图案方向
MatH[K,1]→E
MatH[K,2]→F
MatA[X,Y]→S
X+E→X:
Y+F→Y
MatA[X,Y]→T
'S为当前搬运工位置的地图信息,T为搬运工前方的地图信息
0→O
T=1OrT=3=>MatA[X+E,Y+F]=0OrMatA[X+E,Y+F]=2=>1→O
'如果搬运工前方有箱子,判断箱子可否推动
IfT=0OrT=2OrO:
Then
'搬运工可以发生移动
IfS=2'搬运工原位置的图案的恢复
ThenRedLocateX-E-1,Y-F-1,Str2
ElseLocateX-E-1,Y-F-1,""
IfEnd
IfT=2OrT=3'搬运工的再显示
ThenRedLocateX-1,Y-1,Str4
ElseGreenLocateX-1,Y-1,Str4
IfEnd
IfT=1OrT=3:
Then
'推动了箱子,记录箱子被推动的信息用于撤消操作
MatA[X,Y]-1→MatA[X,Y]
MatA[X+E,Y+F]+1→MatA[X+E,Y+F]
P+1→P:
0→Q
10X+Y→MatE[P,1]
K→MatE[P,2]
T=3=>M+1→M
'判断箱子是否推到了目标位置上
IfMatA[X+E,Y+F]=3:
Then
M-1→M
RedLocateX+E-1,Y+F-1,Str3
ElseBlueLocateX+E-1,Y+F-1,Str3
IfEnd
IfEnd
Else
'搬运工无法前进,搬运工坐标的回退和显示更新
X-E→X:
Y-F→Y
IfS=2
ThenRedLocateX-1,Y-1,Str4
ElseGreenLocateX-1,Y-1,Str4
IfEnd
IfEnd
ElseIfK=74:
Then'按下了数字键7,跳到上一幅图
Locate1,1,"PreLevel":
L-1→L
L=0=>MatI[1,1]→L
Locate1,2,L
Goto3
ElseIfK=54:
Then'按下了数字键9,跳到下一幅图
Lbl5
Locate1,1,"NextLevel"
L+1→L
L>MatI[1,1]=>1→L
Locate1,2,L
Goto3
ElseIfK=47AndP:
Then'按下d键,进行撤消操作
Q=0=>P→Q
IfMatA[X,Y]=2
ThenRedLocateX-1,Y-1,Str2
ElseLocateX-1,Y-1,""
IfEnd
Int(MatE[P,1]/10)→X'从矩阵E中获取上一次箱子移动的信息
MOD(MatE[P,1],10)→Y
MatE[P,2]→K
MatH[K,1]→E
MatH[K,2]→F
StrMid(Str5,MatH[K,3],1)→Str4
P-1→P
MatA[X,Y]+1→MatA[X,Y]
MatA[X+E,Y+F]-1→MatA[X+E,Y+F]
IfMatA[X,Y]=3:
Then'箱子回退到目标位置上,M减少1
M-1→M
RedLocateX-1,Y-1,Str3
ElseBlueLocateX-1,Y-1,Str3
IfEnd
IfMatA[X+E,Y+F]=2:
Then'箱子从目标位置中退出来
M+1→M
RedLocateX+E-1,Y+F-1,Str2
ElseLocateX+E-1,Y+F-1,""
IfEnd
X-E→X:
Y-F→Y
IfMatA[X,Y]=2
ThenRedLocateX-1,Y-1,Str4
ElseGreenLocateX-1,Y-1,Str4
IfEnd
ElseIfK=48AndPThen
'按下了p键,进行恢复操作,实现和撤消操作差不多
P+1→P
IfMatA[X,Y]=2
ThenRedLocateX-1,Y-1,Str2
ElseLocateX-1,Y-1,""
IfEnd
Int(MatE[P,1]/10)→X
MOD(MatE[P,1],10)→Y
MatE[P,2]→K
MatH[K,1]→E
MatH[K,2]→F
StrMid(Str5,MatH[K,3],1)→Str4
MatA[X,Y]-1→MatA[X,Y]
MatA[X+E,Y+F]+1→MatA[X+E,Y+F]
IfMatA[X+E,Y+F]=3:
Then
M-1→M
RedLocateX+E-1,Y+F-1,Str3
ElseBlueLocateX+E-1,Y+F-1,Str3
IfEnd
IfMatA[X,Y]=2:
Then
M+1→M
RedLocateX-1,Y-1,Str2
ElseLocateX-1,Y-1,""
IfEnd
IfMatA[X,Y]=2
ThenRedLocateX-1,Y-1,Str4
ElseGreenLocateX-1,Y-1,Str4
IfEnd
ElseIfK=31OrK=29:
Then'按下了u或l键,显示游戏菜单
MenuStr6,"Continue",4,"Restart",3,"Newgame",1,"Save&Exit",6,"Exit",7
Lbl4
IfMatA[X,Y]=2
ThenRedLocateX-1,Y-1,Str4
ElseGreenLocateX-1,Y-1,Str4
IfEnd
For1→ITo80:
Next
Else
K=39=>Goto3'按下y键,重新载入当前地图
K=69=>Goto1'按下w键,读取其他地图
IfEnd:
IfEnd:
IfEnd
IfEnd:
IfEnd:
IfEnd
For1→ITo50:
Next
WhileEnd
'游戏通关,显示菜单
"Pass"+Str6→Str6
MenuStr6,"Nextlevel",5,"Exit",7
Lbl6:
(-)L→L'将变量L取相反数,以表示游戏保存
'“2i”为程序P~SAVE的调用标记,表示这是程序调用,不是程序的单独运行,以防误操作使程序运行导致数据被意外修改
2i:
Prog"P~SAVE"
Lbl7
二、子程序P~SAVE
'此子程序用于地图或游戏的保存
'ProgramMode:
RUN
Ans<>2i=>Stop:
0'判断是否有程序调用标记
'从四个方向向地图逼近,以忽略地图周围的空白区域,P、Q、U、V记录的是刚好能覆盖地图的最小矩阵的信息
0→P
For2→ITo22
For2→JTo8
IfMatA[I,J]:
Then
I→P:
Break
IfEnd
Next
P=>Break
Next
0→Q
For22→ITo2Step(-)1
For2→JTo8
IfMatA[I,J]:
Then
I→Q:
Break
IfEnd
Next
Q=>Break
Next
0→U
For2→JTo8
For2→ITo22
IfMatA[I,J]:
Then
J→U:
Break
IfEnd
Next
U=>Break
Next
0→V
For8→JTo2Step(-)1
For2→ITo22
IfMatA[I,J]:
Then
J→V:
Break
IfEnd
Next
V=>Break
Next
'判断是游戏的保存还是地图的保存
IfL<0:
Then1→A:
4→B'A和B记录数据储存位置,游戏存档保存的位置为(1,4)
Else
IfMatG[L,1]AndLThen
'地图要保存的位置上已有数据,判断两图储存所占空间大小是否相等
Int(MatG[L,1]/3148)→R
MOD(R,7)-MOD(Int(R/7),7)+1→S
Int(R/49)→R
(MOD(R,21)-MOD(Int(R/21),21)+1)*S→T
IfMOD(T,14)
ThenInt(T/14)+1→T
ElseT/14→T
IfEnd
(Q-P+1)*(V-U+1)→S
IfMOD(S,14)
ThenInt(S/14)+1→S
ElseS/14→S
IfEnd
IfS<>T:
Then'所占储存空间不相等,则不储存该地图
"Map'ssizeisunfit"
Return
IfEnd
Else
'添加新地图
IfL=1:
Then2→A:
5→B'第一幅地图的储存起始位置
Else
'从上一幅图的储存结束位置计算出此次储存的开始位置
MOD(MatG[L-1,1],3148)+1→A
MOD(A,10)+1→B
Int(A/10)+1→A
IfEnd:
IfEnd:
IfEnd
MOD((Q-P+1)*(V-U+1),14)→C'计算出第一个矩阵元素应该储存的方格个数
C=0=>14→C
0→R
'对地图进行编码
ForQ→IToPStep(-)1
ForV→JToUStep(-)1
R*5+MatA[I,J]→R
C-1→C
'储存满14位的五进制,写入到矩阵中,并跳到下一个储存位置
IfC=0:
Then
R→MatI[A,B]:
B+1→B
14→C:
0→R
IfB=11:
Then
A+1→A:
1→B
IfEnd
IfEnd
Next
Next
'保存地图索引信息
IfL>0:
Then
(((((X+21Y-44)*21+P-2)*21+Q-2)*7+U-2)*7+V-2)*3148+10A+B-12→MatG[L,1]
Else
(((((X+21Y-44)*21+P-2)*21+Q-2)*7+U-2)*7+V-2)*3148+10A+B-12→MatI[1,2]
(-)L→MatI[1,3]'记录游戏存档的关卡数
IfEnd
三、子程序P~LOAD
'此子程序用于地图或游戏存档的读取
'ProgramMode:
RUN
IfL:
Then
MatG[L,1]→R
Else
'读取游戏存档信息,并标记删除存档
MatI[1,2]→R
MatI[1,3]→L
0→MatI[1,3]
IfEnd
'解码索引信息
MOD(R,3148)→B
Int(B/10)+1→A
MOD(B,10)+1→B:
Int(R/3148)→R
MOD(R,7)+2→V:
Int(R/7)→R
MOD(R,7)+2→U:
Int(R/7)→R
MOD(R,21)+2→Q:
Int(R/21)→R
MOD(R,21)+2→P:
Int(R/21)→R
MOD(R,21)+2→X
Int(R/21)+2→Y
'初始化矩阵A
ClrText
Fill(0,MatA)
For1→ITo23
4→MatA[I,1]
4→MatA[I,9]
Next
For2→ITo8
4→MatA[1,I]
4→MatA[23,I]
Next
MatI[A,B]→R
0→C:
0→M
ForP→IToQ
ForU→JToV
'解码地图数据
MOD(R,5)→D
D→MatA[I,J]
Int(R/5)→R
C+1→C
IfC=14:
Then
0→C
'修改A和B,跳到前一个储存位置
B-1→B
IfB=0:
Then
A-1→A:
10→B
IfEnd
MatI[A,B]→R
IfEnd
'在屏幕上显示地图
IfD=4:
ThenLocateI-1,J-1,Str1
ElseIfD=2:
ThenRedLocateI-1,J-1,Str2
ElseIfD=1:
ThenBlueLocateI-1,J-1,Str3:
M+1→M
ElseD=3=>RedLocateI-1,J-1,Str3
IfEnd:
IfEnd:
IfEnd
Next
Next
四、地图编辑器P~EDIT
'此程序用于编辑、保存、删除或修改推箱子游戏地图
'ProgramMode:
RUN
"■"→Str1:
"
"→Str2
"□"→Str3:
"·"→Str4
0→L:
(-)1→S
'显示菜单,由于地图是连续储存的,所以只能删除最后一幅地图
'如果计算器上没有任何地图,则直接进入地图编辑
MatI[1,1]=>Menu"Editor","Newmap",1,"Changemap",2,"Dellastmap",8
Lbl1
Fill(0,MatA)
11→X:
4→Y
Goto3
Lbl2
"Inputmap'snumber"?
→L
L<=0OrL>MatI[1,1]=>Goto2
Prog"P~LOAD"
X-