Deprecated: Assigning the return value of new by reference is deprecated in /web/htdocs/www.flaviocdc.net/home/wiki/inc/parserutils.php on line 208 Deprecated: Assigning the return value of new by reference is deprecated in /web/htdocs/www.flaviocdc.net/home/wiki/inc/parserutils.php on line 211 Deprecated: Assigning the return value of new by reference is deprecated in /web/htdocs/www.flaviocdc.net/home/wiki/inc/parserutils.php on line 421 Deprecated: Assigning the return value of new by reference is deprecated in /web/htdocs/www.flaviocdc.net/home/wiki/inc/parserutils.php on line 594 Deprecated: Function split() is deprecated in /web/htdocs/www.flaviocdc.net/home/wiki/inc/auth.php on line 154 Fatal 15 [Flavio Casadei Della Chiesa Wiki]
 
Il contenuto di questo sito è rilasciato sotto licenza Creative Commons License se non specificato diversamente

Fatal 15

#	 Programma gioco del 15
      .data
#	Segmento dati
 
#/--------------------------------------------------------------/
 
#	Stringhe generiche
nordi:          .asciiz "Hai perso,riprova!\n"
ordi:           .asciiz "Congratulazioni... HAI VINTO!!\n"
gd15:           .asciiz "Fatal Fifteen!" # il nome del gioco
 
spazio:         .asciiz " "             #viene utilizzata per la grafica
spazi5:         .asciiz "     "         #idem
istruz:         .asciiz "Istruzioni del gioco:\n\nIl gioco consiste nello spostare le \ncaselle in modo da riordinare i numeri\ndella scacchiera.\n\nGli spostamenti vengono gestiti con le\nfrecce cursore del tastierino numerico.\n\nPer giocare attivare il tasto BLOCNUM\nPer uscire dal gioco premere ESC.\n"
press:          .asciiz "Premere un tasto per continuare..."
 
mosse:		.asciiz "Mosse:"
 
perso:  .asciiz"GAME OVER!\n\n  Ritenta,la prossima volta sarai piu'\n  fortunato(forse).\n\n"
 
vinto:  .asciiz "Congratulazioni,hai risolto il gioco!\n\n"
 
info:   .asciiz "  Fatal fifteen (il gioco del 15 )\n  Realizzato per il corso di:\n  Laboratorio di informatica:\n\t   Architettura.\n\n  Gruppo di laboratorio numero 6:\n  Barbara Bresci\n  Flavio Casadei D.C.\n  Marco Nenciarini.\n" 
 
#/--------------------------------------------------------------/
#	Stringhe ANSI
hansi:   .byte   27, 91, 0   	# i numeri 27 e 91 sono i caratteri
			     	# esc e parentesi rispettivamente
			     	# e vengono utilizzati per inizializzare   
			     	# le sequenze ansi        
modo1:          .asciiz "=1h" 	# modalità testo a colori 40*25
modo3:  	.asciiz "=3h" 	# modalità testo a colori 80*25
acca:           .asciiz "H"   	# utilizzata per la gotoxy
pev:            .asciiz ";"   	# idem
clrscr:         .asciiz "2J" 	# cancella schermo
 
noatt:          .asciiz "0m" 	# attributi disattivati
lamp:           .asciiz "5m" 	# lampeggio
#	colori sfondo
sfonero:        .asciiz "40m"
sforosso: 	.asciiz "41m"
sfoverde: 	.asciiz "42m"
sfobianco:   	.asciiz "47m"
sfoblu:          .asciiz "44m"
#	colori caratteri
colnero:        .asciiz"30m"
colrosso:       .asciiz"31m"
colbianco:      .asciiz "37m"
colblu:         .asciiz"34m"
 
 
#/--------------------------------------------------------------/
#	buffers
 
	.align 2
tabella:        .space 16  	# il vettore che contiene la scacchiera
currblank:	.word 0		# posizione della casella vuota
 
## costanti per la generazione di numeri random
Z:              .word 1103515245	# Base
L:              .word 1			# Seed
I:              .word 24337		# Incremento
M:              .word 65535		# Divisore
 
#	Segmento CODICE
	.text
 
