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. 


整体设计思路:
1.棋盘数据存放在x4000 – x4024中,其中数值0代表该位置为空,数值1(即正数)代表玩家1下的棋子,数值-1(即负数)代表玩家2下的棋子。
2.子程序OUTCB(棋盘输出)可根据棋盘数据为正负零输出O、X或 - 。
3.子程序JUDGEMENT(判断下棋位置)首先定位玩家下棋位置,再判断该位置是否为空,若为数值0,则可下棋,根据下棋玩家赋值1或-1。否则返回0。
4.子程序IFWIN(判断输赢),首先将棋盘分配好坐标,根据坐标的值范围[ (0,0)<=(x , y)<=(5,5) ] 来判断是否溢出。然后判断下棋位置的纵列是否连成4个,若能,返回结束。否则继续依次执行判断横列,斜列能否连成4子。
5.主程序在执行下棋循环超过18次(玩家1、2各下18个棋子),则结束程序,平局输出。


流程图表示:

LC-3下汇编实现简易版四子棋的游戏_第1张图片

汇编代码实现:

; The code is designed by Li Mingzhao.
; Program is a game named Connect Four.
; PLAY1 plays chess first. R6=1 represents the PLAY1. R6=-1 represents the PLAY2.
; The subprogram JUDGEMENT to judge whether the chess piece is legal.
; The subprogram IFWIN to judge whether there is a winner.
; The subprogram OUTCB to output the ChessBoard.
; ChessBoard to save at x4000-x4024.
; 
              .ORIG    x3000
;
              LD       R4,FULL                ; R4 is counter, initialize to 18
              JSR      OUTCB                  ; Output the empty chessboard
NEXTLOOP      LD       R6,PLAY1               ; Now R6 represents PLAY1's turn
AGAIN         JSR      OUTP1IN                ; Hint to PLAY1's input
              TRAP     x20
              TRAP     X21
              JSR      JUDGEMENT              ; Judge the location.
              JSR      OUTNewLine

              ADD      R5,R5,#0               ; R5=1 means right input
              BRnp     REPLAY2                ; If match, it turns to PLAY2
              JSR      OUTERROR 
              BRnzp    AGAIN                  ; If no match, do AGAIN

REPLAY2       JSR      OUTCB
              JSR      IFWIN                  
              ADD      R3,R3,#0               ; R3 means win or not  
              BRp      ONEWIN                 ; If match, PLAY1 wins
              LD       R6,PLAY2               ; PLAY2's turn
AGAIN2        JSR      OUTP2IN                ; Hint to PLAY2's input
              TRAP     x20
              TRAP     X21
              JSR      JUDGEMENT              ; Judge the location.
              JSR      OUTNewLine

              ADD      R5,R5,#0
              BRnp     IFFULL                 ; If match, judge full or not
              JSR      OUTERROR 
              BRnzp    AGAIN2                 ; If no match, do AGAIN2
;
IFFULL        JSR      OUTCB
              JSR      IFWIN
              ADD      R3,R3,#0
              BRp      TWOWIN                 ; If match, PLAY2 wins
              ADD      R4,R4,#-1
              BRp      NEXTLOOP               ; If match, the next round
              JSR      OUTTIE                 ; If match, output tie hint
              BRnzp    STOP                   ; Jump to HALT
;
ONEWIN        JSR      OUTP1WIN               ; output PLAY1 wins
              BRnzp    STOP
;
TWOWIN        JSR      OUTP2WIN               ; output PLAY2 wins
;       
STOP          HALT
;
;
;
;
;
;
OUTP1IN        ST       R7,SaveR7 
               LEA      R0,P1IN               ; Get the address of P1IN
               TRAP     x22                   
               LD       R7,SaveR7
               RET
;             
OUTP2IN        ST       R7,SaveR7
               LEA      R0,P2IN               ; Get the address of P2IN
               TRAP     x22
               LD       R7,SaveR7
               RET      
;
OUTERROR       ST       R7,SaveR7
               ST       R0,SaveR0
               LEA      R0,ERROR              ; Get the first address of ERROR
               TRAP     x22
               LD       R0,ASCIINewLine       ; Output newline
               TRAP     x21
               LD       R0,SaveR0
               LD       R7,SaveR7
               RET    
;  
OUTP1WIN       ST       R7,SaveR7 
               LEA      R0,P1WIN              ; Get the address of P1WIN
               TRAP     x22
               LD       R0,ASCIINewLine       ; Output newline
               TRAP     x21
               LD       R7,SaveR7
               RET    
