Refactor tile printing logic and improve mine probability calculation (FINNALY WORKS)

This commit is contained in:
Afonso Clerigo Mendes de Sousa 2025-03-25 20:15:02 +00:00
parent ec320340d9
commit de5707f280
2 changed files with 156 additions and 115 deletions

BIN
bin/main

Binary file not shown.

View File

@ -2,19 +2,11 @@ section .data
tile_emply db "[ ]", 0 tile_emply db "[ ]", 0
tile_len equ $ - tile_emply tile_len equ $ - tile_emply
tile_emply_dummie db "[ ]", 0
tile_flag db "[!]", 0 tile_flag db "[!]", 0
tile_mine db "[x]", 0 tile_mine db "[x]", 0
tile_near_by1 db "[1]", 0
tile_near_by2 db "[2]", 0
tile_near_by3 db "[3]", 0
tile_near_by4 db "[4]", 0
tile_near_by5 db "[5]", 0
tile_near_by6 db "[6]", 0
tile_near_by7 db "[7]", 0
tile_near_by8 db "[8]", 0
tile_near_by9 db "[9]", 0
user_location db "[*]", 0 user_location db "[*]", 0
user_location_pos db 0 user_location_pos db 0
@ -25,6 +17,7 @@ section .data
newline db 0xA, 0 newline db 0xA, 0
newline_len equ $ - newline newline_len equ $ - newline
digit_buffer db 0
section .bss section .bss
board resb 100 board resb 100
@ -40,7 +33,7 @@ _main:
mov rcx, 100 ; Loop 100 times mov rcx, 100 ; Loop 100 times
fill_loop: fill_loop:
rdrand rax rdrand rax
and rax, 13 ; Reduce probability of mine (1 in 16 chance) and rax, 15 ; Reduce probability of mine (1 in 16 chance)
cmp rax, 1 cmp rax, 1
sete al ; Set al to 1 if rax == 1, otherwise 0 sete al ; Set al to 1 if rax == 1, otherwise 0
mov [r11 + r10], al ; Store at board[r10] mov [r11 + r10], al ; Store at board[r10]
@ -51,58 +44,65 @@ fill_loop:
xor r10, r10 ; Reset counter xor r10, r10 ; Reset counter
print_loop: print_loop:
lea r11, [rel board] ; Load address of board xor rcx , rcx ; Reset mine count
; Determine which tile to print based on board[r10] lea r11, [rel board]
lea r8, [rel tile_emply] ; Default tile movzx rax, byte [r11 + r10] ; Load board[r10]
mov r9, tile_len
; Add logic here to select tile based on board[r10] if needed
; if (user_location_x == r10) && (user_location_y == r10) { ; Print user location
; lea r8, [rel user_location] cmp r10, [rel user_location_pos]
; mov r9, user_location_len jne not_user_location
; call print_String
; }
no_user_location:
; Replace this:
; cmp r10, byte [rel user_location_pos]
; je has_user_location_pos
movzx rax, byte [rel user_location_pos]
cmp r10, rax
je has_user_location_pos
cmp byte [r11 + r10], 0
je empty_tile
cmp byte [r11 + r10], 1
je mine_tile
no_tile:
lea r8, [rel tile_emply]
jmp print_tile
empty_tile:
lea r8, [rel tile_emply]
jmp print_tile
mine_tile:
lea r8, [rel tile_mine]
jmp print_tile
has_user_location_pos:
lea r8, [rel user_location] lea r8, [rel user_location]
jmp print_tile
print_tile:
mov r9, tile_len mov r9, tile_len
call print_String call print_String
jmp next_tile
not_user_location:
; Check if the tile is a mine
cmp rax, 1
jne not_mine
; Print mine
lea r8, [rel tile_mine]
mov r9, tile_len
call print_String
jmp next_tile
not_mine:
; Check if the tile is near a mine
; int3 ; Insert a breakpoint for GDB
call count_adjacent_mines
cmp dl, 0
je print_empty
; Print number of adjacent mines properly using tile_emply.
lea rdi, [rel tile_emply_dummie] ; Load address of "[ ]"
add dl, '0' ; Convert count to ASCII
mov byte [rdi+1], dl ; Overwrite middle character with digit
mov r8, rdi
mov r9, tile_len
call print_String
jmp next_tile
print_empty:
; Print empty tile
lea r8, [rel tile_emply]
mov r9, tile_len
call print_String
jmp next_tile
next_tile:
; Check if newline is needed (every 10th element) ; Check if newline is needed (every 10th element)
cmp r10, 0
je no_newline
mov rax, r10 mov rax, r10
inc rax
xor rdx, rdx xor rdx, rdx
mov rbx, 10 ; Initialize rbx to 10 mov rbx, 10
div rbx ; Divide rax by 10 div rbx
cmp rdx, 9 ; After 0-9, print newline test rdx, rdx ; Check if remainder is 0
jne no_newline jnz no_newline ; If not, don't print newline
lea r8, [rel newline] lea r8, [rel newline]
mov r9, newline_len mov r9, newline_len
call print_String call print_String
@ -112,74 +112,115 @@ no_newline:
cmp r10, 100 cmp r10, 100
jb print_loop jb print_loop
; Print a cursor to show what tile the user is on ; Read arrow keys
; read user input, arrow keys
; if up arrow, decrement user_location_pos
; if down arrow, increment user_location_pos
; if left arrow, decrement user_location_pos
; if right arrow, increment user_location_pos
; Read user input
mov rax, 0x2000003 ; syscall: read
mov rdi, 0 ; file descriptor: stdin
lea rsi, [rel user_input] ; buffer to store input
mov rdx, 1 ; number of bytes to read
syscall
; Check the input and update user_location_pos accordingly
cmp byte [rel user_input], 0x1B ; Escape sequence
jne no_escape
; Read the next two bytes for arrow keys
mov rax, 0x2000003 ; syscall: read
mov rdi, 0 ; file descriptor: stdin
lea rsi, [rel user_input + 1] ; buffer to store input
mov rdx, 2 ; number of bytes to read
syscall
; Check for arrow keys
cmp byte [rel user_input + 1], 0x5B
jne no_arrow
cmp byte [rel user_input + 2], 0x41 ; Up arrow
je move_up
cmp byte [rel user_input + 2], 0x42 ; Down arrow
je move_down
cmp byte [rel user_input + 2], 0x43 ; Right arrow
je move_right
cmp byte [rel user_input + 2], 0x44 ; Left arrow
je move_left
no_arrow:
jmp no_user_location
move_up:
dec byte [rel user_location_pos]
jmp no_user_location
move_down:
inc byte [rel user_location_pos]
jmp no_user_location
move_right:
inc byte [rel user_location_pos]
jmp no_user_location
move_left:
dec byte [rel user_location_pos]
jmp no_user_location
no_escape:
; Exit ; Exit
mov rax, 0x2000001 mov rax, 0x2000001
xor rdi, rdi xor rdi, rdi
syscall syscall
; r8 = string
; r9 = length
print_String: print_String:
mov rax, 0x2000004 mov rax, 0x2000004
mov rdi, 1 mov rdi, 1
mov rsi, r8 mov rsi, r8
mov rdx, r9 mov rdx, r9
syscall syscall
ret ret
; r10 = current tile index
; r11 = board
; rdx = mine count
; r8 = offset
count_adjacent_mines:
xor rdx, rdx
mov r8, 0
; Check top left
mov rax, r10
sub rax, 11
cmp rax, 0
jl .skip_top_left
movzx rax, byte [r11 + rax]
cmp rax, 1
sete al
add dl, al
.skip_top_left:
; Check top
mov rax, r10
sub rax, 10
cmp rax, 0
jl .skip_top
movzx rax, byte [r11 + rax]
cmp rax, 1
sete al
add dl, al
.skip_top:
; Check top right
mov rax, r10
sub rax, 9
cmp rax, 0
jl .skip_top_right
movzx rax, byte [r11 + rax]
cmp rax, 1
sete al
add dl, al
.skip_top_right:
; Check left
mov rax, r10
sub rax, 1
cmp rax, 0
jl .skip_left
movzx rax, byte [r11 + rax]
cmp rax, 1
sete al
add dl, al
.skip_left:
; Check right
mov rax, r10
add rax, 1
cmp rax, 100
jge .skip_right
movzx rax, byte [r11 + rax]
cmp rax, 1
sete al
add dl, al
.skip_right:
; Check bottom left
mov rax, r10
add rax, 9
cmp rax, 100
jge .skip_bottom_left
movzx rax, byte [r11 + rax]
cmp rax, 1
sete al
add dl, al
.skip_bottom_left:
; Check bottom
mov rax, r10
add rax, 10
cmp rax, 100
jge .skip_bottom
movzx rax, byte [r11 + rax]
cmp rax, 1
sete al
add dl, al
.skip_bottom:
; Check bottom right
mov rax, r10
add rax, 11
cmp rax, 100
jge .skip_bottom_right
movzx rax, byte [r11 + rax]
cmp rax, 1
sete al
add dl, al
.skip_bottom_right:
ret