Peg Solitaire (MIPS R2000 Assembly)
Spring 2011 | Project Length: 4 weeks (Elective coursework)
A Peg Solitaire game written from scratch in MIPS R2000 Assembly Language as a solo project. Done as a final project for my Computer Organization class. Validates user input, prints appropriate error messages, and detects when the game has ended.
The class itself was taken as a free elective. The full source code can be downloaded bottom of this page.
Example Session
************************
** Peg Puzzle **
************************
0 1 2 3 4 5 6
+---------+
0 | X X X |
1 +-----+ X X X +-----+
2 | X X X X X X X |
3 | X X X X X X |
4 | X X X X X X X |
5 +-----+ X X X +-----+
6 | X X X |
+---------+
Enter the location of the peg to move (RC, -1 to quit): 00
Illegal location.
Enter the location of the peg to move (RC, -1 to quit): 33
Illegal move, no peg at source location.
Enter the location of the peg to move (RC, -1 to quit): 03
Enter the location where the peg is moving to (RC, -1 to quit): 23
Illegal move, destination location is occupied.
Enter the location where the peg is moving to (RC, -1 to quit): 33
Illegal move, can only jump over one peg, re-enter move.
Enter the location of the peg to move (RC, -1 to quit): 22
Enter the location where the peg is moving to (RC, -1 to quit): 33
Illegal move, can only jump over one peg, re-enter move.
Enter the location of the peg to move (RC, -1 to quit): 13
Enter the location where the peg is moving to (RC, -1 to quit): 33
0 1 2 3 4 5 6
+---------+
0 | X X X |
1 +-----+ X X +-----+
2 | X X X X X X |
3 | X X X X X X X |
4 | X X X X X X X |
5 +-----+ X X X +-----+
6 | X X X |
+---------+
Enter the location of the peg to move (RC, -1 to quit): 33
Enter the location where the peg is moving to (RC, -1 to quit): 13
Illegal move, no peg being jumped over, re-enter move.
Enter the location of the peg to move (RC, -1 to quit): 43
Enter the location where the peg is moving to (RC, -1 to quit): 23
0 1 2 3 4 5 6
+---------+
0 | X X X |
1 +-----+ X X +-----+
2 | X X X X X X X |
3 | X X X X X X |
4 | X X X X X X |
5 +-----+ X X X +-----+
6 | X X X |
+---------+
Enter the location of the peg to move (RC, -1 to quit): 31
Enter the location where the peg is moving to (RC, -1 to quit): 33
0 1 2 3 4 5 6
+---------+
0 | X X X |
1 +-----+ X X +-----+
2 | X X X X X X X |
3 | X X X X X |
4 | X X X X X X |
5 +-----+ X X X +-----+
6 | X X X |
+---------+
Enter the location of the peg to move (RC, -1 to quit): 34
Enter the location where the peg is moving to (RC, -1 to quit): 32
0 1 2 3 4 5 6
+---------+
0 | X X X |
1 +-----+ X X +-----+
2 | X X X X X X X |
3 | X X X X |
4 | X X X X X X |
5 +-----+ X X X +-----+
6 | X X X |
+---------+
Enter the location of the peg to move (RC, -1 to quit): 36
Enter the location where the peg is moving to (RC, -1 to quit): 34
0 1 2 3 4 5 6
+---------+
0 | X X X |
1 +-----+ X X +-----+
2 | X X X X X X X |
3 | X X X |
4 | X X X X X X |
5 +-----+ X X X +-----+
6 | X X X |
+---------+
Enter the location of the peg to move (RC, -1 to quit): 63
Enter the location where the peg is moving to (RC, -1 to quit): 43
0 1 2 3 4 5 6
+---------+
0 | X X X |
1 +-----+ X X +-----+
2 | X X X X X X X |
3 | X X X |
4 | X X X X X X X |
5 +-----+ X X +-----+
6 | X X |
+---------+
There are no more legal moves.
You left 26 pegs on the board.
Code Snippet
Here’s the function that checks if a coordinate is a valid location on the board (i.e. not off the board, not in the dead-zones in the corners):
# # Name: is_valid_coordinate # # Description: Helper method to check if a coord is a valid board location # # Arguments: a0: the coord to be checked # Returns: v0: zero if coord invalid, otherwise non-zero # is_valid_coordinate: addi $sp, $sp, -40 # allocate stack frame (on doubleword boundary) sw $ra, 32($sp) # store the ra & s reg's on the stack sw $s7, 28($sp) sw $s6, 24($sp) sw $s5, 20($sp) sw $s4, 16($sp) sw $s3, 12($sp) sw $s2, 8($sp) sw $s1, 4($sp) sw $s0, 0($sp) # extract row-col format into $s0,$s1 respectively addi $t0, $zero, 10 # t0 = 10 div $a0, $t0 # lo = coord/10, hi(rem) = coord % 10 mflo $s0 # row: s0 := coord / 10 mfhi $s1 # col: s1 := coord % 10 # assume false li $v0, 0 # set default return to false # check for off-board slt $t0, $s0, $zero # if row < 0 bne $t0, $zero, is_valid_coordinate_done # return false slt $t0, $s1, $zero # if col < 0 bne $t0, $zero, is_valid_coordinate_done # return false li $t1, 7 ### replace w/BOARD_WIDTH # t1 = BOARD_WIDTH slt $t0, $s0, $t1 # if row >= BOARD_WIDTH beq $t0, $zero, is_valid_coordinate_done # return false slt $t0, $s1, $t1 # if col >= BOARD_WIDTH beq $t0, $zero, is_valid_coordinate_done # return false is_valid_coordinate_checkRowSmall: # handle row < DEAD_ZONE_SIZE li $t2, 2 ### # t2 = DEAD_ZONE_SIZE sub $t3, $t1, $t2 # t3 = BOARD_WIDTH - DEAD_ZONE_SIZE slt $t0, $s0, $t2 # if !(row < DZS) beq $t0, $zero, is_valid_coordinate_checkRowLarge # skip # top-left corner # if row < DZS && col < DZS, return false slt $t0, $s1, $t2 # if col < DZS bne $t0, $zero, is_valid_coordinate_done # return false # top-right corner # if row < DZS && col >= BW - DZS, false slt $t0, $s1, $t3 # if col >= BW - DZS beq $t0, $zero, is_valid_coordinate_done # return false is_valid_coordinate_checkRowLarge: # handle ROW >= BOARD_WIDTH - DEAD_ZONE_SIZE slt $t0, $s0, $t3 # if !(row >= BW-DZS) bne $t0, $zero, is_valid_coordinate_setTrue # skip # bottom-left corner # if row > BW-DZS && col < DZS, false slt $t0, $s1, $t2 # if col < DZS bne $t0, $zero, is_valid_coordinate_done # return false # bottom-right corner slt $t0, $s1, $t3 # if col >= BW - DZS beq $t0, $zero, is_valid_coordinate_done # return false is_valid_coordinate_setTrue: # peg not in off-board location, must be on board li $v0, 1 # set return to true (non-zero) is_valid_coordinate_done: lw $ra, 32($sp) # restore the ra & s reg's from the stack lw $s7, 28($sp) lw $s6, 24($sp) lw $s5, 20($sp) lw $s4, 16($sp) lw $s3, 12($sp) lw $s2, 8($sp) lw $s1, 4($sp) lw $s0, 0($sp) addi $sp, $sp, 40 # clean up stack jr $ra
Downloads
peg_puzzle.asm (33.5 KB)