#/--------------------------------------------------------------/
###############################################
## procedura write
## riceve in $a0 l'indirizzo della locazione di memoria a partitre
## dalla quale si trova la stringa che si desidera stampare
###############################################
write:
 
	li $v0,4        #codice operativo per la stampa delle stringhe
	syscall         # viene effettuata la chiamata di sistema
	j $ra
 
#/--------------------------------------------------------------/
###############################################
## procedura write_ansi
## riceve in $a0 l'indirizzo di memoria a partire dal quale si trova
## una stringa da stampare.
## Prima di stampare la stringa inizializza le sequenze di caratteri ansi
###############################################
write_ansi:	
	addi $sp, $sp, -8        
	sw $ra, 8($sp)           				
	sw $a0, 4($sp)
	la $a0, hansi	# inizializzazione ansi
	jal write
	lw $a0, 4($sp)
	jal write
	lw $ra, 8($sp)
	addi $sp, $sp, 8
	jr $ra
#/--------------------------------------------------------------/
###############################################
## procedura gotoxy
## riceve in $a1 ed in $a2 due valori numerici che indicano
## il punto dello schermo nel quale si desidera posizionare
## il cursore
###############################################
gotoxy:
	addi $sp, $sp, -4  
	sw $ra, 4($sp)   
	li $v0, 4
	la $a0, hansi    # inizializza la sequenza ansi
	syscall 
	li $v0, 1        # chiamata di sistema per la stampa di un numero
	move $a0, $a2    # ordinata del cursore
	syscall         
	la $a0, pev      # carattere ';' 
	jal write
	li $v0, 1
	move $a0, $a1    # ascissa del cursore
	syscall
	la $a0, acca     # lettera 'H' 
	jal write
	lw $ra, 4($sp)   
	addi $sp, $sp, 4  
	j $ra
 
#/--------------------------------------------------------------/
###############################################
## procedura clear_screen
## questa procedura cancella il contenuto dello schermo
###############################################
clear_screen:
	addi $sp, $sp, -4
	sw $ra, 4($sp)
	la $a0, clrscr
	jal write_ansi
	lw $ra, 4($sp)
	addi $sp, $sp, 4
	jr $ra
 
#/--------------------------------------------------------------/
###############################################
## procedura schermo_blu
## questa procedura colora lo schermo di blu
###############################################
schermo_blu:
	addi $sp, $sp, -4
	sw $ra, 4($sp)
	la $a0, sfoblu
	jal write_ansi
	jal clear_screen
	lw $ra, 4($sp)
	addi $sp, $sp, 4
	jr $ra
 
 
#/--------------------------------------------------------------/
###############################################
## procedura contorno
## traccia la cornice attorno alla scacchiera
###############################################
contorno:
	addi $sp, $sp, -4
	sw $ra, 4($sp)
	la $a0, sfonero			# colore del contorno
	jal write_ansi	
 
	li $a1, 10			# ascissa iniziale 
	li $t0, 31       		# ascissa finale
	la $t1, spazio			# è il carattere ' ' che serve per colorere l'area
forx:   
# traccia due linee orizzontali	 parallele a partire da $a1 fino a $t0 di ordinate $a2=3 e $a2=24
# disegnando un quadratino alla volta
	bgt $a1, $t0, exit_for_x	# esco quando $a1 > $t0
	li $a2, 3			# ordinata prima linea
	jal gotoxy			# si posiziona alla coordinate ($a1,$a2)
	move $a0, $t1
	jal write			# stampa ' ' 
	li $a2, 24			# ordinata seconda linea
	jal gotoxy 
	move $a0, $t1
	jal write
	addi $a1, $a1, 1		# incrementa l'ascissa sel cursore
	j forx
exit_for_x:
	li $a2 3			# ordinata iniziale
	li $t0 24			# ordinata finale
fory:
# traccia due linee verticali parallele partire da $a2 fino a $t0 di ordinate $a1=10 e $a1=31
# disegnando un quadratino alla volta
	bgt $a2, $t0, exit_for_y	#come sopra
	li $a1, 10
	jal gotoxy
	move $a0, $t1	
	jal write
	li $a1, 31
	jal gotoxy
	move $a0, $t1
	jal write
	addi $a2, $a2, 1		
	j fory
