深圳大学计系汇编语言实验--四子棋游戏

题面

四子棋是个双人游戏,两人轮流下棋,棋盘由行和列组成的网格,每个选手每次下一个子直到两人中有一人的棋子连成一条水平线、垂直线或者是对角线。

       本实验需要在LC-3中实现简易版四子棋的游戏,两位选手通过键盘和输出窗口轮流交互操作,棋盘由6 X 6的网格组成。

       游戏规则如下:

       两位选手依次轮流落子;

       选手不能悔棋;

       有子的地方不能继续落子;

       直到有一方的四个棋子能够连成一条水平线、垂直线或者是对角线;

       如果棋盘已满,无人获胜,则平局。

       游戏最初时应该打印空的棋盘,可以用ASCII码"-" (即ASCII 码 x002D)来表示该处为空,"O"(ASCII 码 x004F)表示第一位选手的棋子,"X" (ASCII 码 x0058)来表示第二位选手的棋子,为了让棋盘更易于观察,在各列间加一个空格,第6列之后不要添加,初始棋盘应该如下:

- - - - - -

- - - - - -

- - - - - -

- - - - - -

- - - - - -

- - - - - -

选手一始终先下第一步棋,然后两者轮流落子,在每次落子之后,应该打印该选手的信息,提示他落子,以选手一为例,应该打印信息如下:

Player 1, choose a column:

       为了明确选手的落子的位置,该选手应该输入数字1-6,然后回车,数字1-6指示在落子所在的列,从左到右,无需输入行号,程序应默认从行号6到行号1递减的顺序填入该棋子,若前后输入的列号相同,则行号减一。例如,如果选手第一次在左起第二列落子,应该输入2,然后回车,则该棋子落在行6列2处,当后面输入的列号再次为2时,则将棋子落子行5列2处,以此类推,详情见后续示例输出。程序应该确保选手输入的数字对应正确的列的范围,如果输入不合理,应该输出一条错误信息,提示该选手继续输入,例如,如果对于选手一:

       Player 1, choose a column: D

    Invalid move. Try again.

    Player 1, choose a column: 7

    Invalid move. Try again.

Player 1, choose a column:

       程序应该一直提示该选手,知道输入正确的数字,当用户输入完成,程序应通过显示回馈给选手,然后通过换行符(ASCII 码 x000A)换行。

       当选手输入成功后,程序应打印更新后的棋盘,并检查是否有人获胜,如果没人获胜,则轮到下一位输入。

       当其中一位获胜或平局时,游戏结束,程序显示最后的棋盘情况并终止(Halt)。例如,如果选手二有四子相连,应该输出:

Player 2 Wins.

如果平局,程序应该输出:

Tie Game.

分析

子程序针对多复用内容:保存和恢复还有验证子程序

验证思路:当前点拓展

代码

