• LC-3 汇编语言 Nim游戏


    @_@汇编T_T

    目录

    题目描述

    AC代码

    思路分析


    题目描述

    Nim是一个简单的双人游戏,可能起源于中国。游戏中使用的计数器类型有很多种类,如石头、火柴、苹果等。游戏界面被划分为很多行,每行中有数量不等的计数器:

    行号

    计数器数量

    1

    ○○○

    2

    ○○○○○○

    ……

    ……

    n

    ○○○○○○○○○○

    本次实验对Nim游戏做了一些小的改变,具体如下:游戏界面由三行组成,计数器类型为石头,其中A行包含3个石头,B行包含5个石头,C行包含8个石头。

    规则如下:

    ⑴ 每个玩家轮流从某一行中移除一个或多个石头。

    ⑵ 一个玩家不能在一个回合中从多个行中移除石头。

    ⑶ 当某个玩家从游戏界面上移除最后剩余的石头时,此时游戏结束,该玩家获胜。

    要求

    ⑴ 在游戏开始时,你应该显示游戏界面的初始化状态。具体包括:在每行石头的前面,你应该先输出行的名称,例如“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 2 Wins.

    样例输入/输出

    ROW A: ooo
    ROW B: ooooo
    ROW C: oooooooo
    Player 1, choose a row and number of rocks: B2
    ROW A: ooo
    ROW B: ooo
    ROW C: oooooooo
    Player 2, choose a row and number of rocks: A1
    ROW A: oo
    ROW B: ooo
    ROW C: oooooooo
    Player 1, choose a row and number of rocks: C6
    ROW A: oo
    ROW B: ooo
    ROW C: oo
    Player 2, choose a row and number of rocks: G1
    Invalid move. Try again.
    Player 2, choose a row and number of rocks: B3
    ROW A: oo
    ROW B: 
    ROW C: oo
    Player 1, choose a row and number of rocks: A3
    Invalid move. Try again.
    Player 1, choose a row and number of rocks: C2
    ROW A: oo
    ROW B: 
    ROW C: 
    Player 2, choose a row and number of rocks: A1
    ROW A: o
    ROW B: 
    ROW C: 
    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: A1
    Player 1 Wins.
    ----- Halting the processor ----- 
    

    提示与建议

    ⑴ 记住,程序中所有的输入输出使用ASCII字符,你应该负责进行必要的转换。

    ⑵ 从键盘中输入字符你应该使用TRAP x20(GETC)指令,同时为了回显输入的字符到屏幕上,你应该使用TRAP x21(OUT)指令,该指令紧跟在TRAP x20指令之后。

    ⑶ 你应该在适当的时候使用子程序。

    ⑷ 在你编写的每个子程序中,应该保存并还原所使用的任何寄存器。这将避免你在调试过程中遇到问题。

    ⑸ 在一个回合中,玩家的输入必须包含指定为A,B或C(即大写字母)的行,后面紧跟不大于该行仍然存在的石头数量的数字。

    提示:

    ① 你应该设置程序的开始地址在x3000(如,程序的第一行指令应该为 .ORIG x3000)

    ② 源文件命名为nim.asm

    AC代码

    1. .orig x3000
    2. again jsr print
    3. jsr datain1
    4. jsr print
    5. jsr datain2
    6. br again
    7. print st r0,save_r0
    8. st r1,save_r1
    9. st r7,save_r7
    10. lea r0,row_a
    11. puts
    12. ld r0,stone
    13. ld r1,num_a
    14. loop_a out
    15. add r1,r1,#-1
    16. brp loop_a
    17. ld r0,cr
    18. out
    19. lea r0,row_b
    20. puts
    21. ld r0,stone
    22. ld r1,num_b
    23. loop_b out
    24. add r1,r1,#-1
    25. brp loop_b
    26. ld r0,cr
    27. out
    28. lea r0,row_c
    29. puts
    30. ld r0,stone
    31. ld r1,num_c
    32. loop_c out
    33. add r1,r1,#-1
    34. brp loop_c
    35. ld r0,cr
    36. out
    37. ld r0,save_r0
    38. ld r1,save_r1
    39. ld r7,save_r7
    40. ret
    41. save_r0 .fill #0
    42. save_r1 .fill #0
    43. stone .fill x006f
    44. cr .fill x000d
    45. row_a .stringz "ROW A: "
    46. row_b .stringz "ROW B: "
    47. row_c .stringz "ROW C: "
    48. num_a .fill #3
    49. num_b .fill #5
    50. num_c .fill #8
    51. cue1 st r0,save_r0
    52. st r7,save_r7
    53. lea r0,play1
    54. puts
    55. ld r0,save_r0
    56. ld r7,save_r7
    57. ret
    58. play1 .stringz "Player 1,choose a row and number of rocks:"
    59. cue2 st r0,save_r0
    60. st r7,save_r7
    61. lea r0,play2
    62. puts
    63. ld r0,save_r0
    64. ld r7,save_r7
    65. ret
    66. play2 .stringz "Player 2,choose a row and number of rocks:"
    67. save_r7 .fill #0
    68. datain1 st r0,save_r0
    69. st r2,save_r2
    70. st r3,save_r3
    71. st r7,saver7
    72. try1 jsr cue1
    73. getc
    74. out
    75. add r2,r0,#0
    76. not r2,r2
    77. add r2,r2,#1
    78. getc
    79. out
    80. add r3,r0,#0
    81. ld r0,lf
    82. out
    83. test1a ld r0,char_a
    84. add r0,r2,r0
    85. brnp test1b
    86. ld r0,char_0
    87. not r0,r0
    88. add r0,r0,#1
    89. add r0,r0,r3
    90. brn error1
    91. ld r3,num_a
    92. not r0,r0
    93. add r0,r0,#1
    94. add r3,r0,r3
    95. brn error1
    96. st r3,num_a
    97. ld r3,sum_abc
    98. add r3,r3,r0
    99. brz win1
    100. st r3,sum_abc
    101. br save
    102. test1b ld r0,char_b
    103. add r0,r2,r0
    104. brnp test1c
    105. ld r0,char_0
    106. not r0,r0
    107. add r0,r0,#1
    108. add r0,r0,r3
    109. brn error1
    110. ld r3,num_b
    111. not r0,r0
    112. add r0,r0,#1
    113. add r3,r0,r3
    114. brn error1
    115. st r3,num_b
    116. ld r3,sum_abc
    117. add r3,r3,r0
    118. brz win1
    119. st r3,sum_abc
    120. br save
    121. test1c ld r0,char_c
    122. add r0,r2,r0
    123. brnp error1
    124. ld r0,char_0
    125. not r0,r0
    126. add r0,r0,#1
    127. add r0,r0,r3
    128. brn error1
    129. ld r3,num_c
    130. not r0,r0
    131. add r0,r0,#1
    132. add r3,r0,r3
    133. brn error1
    134. st r3,num_c
    135. ld r3,sum_abc
    136. add r3,r3,r0
    137. brz win1
    138. st r3,sum_abc
    139. br save
    140. win1 ld r0,lf
    141. out
    142. lea r0,wins1
    143. puts
    144. halt
    145. error1 lea r0,invalid
    146. puts
    147. ld r0,lf
    148. out
    149. br try1
    150. datain2 st r0,save_r0
    151. st r2,save_r2
    152. st r3,save_r3
    153. st r7,saver7
    154. try2 jsr cue2
    155. getc
    156. out
    157. add r2,r0,#0
    158. not r2,r2
    159. add r2,r2,#1
    160. getc
    161. out
    162. add r3,r0,#0
    163. ld r0,lf
    164. out
    165. test2a ld r0,char_a
    166. add r0,r2,r0
    167. brnp test2b
    168. ld r0,char_0
    169. not r0,r0
    170. add r0,r0,#1
    171. add r0,r0,r3
    172. brn error2
    173. ld r3,num_a
    174. not r0,r0
    175. add r0,r0,#1
    176. add r3,r0,r3
    177. brn error2
    178. st r3,num_a
    179. ld r3,sum_abc
    180. add r3,r3,r0
    181. brz win2
    182. st r3,sum_abc
    183. br save
    184. test2b ld r0,char_b
    185. add r0,r2,r0
    186. brnp test2c
    187. ld r0,char_0
    188. not r0,r0
    189. add r0,r0,#1
    190. add r0,r0,r3
    191. brn error2
    192. ld r3,num_b
    193. not r0,r0
    194. add r0,r0,#1
    195. add r3,r0,r3
    196. brn error2
    197. st r3,num_b
    198. ld r3,sum_abc
    199. add r3,r3,r0
    200. brz win2
    201. st r3,sum_abc
    202. br save
    203. test2c ld r0,char_c
    204. add r0,r2,r0
    205. brnp error2
    206. ld r0,char_0
    207. not r0,r0
    208. add r0,r0,#1
    209. add r0,r0,r3
    210. brn error2
    211. ld r3,num_c
    212. not r0,r0
    213. add r0,r0,#1
    214. add r3,r0,r3
    215. brn error2
    216. st r3,num_c
    217. ld r3,sum_abc
    218. add r3,r3,r0
    219. brz win2
    220. st r3,sum_abc
    221. br save
    222. win2 ld r0,lf
    223. out
    224. lea r0,wins2
    225. puts
    226. halt
    227. error2 lea r0,invalid
    228. puts
    229. ld r0,lf
    230. out
    231. br try2
    232. save ld r0,lf
    233. out
    234. ld r0,saver0
    235. ld r2,save_r2
    236. ld r3,save_r3
    237. ld r7,saver7
    238. ret
    239. lf .fill x000a
    240. char_a .fill x0041
    241. char_b .fill x0042
    242. char_c .fill x0043
    243. char_0 .fill x0030
    244. wins1 .stringz "Player 1 Wins."
    245. wins2 .stringz "Player 2 Wins."
    246. invalid .stringz "Invalid move. Try again."
    247. sum_abc .fill #16
    248. saver0 .fill #0
    249. save_r2 .fill #0
    250. save_r3 .fill #0
    251. saver7 .fill #0
    252. .end

    思路分析

    程序总体设计

    核心数据结构

    1、显示游戏页面

    首先将寄存器的值存进内存,待子函数完成任务后再将该内存的值存进寄存器,用伪操作.stringz开辟内存用来存储字符串,将Row A、Row B和Row C的石头数目也存储在内存中。

    先用LEA指令将字符串的首地址存进R0,然后通过PUTS输出,用LD指令将字符o的ascll码存进R0,然后用LD指令将石头的数目存进R1,R1作为计数器,用OUT循环输出字符o,最后用LD指令将换行符的ascll码存进R0,用OUT输出。

    2、用户操作

    (1)输出提示

    用伪操作.stringz将提示字符串存进内存中,先将用到的寄存器R0和R7的值存进内存保存起来,然后用LEA指令将字符串的首地址存进R0,用PUTS输出提示,然后将R0和R7的值恢复。

    (2)用户输入

        用GETC读取输入的第一个数据,然后用OUT回显,ADD指令将R0的数据转入R2,然后用NOT将R2取反,ADD将R2加一,即将R2取负,再用GETC读取输入的第二个数据,OUT回显,ADD指令将R0的数据转入R3。

    (3)判断数据是否有效

        用伪操作.fill将字符A、B和C的ascll码存进内存,用LD指令将相应字符的ascll码存进R0,然后ADD指令将R0和R2相加的结果存在R0,通过判断R0是否为0来判断是A、B、C或无效输入。

    (4)取石头

        用LD指令将字符0的ascll码存进R0,然后将R0取负,与R3相加的结果存放到R0中,然后用LD指令将石头的数目存进R3,将R0取负,与R3相加的结果存进R3,最后将R3的值存进内存。

    算法流程

    1、显示游戏页面

    2、player操作

  • 相关阅读:
    什么叫发明专利
    gitlab的使用方法,详解gitlab操作
    ubuntu安装Docker
    面试官:你了解axios的原理吗?有看过它的源码吗?
    谷粒商城-day13-es和商品上架
    Linux命令(126)之help
    干货无废话 JAVA入门环境变量配置
    Postman如何做接口测试,那些不得不知道的技巧
    ICS TRIPLEX T8310 自动化控制模块
    python项目上线
  • 原文地址:https://blog.csdn.net/weixin_62264287/article/details/126391351