学生活动研究 图形计算器游戏扫雷 图形计算器应用能力测试 高中数学校本教学.docx
《学生活动研究 图形计算器游戏扫雷 图形计算器应用能力测试 高中数学校本教学.docx》由会员分享,可在线阅读,更多相关《学生活动研究 图形计算器游戏扫雷 图形计算器应用能力测试 高中数学校本教学.docx(15页珍藏版)》请在冰豆网上搜索。
学生活动研究图形计算器游戏扫雷图形计算器应用能力测试高中数学校本教学
高中数学论文图形计算器应用能力测试活动学生图形计算器游戏扫雷
利用图形计算器的编程功能,在CASIOfx-CG20图形计算器平台上实现了扫雷游戏。
本文中的程序利用了图形计算器中的矩阵来储存数据,通过模拟法和广度搜索算法实现扫雷游戏,游戏中提供了自动挖开和自动标志功能,并能中途保存游戏。
[关键词]
图形计算器;扫雷;
[前言]
观察过以前的获奖论文,大多数的论文只利用到图形计算器的画图功能和小部分的编程功能。
图形计算器编程功能的强大之处并未充分体现出来,而本文正是利用了图形计算器强大的编程功能,从而在图形计算器上实现了扫雷游戏。
[研究目的]
利用图形计算器的编程功能,在图形计算器上实现扫雷游戏,从而锻炼编程能力和算法能力,加深对广度优先搜索算法的理解,同时增强了CASIO图形计算器的娱乐功能,丰富同学们的课余生活。
[程序功能说明]
游戏功能:
玩家通过数字键1、3、7、9、2、4、6和8或B、N、!
和$移动光标选择方格,按u、5或l可以挖开当前选定的方格。
如果挖到地雷则游戏结束并显示所有地雷的位置和标记错误的地方;如果当前方格挖开后显示一个数字n表示这个方格周围8个方块里总共有n个地雷;如果当前方格和周围8个方块里都没有地雷,则会自动挖开一片没有地雷的区域。
按y或m标记当前方格,在有标记的方格再按一次y或m,则取消标记。
(如图1)
图1
自动挖开和自动标记功能:
如果玩家选择了一个已挖开的显示数字的方格,并按下按键u、5或l,则程序会自动判断周围8个方格的情况,从而进行自动标记或自动挖开周围的方格。
游戏保存功能:
游戏中途按p可暂停游戏,选择“Exit”可退出并保存游戏。
(如图2)下次运行程序时,程序会自动读取存档。
(如图3)
图2暂停游戏菜单
图3游戏存档读取中
特色:
1.游戏运行时,左上角会显示未标记的地雷个数。
(如图1)
2.随机生成地图的游戏模式下,开始游戏时光标所在的方格一定没有地雷。
如果总地雷数在范围内,则光标周围八个方格也没有地雷。
这个设计是为了降低游戏难度。
3.程序根据方格上的数字的大小用不同的颜色显示。
(如图4)
图4
[研究过程]
1.确定程序功能,请参考“游戏功能说明”。
2.构思算法:
本程序在游戏实现方面使用模拟法,挖开方格时用非递归的广度搜索算法实现。
使用一个矩阵保存游戏时的地图,一个矩阵元素对应地图上的一个方格。
需要记录的数据:
光标位置、地图信息、未标记的地雷数、未挖开且无标记的方格数
矩阵记录地图信息的方法:
矩阵元素上的数字表示地图对应方格的当前状态:
用负数表示此方格还没有被标记或被挖开;零表示表示地图的边界,对应地图上不显示的地方;正数表示此方格已经被挖开或被标记。
矩阵元素数字表示的具体含义请见下表:
数字
含义
正整数
被标记的方格
已被挖开的周围没有地雷的方格
已被挖开的周围有1至8个地雷的方格
零
地图边界
负整数
未被挖开的周围有1至8个地雷的方格
未被挖开的周围没有地雷的方格
有地雷的方格
游戏保存实现:
将“需要记录的数据”用另一个矩阵记录起来。
按键检测方法:
使用“Getkey”命令获取按键后,因为该命令返回的数值最大为79且一定为非负整数,所以创建一个79×3的矩阵MatH来判断按键。
通过读取MatH[K,3](K为“Getkey”命令的返回值)即可立即判断按键是否有效。
若按键有效,则可以非常方便地利用矩阵的数据移动光标。
挖开方格的实现(广度优先搜索的实现):
当玩家挖开的方格周围八个方格都没有地雷,程序将自动挖开这个八个方格,也就是说对这八个方格的处理和对玩家挖开的方格的处理是一样的。
具体实现时,用一个队列储存待挖开的方格,先将光标所在的方格加入队首。
如果队列不为空,从队尾中取出一个方格,判断该方格周围八个方格是否有地雷。
如果没有,则这八个方格加入到队首,对应方格显示一个空格;否则,只显示该方格上的数字。
用深度优先搜索算法也可以实现方格的挖开,但考虑到广度优先搜索的动态显示效果比深度优先搜索的好,所以选择了广度优先搜索算法。
自动挖开和自动标记的实现:
统计光标周围八个方格中的标记数和未挖开的方格数。
存在未挖开方格的前提下,如果标记数等于光标所在方格上的数字,则将未挖开的方格加入到队首(即挖开这些方格);如果标记数加上未挖开的方格等于方格上的数字,则在未挖开的方格上添加标记。
3.使用图形计算器编程实现。
4.进行程序调试。
5.游戏试用。
具体实现步骤如下:
1.打开图形计算器,按1进入“计算·矩阵”模式。
2.按e进入矩阵存储器。
并创建矩阵:
矩阵名
尺寸
用途
MatA
23×9
程序运行时保存地图信息
MatC
8×2
八个方向的相对偏移量
MatD
23×9
游戏存档存放位置
MatE
100×2
广度搜索时用作储存队列
MatH
79×3
按键判断
MatC的初始化:
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.创建程序“MINE”,代码请参考“程序代码分析”或附件。
5.创建程序“M~DUG”,代码请参考“程序代码分析”或附件。
6.创建程序“M~INIT”,代码请参考“程序代码分析”或附件。
7.创建程序“M~SIGN”,代码请参考“程序代码分析”或附件。
[程序代码分析]
一、主程序MINE
'ProgramMode:
RUN
'_Mat_C,D,A,E,H
(-)1→Z'变量Z记录设定的地雷个数,-1表示未定义
Lbl1
'“7i”是程序M~INIT的调用标志,表示此次调用由程序调用,以防误操作以致程序M~INIT被单独运行
7i:
Prog"M~INIT"
'游戏循环,M记录的是没标记或未挖开的方格数,N记录的是未标记的地雷个数
WhileM>N
Do'按键获取循环,同时使当前选中的方格闪烁,以显示光标位置
LocateX,Y,""
RedLocateX,Y,Str2
Getkey→K
LpWhileK=0
IfMatH[K,3]:
Then'判断是否按下了方向键
'光标发生移动,根据矩阵里的数据,恢复光标目前所在方格的显示
MatA[X+1,Y+1]→R
IfR<0:
ThenLocateX,Y,Str1
ElseIfR=9:
ThenLocateX,Y,""
ElseIfR=1:
ThenGreenLocateX,Y,1
ElseIfR=2:
ThenCyanLocateX,Y,2
ElseIfR=3:
ThenBlueLocateX,Y,3
ElseIfR=4:
ThenYellowLocateX,Y,4
ElseR=5=>MagentaLocateX,Y,5
IfEnd:
IfEnd:
IfEnd:
IfEnd:
IfEnd:
IfEnd
X+MatH[K,1]→X'光标移动
Y+MatH[K,2]→Y
IfMatA[X+1,Y+1]=0:
Then
'判断是否到达了地图边界,由于左上角有两个方格显示未标记的地雷个数,这种情况需要特殊处理
IfX=22:
Then
IfY=1:
Then3→X
Else1→X:
IfEnd
ElseX=0Or(X=2AndMatH[K,1]=(-)1)=>21→X
IfEnd
IfY=8:
Then
IfX>=3:
Then1→Y
Else2→Y:
IfEnd
ElseY=0Or(Y=1AndMatH[K,2]=(-)1)=>7→Y
IfEnd
IfEnd
MatA[X+1,Y+1]→R
IfR<0'根据光标所在方格的状态,修改字符串2
ThenStr1→Str2
ElseIfR>=1AndR<=9
ThenStrMid("12345678·",R,1)→Str2
ElseR>9=>Str3→Str2
IfEnd:
IfEnd
ElseIfK=63OrK=31OrK=29:
Then
'按下了按键u、5或l,调用程序M~DUG
Prog"M~DUG"
IfMatA[X+1,Y+1]<=(-)10:
Then
'判断游戏是否结束了,程序M~DUG执行完毕后,如果光标停在了地雷上则游戏结束
"Lose"→Str4
'显示错误的标记和所有地雷的所在位置
For2→JTo8
For2→ITo22
IfMatA[I,J]<=(-)10
ThenRedLocateI-1,J-1,""
ElseMatA[I,J]>90=>RedLocateI-1,J-1,"×"
IfEnd
Next
Next
Break
IfEnd
'按下了按键y或m,标记地雷
ElseIfK=43OrK=39:
ThenProg"M~SIGN"
ElseIfK=48:
Then'按下了p,暂停游戏
Menu"Pause","Continue",3,"Exit",4
Lbl3
IfEnd:
IfEnd:
IfEnd:
IfEnd
WhileEnd
For1→ITo300:
Next
WhileGetkey=0
WhileEnd
MenuStr4,"Playagain",1,"Exit",2'游戏结束后的菜单
Lbl4'游戏保存的实现
MatA→MatD
M→MatD[1,1]
N→MatD[1,2]
X→MatD[1,3]
Y→MatD[1,4]
Lbl2:
Stop
二、子程序M~INIT
'ProgramMode:
RUN
'此子程序主要用于游戏前的初始化,主要是地图的随机生成和游戏存档的读取
Ans<>7i=>Prog"MINE":
0'调用标志判断,如果不是由程序调用,则调用主程序
Z<>(-)1=>Goto4'地雷数已定义,直接开始随机生成地图
'字符串1保存未挖开且无标记方格的字符,字符串3保存标记地雷用的字符
"■"→Str1:
"
"→Str3
'没有游戏存档时,询问地雷数的设置
MatD[1,1]=0=>Menu"Thenumofmines","31",1,"35",2,"User-defined",3
Goto5'有游戏存档时直接读取游戏存档
Lbl1:
31→Z:
Goto4
Lbl2:
35→Z:
Goto4
Lbl3:
"Numofmines="?
→Z
Lbl4
IntZ→N
N<=0OrN>99=>Goto3
ClrText
"Youwin"→Str4'初始化游戏结果,用于游戏结束时显示
Str1→Str2'初始化字符串2,字符串2保存当前光标位置的字符
'初始化矩阵A,并随机生成地图
Fill(0,MatA)
For1→IToN
Do
RanInt#(2,22)→X
RanInt#(2,8)→Y
LpWhile(Y=2And(X=2OrX=3))Or(MatA[X,Y]<=(-)10)
(-)10→MatA[X,Y]
For1→JTo8
'将周围八个矩阵元素上的数值减去一,表示这八个方格周围的地雷数增加了一
MatA[X+MatC[J,1],Y+MatC[J,2]]-1→MatA[X+MatC[J,1],Y+MatC[J,2]]
Next
Next
For2→JTo8
For2→ITo22
'数值为零的位置,表示周围没有地雷,以防与边界混淆,用-9表示
MatA[I,J]=0=>(-)9→MatA[I,J]
Next
Next
'定义边界
For1→ITo23
0→MatA[I,1]
0→MatA[I,9]
Next
For2→ITo8
'显示地图,因为未挖开任何一个方格,所以全为黑色的正方形。
用这种方法显示可以加快显示速度
Locate1,I-1,"■■■■■■■■■■■■■■■■■■■■■"
0→MatA[1,I]
0→MatA[23,I]
Next
0→MatA[2,2]
0→MatA[3,2]
'显示未标记的地雷个数
IfN>9:
Then
Locate1,1,N
Else
Locate1,1,0
Locate2,1,N
IfEnd
IfN>30AndN<=60:
Then
'使总地雷数在范围内时,光标所在方格及其周围八个方格上没有地雷
Do
RanInt#(1,21)→X
RanInt#(1,7)→Y
LpWhile(Y=1And(X=1OrX=2))Or(MatA[X+1,Y+1]<>(-)9)
Else
'使光标所在的方格一定没有地雷
Do
RanInt#(1,21)→X
RanInt#(1,7)→Y
LpWhile(Y=1And(X=1OrX=2))Or(MatA[X+1,Y+1]<=(-)10)
IfEnd
145→M:
0→E:
0→F
Return
Lbl5
"Youwin"→Str4
'游戏存档的读取
MatD→MatA
MatA[1,1]→M:
MatA[1,2]→N
MatA[1,3]→X:
MatA[1,4]→Y
0→MatD[1,1]:
0→MatA[1,1]:
0→MatA[1,2]:
0→MatA[1,3]:
0→MatA[1,4]
MatA[X+1,Y+1]→R
IfR<0
ThenStr1→Str2
ElseIfR>30
ThenStr3→Str2
ElseR>=1AndR<=9=>StrMid("12345678·",R,1)→Str2
IfEnd:
IfEnd
'N的显示
IfN>9:
Then
Locate1,1,N
Else
Locate1,1,0
Locate2,1,N
IfEnd
'地图的显示
For1→JTo7
For1→ITo21
MatA[I+1,J+1]→R
IfR<0:
ThenLocateI,J,Str1
ElseIfR>=30:
ThenRedLocateI,J,Str3
ElseIfR=1:
ThenGreenLocateI,J,1
ElseIfR=2:
ThenCyanLocateI,J,2
ElseIfR=3:
ThenBlueLocateI,J,3
ElseIfR=4:
ThenYellowLocateI,J,4
ElseIfR=5:
ThenMagentaLocateI,J,5
ElseR>=6AndR<=8=>RedLocateI,J,R
IfEnd:
IfEnd:
IfEnd
IfEnd:
IfEnd:
IfEnd
IfEnd:
Next
Next
三、子程序M~DUG
'ProgramMode:
RUN
'按下按键u、5或l后的所有操作都由这个子程序实现
MatA[X+1,Y+1]→R
R<=(-)10OrR>=9=>Return'如果当前方格有地雷或标记,则返回主程序
IfR>0:
Then'当前方格显示数字,则统计未挖开方格数A和标记数B
0→P'变量P记录队首在矩阵E中的位置
0→A:
0→B
For1→ITo8
IfMatA[X+MatC[I,1]+1,Y+MatC[I,2]+1]<0:
Then1+A→A
ElseMatA[X+MatC[I,1]+1,Y+MatC[I,2]+1]>=30=>1+B→B
IfEnd
Next
IfA<>0AndR=B:
Then
'实现自动挖开功能
For1→ITo8
X+MatC[I,1]→X
Y+MatC[I,2]→Y
IfMatA[X+1,Y+1]<0:
Then
'挖开了地雷说明标记有错误,返回主程序,游戏结束
MatA[X+1,Y+1]<=(-)10=>Return
1+P→P
X+1→MatE[P,1]
Y+1→MatE[P,2]
(-)MatA[X+1,Y+1]→MatA[X+1,Y+1]
IfEnd
X-MatC[I,1]→X
Y-MatC[I,2]→Y
Next
ElseIfA<>0AndR=A+B:
Then
'实现自动标记功能
For1→ITo8
X+MatC[I,1]→X
Y+MatC[I,2]→Y
MatA[X+1,Y+1]<0=>Prog"M~SIGN"
X-MatC[I,1]→X
Y-MatC[I,2]→Y
Next
StrMid("12345678·",MatA[X+1,Y+1],1)→Str2
IfEnd:
IfEnd
Else
(-)R→MatA[X+1,Y+1]
StrMid("12345678·",MatA[X+1,Y+1],1)→Str2
'将当前方格加入队首
1→P
X+1→MatE[1,1]
Y+1→MatE[1,2]
IfEnd
0→Q'变量Q记录队尾的下一个位置
WhileP<>Q'当队列不为空时执行循环
'取出队尾方格
MOD(Q,100)+1→Q
MatE[Q,1]→S
MatE[Q,2]→T
MatA[S,T]→R
IfR>=1AndR<9:
Then'方格为数字直接将其显示出来
M-1→M:
S-1→S:
T-1→T
IfR=1:
ThenGreenLocateS,T,1
ElseIfR=2:
ThenCyanLocateS,T,2
ElseIfR=3:
ThenBlueLocateS,T,3
ElseIfR=4:
ThenYellowLocateS,T,4
ElseIfR=5:
ThenMagentaLocateS,T,5
ElseIfR>=6AndR<=8:
ThenRedLocateS,T,R
IfEnd:
IfEnd:
IfEnd
IfEnd:
IfEnd:
IfEnd
ElseIfR=9:
Then'方格周围八个方格没有地雷
M-1→M
LocateS-1,T-1,""
For1→ITo8
S+MatC[I,1]→A
T+MatC[I,2]→B
MatA[A,B]→R
IfR<0:
Then'方格符合条件则加入队首
(-)R→MatA[A,B]
MOD(P,100)+1→P
A→MatE[P,1]
B→MatE[P,2]
IfEnd
Next
IfEnd:
IfEnd
WhileEnd
四、子程序M~SIGN
'ProgramMode:
RUN
'此子程序实现标记地雷
MatA[X+1,Y+1]→S
S>=0AndS<30=>Return'已挖开的方格不能标记
IfS<0:
Then
'当前方格未被标记,进行标记
S+100→MatA[X+1,Y+1]'将矩阵A上对应的矩阵元素加上100,以表示此方格已被标记,同时可以通过减去100恢复未标记的状态
N-1→N:
M-1→M
RedLocateX,Y,Str3
Str3→Str2
Else
'当前方格已被标记,则取消标记
LocateX,Y,Str1
S-100→MatA[X+1,Y+1]
N+1→N:
M+1→M
Str1→Str2
IfEnd
'更新N的显示
IfN>=10
ThenLocate1,1,N
ElseIfN>=0
ThenLocate1,1,0
Locate2,1,N
IfEnd:
IfEnd
[总结]
1.扫雷游戏能在图形计算器上实现最重要的基础是利用了矩阵储存数据,矩阵的作用相当于内存和硬盘在计算机中的作用。
在笔者编写的其他的较复杂的图形计算器程序中,矩阵都起到了不可或缺的作用。
2.对矩阵元素储存地图信息的方法的设计影响到程序的编写复杂度。
正负数表示地图上的方格是否已被挖开或标记,使得程序中可以方便地判断方格的状态;当挖开该方格时,只需将其数值取相反数即可。
加上一个大数表示标记方格的方法,既保存了原有的地图信息,又立即标记了该方格。
3.通过读取矩阵里的信息可以立即判断按键是否有效,同时矩阵元素储存的数据提供了坐标的偏移量。
这个方法可以减少程序中的判断,加快程序的运行速度,使代码更简短,更易编写,更易读。