;
; Mario Chan   2022/5/20   SZU   "hahahahaha"
;                       ::
;                      :;J7, :,                        ::;7:
;                      ,ivYi, ,                       ;LLLFS:
;                      :iv7Yi                       :7ri;j5PL
;                     ,:ivYLvr                    ,ivrrirrY2X,
;                     :;r@Wwz.7r:                :ivu@kexianli.
;                    :iL7::,:::iiirii:ii;::::,,irvF7rvvLujL7ur
;                   ri::,:,::i:iiiiiii:i:irrv177JX7rYXqZEkvv17
;                ;i:, , ::::iirrririi:i:::iiir2XXvii;L8OGJr71i
;              :,, ,,:   ,::ir@mingyi.irii:i:::j1jri7ZBOS7ivv,
;                ,::,    ::rv77iiiriii:iii:i::,rvLq@huhao.Li
;            ,,      ,, ,:ir7ir::,:::i;ir:::i:i::rSGGYri712:
;           :::  ,v7r:: ::rrv77:, ,, ,:i7rrii:::::, ir7ri7Lri
;          ,     2OBBOi,iiir;r::        ,irriiii::,, ,iv7Luur:
;        ,,     i78MBBi,:,:::,:,  :7FSL: ,iriii:::i::,,:rLqXv::
;        :      iuMMP: :,:::,:ii;2GY7OBB0viiii:i:iii:i:::iJqL;::
;       ,     ::::i   ,,,,, ::LuBBu BBBBBErii:i:i:i:i:i:i:r77ii
;      ,       :       , ,,:::rruBZ1MBBqi, :,,,:::,::::::iiriri:
;     ,               ,,,,::::i:  @arqiao.       ,:,, ,:::ii;i7:
;    :,       rjujLYLi   ,,:::::,:::::::::,,   ,:i,:,,,,,::i:iii
;    ::      BBBBBBBBB0,    ,,::: , ,:::::: ,      ,,,, ,,:::::::
;    i,  ,  ,8BMMBBBBBBi     ,,:,,     ,,, , ,   , , , :,::ii::i::
;    :      iZMOMOMBBM2::::::::::,,,,     ,,,,,,:,,,::::i:irr:i:::,
;    i   ,,:;u0MBMOG1L:::i::::::  ,,,::,   ,,, ::::::i:i:iirii:i:i:
;    :    ,iuUuuXUkFu7i:iii:i:::, :,:,: ::::::::i:i:::::iirr7iiri::
;   :     :rk@Yizero.i:::::, ,:ii:::::::i:::::i::,::::iirrriiiri::,
;     :      5BMBBBBBBSr:,::rv2kuii:::iii::,:i:,, , ,,:,:i@petermu.,
;          , :r50EZ8MBBBBGOBBBZP7::::i::,:::::,: :,:,::i;rrririiii::
;              :jujYY7LS0ujJL7r::,::i::,::::::::::::::iirirrrrrrr:ii:
;           ,:  :@kevensun.:,:,,,::::i:i:::::,,::::::iir;ii;7v77;ii;i,
;           ,,,     ,,:,::::::i:iiiii:i::::,, ::::iiiir@xingjief.r;7:i,
;        , , ,,,:,,::::::::iiiiiiiiii:,:,:::::::::iiir;ri7vL77rrirri::
;         :,, , ::::::::i:::i:::i:i::,,,,,:,::i:i:::iir;@Secbone.ii:::


.ORIG x3000
;=====设置棋盘=====

LEA R0, Array

LEA R1, First_Line
STR R1, R0, #0

LEA R1, Second_Line
STR R1, R0, #1

LEA R0, Array
LEA R1, Third_Line
STR R1, R0, #2

LEA R0, Array
LEA R1, Forth_Line
STR R1, R0, #3

LEA R0, Array
LEA R1, Fifth_Line
STR R1, R0, #4

LEA R0, Array
LEA R1, Sixth_Line
STR R1, R0, #5

;===========================================落棋区域,R6锁死==============================================
AND R6, R6, #0 ; R6表示当前是player1(z)还是2(n)

JSR Display; 输出

While ADD R6, R6, #0; 输入
      BRn Player_2_Ask
      LEA R0, Ask_column1
      PUTS;
      BRnzp Player_Ask_Finish
      Player_2_Ask LEA R0, Ask_column2
      PUTS;
      Player_Ask_Finish IN ; 输入结果存在R0
      LD R1, ASC_Number
      NOT R1, R1
      ADD R1, R1, #1
      ADD R0, R0, R1

      BRn Invalid; 判负
      ADD R1, R0, #-6 ;判是否超过6
      BRp Invalid
      LEA R1, Have ;找到对应的列
      ADD R0, R0, #-1
      ADD R1, R1, R0
      LDR R2, R1, #0
      BRn Invalid; 已经填满,非法
      BRnzp Valid

; --输出不合法
Invalid LEA R0, Invalid_move
        PUTS
        BRnzp Player_Ask_Finish