exit_for_y:
 
	lw $ra, 4($sp)
	addi $sp, $sp, 4
	j $ra
 
#/--------------------------------------------------------------/
###############################################
## procedura resetscreen
## Questa procedura riporta lo schermo alla sua configurazione iniziale
## togliendo gli attributi a tutti i caratteri e ripristinando la modalità video
###############################################
resetscreen:                
	addi $sp, $sp, -4       # viene aggiustato lo stack
	sw $ra, 4($sp)          # vengono salvati i registri
	la $a0, noatt		# cancella gli attributi ai caratteri
	jal write_ansi
	la $a0, modo3           # modo testo 80x25
	jal write_ansi
	jal clear_screen	#ripulisce lo schermo
	lw $ra, 4($sp)          # ripristino dei registri
	addi $sp, $sp, 4        # riposizionamento dello stack
	j $ra
 
 
#/--------------------------------------------------------------/
###############################################
# Procedura Quadratino 
# Ricevce 3 parametri:
# $a1 = x (ascissa)
# $a2 = y (ordinata)
# $a3 = numero (16 = casella vuota)
# Traccia un quadrato di lato 5 a partire dalle coordinate (x, y),
# e stampa il relativo numero.
###############################################
quadratino:
	addi $sp, $sp, -4 
	sw $ra, 4($sp) 
## Prima fase:selezione del colore del quadratino
if_color:        
	li $t0, 16		# la casella vuota
	la $a0, sfonero		# imposta il colore nero
##Se il numero ricevuto in $a3 è  16 (casella vuota) allora il quadratino è di 
##colore nero 
	beq $t0, $a3, endif_color
else_color:        
##	begin 
## il numero non rappresenta la casella vuota quindi il colore viene scelto in base
## alla seguente formula  colore :=((((numero - 1) div 4) + numero))mod 2)
## dove colore($a3) può prendere valore 0 oppure 1
## implementazione della formula	
	addi $t0, $a3, -1	# numero -1
	srl $t0, $t0, 2		# (numero -1) div 4
	add $t0, $t0, $a3	# ((numero - 1) div 4) + numero)
	andi $t0, $t0, 1        # ((numero - 1) div 4) + numero)mod 2)
# fine selezione del colore
	la $a0, sfobianco	# colore impostato a bianco
if_color2:
	beqz $t0, endif_color2  # se $t0 <> 0 allora colore:=rosso
	la $a0, sforosso	# colore impostato a rosso
endif_color2:
##	end
#       j endif_color
endif_color:
	jal write_ansi		# assegna il colore al quadratino
## inizio seconda fase: colora il quadratino 
	addi $t0, $a2, 5	# 5 linee orizzontali
for_sfondo:        
## disegna 5 spazi colorato adiacenti su 5 righe partendo dalla riga indicata da $a2 fino
## a quella indicata da $a2 + 5
	bge $a2, $t0, endfor_sfondo	   		
	jal gotoxy                
	la $a0, spazi5	# 5 spazi colorati
	jal write	
	addi $a2, $a2, 1
	j for_sfondo        
endfor_sfondo:        	
## inizio terza fase: stampa del numero
	addi $a1, $a1, 2	# viene posizionato il cursore per stampare il numero
	addi $a2, $a2, -3
	jal gotoxy
	la $a0, colnero		# il numero è di colore nero
	jal write_ansi
	li $v0, 1
	move $a0, $a3
	syscall 		# stampa il numero
	lw $ra 4($sp)
	addi $sp $sp 4
	j $ra
 
 
#/--------------------------------------------------------------/
###############################################
# procedura stampa_tabella
# Stampa la scacchiera del gioco leggendo i valori in memoria
###############################################
stampa_tabella:
	addi $sp, $sp, -16
	sw $ra 16($sp)
	li  $t0, 0
	li $a2, 4		# ordinata di partenza per la scacchiera
	li $t2,24		# ordinata finale per la scacchiera
for_y:
	bge $a2, $t2, endfor_y  # esco se $a2 >= $t2
	li $a1, 11		# ascissa iniziale
	li $t1, 31		# ascissa finale
