实验报告 一、实验目的与要求 使用LC3汇编语言实现点格棋,根据英文指导文档实现各各模块之后再组合。
什么是点格棋?
Dots and Boxes is a two-player game played on a variable-size grid of dots. For this assignment, the playing board is a 4x4 grid of dots, and the two players are denoted by two symbols: 1 and 2
简单来说,就是使用连接点与点之间来实现圈地的游戏,谁最后将某个方块圈起来,那个方块就归谁,一个方块记一分,直到4x4下16个方块全都有所属时游戏结束。
二、实验步骤与过程 主要函数罗列: 大体在main函数里实现以下几个函数:
1、print_map():打印每次下棋后的地图
2、display_prompt():更新玩家控制权,控制棋子坐标输入和退出游戏
3、is_input_valid():检测坐标输入是否合法
4、is_occupied():检测输入的坐标是否已经被之前输入的占用
5、apply_move():实现棋子在地图上的更新
6、fill_box():重中之重,检测每次输入是否导致了玩家得分,并且将被圈起来的方块的占位符更新为队友玩家的编号
7、is_gameover():检测游戏是否达成结束条件
实现步骤一:C语言代码逻辑框架实现 LC3汇编语言属于机器语言,有多个函数的大工程不便于直接实现。在流程图的基础上,先用C语言写出了点格棋游戏。
实现步骤二:分模块化实现LC3程序 在C语言的框架下,我们一步一步翻译成LC3。
实现步骤三:编译和调试LC3代码 通过asm->编译代码,一开始出现了不少error,诸如未定义的label,语法错误等,有些错误是等到运行时才知道的,需要通过一步步debug来发现问题。
调试并排除完错误后,运行程序,得到正确结果:
三、实验结论或体会 通过此次实验,我学到了:
1、通过LC3仿真器运行和调试LC3代码,通过ide编写可执行的LC3代码。
2、磨炼了自己的心性,耐心地编写LC3汇编代码,并调试出错误。
3、通过阅读英语lab指导,提高了阅读计算机类英语文档的水平。
4、通过C->LC3的代码编写过程,熟悉了C语言在LC3框架上的底层实现。
5、对LC3的各种伪操作和命令有了更深入的理解。
附件: 点格棋c语言实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 #include <iostream> int member = 1 , current_mem = 1 , sum = 0 ;int r0, r1, r2, r3, r4;int score[3 ] = {0 };char row_number, column_letter = 0 ;char map[49 ];void initialize_map () { for (int i = 0 ; i < 7 ; i++){ for (int j = 0 ; j < 7 ; j++){ map[7 * i + j] = ' ' ; } } for (int i = 0 ; i < 7 ; i += 2 ){ for (int j = 0 ; j < 7 ; j += 2 ){ map[7 * i + j] = '*' ; } } } void print_map () { printf ("%d : %d\n" , score[1 ], score[2 ]); printf (" ABCDEFG\n" ); for (int i = 0 ; i < 7 ; i++){ printf ("%d" , i); for (int j = 0 ; j < 7 ; j++){ printf ("%c" , map[7 * i + j]); } printf ("\n" ); } } void display_prompt () { current_mem = member; if (member == 1 ){ printf ("Player 1, input a move (or 'Q' to quit):" ); member = 2 ; } else { printf ("Player 2, input a move (or 'Q' to quit):" ); member = 1 ; } row_number = getchar (); if (row_number == 'Q' ){ exit (0 ); } else { column_letter = getchar (); } char c = getchar (); } void is_input_valid () { r0 = row_number - '0' ; r1 = column_letter - 'A' ; if (((r0 % 2 ) && !(r1 % 2 )) || (!(r0 % 2 ) && (r1 % 2 ))){ r3 = 0 ; } else { r3 = -1 ; } } void translate_move () { } void is_occupied () { if (map[7 * r0 + r1] == ' ' ){ r3 = 0 ; } else { r3 = -1 ; } } void get_address () {} void apply_move () { if (r0 % 2 ){ map[7 * r0 + r1] = '|' ; } else { map[7 * r0 + r1] = '-' ; } } void fill_box () { if (map[7 * r0 + r1] == '|' ){ if (r1 != 0 ){ if (map[7 * r0 + r1 - 2 ] == '|' && map[7 * (r0 - 1 ) + r1 - 1 ] == '-' && map[7 * (r0 + 1 ) + r1 - 1 ] == '-' ){ map[7 * r0 + r1 - 1 ] = current_mem + '0' ; r3 += 1 ; } } if (r1 != 6 ){ if (map[7 * r0 + r1 + 2 ] == '|' && map[7 * (r0 - 1 ) + r1 + 1 ] == '-' && map[7 * (r0 + 1 ) + r1 + 1 ] == '-' ){ map[7 * r0 + r1 + 1 ] = current_mem + '0' ; r3 += 1 ; } } } if (map[7 * r0 + r1] == '-' ){ if (r0 != 0 ){ if (map[7 * (r0 - 2 ) + r1] == '-' && map[7 * (r0 - 1 ) + r1 - 1 ] == '|' && map[7 * (r0 - 1 ) + r1 + 1 ] == '|' ){ map[7 * (r0 - 1 ) + r1] = current_mem + '0' ; r3 += 1 ; } } if (r0 != 6 ){ if (map[7 * (r0 + 2 ) + r1] == '-' && map[7 * (r0 + 1 ) + r1 - 1 ] == '|' && map[7 * (r0 + 1 ) + r1 + 1 ] == '|' ){ map[7 * (r0 + 1 ) + r1] = current_mem + '0' ; r3 += 1 ; } } } score[current_mem] += r3; sum += r3; } void is_gameover () { if (sum == 16 ){ if (score[1 ] > score[2 ]){ printf ("Game over. Player 1 is the winner!" ); } else { printf ("Game over. Player 2 is the winner!" ); } exit (0 ); } } int main () { initialize_map (); while (true ){ print_map (); display_prompt (); is_input_valid (); if (r3 == -1 ){ printf ("invalid input" ); continue ; } is_occupied (); if (r3 == -1 ){ printf ("invalid input" ); continue ; } apply_move (); fill_box (); is_gameover () } return 0 ; }
LC3源代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 .ORIG x3000 AND R5 R5 #0 ;R5存储游戏控制权,0是player1,1是player2 LOOP0 JSR print_map JSR display_prompt JSR is_input_valid AND R0 R0 #0 ADD R0 R3 #1 BRz invalid_R3 JSR is_occupied AND R0 R0 #0 ADD R0 R3 #1 BRz invalid_R3 JSR apply_move JSR fill_box JSR is_gameover BRnzp DONE0 invalid_R3 LEA R0 invalid_input PUTS DONE0 BRnzp LOOP0 HALT invalid_input .STRINGZ "\ninvalid_input\n" is_gameover AND R6 R6 #0 ADD R6 R6 R7 LD R0 sum ADD R0 R0 #-16 BRz over AND R7 R7 #0 ADD R7 R7 R6 ret over LD R3 score2 LD R0 score1 NOT R3 R3 ADD R3 R3 #1 ADD R0 R0 R3 BRp _1dayu2 LEA R0 p1_win BRnzp _2dayu1 _1dayu2 LEA R0 p1_win _2dayu1 PUTS HALT p1_win .STRINGZ "\nGame over. Player 1 is the winner!\n" p2_win .STRINGZ "\nGame over. Player 2 is the winner!\n" display_prompt AND R6 R6 #0 ADD R6 R6 R7 AND R5 R5 R5 BRz player1 BRp player2 ret player1 LEA R0 p1 PUTS ADD R5 R5 #1 BRnzp Getchar player2 LEA R0 p2 PUTS ADD R5 R5 #-1 Getchar GETC ;R1 R2 分别存储数字和字母 LD R1 char ADD R1 R1 R0 BRz quit AND R1 R1 #0 ADD R1 R1 R0 GETC AND R2 R2 #0 ADD R2 R2 R0 AND R7 R7 #0 ADD R7 R7 R6 ret quit HALT char .FILL #-81 p1 .STRINGZ "Player 1, input a move (or 'Q' to quit):\n" p2 .STRINGZ "Player 2, input a move (or 'Q' to quit):\n" apply_move AND R6 R6 #0 ADD R6 R6 R1 ADD R6 R6 R6 ADD R6 R6 R6 ADD R6 R6 R6 ADD R6 R6 R1 ADD R6 R6 R2 AND R0 R1 #1 BRp jishu LD R0 henggang BRnzp oushu jishu LD R0 shugang oushu ADD R6 R6 R4 ST R6 address STI R0 address ret shugang .FILL #124 henggang .FILL #45 _shugang .FILL #-124 _henggang .FILL #-45 sum .FILL #0 score1 .FILL #0 score2 .FILL #0 fill_box AND R3 R3 #0 ST R7 ret_address ST R1 R_1 ;保存R1R2 ST R2 R_2 AND R0 R0 #0 ADD R0 R0 R1 ADD R0 R0 R0 ADD R0 R0 R0 ;同理R4[9 * R1 + R2] ADD R0 R0 R0 ADD R0 R0 R1 ADD R0 R0 R2 ;R1R2到此步骤已经没有作用了,偏移已经存在R0 ADD R0 R0 R4 ST R0 address LDI R6 address ;R6存变量上述的R4[] LD R1 _shugang ADD R1 R1 R6 BRz situation1 BRnzp situation2 situation1 LD R2 R_2 ADD R1 R2 #0 BRnp situation1_1 ADD R1 R2 #-6 BRnp situation1_2 situation1_1 LD R2 _henggang ;R2存横杠,R6存竖杆 LD R6 _shugang ADD R1 R0 #-2 ST R1 address LDI R1 address ADD R1 R6 R1 BRnp end1 ADD R1 R0 #-10 ST R1 address LDI R1 address ADD R1 R2 R1 BRnp end1 ADD R1 R0 #8 ST R1 address LDI R1 address ADD R1 R2 R1 BRnp end1 ADD R1 R0 #-1 ST R1 address JSR apply_get_score ADD R3 R3 #1 end1 LD R1 R_1 ADD R1 R1 #-6 BRz situation1_2 BRnzp DONE2 situation1_2 LD R2 _henggang ;R2存横杠,R6存竖杆 LD R6 _shugang ADD R1 R0 #2 ST R1 address LDI R1 address ADD R1 R6 R1 BRnp end2 ADD R1 R0 #-8 ST R1 address LDI R1 address ADD R1 R2 R1 BRnp end2 ADD R1 R0 #10 ST R1 address LDI R1 address ADD R1 R2 R1 BRnp end2 ADD R1 R0 #1 ST R1 address JSR apply_get_score ADD R3 R3 #1 end2 BRnzp DONE2 situation2 LD R1 R_1 ADD R2 R1 #0 BRnzp situation2_1 ADD R2 R1 #-6 BRnzp situation2_2 situation2_1 LD R2 _henggang ;R2存横杠,R6存竖杆 LD R6 _shugang ADD R1 R0 #-9 ADD R1 R1 #-9 ST R1 address LDI R1 address ADD R1 R2 R1 BRnp end3 ADD R1 R0 #-10 ST R1 address LDI R1 address ADD R1 R6 R1 BRnp end3 ADD R1 R0 #-8 ST R1 address LDI R1 address ADD R1 R6 R1 BRnp end3 ADD R1 R0 #-9 ST R1 address JSR apply_get_score ADD R3 R3 #1 end3 LD R2 R_2 ADD R2 R2 #-6 BRz situation2_1 BRnzp DONE2 situation2_2 LD R2 _henggang ;R2存横杠,R6存竖杆 LD R6 _shugang ADD R1 R0 #9 ADD R1 R1 #9 ST R1 address LDI R1 address ADD R1 R2 R1 BRnp DONE2 ADD R1 R0 #8 ST R1 address LDI R1 address ADD R1 R6 R1 BRnp DONE2 ADD R1 R0 #10 ST R1 address LDI R1 address ADD R1 R6 R1 BRnp DONE2 ADD R1 R0 #9 ST R1 address JSR apply_get_score ADD R3 R3 #1 DONE2 LD R7 ret_address LD R0 sum ADD R0 R3 R0 ST R0 sum AND R5 R5 R5 BRz player1_get_score BRnzp player2_get_score player1_get_score LD R0 score1 ADD R0 R3 R0 ST R0 score1 ret player2_get_score LD R0 score2 ADD R0 R3 R0 ST R0 score2 ret ;关键函数fillbox,R0 R3 R6可用,R3暂时用来存分数,R0用来存偏移后的地址 ;R1 R2存行列,R4是map首地址,R5控制权,R7返回地址 map .STRINGZ " ABCDEFG\n0*#*#*#*\n1#######\n2*#*#*#*\n3#######\n4*#*#*#*\n5#######\n6*#*#*#*\n" address .FILL #0 ret_address .FILL #0 R_1 .FILL #0 R_2 .FILL #0 is_input_valid AND R6 R6 #0 ADD R6 R6 R7 LD R0 num1 ADD R1 R1 R0 LD R0 char1 ADD R2 R2 R0 AND R0 R2 #1 AND R4 R1 #1 NOT R3 R0 ;异或操作 AND R3 R3 R4 NOT R4 R4 AND R0 R0 R4 ;R4释放掉 AND R4 R4 #0 NOT R0 R0 NOT R3 R3 AND R0 R0 R3 AND R3 R3 #0 ;R3赋值为0,有意义 NOT R0 R0 BRz invalid AND R7 R7 #0 ADD R7 R7 R6 ret invalid ADD R3 R3 #-1 AND R7 R7 #0 ADD R7 R7 R6 ret num1 .FILL #-48 char1 .FILL #-65 is_occupied AND R6 R6 #0 ;9 * 8 的地图 ADD R6 R6 R7 LEA R4 map ADD R4 R4 #10 AND R7 R7 #0 ADD R7 R1 R7 ADD R7 R7 R7 ADD R7 R7 R7 ADD R7 R7 R7 ADD R7 R7 R1 ;实现R1乘以10 ADD R7 R7 R2 ADD R7 R7 R4 ST R7 address LDI R0 address LD R7 space ADD R0 R7 R0 BRz not_occupy AND R3 R3 #0 ADD R3 R3 #-1 BRnzp DONE1 not_occupy AND R3 R3 #0 DONE1 AND R7 R7 #0 ADD R7 R7 R6 ret space .FILL #-35 print_map AND R6 R6 #0 ADD R6 R6 R7 LEA R0 map PUTS AND R7 R7 #0 ADD R7 R7 R6 ret apply_get_score AND R5 R5 R5 BRz apply_player1 LD R1 pl2 STI R1 address ret apply_player1 LD R1 pl1 STI R1 address ret pl1 .FILL x31 pl2 .FILL x32 .END