;--输入合法
Valid LEA R3, Array
      ADD R3, R3, R2; R3此时是行首指针
      LDR R3, R3, #0
      ADD R3, R3, R0; 找到了改值地址
      ADD R4, R6, #0
      STR R4, R3, #0
      
      ;R2是行(已经-1),R0是列,R3为当前地址

      ADD R2, R2, #-1
      STR R2, R1, #0 ; 让该列-1
               
      JSR Display; 输出
      
      JSR Check_Line; 返回0表示未定胜局
      LD R5, Return_value
      BRz Check_Column
      BRnzp PUTS_Winner

      Check_Column JSR Check_column; 返回0表示未定胜局
      LD R5, Return_value
      BRz Check_Diagonal
      BRnzp PUTS_Winner

      Check_Diagonal JSR Check_diagonal; 返回0表示未定胜局
      LD R5, Return_value
      BRz Check_Fill
      BRnzp PUTS_Winner

      Check_Fill
      LD R5, left_fill; 检查是否填完了
      ADD R5, R5, #-1
      BRz DONE
      ST R5, left_fill
      NOT R6, R6
      BRnzp While

PUTS_Winner ADD R6, R6, #0
            BRn Winner_is_2 
            LEA R0, Win_1
            BRnzp PUT_Win
            Winner_is_2 LEA R0, Win_2
            PUT_Win PUTS
            HALT
       
DONE LEA R0, Win_both; 平局
     PUTS 
     HALT

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%数据以及子程序区域%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

;--字符--

player_one .FILL x004F
player_two .FILL x0058
no_chess   .FILL x002D
change_line .FILL x000A
Space .FILL x0020
ASC_Number .FILL x0030
Ask_column1 .STRINGZ  "Player 1, choose a column: "
Ask_column2 .STRINGZ  "Player 2, choose a column: "
Invalid_move .STRINGZ "Invalid move. Try again."
Win_1 .STRINGZ "Player 1 Wins."
Win_2 .STRINGZ "Player 2 Wins."
Win_both .STRINGZ "Tie Game."

;---保留字,注意R7---

Save0 .FILL x0000
Save1 .FILL x0000
Save2 .FILL x0000
Save3 .FILL x0000
Save4 .FILL x0000
Save5 .FILL x0000
Save6 .FILL x0000
Return_value .FILL x0000
left_fill .FILL x0024

;--棋盘--
Array .BLKW 6 #0
First_Line .BLKW 6 #1
Second_Line .BLKW 6 #1
Third_Line .BLKW 6 #1
Forth_Line .BLKW 6 #1
Fifth_Line .BLKW 6 #1
Sixth_Line .BLKW 6 #1
Have .BLKW 6 #5

;----保存和恢复除了R7的所有寄存器------
;调用前面加上ST R7,save7,后面加上LD R7,save7

SaveR  ST R0,Save0
       ST R1,Save1
       ST R2,Save2
       ST R3,Save3
       ST R4,Save4
       ST R5,Save5
       ST R6,Save6
       RET
RecoverR LD R0,Save0
         LD R1,Save1
         LD R2,Save2
         LD R3,Save3
         LD R4,Save4
         LD R5,Save5
         LD R6,Save6
         RET

;---------------判断横向是否连成4个--------------------

Check_Line ST R7, Save7; 存值
	   JSR SaveR
	   LD R7, Save7
           
           ; R2行,R0列,R3为当前地址, R4为值
           NOT R1, R4
           ADD R1, R1, #1
           AND R4, R4, #0; 计数器
           ADD R4, R4, #1
           ADD R5, R3, #1; 指针
           LOOP1 ADD R6, R5, #-6
                 BRz LOOP1_DONE
                 LDR R2, R5, #0
                 ADD R6, R1, R2
                 BRnp LOOP1_DONE
                 ADD R4, R4, #1
                 ADD R5, R5, #1
                 BRnzp LOOP1
           LOOP1_DONE

           ADD R5, R3, #-1; 指针
           LOOP2 ADD R5, R5, #0
                 BRn LOOP2_DONE
                 LDR R2, R5, #0
                 ADD R6, R1, R2
                 BRnp LOOP2_DONE
                 ADD R4, R4, #1
                 ADD R5, R5, #-1
                 BRnzp LOOP2
           LOOP2_DONE 
           ADD R4, R4, #-4
           BRzp SKIP1
                 AND R0, R0, #0
                 ST R0, Return_value
                 BRnzp SKIP2
           SKIP1 AND R0, R0, #0
                 ADD R0, R0, #1
                 ST R0, Return_value

           SKIP2
           ST R7, Save7; 还原值
	   JSR RecoverR
	   LD R7, Save7
	   RET