for_x:
	bge $a1, $t1, endfor_x	# esce se $a1 >= $t1
	lb $a3, tabella($t0)	# carica il numero da stampare sulla casella
	sw $a1, 12($sp)
	sw $t0, 8($sp)    
	sw $a2, 4($sp)	 
 
	jal quadratino
 
	lw $a2, 4($sp)
	lw $a1, 12($sp)  
	lw $t0, 8($sp)    	
 
	addi $t0, $t0, 1
	addi $a1, $a1, 5  
	j for_x
endfor_x:
	addi $a2 $a2 5
	j for_y
endfor_y:
	la $a0, colbianco
	jal write_ansi
	la $a0, sfonero
	jal write_ansi
	lw $ra, 16($sp)
	addi $sp, $sp, 16
	j $ra
 
 
 
#/--------------------------------------------------------------/
###############################################
##Procedura schermata finale
## A seconda del valore di $s1 (vettore ordinato) stampa un messaggio
###############################################
schermata_finale:
	addi $sp, $sp, -4
	sw $ra, 4($sp)
	la $a0, sforosso
## selezione colore di sfondo
test_win1:
	beqz $s1, end_test_win1
	la $a0, sfoverde
end_test_win1:
	jal write_ansi
	la $a0, spazio
	jal write
	jal clear_screen
## selezione messaggio
	li $a1, 15
	li $a2,  2
	jal gotoxy
	la $a0, perso
test_win2:
	beqz $s1, end_test_win2
	li $a1, 2
	li $a2, 2
	jal gotoxy
	la $a0, vinto
end_test_win2:
	jal write
	la $a0, info
	jal write
	lw $ra, 4($sp)
	addi $sp, $sp, 4
	jr $ra
 
 
#/--------------------------------------------------------------/
###############################################
# Procedura Schermata Iniziale
# Stampa una schermata di introduzione al gioco
###############################################
schermata_iniziale:
	addi $sp, $sp, -4
	sw $ra, 4($sp)
	la $a0, modo1
	jal write_ansi		# Modalità video 40x25
	li $a1, 10
	li $a2, 3
	jal gotoxy		
	la $a0, istruz		# Stampa le istruzioni
	jal write
	li $a1, 3
	li $a2, 16
	jal gotoxy
	la $a0, lamp
	jal write_ansi		# Stampa premi un tasto (lampeggiante)
	la $a0, press
	jal write
	la $a0, noatt
	jal write_ansi		# Ripristina gli attributi
	lw $ra, 4($sp)
	addi $sp, $sp, 4
	jr $ra
 
#/--------------------------------------------------------------/
###############################################
## procedura ordinato
## questa procedura restituisce in $s1 un valore numerico:
## 1 se la scacchiera (il vettore tebella) è ordinata
## 0 altrimenti.
###############################################
ordinato:
	li $s1, 1                	# all'inizio si suppone che il vettore sia gi… ordinato
	li $t0, 0                	# indice che scorre il vettore inizializzato a 0
	li $t1, 15               	# numero di elementi del vettore
while_ord:
	bge $t0, $t1, endw_ord  	# if indice >= numero elementi
	beqz $s1, endw_ord     		# and ordinato(tabella)
	lbu $t2, tabella($t0)    	# carico l'elemento di indice $t0 in $t2
	addi $t3, $t0, 1          	# $t3 = $t0+1
if_ordin:  
	beq $t3, $t2, increm   		# se $t2 <> $t3 allora la scacchiera non è ordinata         			     
else_ord:    				
	li $s1, 0                	# $s1 prende 0 dato che una casella Š fuori posto
increm:
	addi $t0, $t0, 1
	j while_ord                
endw_ord:
	j $ra
 
 
 
#/--------------------------------------------------------------/
###############################################
## procedura inittab
## inizializza la scacchiera con i numeri da 1 a 15, mentre
## la casella vuota è rappresentata dal numero 16.
###############################################
inittab:
	li $t0, 0                	# contatore che scandisce il vettore
	li $t1, 15               	# posizione massima dell'indice
for_init:
	bgt $t0, $t1, exit_for_init     # esco quando ho completato l'inserimento del vettore
	addi $t2, $t0, 1          	# $t2 = $t0+1
	sb $t2, tabella($t0)     	# viene memorizzato il valore di $t2 nella
					# casella corrispondente a $t0
	addi $t0, $t0, 1          	# $t0 viene incrementato di un unita'        
	j for_init              