;  
OUTP2WIN       ST       R7,SaveR7
               LEA      R0,P2WIN              ; Get the address of P2WIN
               TRAP     x22
               LD       R0,ASCIINewLine       ; Output newline
               TRAP     x21
               LD       R7,SaveR7
               RET      
;
OUTTIE         ST       R7,SaveR7
               LEA      R0,TIE                ; Get the address of TIE
               TRAP     x22
               LD       R0,ASCIINewLine       ; Output newline
               TRAP     x21
               LD       R7,SaveR7
               RET    
; 
OUTX           ST       R7,SaveR7
               LD       R0,ASCIIX
               TRAP     x21
               LD       R7,SaveR7
               RET  
;
OUTO           ST       R7,SaveR7
               LD       R0,ASCIIO
               TRAP     x21
               LD       R7,SaveR7
               RET  
;
OUTNull        ST       R7,SaveR7
               LD       R0,ASCIINull
               TRAP     x21
               LD       R7,SaveR7
               RET 
; 
OUTSpace       ST       R7,SaveR7
               LD       R0,ASCIISpace
               TRAP     x21
               LD       R7,SaveR7
               RET  
;
OUTNewLine     ST       R7,SaveR7
               ST       R0,SaveR0
               LD       R0,ASCIINewLine
               TRAP     x21
               LD       R0,SaveR0
               LD       R7,SaveR7              
               RET           
;
;
PLAY1          .FILL    #1
PLAY2          .FILL    #-1
FULL           .FILL    #18
SaveR00        .FILL    #0
SaveR0         .FILL    #0
SaveR1         .FILL    #0
SaveR2         .FILL    #0
SaveR3         .FILL    #0
SaveR4         .FILL    #0
SaveR5         .FILL    #0
SaveR6         .FILL    #0
SaveR7         .FILL    #0
SaveR07        .FILL    #0
  
THIRDSIX       .FILL    #36
ASCII          .FILL    #-48
ChessBoard     .FILL    x4000
LASTLINE       .FILL    x401E
P1IN           .STRINGZ "Player 1, choose a column:"
P2IN           .STRINGZ "Player 2, choose a column:"
ERROR          .STRINGZ "Invalid move. Try again."
P1WIN          .STRINGZ "Player 1 Wins."
P2WIN          .STRINGZ "Player 2 Wins."
TIE            .STRINGZ "Tie Game."
ASCIIX         .FILL    x0058
ASCIIO         .FILL    x004F
ASCIINull      .FILL    x002D
ASCIISpace     .FILL    x0020
ASCIINewLine   .FILL    x000A
;
;
;Judge the location. If match, R5=1, else R5=0; R6 represent the PLAY1 or PLAY2.
JUDGEMENT     ST       R1,SaveR1
              ST       R2,SaveR2
              ST       R3,SaveR3
              ST       R7,SaveR07
              
              AND      R3,R3,#0                
              ADD      R3,R3,#6               ; R3 count for the line, initialize to 6
              LD       R1,ASCII 
              ADD      R1,R1,R0               ; Convert from ASCII to number value
              LD       R0,LASTLINE            ; Count the first location
              ADD      R1,R1,#-1
              BRn      BACK                   
              ADD      R2,R1,#-5
              BRp      BACK      
              ADD      R0,R0,R1
CheckNext     LDR      R1,R0,#0
              BRnp     NEXTLINE               ; Judge the next line
              STR      R6,R0,#0               
              AND      R5,R5,#0               ; R5 means the right or wrong location
              ADD      R5,R5,#1               
              BRnzp    BACK2                  ; If match, right location

NEXTLINE      ADD      R0,R0,#-6
              ADD      R3,R3,#-1
              BRnz     BACK
              BRnzp    CheckNext              ; If match, jump to check next line
             
BACK          AND      R5,R5,#0
BACK2         LD       R1,SaveR1
              LD       R2,SaveR2
              LD       R3,SaveR3
              LD       R7,SaveR07
              RET 
;
;
; Output the ChessBoard.             
OUTCB         ST       R0,SaveR00
              ST       R1,SaveR1
              ST       R2,SaveR2
              ST       R3,SaveR3
              ST       R7,SaveR07

              AND      R1,R1,#0               ; Clear R1
              AND      R2,R2,#0               ; Clear R2
              LD       R1,THIRDSIX            ; R1 is a counter, initialize to 36
              LD       R3,ChessBoard
