#     Minesweeper
#
#  30 September 2012                      <Sahil Gupta>
.data

# MineArray is the array representing the 10X10 grid of mines where outermost rows and columns
# have been left for tackling neighbor checking exceptions and ignoring these. Inner elements
# are numbered 10 for unopened.

MineArray:	.word	185273099, 185273099, 168495883, 168430090, 185207306, 168430091, 168430090, 168495882, 168430090, 185207306, 168430091, 168430090, 168495882, 168430090, 185207306, 168430091, 168430090, 168495882, 168430090, 185207306, 168430091, 168430090, 185273098, 185273099, 185273099

# Here the neighbors for a square will be stored
Neighbors:		.word 	0,0

.text
MineSweep: 		swi		567	   	  			# Bury mines (returns # buried in $1)
				addi	$16,$0,9			# $16 = 9
				addi	$17,$0,-1			# $17 = -1
				addi	$18,$0,10			# $18 = 10
				addi	$19,$0,11			# $19 = 11
		   		addi	$20, $1, 0			# Minecount/$20 = Number of mines returned by $1

Solver:			addi	$20,$1,0			# Minecount = 0
				addi 	$21,$0,1			# Index of outermost loop/row counter/i = 0
				addi 	$22,$0,1			# Index of outermost loop/col counter/j = 0
				beq 	$20,$0,BreakProgram	# If(Minecount == 0), then go to end of program 
				add 	$23,$0,$17			# Index of innermost loop/row counter for neighbors/i1 = 0
				add 	$24,$0,$17			# Index of innermost loop/col counter for neighbors/j1 = 0
				addi 	$25,$0,0			# Changetracker1 for C program/Detects if change is made
				addi 	$26,$0,0			# Detects if necessary guess needs to be made
				j 		MineDetector		# Jump to MineDetector

Solver1:		bne 	$25,$0,Solver		# If change made, then go to Solver
				addi 	$21,$0,1			# Index of outermost loop/row counter/i++
				addi 	$22,$0,1			# Index of outermost loop/col counter/j++
				addi 	$23,$17, 0			# Index of innermost loop/row counter for neighbors/i1--
				addi 	$24,$17, 0			# Index of innermost loop/col counter for neighbors/j1--
				addi 	$26,$0,1			# Necessary guess needs to be made
				j		MineDetector		# Jump to MineDetector
			
MineDetector:   beq 	$20,$0,BreakProgram	# If(Minecount == 0), then go to end of program 
				addi 	$27,$0,0			# Flagged squares = 0
				addi 	$28,$0,0			# Unopened squares = 0
				addi 	$23,$17,0
				mult 	$21,$18				# row*fs
				mflo 	$13
				add 	$12,$13,$22			# row*fs + col
				lb 		$13,MineArray($12)	# load the value from the offset found
				bne 	$26,$0,Guess		# if Necessary Guess needs to be made, go to Guess subroutine
				beq		$13,$19,NextSquare	# if square is invalid, then go to Next Square in the rows
				beq 	$13,$17,Flagger		# if square has a bomb, then go to flagger
				beq 	$13,$16,Flagger		# if square has a flag, then go to flagger
				beq 	$13,$18,NextSquare	# if square is unopened, then go to Next Square in the rows
			
SolveNeighor:	mult	$23,$18
				mflo	$2
				add 	$2,$2,$24
				add 	$15,$2,$12
				beq 	$23,$0,CheckItself
			
SolveNeighor2:	lb 		$2,MineArray($15)	  # Value of the neighbor
				beq 	$2,$19,ChangeNeighbor # Change the neighbor if the val is invalid
				beq 	$2,$18,Unopened		  # If(Square is unopened), then unopened counter++
				beq 	$2,$17,Flagger1		  # If(Square is flagged), then flagged counter++
				beq 	$2,$16,Flagger1		  # If(Square is bomb), then flagged counter++
			
ChangeNeighbor:	addi 	$24,$24,1
				addi 	$2,$0,2
				beq		$24,$2,SquareNext1
				j 		SolveNeighor
			
SquareNext1:	addi	$24,$17,0
				addi 	$23,$23,1
				beq 	$23,$2,CaseTest
				j 		SolveNeighor
					
CaseTest:		beq		$28,$0,NextSquare		# This subroutine helps with testing the two conditions
				beq		$13,$0,CaseTest1		# If(TestCase1 == true), then test the case1
				beq	 	$13,$27,CaseTest1		# If(TestCase2 == true), then test the case2
				add 	$2,$27,$28
				beq 	$13,$2,CaseTest2
			
NextSquare:		addi 	$22,$22,1				# Index of innermost loop/col counter for neighbors/j1++
				beq 	$22,$16,NextRow			# In(Col == 10), then go to the next row
				j	 	MineDetector			# Jump to mine detector
			
NextRow:		addi 	$22,$0,1
				addi 	$21,$21,1
				beq 	$21,$16,Solver1
				j 		MineDetector
			
CheckItself:	beq 	$24,$0,ChangeNeighbor
				j 		SolveNeighor2
				
Flagger:		addi 	$20,$20,-1				# Minecount--
				j	 	NextSquare
					
Unopened:		sb 		$15,Neighbors($28)
				addi 	$28,$28,1				# Unopened counter++
				j 		ChangeNeighbor
			
Flagger1:      	addi 	$27,$27,1				# Flagged counter++
				j 		ChangeNeighbor

CaseTest1: 		addi 	$3,$0,0
				j 		StatCalc

CaseTest2: 		addi	$3,$0,1
				j 		StatCalc	

OffsetCalc:  	mflo 	$4						# This subroutine helps im calculating the offset
				mfhi 	$6
				addi 	$4,$4,-1
				addi 	$6,$6,-1
				addi 	$14,$0,8
				mult 	$4,$14
				mflo 	$2
				add 	$2,$2,$6
				bne 	$26,$0,Guess1
				j 		FirstBox

StatCalc: 		addi 	$28,$28,-1
				lb 		$27,Neighbors($28)
				div 	$27, $18
				j		OffsetCalc
			
FirstBox:		swi 	568
				sb 		$4, MineArray($27)
				sb 		$19, MineArray($12)
				bne		$28,$0,StatCalc
				addi 	$25,$0,1
				j 		NextSquare
			
Guess:   		bne 	$13,$18,NextSquare
				div 	$12,$18
				j 		OffsetCalc
			
Guess1:			addi 	$3,$0,-1				# Guess
				swi 	568						# Call to software interrupt for guessing
				sb 		$4, MineArray($12)		# Store the new value in MineArray
				addi 	$25,$0,1                
				j 		Solver

BreakProgram:	jr  	$31						# Return to OS