exit_for_init:  
	li $t0, 15              	# posizione corrente casella vuota!
	sw $t0, currblank		# memorizzata in currblank
	jr $ra
 
 
 
#/--------------------------------------------------------------/
###############################################			
# Procedura Swap
# swap riceve due indici della tabella $a2, $a3 e scambia 
# il loro contenuto
###############################################
swap:
	lb $t0, tabella($a3)
	lb $t1, tabella($a2)
	beq $t0, $t1, fine_swap  	# se gli indici sono uguali non eseguo niente
	sb $t1, tabella($a3)		# scambia il contenuto dei registri
	sb $t0, tabella($a2)
	li $t2, 16
#se uno di due registri è la posizione della casella vuota
# è necessario riaggiornare la sua posizione
if_vuoto1:        
	bne $t1, $t2, else_vuoto1	# se $t1 è la casella vuota 
	sw $a3, currblank		# mette $a3 in currblank (posizione casella vuota)
	j endif_vuoto1
else_vuoto1:        
	if_vuoto2:        
		bne $t0, $t2, endif_vuoto2 # (idem)
		sw $a2, currblank	 
	     #   j endif_vuoto2
	endif_vuoto2:
endif_vuoto1:
fine_swap:
	jr $ra
 
#/--------------------------------------------------------------/
###############################################
# Procedura direzioni
# riceve in $a1 un numero che rappresenta una delle 4 direzioni possibili 
# su giù destra sinistra
# restituisce in $v1 0 se non Š possibile eseguire quelle mossa
# 1 altrimenti
###############################################
direzioni:
 
	li $v1, 1 	# Š possibile spostarsi
	lw $t2, currblank
case_dir:
	 la $t0, case_dir_of
	 sll $t1, $a1, 2
	 add $t1, $t0, $t1
	 jr $t1
case_dir_of: 	b su   		#0
	   	b giu  		#1
	   	b destra  	#2
	   	b sinistra  	#3
su:
	 li $t1, 3	# se la posizione della casella vuota è minore di 3 non è possibile 
			# spostarsi
	 bgt $t2, $t1, end_su
	 li $v1, 0
end_su:
	j end_case_dir
giu:
	li $t1, 12	# se la posizione della casella vuota è maggiore o uguale a 12
			# non è possibile eseguire questo spostamento
	blt $t2, $t1, end_giu
	li $v1, 0
end_giu:
	j end_case_dir
destra:                
       andi $t1, $t2, 3 	# currblank mod 4
       li $t2, 3
       bne $t1, $t2, end_destra	# Se la posizione della casella vuota è congrua 3 modulo 4
				# non si può andare a destra
       li $v1, 0
end_destra:
	   j end_case_dir
sinistra:
	andi $t1, $t2, 3 	#  currblank mod 4	
				# se la posizione della casella vuota è un multiplo
				# di 4 non si può andare a sinistra
	bnez $t1, end_sinistra
	li $v1, 0
end_sinistra:
#	j end_case_dir			
end_case_dir:	
	 jr $ra
#/--------------------------------------------------------------/
###############################################
# Procedura waitcommand
# Aspetta fino a che il giocatore non da
# un comando valido, e lo
# restituisce in $v0
###############################################
waitcommand:
repeat_until_valid:
 
	li $t2, 1		# Tasto valido
repeat_until_keypressed:
	lw   $t0, 0xffff0000    # receiver control
	andi $t0, $t0, 1	# least significant bit
	beqz $t0, repeat_until_keypressed     
# a questo punto è stato premuto un tasto
if_key:	
	lw   $t0, 0xffff0004    # receiver data (tasto letto)
# viene confrontato il tasto letto con i tasti predefiniti per il gioco
	li   $t1, 50		# freccia giu
	beq  $t0, $t1, press_giu
	li   $t1, 52		# freccia destra
	beq  $t0, $t1, press_sin
	li   $t1, 54		# freccia sinistra
	beq  $t0, $t1, press_des
	li   $t1, 56		# freccia su
	beq  $t0, $t1, press_su
	li   $t1, 27		# tasto esc
	beq  $t0, $t1, press_esc
