试验四 实验四 LC-3简单游戏设计(Nim游戏)
一、实验内容:
本次实验对Nim游戏做了一些小的改变,具体如下:游戏界面由三行组成,计数器类型为石子,其中A行包含3个石子,B行包含5个石子,C行包含8个石子。
规则如下:
1. 每个玩家轮流从某一行中移除一个或多个石子。
2. 一个玩家不能在一个回合中从多个行中移除石子。
3. 当某个玩家从游戏界面上移除最后一个石子时,此时游戏结束,该玩家战败。
二、实验要求:
- 在游戏开始时,你应该显示游戏界面的初始化状态。具体包括:在每行石子的前面,你应该先输出行的名称,例如“ROW A”。你应该使用ASCII字符小写字母“o”(ASCII码 x006F)来表示石子。游戏界面的初始化状态应该如下:
ROW A: ooo
ROW B: ooooo
ROW C: oooooooo
- 游戏总是从玩家1先开始,之后玩家1和玩家2轮流进行。在每一个回合开始时,你应该输出轮到哪一个玩家开始,并提示玩家进行操作。例如,对于玩家1,应该有如下显示:
Player 1,choose a row and number of rocks:
- 为了指定要移除哪一行中的多少石子,玩家应该输入一个字母后跟一个数字(输入结束后不需要按Enter键),其中字母(A,B或C)指定行,数字(从1到所选行中石子的数量)指定要移除的石子的数量。你的程序必须要确保玩家从有效的行中移除有效数量的石子,如果玩家输入无效,你应该输出错误提示信息并提示该玩家再次进行输入。
例如:如果轮到玩家1
Player 1, choose a row and number of rocks: D4
Invalid move. Try again.
Player 1, choose a row and number of rocks: A9
Invalid move. Try again.
Player 1, choose a row and number of rocks: A*
Invalid move. Try again.
Player 1, choose a row and number of rocks: &4
Invalid move. Try again.
Player 1, choose a row and number of rocks:
你的程序应保持提示玩家,直到玩家选择有效的输入为止。确保你的程序能够回显玩家的输入到屏幕上,当回显玩家的输入后,此时应该输出一个换行符(ASCII码x000A)使光标指向下一行。
- 玩家选择有效的输入后,你应该检查获胜者。如果有一个玩家获胜,你应该显示相应的输出来表明该玩家获胜。如果没有胜利者,你的程序应该更新游戏界面中每行石子的数量,重新显示更新的游戏界面,并轮到下一个玩家继续。
- 当某个玩家从游戏界面上移除最后一个石子时,游戏结束。此时,你的程序应该显示获胜者然后停止。例如,如果玩家2移除了最后一个石子,你的程序应该输出一下内容:
Player 1 Wins.
三、实验设计思路:
- 编写主程序,调用子程序print,实现游戏界面的输出
- 调用子程序Cin1,提示玩家1输入,并进行判断在子程序里判断输入是否合法,合法就更新游戏界面,不合法提示再输入;
- 返回主程序判断是否有人赢了,没有的话游戏继续,轮到玩家2输入,流程和玩家1一致;
- 有人赢了,输出赢的人,游戏结束。如果没人赢,就继续循环步骤2、3直到有人赢
- 程序中寄存器的作用:
R0:用于字符串的输入和输出
R1,R2,R3:分别存储A、B、C行的石头数
R4:用于判断字符和数字是否输入正确,进行计算
R5、R6:分别存储输入的字母和数字的ASCII码
R7:返回主程序以及参与判断是否胜利的计算
四、实验步骤
(一)主程序编写
- 程序从x3000开始,开始编写主程序:先初始化R1,R2,R3的值,表示A、B、C行的值,R5、R6分别存储输入的字母和数字的ASCII码
- 调用子程序print,实现游戏界面的输出
- 调用子程序Cin1,提示玩家1输入,并进行判断在子程序里判断输入是否合法,合法就更新游戏界面,不合法提示再输入;
- 返回主程序判断是否有人赢了,如果winnerA存的是1,玩家2胜利,没有的话游戏继续,轮到玩家2输入,流程和玩家1一致;
- 输出胜利者是谁,游戏结束
continue JSR Print ;调用子程序Print:输出游戏盘面
JSR Cin1 ;调用子程序Cin:
LD R4,winnerA ;把地址winnerA的内容存入R4,判断是否有人赢了
ADD R4,R4,#-1 ;R4等于1,则玩家2胜
BRz winner2
JSR Print ;输出界面
JSR Cin2 ;提示玩家2输入并判断输入是否合法
LD R4,winnerB ;
ADD R4,R4,#-2 ;R4等于2,则玩家1胜
BRz winner1
BRnzp continue ;如果没有分出胜负,则继续游戏
winner1 LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R0,p1win
PUTS ;输出字符串
BRnzp end ;
winner2 LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R0,p2win
PUTS ;输出字符串
BRnzp end ;
end HALT ;
- 主程序的数据区
char .fill x41 ;存储输入的字符的ASCII码
num .fill #0 ;存储输入数字的ASCII码
p1win .STRINGZ "Player1 Wins."
p2win .STRINGZ "Player2 Wins."
winnerA .fill #0
winnerB .fill #0
chanline .fill x000A
(二)编写子程序Print:用于输出游戏页面
- 首先保存R7,将R1、R2、R3作为循环计数器,分别输出所在行的石头数o
- 然后换行,恢复R7,返回主程序
;子程序:Print,输出游戏盘面
Print ST R7,SaveR7 ;保存R7,放置无法返回主程序
;输出行A
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R4,rowA
ADD R0,R4,#0
PUTS ;输出“ROW A:"
LD R0,Ochar ;将字符o的ASCII码存入R0
ADD R4,R1,#0 ;将行A的石头数传给R4,让它作为计数器输出
againA BRz RB ;如果R4等于0,跳转到输出行B
OUT ;输出石头‘o'
ADD R4,R4,#-1 ;循环次数减一
BRnzp againA ;
;输出行B
RB LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R4,rowB
ADD R0,R4,#0
PUTS ;输出“ROW B:"
LD R0,Ochar ;将字符o的ASCII码存入R0
ADD R4,R2,#0 ;将行B的石头数传给R4,让它作为计数器输出
againB BRz RC ;如果R4等于0,跳转到输出行C
OUT ;输出石头‘o'
ADD R4,R4,#-1 ;循环次数减一
BRnzp againB ;
;输出行C
RC LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R4,rowC ;
ADD R0,R4,#0 ;
PUTS ;输出“ROW C:"
LD R0,Ochar ;将字符o的ASCII码存入R0
ADD R4,R3,#0 ;将行C的石头数传给R4,让它作为计数器输出
againC BRz Next ;如果R4等于0,跳转到Next
OUT ;输出石头‘o'
ADD R4,R4,#-1 ;循环次数减一
BRnzp againC ;
Next LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LD R7,SaveR7 ;恢复R7
RET ;返回主程序
Ochar .fill x006F ;石头'o'
SaveR7 .fill #0
rowA .STRINGZ "ROW A:"
rowB .STRINGZ "ROW B:"
rowC .STRINGZ "ROW C:"
(三)编写子程序Cin1:
- 首先保存R7,初始化winnerA标志为0,调用系统程序输入字符并回显,把输入的字母和数字字符(将字符转化成整型)的ASCII码存入R5、R6中
;子程序Cin1:提示输入以及判断是否合法
Cin1 ST R7,SaveR7 ;保存R7,放置无法返回主程序
AND R4,R4,#0 ;
ST R4,winnerA ;每次输入前保证winnerA这个标志为0,如果回去是1,说明就有人赢了
;输出提示语以及输入
Again1 LEA R0,play1
PUTS ;输出提示输入语“Player1,choose a row and ....."
GETC ;输入字母存在R0中
OUT ;回显
ADD R5,R0,#0 ;将输入的字母ASCII码赋给R5
GETC ;输入数字存在R0中
OUT ;回显
LD R6,NumASC ;将字符'0'的ASCII码的相反数赋给R6
ADD R6,R0,R6 ;将输入的字符型数字转化为整型数字(如'2'-'0'=2)
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
- 对输入的字符进行判断:不等于A、B、C的都是不合法的,先让R5减去字符A的ASCII码,结果存入R4,如果结果小于0就不合法,说明输入的字符比A小,R4再减去2,如果大于0,也不合法,说明输入的字符比C大
;对输入的字符和数字进行判断
ADD R6,R6,#0
BRn error2 ;如果输入的数字小于0,报错
LD R4,NegofA ;将-A的 ASCIII码存入R4
ADD R4,R5,R4 ;将将输入的字母ASCII码减去A的,使得字母A,B,C对应数字0,1,2都>=0
BRn error1 ;如果R4小于0,说明输入的字符小于A,无效
ADD R4,R4,#-2 ;现在字母A,B,C对应数字-1,-2,0都<=0
BRp error1 ;如果R4大于0,说明输入的字符大于C,无效
BRnzp right1 ;如果上面都没跳转,说明输入的字符有效
error1 LEA R0,Tagain
PUTS ;字符输入错误,输出提示语:Invalid move.Try again.
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
BRnzp Again1 ;重新输入
- 对输入的数字是否有效进行判断:对行A:如果有效,更新完之后,还要判断是否有人赢了,如果该行为0,且其他行数的石头数为0,说明该玩家移走的是最后一个石头,战败,winnerA置为1
;字符输入正确,开始对输入的数字进行判断
right1 ADD R4,R6,#0
NOT R4,R4
ADD R4,R4,#1 ;-R4,便于判断该数字是否所在行的石头数
LD R0,NegofB
ADD R0,R5,R0 ;将输入的字母ASCII码减去B的,使得字母A,B,C对应数字-1,0,1
;判断行A
BRzp RowB ;如果R0>=0,说明输入的不是A,进行下一个判断,是否为行B
;如果输入的是行A,进行比较石头数
ADD R7,R1,R4 ;存储修改后的石头数
BRn error2 ;小于0,说明输入的石头数大于行A的石头数,报错
ADD R1,R7,#0 ;输入正确的话,更新行A的石头数
BRz win111 ;如果更新后石头数R1等于0,跳转
BRnzp over1 ;
win111 ADD R7,R2,R3 ;R7=R2+R3,如果和为0,说明最后一个石头已经被拿走
BRz win112
BRnzp over1 ;和不为0,界面上还有石头,返回
win112 AND R4,R4,#0
ADD R4,R4,#1
ST R4,winnerA ;如果更新后石头数为0且其他两行石头数为0,则玩家2胜利,存储到内存里
BRnzp over1
- 同理对行B、行C进行类似的判断,此处省略代码(详见完整代码)
- 最后错误的输出提示语,恢复R7,返回主程序
error2 LEA R0,Tagain
PUTS ;字符输入错误,输出提示语:Invalid move.Try again.
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
BRnzp Again1 ;重新输入
over1 LD R7,SaveR7 ;恢复R7
RET
(四)编写子程序Cin2:
基本与子程序Cin1一致,区别在于:对输入的数字进行判断时,判断有人战败时,将winnerB置为2,其他方法完全一样,具体代码不再赘述(详见完整代码)
(五)通过LC-3仿真器调试和运行相关程序
- 打开simulate.exe,导入上述的.obj文件,进行运行和调试
- 运行程序:在halt指令所在行前双击,设置断点,点击运行程序run program键,运行结果:主界面如下:输入B2,结果运行如下:
输入A1,C6,G1,结果运行如下:
继续输入,最后输入A1,输出Player2 wins,结果正确
五、实验结论
- 整体上较好的实现本次实验目的,完成了对Nim这一简单游戏的设计。
- 通过本次实验,我更加熟悉地掌握了LC-3Edit和simulate的使用方法,对于汇编代码的使用和理解更为深刻。
- 另外,在本次实验中,学会了使用子程序来简化汇编代码,尤其是那些需要反复执行的操作,可以通过编写多个子程序,使得主程序简明易懂,值得注意的是,编写子程序时要注意寄存器的保存和恢复,尤其是R7这个隐式的寄存器,才能正常返回主程序。
- 总体来说,通过此次实验,我熟练地掌握了子程序的编写和调用,动手实践,也让我对其中的细节更加关注,及时发现问题,解决问题,收益匪浅。
六、实验完整代码(仅供参考)
;此程序实现功能:
;实现了Nim游戏的简单设计
;
;
;主程序:
.ORIG x3000 ;程序从x3000开始
AND R1,R1,#0 ;
AND R2,R2,#0 ;
AND R3,R3,#0 ;
ADD R1,R1,#3 ;R1表示行A石头个数
ADD R2,R2,#5 ;R2表示行B石头个数
ADD R3,R3,#8 ;R3表示行C石头个数
LD R5,char ;R5存储输入的字符的ASCII码
LD R6,num ;R6存储输入数字的ASCII码
continue JSR Print ;调用子程序Print:输出游戏盘面
JSR Cin1 ;调用子程序Cin:提示玩家1输入行号和数字,并进行检查输入是否合法
LD R4,winnerA ;把地址winnerA的内容存入R4,判断是否有人赢了
ADD R4,R4,#-1 ;R4等于1,则玩家2胜
BRz winner2 ;
JSR Print ;输出界面
JSR Cin2 ;提示玩家2输入并判断输入是否合法
LD R4,winnerB
ADD R4,R4,#-2 ;R4等于2,则玩家1胜
BRz winner1 ;
BRnzp continue ;如果没有分出胜负,则继续游戏
winner1 LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R0,p1win
PUTS ;输出字符串
BRnzp end ;
winner2 LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R0,p2win
PUTS ;输出字符串
BRnzp end ;
end HALT ;
char .fill x41 ;存储输入的字符的ASCII码
num .fill #0 ;存储输入数字的ASCII码
p1win .STRINGZ "Player1 Wins."
p2win .STRINGZ "Player2 Wins."
winnerA .fill #0
winnerB .fill #0
chanline .fill x000A
;
;
;-----------------------------------------------------------------------
;子程序:Print,输出游戏盘面
Print ST R7,SaveR7 ;保存R7,放置无法返回主程序
;输出行A
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R4,rowA
ADD R0,R4,#0
PUTS ;输出“ROW A:"
LD R0,Ochar ;将字符o的ASCII码存入R0
ADD R4,R1,#0 ;将行A的石头数传给R4,让它作为计数器输出
againA BRz RB ;如果R4等于0,跳转到输出行B
OUT ;输出石头‘o'
ADD R4,R4,#-1 ;循环次数减一
BRnzp againA ;
;输出行B
RB LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R4,rowB
ADD R0,R4,#0
PUTS ;输出“ROW B:"
LD R0,Ochar ;将字符o的ASCII码存入R0
ADD R4,R2,#0 ;将行B的石头数传给R4,让它作为计数器输出
againB BRz RC ;如果R4等于0,跳转到输出行C
OUT ;输出石头‘o'
ADD R4,R4,#-1 ;循环次数减一
BRnzp againB ;
;输出行C
RC LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LEA R4,rowC
ADD R0,R4,#0 ;
PUTS ;输出“ROW C:"
LD R0,Ochar ;将字符o的ASCII码存入R0
ADD R4,R3,#0 ;将行C的石头数传给R4,让它作为计数器输出
againC BRz Next ;如果R4等于0,跳转到Next
OUT ;输出石头‘o'
ADD R4,R4,#-1 ;循环次数减一
BRnzp againC ;
Next LD R0,chanline ;把换行符传入R0
OUT ;输出换行
LD R7,SaveR7 ;恢复R7
RET ;返回主程序
Ochar .fill x006F ;石头'o'
SaveR7 .fill #0
rowA .STRINGZ "ROW A:"
rowB .STRINGZ "ROW B:"
rowC .STRINGZ "ROW C:"
;-----------------------------------------------------------------------
;子程序Cin1:提示输入以及判断是否合法
Cin1 ST R7,SaveR7 ;保存R7,放置无法返回主程序
AND R4,R4,#0 ;
ST R4,winnerA ;每次输入前保证winnerA这个标志为0,如果回去是1,说明就有人赢了
;输出提示语以及输入
Again1 LEA R0,play1
PUTS ;输出提示输入语“Player1,choose a row and ....."
GETC ;输入字母存在R0中
OUT ;回显
ADD R5,R0,#0 ;将输入的字母ASCII码赋给R5
GETC ;输入数字存在R0中
OUT ;回显
LD R6,NumASC ;将字符'0'的ASCII码的相反数赋给R6
ADD R6,R0,R6 ;将输入的字符型数字转化为整型数字(如'2'-'0'=2)
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
;对输入的字符和数字进行判断
ADD R6,R6,#0
BRn error2 ;如果输入的数字小于0,报错
LD R4,NegofA ;将-A的 ASCIII码存入R4
ADD R4,R5,R4 ;将将输入的字母ASCII码减去A的,使得字母A,B,C对应数字0,1,2都>=0
BRn error1 ;如果R4小于0,说明输入的字符小于A,无效
ADD R4,R4,#-2 ;现在字母A,B,C对应数字-1,-2,0都<=0
BRp error1 ;如果R4大于0,说明输入的字符大于C,无效
BRnzp right1 ;如果上面都没跳转,说明输入的字符有效
error1 LEA R0,Tagain
PUTS ;字符输入错误,输出提示语:Invalid move.Try again.
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
BRnzp Again1 ;重新输入
;字符输入正确,开始对输入的数字进行判断
right1 ADD R4,R6,#0
NOT R4,R4
ADD R4,R4,#1 ;-R4,便于判断该数字是否所在行的石头数
LD R0,NegofB
ADD R0,R5,R0 ;将输入的字母ASCII码减去B的,使得字母A,B,C对应数字-1,0,1
;判断行A
BRzp RowB ;如果R0>=0,说明输入的不是A,进行下一个判断,是否为行B
;如果输入的是行A,进行比较石头数
ADD R7,R1,R4 ;存储修改后的石头数
BRn error2 ;小于0,说明输入的石头数大于行A的石头数,报错
ADD R1,R7,#0 ;输入正确的话,更新行A的石头数
BRz win111 ;如果更新后石头数R1等于0,跳转
BRnzp over1
win111 ADD R7,R2,R3 ;R7=R2+R3,如果和为0,说明最后一个石头已经被拿走
BRz win112
BRnzp over1 ;和不为0,界面上还有石头,返回
win112 AND R4,R4,#0
ADD R4,R4,#1
ST R4,winnerA ;如果更新后石头数为0且其他两行石头数为0,则玩家2胜利,存储到内存里
BRnzp over1
RowB ADD R0,R0,#0
BRp RowC ;如果R0>0,说明输入的不是B,进行下一个判断,是否为行C
;如果输入的是行B,进行比较石头数
ADD R7,R2,R4 ;存储修改后的石头数
BRn error2 ;小于0,说明输入的石头数大于行A的石头数,报错
ADD R2,R7,#0 ;输入正确的话,更新行B的石头数
BRz win121 ;如果更新后石头数R2等于0,跳转
BRnzp over1 ;
win121 ADD R7,R1,R3 ;R7=R1+R3,如果和为0,说明最后一个石头已经被拿走
BRz win122 ;
BRnzp over1 ;和不为0,界面上还有石头,返回
win122 AND R4,R4,#0
ADD R4,R4,#1
ST R4,winnerA ;如果更新后石头数为0且其他两行石头数为0,则玩家2胜利,存储到内存里
BRnzp over1
;如果输入的是行C,进行比较石头数
RowC ADD R7,R3,R4 ;存储修改后的石头数
BRn error2 ;小于0,说明输入的石头数大于行C的石头数,报错
ADD R3,R7,#0 ;输入正确的话,更新行C的石头数
BRz win131 ;如果更新后石头数R2等于0,跳转
BRnzp over1 ;
win131 ADD R7,R1,R2 ;R7=R1+R2,如果和为0,说明最后一个石头已经被拿走
BRz win132
BRnzp over1 ;和不为0,界面上还有石头,返回
win132 AND R4,R4,#0
ADD R4,R4,#1
ST R4,winnerA ;如果更新后石头数为0且其他两行石头数为0,则玩家2胜利,存储到内存里
BRnzp over1
error2 LEA R0,Tagain
PUTS ;字符输入错误,输出提示语:Invalid move.Try again.
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
BRnzp Again1 ;重新输入
over1 LD R7,SaveR7 ;恢复R7
RET
;-----------------------------------------------------------------------
Cin2 ST R7,SaveR7 ;保存R7,放置无法返回主程序
AND R4,R4,#0 ;
ST R4,winnerB ;每次输入前保证winnerB这个标志为0,如果回去是2,说明就有人赢了
;
;输出提示语以及输入
Again2 LEA R0,play2 ;
PUTS ;输出提示输入语“Player2,choose a row and ....."
GETC ;输入字母存在R0中
OUT ;回显
ADD R5,R0,#0 ;将输入的字母ASCII码赋给R5
GETC ;输入数字存在R0中
OUT ;回显
LD R6,NumASC ;将字符'0'的ASCII码的相反数赋给R6
ADD R6,R0,R6 ;将输入的字符型数字转化为整型数字(如'2'-'0'=2)
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
;对输入的字符和数字进行判断
ADD R6,R6,#0
BRn error4 ;如果输入的数字小于0,报错
LD R4,NegofA ;将-A的 ASCIII码存入R4
ADD R4,R5,R4 ;将将输入的字母ASCII码减去A的,使得字母A,B,C对应数字0,1,2都>=0
BRn error3 ;如果R4小于0,说明输入的字符小于A,无效
ADD R4,R4,#-2 ;现在字母A,B,C对应数字-1,-2,0都<=0
BRp error1 ;如果R4大于0,说明输入的字符大于C,无效
BRnzp right2 ;如果上面都没跳转,说明输入的字符有效
error3 LEA R0,Tagain
PUTS ;字符输入错误,输出提示语:Invalid move.Try again.
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
BRnzp Again2 ;重新输入
;字符输入正确,开始对输入的数字进行判断
right2 ADD R4,R6,#0
NOT R4,R4
ADD R4,R4,#1 ;-R4,便于判断该数字是否所在行的石头数
LD R0,NegofB ;
ADD R0,R5,R0 ;将输入的字母ASCII码减去B的,使得字母A,B,C对应数字-1,0,1
;判断行A
BRzp RowB2 ;如果R0>=0,说明输入的不是A,进行下一个判断,是否为行B
;如果输入的是行A,进行比较石头数
ADD R7,R1,R4 ;存储修改后的石头数
BRn error4 ;小于0,说明输入的石头数大于行A的石头数,报错
ADD R1,R7,#0 ;输入正确的话,更新行A的石头数
BRz win211 ;如果更新后石头数R1等于0,跳转
BRnzp over2 ;
win211 ADD R7,R2,R3 ;R7=R2+R3,如果和为0,说明最后一个石头已经被拿走
BRz win212 ;
BRnzp over2 ;和不为0,界面上还有石头,返回
win212 AND R4,R4,#0
ADD R4,R4,#2
ST R4,winnerB ;如果更新后石头数为0且其他两行石头数为0,则玩家1胜利,存储到内存里
BRnzp over2 ;
RowB2 ADD R0,R0,#0
BRp RowC2 ;如果R0>0,说明输入的不是B,进行下一个判断,是否为行C
;如果输入的是行B,进行比较石头数
ADD R7,R2,R4 ;存储修改后的石头数
BRn error4 ;小于0,说明输入的石头数大于行A的石头数,报错
ADD R2,R7,#0 ;输入正确的话,更新行B的石头数
BRz win221 ;如果更新后石头数R2等于0,跳转
BRnzp over2 ;
win221 ADD R7,R1,R3 ;R7=R1+R3,如果和为0,说明最后一个石头已经被拿走
BRz win222 ;
BRnzp over2 ;和不为0,界面上还有石头,返回
win222 AND R4,R4,#0
ADD R4,R4,#2
ST R4,winnerB ;如果更新后石头数为0且其他两行石头数为0,则玩家1胜利,存储到内存里
BRnzp over2 ;
;如果输入的是行C,进行比较石头数
RowC2 ADD R7,R3,R4 ;存储修改后的石头数
BRn error4 ;小于0,说明输入的石头数大于行C的石头数,报错
ADD R3,R7,#0 ;输入正确的话,更新行C的石头数
BRz win231 ;如果更新后石头数R2等于0,跳转
BRnzp over2 ;
win231 ADD R7,R1,R2 ;R7=R2+R3,如果和为0,说明最后一个石头已经被拿走
BRz win232 ;
BRnzp over2 ;和不为0,界面上还有石头,返回
win232 AND R4,R4,#0
ADD R4,R4,#2
ST R4,winnerB ;如果更新后石头数为0且其他两行石头数为0,则玩家1胜利,存储到内存里
BRnzp over2 ;
error4 LEA R0,Tagain
PUTS ;字符输入错误,输出提示语:Invalid move.Try again.
LD R0,chanline ;把换行符传入R0
OUT ;输出换行
BRnzp Again2 ;重新输入
over2 LD R7,SaveR7 ;恢复R7
RET
NegofA .fill xFFBF ;存储-A的ASCII码
NegofB .fill xFFBE ;存储-B的ASCII码
NumASC .fill xFFD0 ;字符'0'的ASCII码的相反数
Tagain .STRINGZ "Invalid move.Try again."
play1 .STRINGZ "Player1,choose a row and number of rocks."
play2 .STRINGZ "Player2,choose a row and number of rocks."
.END