;---------------判断纵向是否连成4个--------------------

Check_column ST R7, Save7; 存值
	     JSR SaveR
	     LD R7, Save7

	     ; R2行(已经-1),R0列,R3为当前地址, R4为值	     
	     ADD R2, R2, #2
 	     ADD R1, R0, #0 ; R1为列, R2为行

             AND R5, R5, #0 ; 计数器
             ADD R5, R5, #1
             NOT R4, R4 ;值
             ADD R4, R4, #1
 
             LOOP3 ADD R0, R2, #-6
                   BRz LOOP3_DONE
                   LEA R0, Array
                   ADD R0, R0, R2
                   LDR R0, R0, #0
                   ADD R0, R0, R1 ; 找到地址
                   LDR R0, R0, #0
                   ADD R0, R0, R4
                   BRnp LOOP3_DONE
                   ADD R2, R2, #1
                   ADD R5, R5, #1
                   BRnzp LOOP3
             LOOP3_DONE 
                   ADD R5, R5, #-4
                   BRn SKIP3
		   AND R0, R0, #0
                   ADD R0, R0, #1
                   ST R0, Return_value
                   BRnzp SKIP4
                SKIP3
                   AND R0, R0, #0
                   ST R0, Return_value
                   
	     SKIP4
	     ST R7, Save7; 存值
	     JSR RecoverR
	     LD R7, Save7
	     RET

;-------------------判断斜线是否有4个----------------------

Check_diagonal ST R7, Save7; 存值
	       JSR SaveR
	       LD R7, Save7
	
               ; R2行(已经-1),R0列,R3为当前地址, R4为值	     
	       ADD R2, R2, #1
 	       ADD R1, R0, #0 ; R1为列, R2为行

               AND R5, R5, #0 ; R5计数器
               ADD R5, R5, #1
               NOT R6, R4 ; R6为值
               ADD R6, R6, #1

               ADD R3, R2, #1 ; R3表示行, R4表示列
               ADD R4, R1, #1
               LOOP5 ADD R0, R3, #-6
	             BRz LOOP5_DONE
 	       	     ADD R0, R4, #-6
	             BRz LOOP5_DONE
                     LEA R0, Array
                     ADD R0, R0, R3
                     LDR R0, R0, #0
                     ADD R0, R0, R4
                     LDR R0, R0, #0
                     ADD R0, R0, R6
                     BRnp LOOP5_DONE
                     ADD R5, R5, #1
                     ADD R3, R3, #1
                     ADD R4, R4, #1
                     BRnzp LOOP5

 	       LOOP5_DONE
                     ADD R3, R2, #-1
                     ADD R4, R1, #-1
               LOOP6 ADD R3, R3, #0
	             BRn LOOP6_DONE
 	       	     ADD R4, R4, #0
	             BRn LOOP6_DONE
                     LEA R0, Array
                     ADD R0, R0, R3
                     LDR R0, R0, #0
                     ADD R0, R0, R4
                     LDR R0, R0, #0
                     ADD R0, R0, R6
                     BRnp LOOP6_DONE
                     ADD R5, R5, #1
                     ADD R3, R3, #-1
                     ADD R4, R4, #-1
                     BRnzp LOOP6

               LOOP6_DONE
                     ADD R5, R5, #-4
                     BRzp YES
                     AND R5, R5, #0
                     ADD R5, R5, #1
                     ADD R3, R2, #1
                     ADD R4, R1, #-1
               LOOP7 ADD R0, R3, #-6
	             BRz LOOP7_DONE
 	       	     ADD R4, R4, #0
	             BRn LOOP7_DONE
                     LEA R0, Array
                     ADD R0, R0, R3
                     LDR R0, R0, #0
                     ADD R0, R0, R4
                     LDR R0, R0, #0
                     ADD R0, R0, R6
                     BRnp LOOP7_DONE
                     ADD R5, R5, #1
                     ADD R3, R3, #1
                     ADD R4, R4, #-1
                     BRnzp LOOP7

               LOOP7_DONE
                     ADD R3, R2, #-1
                     ADD R4, R4, #1
               LOOP8 ADD R3, R3, #0
	             BRn LOOP8_DONE
 	       	     ADD R0, R4, #-6
	             BRn LOOP8_DONE
                     LEA R0, Array
                     ADD R0, R0, R3
                     LDR R0, R0, #0
                     ADD R0, R0, R4
                     LDR R0, R0, #0
                     ADD R0, R0, R6
                     BRnp LOOP8_DONE
                     ADD R5, R5, #1
                     ADD R3, R3, #-1
                     ADD R4, R4, #1
                     BRnzp LOOP8
               LOOP8_DONE
                     ADD R5, R5, #-4
                     BRzp YES
                     BRnzp REC
               
               YES AND R0, R0, #0
                   ADD R0, R0, #1
                   ST R0, Return_value
                   BRnzp REC
                   AND R0, R0, #0
                   ST R0, Return_value
               REC
	       ST R7, Save7; 还原值
	       JSR RecoverR
	       LD R7, Save7
	       RET