tasto_errato:
	li $t2, 0		
	j endif_key
press_giu:
	li   $v0, 0
	j endif_key
press_su:
	li   $v0, 1
	j endif_key
press_sin:
	li   $v0, 2
	j endif_key
press_des:
	li   $v0, 3
	j endif_key
press_esc:
	li   $v0, 4
#        j endif_key
endif_key:
	beqz $t2, repeat_until_valid	# Attende un tasto valido	
	jr $ra
 
#/--------------------------------------------------------------/
###############################################
#Random:
# restituisce in $v0 un numero pseudocasuale fra
# 0 e ($a0 - 1) compresi
###############################################
random:		lw      $t0, Z		# Base
		lw      $t1, L		# Seme
		lw      $t2, I		# Incremento
		lw      $t3, M		# divisore
		mul     $t1, $t1, $t0	# seme:=seme*base
		add     $t1, $t1, $t2   # seme:=seme+incremento 
		divu    $t1, $t3	# seme:=abs(seme mod divisore)
		mfhi    $t1
		sw      $t1, L		# memorizza il seme
		divu    $t1, $a0	# $v0:=(seme mod $a0)
		mfhi    $v0
		j       $ra
 
 
###############################################
#initrand:
#     inizializza i numeri casuali con seed $a0
###############################################
 
initrand:		sw    $a0 , L  # Salva il seme in L
		j       $ra
 
 
#/--------------------------------------------------------------/
###############################################
## Perocedura permuta:
## Permuta le caselle della scacchiera in modo da otenere una configurazioen
## casuale.
###############################################
permuta:
	addi $sp, $sp, -12
	sw $ra, 4($sp)
	sw $s0, 8($sp)
	sw $s1, 12($sp)
	li $t0, 0
key_pressed:
	lw   $t1, 0xffff0000    # receiver control
	addiu $t0, $t0, 1	# contatore che funge da temporizzatore
	andi $t1, $t1, 1
	beqz $t1, key_pressed
 
	lw   $t1, 0xffff0004    # tasto letto
	li   $t2, 35	 	# trucchetto!!!
if_tasto_segreto:
	beq $t1, $t2,endif_tasto_segreto # se viene premuto il tasto segreto, la scacchiera
					 # non viene permutata	
else_tasto_segreto:
	move $a0, $t0
	jal initrand		# inizializza il seme con $a0
	li $s0, 64		# mischia la scacchiera 64 volte (deve essere un numero pari)
# Questo accorgimento permette di ottenere un numero di configurazioni 
# irrisolvibili limitato, in quanto ad ogni ciclo scambia un numero pari con uno dispari, quindi facendolo
# un numero pari di volte la configurazione finale è risolvibile a
# meno di eccezioni:vedi relazione.
for_random:
	beqz $s0, endfor_random
	li $a0,8 		# $a0 prende 8
	jal random		
	sll $s1, $v0 ,1	# $s1 ( primo numero casuale)=$v0 (risultato della random)*2
	jal random
	sll $a2, $v0, 1	# come sopra ( $a2 è il secondo numero casuale)
	addi $a2, $a2,1	# $a2:=$a2+1
	move $a3, $s1
	jal swap		# scambia i due indici	
	addi $s0, $s0, -1
	j for_random
endfor_random:
 
endif_tasto_segreto:	
	lw $s1, 12($sp)
	lw $s0, 8($sp)
	lw $ra, 4($sp)
	addi $sp, $sp, 12
	jr $ra
 
#/--------------------------------------------------------------/
###############################################
## Procedura gioco 
# $s1 contiene un valore che indica se la tabella e' ordinata
# currblank contiene la  posizione della casella vuota nel vettore 
# $v1 indica, a seconda della posizione della casella vuota, se lo spostamento scelto
# e' possibile
# $a1 mossa scelta: 	0 sposta la casella vuota in alto
#			1 sposta la casella vuota in basso  
#			2 sposta la casella vuota a destra
#			3 sposta la casella vuota a sinistra
# $s2 exit		# indica se la procedura deve terminare per uno dei seguenti motivi
			# La tabella è ordinata
			# il giocatore ha premuto esc
## NOTA: gli spostamenti della casella vuota non vengono gestiti direttamente dalla pressione dei tasti freecia
## ma dalla procedura waitcommnd che trasforma tali tasti ( incluso l'escape ) in una mossa valida	
###############################################
gioco:
	addi $sp, $sp, -8
	sw $s0, 4($sp)
	sw $ra, 8($sp)
	li $s0, 0 	# numero mosse
	li $s2, 0 	# exit = false
	li $s1, 0 	# tabella non ordinata
	li $s4,	1000	# numero massimo di mosse
while_:
# While (not exit) and (not ordinato) and (mosse<1000) do 
 
	bnez $s2, endwhile_		# se exit=true esce
	ble  $s4, $s0, endwhile_	# se ho esaurito le mosse esce
	bnez $s1, endwhile_		# se la tabella è ordinata esce
do_:
	la $a0, sfoblu
	jal write_ansi
	li $a1, 33	# stampa il numero di mosse
	li $a2, 4
	jal gotoxy		 
	la $a0, mosse
	jal write
	li $a1, 35
	li $a2, 5
	jal gotoxy		 
	li $v0, 1
	move $a0, $s0
	syscall
	li $a1, 0	# posiziona il cursore in un area vuota
	li $a2, 23
	jal gotoxy
 
	jal waitcommand	# attende la pressione di un comando valido
	move $a1, $v0 	# mossa 
	li $t0, 4	# mossa=uscita
if_carattere:	
	blt $a1 $t0 else_if_carattere	# se non e'stato premuto esc allora il gioco puo'continuare
	li $s2 1		# viene impostato $s2 ad 1 (uscita:=true)
	j endif_carattere	
else_if_carattere:
	jal direzioni		# valuta se è possibile la mossa contenuta in $a1
if_mossa_possibile:
	beqz $v1 endif_mossa_possibile		# Se la mossa non e'possiblie salta
else_mossa_possibile:
# calcolo della casella da scambiare
	lw $a2, currblank 	# mette in $a2 la posizione della casella vuota
	la $t0 case_swap	# indirizzo della tabella case
	sll $t1 $a1 2 		# l' indice ( la mossa ) e' moltiplicato per 4 perche' le istruzioni
				# distano di 4 bytes
	add $t1 $t1 $t0		# in $t1 sommiamo l'indirizzo della tabella con l'indice
	jr $t1			# salta all'istruzione adeguata 
case_swap:      b swap_su	# viene scambiata la casella vuota con quella in alto
		b swap_giu	# viene scambiata la casella vuota con quella in basso
		b swap_sx	# viene scambiata la casella vuota con quella a sinistra
		b swap_dx	# viene scambiata la casella vuota con quella a destra
## Calcolo indici per lo swap
swap_su:
       addi $a3 $a2 -4		
       j  end_case_swap
swap_giu:
       addi $a3 $a2 4
       j  end_case_swap
swap_sx:
       addi $a3 $a2 1
       j  end_case_swap
swap_dx:        
       addi $a3 $a2 -1
#       j  end_case_swap
end_case_swap:
	jal swap		# scambio delle caselle
 
	addi $s0, $s0, 1	# una mossa in più
 
	jal stampa_tabella
	jal ordinato		# controllo ordinamento della tabella
 
endif_mossa_possibile:
 
endif_carattere:	
	j while_
endwhile_:
	lw $s0, 4($sp)
	lw $ra, 8($sp)
	addi $sp $sp 8
	jr $ra
#/--------------------------------------------------------------/
#/--------------------------------------------------------------/
#/--------------------------------------------------------------/
 
		.globl main
main:
	jal inittab
	jal schermata_iniziale	
	jal permuta
	jal clear_screen
	jal schermo_blu	
	li $a1 13
	li $a2 1
	jal gotoxy
	la $a0 gd15
	jal write
	jal contorno
	jal stampa_tabella	
	jal gioco
	jal schermata_finale
	jal waitcommand
	jal resetscreen
 
	li $v0, 10
	syscall
 
fatal_15.txt · Ultima modifica: 2009/02/23 15:14 da fcasadei
 
Recent changes RSS feed