Creating Positions and Jumps in a Checkers Game

.data askrow: .asciiz "Row: " askcol: .asciiz "Column: " askval: .asciiz "Value: " askr1: .asciiz "R1: " askc1: .asciiz "C1: " askr2: .asciiz "R2: " askc2: .asciiz "C2: " res1: .asciiz "isValidMove(): " res2: .asciiz "isValidJump(): " invalidPos: .asciiz "Invalid position. Please try again.\n" board: .word 0 #pointer to allocated board space .text .globl main # --------------------------------------------------------------- # main function # C prototype: # main() # --------------------------------------------------------------- main: li $a0,400 # allocate space for 10x10 values of 4 bytes syscall $malloc la $t0,board sw $v0,($t0) # save pointer to allocated space in the board variable # initialize board to zeros la $t0,board # load board pointer lw $t0,($t0) li $t1,100 # counter for 400 elements 1: sw $0,($t0) # save 0 in the board addi $t0,$t0,4 # go to next board position addi $t1,$t1,-1 # decrement number of remaining elements bnez $t1,1b la $t0,board lw $s0,($t0) # load board pointer in s0 loop: move $a0,$s0 # move board pointer to a0 jal displayBoard la $a0,askrow # ask for a row syscall $print_string syscall $read_int # read row from user move $t1,$v0 # save row in t1 beq $t1,-1,loop2 la $a0,askcol # ask for a column syscall $print_string syscall $read_int # read column from user move $t2,$v0 # save column in t2 move $a0,$t1 move $a1,$t2 jal isLegalPosition # verify that the position is legal bnez $v0,2f # if legal, skip to 2 la $a0,invalidPos # print error message syscall $print_string b loop # start over 2: la $a0,askval # ask for a value syscall $print_string syscall $read_int # read value from user # save value in board li $t3,10 mul $t4,$t3,$t1 # row*10 add $t4,$t4,$t2 # row*10+col sll $t4,$t4,2 # multiply by 4 to get offset in bytes add $t4,$t4,$s0 # add offset to board address sw $v0,($t4) # save value at selected position in board b loop loop2: move $a0,$s0 # move board pointer to a0 jal displayBoard la $a0,askr1 # ask for r1 syscall $print_string syscall $read_int # read r1 from user move $s1,$v0 # save r1 in s1 la $a0,askc1 # ask for c1 syscall $print_string syscall $read_int # read c1 from user move $s2,$v0 # save c1 in s2 la $a0,askr2 # ask for r2 syscall $print_string syscall $read_int # read r2 from user move $s3,$v0 # save r2 in s3 la $a0,askc2 # ask for c2 syscall $print_string syscall $read_int # read c2 from user move $s4,$v0 # save c2 in s4 move $a0,$s0 move $a1,$s1 move $a2,$s2 move $a3,$s3 addi $sp,$sp,-4 # allocate space in stack sw $s4,0($sp) # save c2 in the stack jal isValidMove # call isValidMove add $sp,$sp,4 # restore stack pointer la $a0,res1 # print isValidMove syscall $print_string move $a0,$v0 syscall $print_int # print the return value li $a0,'\n syscall $print_char # print a new line move $a0,$s0 move $a1,$s1 move $a2,$s2 move $a3,$s3 addi $sp,$sp,-4 # allocate space in stack sw $s4,0($sp) # save c2 in the stack jal isValidJump # call isValidJump add $sp,$sp,4 # restore stack pointer la $a0,res2 # print isValidJump syscall $print_string move $a0,$v0 syscall $print_int # print the return value li $a0,'\n syscall $print_char # print a new line b loop2 syscall $exit # exit from the program # --------------------------------------------------------------- # function to determine is a move is legal, # C prototype: # int isLegalPosition(int row, int column) # Arguments: # $a0=row # $a1=column # Return value: # $v0 # --------------------------------------------------------------- isLegalPosition: li $v0,0 # set return value as illegal by default bltz $a0,1f # row<0 is illegal bgt $a0,9,1f # row>9 is illegal bltz $a1,1f # col<0 is illegal bgt $a1,9,1f # col>9 is illegal add $t0,$a0,$a1 # add col and row andi $t0,$t0,1 # see if it's an odd number bnez $t0,1f # if it's odd it's illegal because the position is black li $v0,1 # if we get here, set return value to 1, legal position 1: jr $ra # --------------------------------------------------------------- # function to determine if a move is valid, C prototype: # C prototype: # int isValidMove(int *board, int r1, int c1, int r2, int c2) # Arguments: # $a0 = *board # $a1 = r1 # $a2 = c1 # $a3 = r2 # ($sp) = c2 # Return value: # $v0 # --------------------------------------------------------------- isValidMove: addi $sp,$sp,-4 # allocate space in stack sw $ra,0($sp) # save return address in the stack move $t1,$a1 # t1=r1 move $t2,$a2 # t2=c1 move $t3,$a3 # t3=r2 lw $t4,4($sp) # t4 = c2 (from stack) move $t5,$a0 # load board pointer in t5 move $a0,$t1 move $a1,$t2 jal isLegalPosition # see if r1,c1 is a valid position beqz $v0,rfail # illegal position returns 0 move $a0,$t3 move $a1,$t4 jal isLegalPosition # see if r2,c2 is a valid position beqz $v0,rfail # illegal position returns 0 li $v0,0 # set $v0 to 0 to return 0 by default li $t0,10 mul $t6,$t3,$t0 # r2*10 add $t6,$t6,$t4 # r2*10+c2 sll $t6,$t6,2 # multiply by 4 to get offset in bytes add $t6,$t6,$t5 # address of board[r2*10+c2] lw $t6,($t6) # load board(r2,c2) bnez $t6,rfail # if it's not empty, return 0 mul $t7,$t1,$t0 # r1*10 add $t7,$t7,$t2 # r1*10+c2 sll $t7,$t7,2 # multiply by 4 to get offset in bytes add $t7,$t7,$t5 # address of board[r1*10+c1] lw $t7,($t7) # load board(r1,c1) beqz $t7,rfail # if the piece to move is empty return 0 andi $t0,$t7,4 # see if the piece was a king bnez $t0,kpiece # if it's king, skip andi $t0,$t7,2 # see if the piece was a white beqz $t0,rpiece # if it's red go to red piece wpiece: #white piece sub $t0,$t1,$t3 # r1-r2 beq $t0,1,tstcol # if r1-r2==1, test columns b rfail # else fail rpiece: # red piece sub $t0,$t3,$t1 # r2-r1 beq $t0,1,tstcol # if r2-r1==1, test columns b rfail # else fail kpiece: # king piece sub $t0,$t3,$t1 # r2-r1 beq $t0,1,tstcol # if r2-r1==1, go to test columns beq $t0,-1,tstcol # if r2-r1==-1, go to test columns b rfail tstcol: sub $t0,$t4,$t2 # c2-c1 beq $t0,1,rok # if c2-c1==1, pass ok bne $t0,-1,rfail # if c2-c1!=-1, fail rok: li $v0,1 rfail: lw $ra,0($sp) # load return address from the stack addi $sp,$sp,4 # restore stack pointer jr $ra # --------------------------------------------------------------- # function to determine if a jump is valid # C prototype: # int isValidJump(int *board, int r1, int c1, int r2, int c2) # Arguments: # $a0 = *board # $a1 = r1 # $a2 = c1 # $a3 = r2 # ($sp) = c2 # Return value: # $v0 # --------------------------------------------------------------- isValidJump: addi $sp,$sp,-4 # allocate space in stack sw $ra,0($sp) # save return address in the stack move $t1,$a1 # t1=r1 move $t2,$a2 # t2=c1 move $t3,$a3 # t3=r2 lw $t4,4($sp) # t4 = c2 (from stack) move $t5,$a0 # load board pointer in t5 move $a0,$t1 move $a1,$t2 jal isLegalPosition # see if r1,c1 is a valid position beqz $v0,rfail2 # illegal position returns 0 move $a0,$t3 move $a1,$t4 jal isLegalPosition # see if r2,c2 is a valid position beqz $v0,rfail2 # illegal position returns 0 li $v0,0 # set $v0 to 0 to return 0 by default li $t0,10 mul $t6,$t3,$t0 # r2*10 add $t6,$t6,$t4 # r2*10+c2 sll $t6,$t6,2 # multiply by 4 to get offset in bytes add $t6,$t6,$t5 # address of board[r2*10+c2] lw $t6,($t6) # load board(r2,c2) bnez $t6,rfail2 # if it's not empty, return 0 li $t0,10 add $t8,$t1,$t3 # add r1+r2 srl $t8,$t8,1 # position of middle piece r=(r1+r2)/2 mul $t6,$t8,$t0 # r*10 add $t8,$t2,$t4 # add c1+c2 srl $t8,$t8,1 # position of middle piece c=(c1+c2)/2 add $t6,$t6,$t8 # r*10+c sll $t6,$t6,2 # multiply by 4 to get offset in bytes add $t6,$t6,$t5 # address of board[r*10+c] lw $t6,($t6) # load board(r,c) beqz $t6,rfail2 # if it's empty, return 0 mul $t7,$t1,$t0 # r1*10 add $t7,$t7,$t2 # r1*10+c2 sll $t7,$t7,2 # multiply by 4 to get offset in bytes add $t7,$t7,$t5 # address of board[r1*10+c1] lw $t7,($t7) # load board(r1,c1) xor $t8,$t6,$t7 # compare the middle piece and the jumping piece andi $t8,$t8,2 # see if the pieces were different color beqz $t8,rfail2 # if they were equal color, fail, can't jump over it andi $t0,$t7,4 # see if the piece was a king bnez $t0,kpiece2 # if it's king, skip andi $t0,$t7,2 # see if the piece was a white beqz $t0,rpiece2 # if it's red go to red piece wpiece2: #white piece sub $t0,$t1,$t3 # r1-r2 beq $t0,2,tstcol2 # if r1-r2==2, test columns b rfail2 # else fail rpiece2: # red piece sub $t0,$t3,$t1 # r2-r1 beq $t0,2,tstcol2 # if r2-r1==2, test columns b rfail2 # else fail kpiece2: # king piece sub $t0,$t3,$t1 # r2-r1 beq $t0,2,tstcol2 # if r2-r1==2, go to test columns beq $t0,-2,tstcol2 # if r2-r1==-2, go to test columns b rfail2 tstcol2: sub $t0,$t4,$t2 # c2-c1 beq $t0,2,rok2 # if c2-c1==2, pass ok bne $t0,-2,rfail2 # if c2-c1!=-2, fail rok2: li $v0,1 rfail2: lw $ra,0($sp) # load return address from the stack addi $sp,$sp,4 # restore stack pointer jr $ra # --------------------------------------------------------------- # function to print the board # C prototype: # void displayBoard(int* board) # $a0 = *board # --------------------------------------------------------------- displayBoard: move $t0,$a0 # save board address in t0 li $t1,9 # counter for rows 1: li $t2,0 # counter for columns 2: add $t3,$t1,$t2 # add row+column andi $t3,$t3,1 # see if the sum is odd beqz $t3,3f # if is even, skip li $a0,219 # black square b print # print it 3: li $t3,10 mul $t4,$t3,$t1 # row*10 add $t4,$t4,$t2 # row*10+col sll $t4,$t4,2 # multiply by 4 to get offset in bytes add $t4,$t4,$t0 # add offset to board address lw $a0,($t4) # load value at current position in board bne $a0,3,4f # if board[row,col]!=3 li $a0,'w b print 4: bne $a0,1,5f # if board[row,col]!=1 li $a0,'r b print 5: bne $a0,5,6f # if board[row,col]!=5 li $a0,'R b print 6: bne $a0,7,7f # if board[row,col]!=7 li $a0,'W b print 7: li $a0,32 # white square (space) print: syscall $print_char # print the char addi $t2,$t2,1 # increment column blt $t2,10,2b # repeat while the column < 10 li $a0,'\n syscall $print_char # print a new line addi $t1,$t1,-1 # decrement row number bgez $t1,1b # repeat while the row >=0 jr $ra