NEXT3         ADD      R3,R3,#1               ; R3 is a counter for newline 
              LDR      R0,R3,#-1
              BRp      O
              BRz      NULL                   
              BRn      X 
O             JSR      OUTO                   ; If postive, output 'O'
              BRnzp    NEXT
NULL          JSR      OUTNull                ; If zero, output '-'
              BRnzp    NEXT
X             JSR      OUTX                   ; If negtive, output 'O'
NEXT          ADD      R2,R2,#1               ; Increment count
              ADD      R0,R2,#-6
              BRz      NewLine
              JSR      OUTSpace               ; If match, output ' '
              BRnzp    NEXT2
NewLine       AND      R2,R2,#0               ; Clear R2
              JSR      OUTNewLine     
NEXT2         ADD      R1,R1,#-1              ; Discrement count
              BRp      NEXT3   

              LD       R0,SaveR00
              LD       R1,SaveR1
              LD       R2,SaveR2
              LD       R3,SaveR3
              LD       R7,SaveR07          
              RET
;
;
;WIN OR FAIL. If win, R3=1, else R3=0; R6 represent the PLAY1 or PLAY2.R0 is the location.
IFWIN         ST       R1,SaveR11
              ST       R2,SaveR22
              ST       R4,SaveR44
              ST       R5,SaveR55
              ST       R6,SaveR66 
              ST       R7,SaveR77 
    
              AND      R1,R1,#0               ; R1 is a counter for four, initialize to 0
              AND      R3,R3,#0               ; Clear R3
              AND      R4,R4,#0               ; Clear R4
              AND      R2,R2,#0               ; Clear R2
              ADD      R7,R0,#0
;Calculate the coordinate position. R2 for list. R4 for row.
              LD       R5,LOAC                ; Load R5 -x4000
              ADD      R5,R7,R5
DELETE6       ADD      R5,R5,#-6
              BRn      ROWSUM
              ADD      R4,R4,#1               ; R4 to count for row
              BRnzp    DELETE6
ROWSUM        ADD      R2,R5,#6               ; R2 to count for list
              ST       R4,SaveROW             ; Save the data of row.
              ST       R2,Savelist            ; Save the data of list.
              
              NOT      R6,R6
              ADD      R6,R6,#1               ; If add -R6 to zero, match
; Up-column              
CHECKNEXT     ADD      R4,R4,#-1              ; To check whether it's flow or not
              BRn      DIRECTION
              ADD      R7,R7,#-6          
              LDR      R5,R7,#0
              ADD      R5,R5,R6
              BRnp     DIRECTION
              ADD      R1,R1,#1               ; If match, increment count
              BRnzp    CHECKNEXT
; Down-column              
DIRECTION     LD       R4,SaveROW
              ADD      R7,R0,#0               ; Initialize the R7
CHECKNEXT1    ADD      R4,R4,#1               ; To check whether it's flow or not
              BRn      JUDGEFOUR
              ADD      R7,R7,#6
              LDR      R5,R7,#0
              ADD      R5,R5,R6
              BRnp     JUDGEFOUR
              ADD      R1,R1,#1               ; If match, increment count
              BRnzp    CHECKNEXT1

JUDGEFOUR     ADD      R5,R1,#-3              ; If R5>=3, someone wins the game
              BRn      CROW                   ; Else to check the next group  
              ADD      R3,R3,#1
              BRnzp    SOMEONEWIN         

CROW          AND      R1,R1,#0               ; R1 is a counter for four, initialize to 0
              ADD      R7,R0,#0               ; Initialize the R7
              LD       R2,Savelist
CHECKNEXT2    ADD      R2,R2,#-1              ; To check whether it's flow or not
              BRn      CROW1
              ADD      R7,R7,#-1
              LDR      R5,R7,#0
              ADD      R5,R6,R5
              BRnp     CROW1
              ADD      R1,R1,#1               ; If match, increment count
              BRnzp    CHECKNEXT2

CROW1         ADD      R7,R0,#0               ; Initialize the R7
              LD       R2,Savelist