;----------------------输出子程序--------------------------
;字符常量复刻
player_one2 .FILL x004F
player_two2 .FILL x0058
change_line2 .FILL x000A
Space2 .FILL x0020
no_chess2  .FILL x002D

Output_R7 .FILL x0000
Save7 .FILL x0000

Display ST R7, Save7; 存值
	JSR SaveR
	LD R7, Save7

	LEA R1, Array
	LDR R2, R1, #0 ; 第一维指向第一行指针
	AND R3, R3, #0; 第一维计数器
	
	LOOP_Display1 ADD R5, R3, #-6
	              BRz Display_Done; 六行扫描完
		      AND R4, R4, #0; 第二维计数器
	              LOOP_Display2 LDR R0, R2, #0; 字符放在R0
				    BRz Player1
                                    BRp NoPlayer
                                    BRn Player2
                                    Player1 LD R0, player_one2
				    BRnzp OUTPUT
				    Player2 LD R0, player_two2
				    BRnzp OUTPUT
                                    NoPlayer LD R0, no_chess2
				    BRnzp OUTPUT

				    OUTPUT 
                                    	ST R7, Output_R7
                                    	OUT
                                    	LD R7, Output_R7

				    ADD R2, R2, #1
				    ADD R4, R4, #1
				    ADD R5, R4, #-6
				    BRz Line_Finish; 如果最后一位,跳转
				    LD R0, Space2
				    ST R7, Output_R7
                                    OUT
                                    LD R7, Output_R7
				    BRnzp LOOP_Display2

				    Line_Finish 
                                    LD R0, change_line2
				    ST R7, Output_R7
                                    OUT
                                    LD R7, Output_R7
                                    ADD R1, R1, #1
                                    LDR R2, R1, #0
				    ADD R3, R3, #1
				    BRnzp LOOP_Display1
	Display_Done ST R7, Save7; 还原值
	             JSR RecoverR
	             LD R7, Save7
	             RET
;------------------------------------------------------
.END


;*********************************************
;                   _ooOoo_
;                  o8888888o
;                  88" . "88
;                  (| -_- |)
;                  O\  =  /O
;               ____/`---'\____
;             .'  \\|     |//  `.
;            /  \\|||  :  |||//  \
;           /  _||||| -:- |||||-  \
;           |   | \\\  -  /// |   |
;           | \_|  ''\---/''  |   |
;           \  .-\__  `-`  ___/-. /
;         ___`. .'  /--.--\  `. . __
;      ."" '<  `.___\_<|>_/___.'  >'"".
;     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
;    \  \ `-.   \_ __\ /__ _/   .-` /  /
;======`-.____`-.___\_____/___.-`____.-'======
;                   `=---='
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;           Buddha Bless, No Bug !

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值