tic-tac-toe dne
This commit is contained in:
307
game.s
307
game.s
@@ -1,18 +1,315 @@
|
||||
; TODO out of moves check
|
||||
|
||||
global _start
|
||||
|
||||
section .text
|
||||
|
||||
_start:
|
||||
checkVictory:
|
||||
mov rax, 0
|
||||
|
||||
mov cl, [fieldBuffer + 12]
|
||||
and cl, [fieldBuffer + 14]
|
||||
and cl, [fieldBuffer + 16]
|
||||
cmp cl, dil
|
||||
je .returnTrue
|
||||
|
||||
mov cl, [fieldBuffer + 22]
|
||||
and cl, [fieldBuffer + 24]
|
||||
and cl, [fieldBuffer + 26]
|
||||
cmp cl, dil
|
||||
je .returnTrue
|
||||
|
||||
mov cl, [fieldBuffer + 32]
|
||||
and cl, [fieldBuffer + 34]
|
||||
and cl, [fieldBuffer + 36]
|
||||
cmp cl, dil
|
||||
je .returnTrue
|
||||
|
||||
mov cl, [fieldBuffer + 12]
|
||||
and cl, [fieldBuffer + 22]
|
||||
and cl, [fieldBuffer + 32]
|
||||
cmp cl, dil
|
||||
je .returnTrue
|
||||
|
||||
mov cl, [fieldBuffer + 14]
|
||||
and cl, [fieldBuffer + 24]
|
||||
and cl, [fieldBuffer + 34]
|
||||
cmp cl, dil
|
||||
je .returnTrue
|
||||
|
||||
mov cl, [fieldBuffer + 16]
|
||||
and cl, [fieldBuffer + 26]
|
||||
and cl, [fieldBuffer + 36]
|
||||
cmp cl, dil
|
||||
je .returnTrue
|
||||
|
||||
mov cl, [fieldBuffer + 12]
|
||||
and cl, [fieldBuffer + 24]
|
||||
and cl, [fieldBuffer + 36]
|
||||
cmp cl, dil
|
||||
je .returnTrue
|
||||
|
||||
mov cl, [fieldBuffer + 16]
|
||||
and cl, [fieldBuffer + 24]
|
||||
and cl, [fieldBuffer + 32]
|
||||
cmp cl, dil
|
||||
je .returnTrue
|
||||
|
||||
mov rax, 0
|
||||
ret
|
||||
.returnTrue:
|
||||
mov rax, 1
|
||||
ret
|
||||
|
||||
|
||||
makeAIMove:
|
||||
rdtsc
|
||||
mov rbx, rax
|
||||
.loop:
|
||||
; RAND from wiki https://en.wikipedia.org/wiki/Linear_congruential_generator. Numerical Recipes ranqd1, Chapter 7.1, §An Even Quicker Generator, Eq. 7.1.6 parameters from Knuth and H. W. Lewis
|
||||
mov rdx, 1664525
|
||||
mul rdx
|
||||
add rax, 1013904223
|
||||
mov rbx, rax
|
||||
|
||||
; clamping to 1-3 range and moving to rdi
|
||||
mov rsi, 3
|
||||
mov rax, 0
|
||||
mov ah, bh
|
||||
mov dx, 0
|
||||
div si ;TODO for some reason div sil causes division by zero
|
||||
inc dx
|
||||
mov di, dx
|
||||
shl di, 8
|
||||
mov rax, 0
|
||||
mov ah, bl
|
||||
mov dx, 0
|
||||
div si
|
||||
inc dx
|
||||
mov dil, dl
|
||||
mov rsi, 'o'
|
||||
call placeChar
|
||||
cmp rax, 0
|
||||
je .return
|
||||
mov rax, rbx
|
||||
jmp .loop
|
||||
|
||||
.return:
|
||||
ret
|
||||
|
||||
drawField:
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, helloThere ; str
|
||||
mov rdx, helloThereLen ; size
|
||||
mov rsi, fieldBuffer ; str
|
||||
mov rdx, fieldBufferLen ; size
|
||||
syscall ;
|
||||
ret
|
||||
|
||||
|
||||
placeChar:
|
||||
;computing pos in string
|
||||
mov dx, di
|
||||
|
||||
mov rcx, 0
|
||||
; cl = dh * 10
|
||||
mov cl, dh
|
||||
shl cl, 3
|
||||
add cl, dh
|
||||
add cl, dh
|
||||
|
||||
; cl += dl * 2
|
||||
shl dl, 1
|
||||
add cl, dl
|
||||
|
||||
;checking if it was occupied char to the string
|
||||
mov rax, 0
|
||||
mov byte al, [fieldBuffer + rcx]
|
||||
sub al, ' '
|
||||
jne .return
|
||||
;placing char to the string
|
||||
mov byte [fieldBuffer + rcx], sil
|
||||
.return:
|
||||
ret
|
||||
|
||||
|
||||
readXY:
|
||||
; clearing input buffer
|
||||
mov dword [userInputBuffer], 0
|
||||
|
||||
mov rax, 0 ; sys_read
|
||||
mov rdi, 0 ; in
|
||||
mov rsi, userInputBuffer ; str
|
||||
mov rdx, 256 ; size
|
||||
syscall ;
|
||||
|
||||
; only accept strings with length of 4 (reading more to skip some invalid inputs)
|
||||
cmp rax, 4
|
||||
jne .return
|
||||
|
||||
mov ax, 0
|
||||
cmp byte [userInputBuffer+1], ' ' ; second should be whitespace
|
||||
jne .return
|
||||
cmp byte [userInputBuffer+3], 0xA ; fourth should be \n
|
||||
jne .return
|
||||
|
||||
mov al, [userInputBuffer] ; x
|
||||
sub al, '0'
|
||||
mov ah, [userInputBuffer + 2] ; y
|
||||
sub ah, '0'
|
||||
.return:
|
||||
ret
|
||||
|
||||
_start:
|
||||
; call drawField
|
||||
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, greetingsMessage ; str
|
||||
mov rdx, greetingsMessageLen ; size
|
||||
syscall ;
|
||||
|
||||
call drawField
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, readInputsMessage ; str
|
||||
mov rdx, readInputsMessageLen ; size
|
||||
syscall ;
|
||||
|
||||
.loop:
|
||||
;reading input
|
||||
call readXY
|
||||
|
||||
;reading check x,y range
|
||||
cmp al, 1
|
||||
jl .printInputError
|
||||
cmp al, 3
|
||||
jg .printInputError
|
||||
cmp ah, 1
|
||||
jl .printInputError
|
||||
cmp ah, 3
|
||||
jg .printInputError
|
||||
|
||||
mov rdi, rax ; passing xy to placeChar function
|
||||
mov sil, 'x' ; passing char to placeChar function
|
||||
call placeChar
|
||||
|
||||
; failed to place a char
|
||||
jne .printOccupiedError
|
||||
|
||||
;check win condition
|
||||
mov rdi, 'x'
|
||||
call checkVictory
|
||||
cmp rax, 0
|
||||
jne .printYouWon
|
||||
|
||||
;drawing field again
|
||||
call drawField
|
||||
|
||||
;ai thinking...
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, aiThinkingMessage ; str
|
||||
mov rdx, aiThinkingMessageLen ; size
|
||||
syscall ;
|
||||
|
||||
mov rbx, 10
|
||||
.thinkingReallyHardLoop:
|
||||
mov rax, 1000000000
|
||||
.thinkingReallyHardInnerLoop:
|
||||
dec rax
|
||||
jne .thinkingReallyHardInnerLoop
|
||||
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, aiThinkingDotMessage ; str
|
||||
mov rdx, aiThinkingDotMessageLen ; size
|
||||
syscall ;
|
||||
dec rbx
|
||||
jne .thinkingReallyHardLoop
|
||||
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, endlnMessage ; str
|
||||
mov rdx, endlnMessageLen ; size
|
||||
syscall ;
|
||||
|
||||
call makeAIMove
|
||||
call drawField
|
||||
mov rdi, 'o'
|
||||
call checkVictory
|
||||
cmp rax, 0
|
||||
jne .printYouLost
|
||||
|
||||
;printing input message again
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, readInputsMessage ; str
|
||||
mov rdx, readInputsMessageLen ; size
|
||||
syscall ;
|
||||
|
||||
jmp .loop
|
||||
|
||||
.printInputError:
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, wrongValuesMessage ; str
|
||||
mov rdx, wrongValuesMessageLen ; size
|
||||
syscall ;
|
||||
jmp .loop
|
||||
.printOccupiedError:
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, occupiedMessage ; str
|
||||
mov rdx, occupiedMessageLen ; size
|
||||
syscall ;
|
||||
jmp .loop
|
||||
|
||||
|
||||
.printYouWon:
|
||||
call drawField
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, youWonMessage ; str
|
||||
mov rdx, youWonMessageLen ; size
|
||||
syscall ;
|
||||
jmp .exit
|
||||
|
||||
.printYouLost:
|
||||
call drawField
|
||||
mov rax, 1 ; sys_write
|
||||
mov rdi, 1 ; out
|
||||
mov rsi, youLostMessage ; str
|
||||
mov rdx, youLostMessageLen ; size
|
||||
syscall ;
|
||||
|
||||
.exit:
|
||||
; exiting program
|
||||
mov rax, 60 ; sys_exit
|
||||
mov rdi, 0 ; code
|
||||
syscall ;
|
||||
|
||||
section .rodata
|
||||
helloThere: db "Hello there ;)", 0xA, "General Kenobi!!!", 0xA
|
||||
helloThereLen: equ $ - helloThere
|
||||
greetingsMessage: db "Welcome to tic-tac-toe!", 0xA
|
||||
greetingsMessageLen: equ $ - greetingsMessage
|
||||
readInputsMessage: db "Type [x y] to place a cross:", 0xA
|
||||
readInputsMessageLen: equ $ - readInputsMessage
|
||||
wrongValuesMessage: db "Unexpected x or y value. Could be 1,2 or 3 in [x y] format. Try again:", 0xA
|
||||
wrongValuesMessageLen: equ $ - wrongValuesMessage
|
||||
occupiedMessage: db "Cell is already occupied. Try again:", 0xA
|
||||
occupiedMessageLen: equ $ - occupiedMessage
|
||||
youWonMessage: db "YOU WON!!!", 0xA
|
||||
youWonMessageLen: equ $ - youWonMessage
|
||||
youLostMessage: db "you lost T_T", 0xA
|
||||
youLostMessageLen: equ $ - youLostMessage
|
||||
aiThinkingMessage: db "AI thinking"
|
||||
aiThinkingMessageLen: equ $ - aiThinkingMessage
|
||||
aiThinkingDotMessage: db "."
|
||||
aiThinkingDotMessageLen: equ $ - aiThinkingDotMessage
|
||||
endlnMessage: db 0xA
|
||||
endlnMessageLen: equ $ - endlnMessage
|
||||
|
||||
section .bss
|
||||
userInputBuffer resb 256
|
||||
section .data
|
||||
fieldBuffer: db "#########", 0xA, "# #", 0xA, "# #", 0xA, "# #", 0xA, "#########", 0xA
|
||||
fieldBufferLen: equ $ - fieldBuffer
|
||||
Reference in New Issue
Block a user