CHECKNEXT3    ADD      R2,R2,#1               ; To check whether it's flow or not
              ADD      R5,R2,#-6
              BRzp     JUDGEFOUR2     
              ADD      R7,R7,#1
              LDR      R5,R7,#0
              ADD      R5,R5,R6
              BRnp     JUDGEFOUR2
              ADD      R1,R1,#1               ; If match, increment count 
              BRnzp    CHECKNEXT3 

JUDGEFOUR2    ADD      R5,R1,#-3              ; If R5>=3, someone wins the game
              BRn      INCLINED               ; Else to check the next group
              ADD      R3,R3,#1
              BRnzp    SOMEONEWIN  

INCLINED      AND      R1,R1,#0               ; R1 is a counter for four, initialize to 0
              ADD      R7,R0,#0               ; Initialize the R7
              LD       R2,Savelist
              LD       R4,SaveROW
              
NEXTINCL      ADD      R4,R4,#-1              ; To check whether it's flow or not
              BRn      INCLINED2
              ADD      R2,R2,#-1              ; To check whether it's flow or not
              BRn      INCLINED2
              ADD      R7,R7,#-7
              LDR      R5,R7,#0
              ADD      R5,R5,R6
              BRnp     INCLINED2
              ADD      R1,R1,#1               ; If match, increment count
              BRnzp    NEXTINCL

INCLINED2     ADD      R7,R0,#0               ; Initialize the R7
              LD       R2,Savelist
              LD       R4,SaveROW

NEXTINCL1     ADD      R4,R4,#1               ; To check whether it's flow or not
              ADD      R5,R4,#-6
              BRzp     JUDGEFOUR3 
              ADD      R2,R2,#1               ; To check whether it's flow or not
              ADD      R5,R2,#-6 
              BRzp     JUDGEFOUR3
              ADD      R7,R7,#7
              LDR      R5,R7,#0
              ADD      R5,R5,R6
              BRnp     JUDGEFOUR3
              ADD      R1,R1,#1               ; If match, increment count
              BRnzp    NEXTINCL1 
  
JUDGEFOUR3    ADD      R5,R1,#-3              ; If R5>=3, someone wins the game
              BRn      BIAS                   ; Else to check the next group 
              ADD      R3,R3,#1
              BRnzp    SOMEONEWIN  

BIAS          AND      R1,R1,#0               ; R1 is a counter for four, initialize to 0
              ADD      R7,R0,#0               ; Initialize the R7
              LD       R2,Savelist
              LD       R4,SaveROW
              
NEXTBIAS      ADD      R4,R4,#1               ; To check whether it's flow or not
              ADD      R5,R4,#-6
              BRzp     NEXTBIAS2
              ADD      R2,R2,#-1              ; To check whether it's flow or not
              BRn      NEXTBIAS2
              ADD      R7,R7,#5
              LDR      R5,R7,#0
              ADD      R5,R5,R6
              BRnp     NEXTBIAS2
              ADD      R1,R1,#1               ; If match, increment count
              BRnzp    NEXTBIAS

NEXTBIAS2     ADD      R7,R0,#0               ; Initialize the R7
              LD       R2,Savelist
              LD       R4,SaveROW

NEXTBIAS1     ADD      R4,R4,#-1              ; To check whether it's flow or not
              BRn      JUDGEFOUR4
              ADD      R2,R2,#1               ; To check whether it's flow or not
              ADD      R5,R2,#-6
              BRzp     JUDGEFOUR4
              ADD      R7,R7,#-5
              LDR      R5,R7,#0
              ADD      R5,R5,R6
              BRnp     JUDGEFOUR4
              ADD      R1,R1,#1               ; If match, increment count
              BRnzp    NEXTBIAS1 
  
JUDGEFOUR4    ADD      R5,R1,#-3              ; If R5>=3, someone wins the game
              BRn      SOMEONEWIN             ; Else end this subprogram
              ADD      R3,R3,#1
              BRnzp    SOMEONEWIN 
               

SOMEONEWIN    LD       R1,SaveR11
              LD       R2,SaveR22
              LD       R4,SaveR44
              LD       R5,SaveR55
              LD       R6,SaveR66
              LD       R7,SaveR77
              RET 
;
SaveR11        .FILL    #0
SaveR22        .FILL    #0
SaveR44        .FILL    #0
SaveR55        .FILL    #0
SaveR66        .FILL    #0
SaveR77        .FILL    #0

Savelist       .FILL    #0
SaveROW        .FILL    #0  
LOAC           .FILL    xC001
;

                .END


你可能感兴趣的:(计算机系统)