Skip to content

Instantly share code, notes, and snippets.

@willianrschuck
Last active March 11, 2025 01:11
Show Gist options
  • Save willianrschuck/083c141a0e129a336e63c5c52c094785 to your computer and use it in GitHub Desktop.
Save willianrschuck/083c141a0e129a336e63c5c52c094785 to your computer and use it in GitHub Desktop.
Jogo de Damas Simplificado
# ------- 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