Last active
March 11, 2025 01:11
-
-
Save willianrschuck/083c141a0e129a336e63c5c52c094785 to your computer and use it in GitHub Desktop.
Jogo de Damas Simplificado
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ------- Jogo de Damas em Assembly ------- | |
# Curso: Bacharelado em Ciência da Computação | |
# Disciplina: Arquitetura de Computadores II | |
# Autores: Willian R. Schuck, Kimberly Geremia | |
.data | |
tabuleiro: .space 64*4 | |
atual: .space 4 | |
anterior: .space 4 | |
brancasJogam:.asciiz" Brancas Jogam\n" | |
negrasJogam: .asciiz" Negras Jogam\n" | |
linhaTop: .asciiz" 1 2 3 4 5 6 7 8\n" | |
linha: .asciiz" -+---+---+---+---+---+---+---+---+\n" | |
limpa: .asciiz"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" | |
barra: .asciiz" |" | |
espaco: .asciiz" " | |
nl: .asciiz"\n" | |
charLateral: .byte 'A' | |
vetCodigos: .byte ' ', 'b', 'n', 'B', 'N' | |
.text | |
# Essa função coloca todas as peças nas posições iniciais | |
resetaTabuleiro: | |
la $t9, tabuleiro # o registrador t9 aponta para a primeira pos. do tabuleiro | |
li $t0, 0 # t0 serve como contador para percorrer as posições do tabuleiro | |
# como não há distinção de valores, o vetor pode ser percorrido com apenas uma | |
# variável de apoio (t0) | |
loopZera: | |
bge $t0, 64, fimLoopZera # se t0 >= 64 finaliza o loop | |
addi $t0, $t0, 1 | |
sw $zero, ($t9) # armazena no endereço t9 o valor 0 (registrador zero) | |
addi $t9, $t9, 4 # incrementa t9 em 4, que corresponde ao tamanho do dado | |
j loopZera | |
fimLoopZera: | |
# para inserir as peças é preciso saber se a posição está ou não na diagonal | |
# e por isso é preciso de duas variaveis de controle | |
la $t9, tabuleiro | |
li $t0, 0 # t0 serve de variavel de apoio para percorrer as linhas do tabuleiro | |
loopInsereBrancasI: | |
bge $t0, 3, fimLoopInsereBrancasI # percorre apenas as linhas 0, 1 e 2 | |
li $t1, 0 # variavel de controle do segundo laço, é zerada a cada iteração de t0 | |
loopInsereBrancasJ: | |
bge $t1, 8, fimLoopInsereBrancasJ # | |
# somando t0 e t1 (linha e coluna) e calculndo o resto da divisão por 2 | |
# podemos determinar se essa posição está ou não na diagonal desejada | |
# se o resto for 0 a posição não pertence a diagonal de peças | |
# caso contrário pertence | |
add $t2, $t0, $t1 | |
rem $t2, $t2, 2 | |
# como 0 corresponde a um lugar vazio e 1 corresponde a peça Branca | |
# basta armazenar o valor em t9 que é a posição que está sendo manipulada | |
sw $t2, ($t9) | |
# as posições são incrementadas SEMPRE de 4 em 4, portanto não é necessário | |
# efetuar os cálculos a partir de t9 = tabuleiro, ao invés disso apenas se incrementa t9 | |
add $t9, $t9, 4 | |
addi $t1, $t1, 1 | |
j loopInsereBrancasJ | |
fimLoopInsereBrancasJ: | |
addi $t0, $t0, 1 | |
j loopInsereBrancasI | |
fimLoopInsereBrancasI: | |
la $t9, tabuleiro | |
add $t9, $t9, 160 | |
li $t0, 5 | |
loopInsereNegrasI: | |
bge $t0, 8, fimLoopInsereNegrasI # percorre as linhas 5, 6 e 7 | |
li $t1, 0 | |
loopInsereNegrasJ: | |
bge $t1, 8, fimLoopInsereNegrasJ | |
add $t2, $t0, $t1 | |
rem $t2, $t2, 2 | |
mul $t2, $t2, 2 | |
sw $t2, ($t9) | |
add $t9, $t9, 4 | |
addi $t1, $t1, 1 | |
j loopInsereNegrasJ | |
fimLoopInsereNegrasJ: | |
addi $t0, $t0, 1 | |
j loopInsereNegrasI | |
fimLoopInsereNegrasI: | |
la $t0, atual | |
la $t1, anterior | |
li $t2, 1 | |
sw $t2, ($t0) | |
li $t2, 2 | |
sw $t2, ($t1) | |
jr $ra | |
mostrar: | |
la $a0, limpa | |
li $v0, 4 | |
syscall | |
la $t0, atual | |
lw $t0, ($t0) | |
sub $t0, $t0, 1 | |
li $v0, 4 | |
beqz $t0, printBrancas | |
la $a0, negrasJogam | |
j fimPrint | |
printBrancas: | |
la $a0, brancasJogam | |
fimPrint: | |
syscall | |
li $t0, 0 # i | |
li $t1, 0 # j | |
la $a0, linhaTop | |
li $v0, 4 | |
syscall | |
loopMostraI: | |
bge $t0, 8, fimLoopMostraI | |
li $t1, 0 | |
la $a0, linha | |
li $v0, 4 | |
syscall | |
# Mostrar letra da linha | |
lb $a0, charLateral | |
add $a0, $a0, $t0 | |
li $v0, 11 | |
syscall | |
# Imprime o espaçador no console | |
la $a0, barra | |
li $v0, 4 | |
syscall | |
loopMostraJ: | |
bge $t1, 8, fimLoopMostraJ | |
la $t9, tabuleiro | |
# Chega até o endereço da posição | |
mul $t2, $t0, 32 | |
mul $t3, $t1, 4 | |
add $t2, $t2, $t3 | |
add $t9, $t9, $t2 | |
lw $t9, ($t9) | |
la $t8, vetCodigos | |
add $t8, $t8, $t9 | |
# Imprime um espaco | |
li $v0, 11 | |
lb $a0, vetCodigos | |
syscall | |
# Imprime o valor | |
lb $a0, ($t8) | |
li $v0, 11 | |
syscall | |
li $v0, 4 | |
la $a0, barra | |
syscall | |
addi $t1, $t1, 1 | |
j loopMostraJ | |
fimLoopMostraJ: | |
li $v0, 4 | |
la $a0, nl | |
syscall | |
addi $t0, $t0, 1 | |
j loopMostraI | |
fimLoopMostraI: | |
la $a0, linha | |
li $v0, 4 | |
syscall | |
jr $ra | |
# Na função mover precisamos armazenar quatro valores, são eles: | |
# - posição da peça origem | |
# - posição destino | |
# - [!] indices do laço for (t0 e t1) | |
# É também necessário verificar o tipo de movimento. | |
# se a posição de destino está vazia ou tem um valor igual ao da posição de | |
# origem, ocorre uma permutação | |
# caso contrário, a posição origem recebe o valor nulo e a posição destino | |
# recebe a peça | |
mover: | |
li $v0, 12 | |
syscall | |
sub $v0, $v0, 65 | |
move $s1, $v0 | |
li $v0, 5 | |
syscall | |
sub $v0, $v0, 1 | |
move $s0, $v0 | |
li $v0, 12 | |
syscall | |
sub $v0, $v0, 65 | |
move $s3, $v0 | |
# [!] Registrador s8 pode não estar presente em todos os simuladores | |
move $s8, $s3 # Copia o valor da linha para uso posterior na função verificaDama | |
li $v0, 5 | |
syscall | |
sub $v0, $v0, 1 | |
move $s2, $v0 | |
# -- [ Origem ] -- | |
mul $t0, $s1, 32 | |
mul $t1, $s0, 4 | |
add $t0, $t0, $t1 | |
la $t7, tabuleiro | |
add $t7, $t7, $t0 | |
lw $s6, ($t7) # s6 = valor origem | |
# t7 continua com o edereço de origem | |
# -- [ Destino ] -- | |
mul $t0, $s3, 32 | |
mul $t1, $s2, 4 | |
add $t0, $t0, $t1 | |
la $t8, tabuleiro | |
add $t8, $t8, $t0 | |
lw $s7, ($t8) # s7 = valor destino | |
# t8 ainda armazena o edereço de destino | |
# ---- [!] Importante ---- | |
# Registradores s1 e s0 armazenam a posição origem | |
# Registradores s3 e s2 armazenam a posição destino | |
# Registrador s6 armazena o VALOR na posição origem | |
# Registrador s7 armazena o VALOR na posição destino | |
# Registradores t7 e t8 armazenam os edereços de memoria das posições origem e destino, respectivamente | |
# previne que um espaço vazio seja jogado como peça | |
beqz $s6, fimMover | |
# previne que a peça do oponente seja jogada | |
la $t0, atual | |
lw $t0, ($t0) | |
rem $t2, $s6, $t0 | |
bnez $t2, fimMover | |
# se as peças são iguais nao come | |
beq $s6, $s7, fimMover | |
# t2 = deslocamento linha | |
sub $t2, $s3, $s1 | |
# t3 = deslocamento coluna | |
sub $t3, $s2, $s0 | |
# Verifica se o destino está na diagonal | |
# Calcula o módulo de t2 e t3 par ser possível comparar os dois valores com a isntrução bne | |
bltz $t2, dlMenor | |
move $t0, $t2 | |
j fimDl | |
dlMenor: | |
sub $t0, $zero, $t2 | |
fimDl: | |
bltz $t3, dcMenor | |
move $t1, $t3 | |
j fimDc | |
dcMenor: | |
sub $t1, $zero, $t3 | |
fimDc: | |
# Verifica se o deslocamento horizontal e vertical é igual, se sim é porque o deslocamento é diagonal | |
bne $t0, $t1, fimMover | |
# Impede que a peça se mova mais que uma casa (ou se "mova" para a mesma casa) | |
bne $t0, 1, fimMover | |
bne $t1, 1, fimMover | |
# Verifica se nessa jogada o jogador vai comer uma peça | |
# se sim, não é necessário verificar a direção da jogada | |
bnez $s7, fimValidaDesl | |
bgt $s6, 2, fimValidaDesl | |
# Verifica deslocamento pelo tipo da peça | |
la $t0, atual | |
lw $t0, ($t0) | |
rem $t0, $t0, 2 | |
beqz $t0, validaDeslPreta | |
blez $t2, fimMover | |
j fimValidaDesl | |
validaDeslPreta: | |
bgez $t2, fimMover | |
fimValidaDesl: | |
# se o destino for um espaço em branco, ocorre apenas o movimento (nao come nenhuma peça) | |
beqz $s7, naoCome | |
# s4 e s5 armazenam a posição destino da peça que come | |
add $s4, $t2, $s3 | |
add $s5, $t3, $s2 | |
bge $s4, 8, fimMover | |
bge $s5, 8, fimMover | |
blt $s4, 0, fimMover | |
blt $s5, 0, fimMover | |
move $s8, $s4 | |
mul $t0, $s4, 32 | |
mul $t1, $s5, 4 | |
add $t0, $t0, $t1 | |
la $t1, tabuleiro | |
add $t1, $t1, $t0 | |
lw $t9, ($t1) | |
# t9 = valor destino | |
# t1 = endereço destino | |
# Verifica se a peça pode se tornar uma dama | |
# Se a posição de destino não estiver vazia, não de pode comer a peça | |
bnez $t9, fimMover | |
# Armazena o endereço de destino em t8 | |
move $t9, $t1 | |
sw $s6, ($t9) | |
sw $zero, ($t7) | |
sw $zero, ($t8) | |
# anterior = atual | |
la $t0, atual | |
la $t1, anterior | |
lw $t2, ($t0) | |
sw $t2, ($t1) | |
j verificaDama | |
naoCome: | |
move $t9, $t8 | |
sw $s6, ($t9) | |
sw $zero, ($t7) | |
# anterior = atual | |
la $t0, atual | |
la $t1, anterior | |
lw $t2, ($t0) | |
sw $t2, ($t1) | |
# muda atual | |
beq $t2, 2, setarBranca | |
li $t2, 2 | |
sw $t2, ($t0) | |
j verificaDama | |
setarBranca: | |
li $t2, 1 | |
sw $t2, ($t0) | |
li $s5, 15 | |
li $s4, 15 | |
verificaDama: | |
la $t0, atual | |
lw $t0, ($t0) | |
rem $t0, $t0, 2 | |
beqz $t0, damaNegra | |
bne $s8, 7, fimMover | |
li $t0, 3 | |
sw $t0, ($t9) | |
j fimMover | |
damaNegra: | |
bnez $s8, fimMover | |
li $t0, 4 | |
sw $t0, ($t9) | |
fimMover: | |
jr $ra | |
main: | |
jal resetaTabuleiro | |
jogar: | |
jal mostrar | |
jal mover | |
j jogar |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment