Advertisement
j1nja

Untitled

Feb 21st, 2022
1,716
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. %include 'io.inc'
  2.  
  3. section .data
  4.     title: db "TICTACTOE MADE BY ALEXEY", 10, 10
  5.     instruction: db "Enter the number of cell (1-9) to put X on: ", 10, 0
  6.     formatChar: db "%c", 0
  7.     formatDec: db "%d", 0
  8.     fullError: db "Cannot put X on cell . because this cell is full.", 10, 0
  9.     oobError: db "No such cell. Cells are numbered 1-9.", 10, 0
  10.     ; oob: out of bounds
  11.     win: db "You won! Restart? (y/n)", 10, 0
  12.     fail: db "You failed! Restart? (y/n)", 10, 0
  13.     tie: db "Tie! Restart? (y/n)", 10, 0
  14.     escape: db "cls", 0
  15.     boardBorder1: db "   -   -   -  ", 10, 0
  16.     boardBorder2: db " | . | . | . |", 10, 0
  17.    
  18.     board: times 9 db ' '  ; ' ', 'X', 'O'
  19.     fullErrorIsVisible: db 0    ; 0 no, 1 yes
  20.     oobErrorIsVisible: db 0    ; 0 no, 1 yes
  21.     gameStatus: db 0        ; 0 on, 1 failed, 2 won, 3 tied
  22.    
  23.  
  24.  
  25. section .bss
  26.     input: resb 1
  27.     dummy: resb 1
  28.  
  29. section .text
  30. global CMAIN
  31.  
  32. extern _ExitProcess@4
  33.  
  34. CMAIN:
  35.     mov ebp, esp; for correct debugging
  36.     nop
  37.  
  38.     ; system clear
  39.     push escape
  40.     call system
  41.     add esp, 4
  42.  
  43.     ; draw title
  44.     PRINT_STRING title
  45.  
  46.  
  47.     call drawBoard
  48.  
  49.     ; gs ?
  50.     mov al, byte [gameStatus]
  51.     cmp al, 1
  52.     jl gameIsOn
  53.     je gameFailed
  54.    
  55.     cmp al, 3
  56.     jl gameWon
  57.     jmp gameTied
  58.  
  59. ; expects char in ascii to be in eax.
  60. printChar:
  61.     ; save
  62.     push eax ; esp points to the char
  63.     push edx
  64.     push ecx
  65.     push ebx
  66.  
  67.     ; print
  68.     mov eax, 4
  69.     mov ebx, 1
  70.     sub ecx, 4
  71.     mov ecx, esp
  72.     mov edx, 1
  73.     PRINT_CHAR [ecx]
  74.  
  75.     ; restore
  76.     pop eax
  77.     pop edx
  78.     pop ecx
  79.     pop ebx
  80.     ret
  81.  
  82.    
  83.  
  84.  
  85.  
  86. drawBoard:
  87.     push eax
  88.     push ebx
  89.     push ecx
  90.     push edx
  91.     push board
  92.    
  93.     .L1:
  94.     PRINT_STRING boardBorder1
  95.  
  96.     pop edx
  97.     mov al, byte [edx]
  98.     mov ecx, boardBorder2
  99.     mov ebx, 3
  100.     call editByte
  101.  
  102.     add edx, 1
  103.     mov al, byte [edx]
  104.     mov ebx, 7
  105.     call editByte
  106.  
  107.     add edx, 1
  108.     mov al, byte [edx]
  109.     mov ebx, 11
  110.     call editByte
  111.  
  112.     add edx, 1
  113.     push edx
  114.  
  115.     PRINT_STRING boardBorder2
  116.  
  117.     pop edx
  118.     cmp edx, board+9
  119.     push edx
  120.     jne .L1
  121.  
  122.    
  123.     PRINT_STRING boardBorder1
  124.  
  125.     mov eax, 10
  126.     push eax
  127.     push formatChar
  128.     call printf
  129.        
  130.     pop edx
  131.     pop ecx
  132.     pop ebx
  133.     pop eax
  134.     mov esp, 0x61ff0c-4
  135.     ret
  136.  
  137. exit:  
  138.     call _ExitProcess@4
  139.  
  140.  
  141. gameIsOn:
  142.  
  143.     ; print fullError?
  144.     cmp byte [fullErrorIsVisible], 1
  145.     jne .skipFullErrorLogging; skip error msg
  146.  
  147.         ; edit byte
  148.         mov al, byte [input]
  149.         mov ebx, 21
  150.         mov ecx, fullError
  151.         call editByte
  152.  
  153.         ; error msg
  154.         PRINT_STRING fullError
  155.        
  156.  
  157.     .skipFullErrorLogging:
  158.  
  159.     ; print oebError?
  160.     cmp byte [oobErrorIsVisible], 1
  161.     jne .skipOobErrorLogging; skip error msg
  162.  
  163.        
  164.         PRINT_STRING oobError
  165.        
  166.  
  167.     .skipOobErrorLogging:
  168.  
  169.     ; oev = 0, fev = 0
  170.     mov byte [fullErrorIsVisible], 0
  171.     mov byte [oobErrorIsVisible], 0
  172.  
  173.     ; instruction msg
  174.     PRINT_STRING instruction
  175.  
  176.     ; input 1-9
  177.     call getChar
  178.    
  179.     ; i > 0?
  180.     cmp byte [input], '1'
  181.     jge .skipOobErrorRedirect ;no oob error
  182.  
  183.         ; oob error!
  184.         mov byte [oobErrorIsVisible], 1
  185.         jmp CMAIN
  186.  
  187.     .skipOobErrorRedirect:
  188.  
  189.     ; i < 10?
  190.     cmp byte [input], '9'
  191.     jle .skipOobErrorRedirect2 ;no oob error
  192.  
  193.         ; oob error!
  194.         mov byte [oobErrorIsVisible], 1
  195.         jmp CMAIN
  196.  
  197.     .skipOobErrorRedirect2:
  198.  
  199.  
  200.     ; board[input] = ' '?
  201.     xor eax, eax
  202.     mov al, byte [input]
  203.     sub al, '1'
  204.     mov ebx, board
  205.     add ebx, eax
  206.     mov al, byte [ebx]
  207.     cmp al, ' '
  208.     je .skipFullErrorRedirect ;no full error
  209.  
  210.         ; full error!
  211.         mov byte [fullErrorIsVisible], 1
  212.         jmp CMAIN
  213.  
  214.     .skipFullErrorRedirect:
  215.  
  216.     ; enter the X
  217.     mov byte [ebx], 'X'
  218.    
  219.     mov al, 'X'
  220.     call isGameOver
  221.     cmp ah, 0
  222.     je .isTie
  223.  
  224.         mov byte [gameStatus], 2
  225.         jmp CMAIN
  226.  
  227.     .isTie:
  228.     call areAnyMovesLeft
  229.     cmp ah, 1
  230.     je .cpuMove
  231.  
  232.         mov byte [gameStatus], 3
  233.         jmp CMAIN
  234.  
  235.     .cpuMove:
  236.     call cpuAlgorithm
  237.  
  238.     mov al, 'O'
  239.     call isGameOver
  240.     cmp ah, 0
  241.     je .isTieAgain
  242.  
  243.         mov byte [gameStatus], 1
  244.         jmp CMAIN
  245.  
  246.     .isTieAgain:
  247.     call areAnyMovesLeft
  248.     cmp ah, 1
  249.     je .notTie
  250.  
  251.         mov byte [gameStatus], 3
  252.         jmp CMAIN
  253.  
  254.     .notTie:
  255.     jmp CMAIN
  256.  
  257.  
  258. gameWon:
  259.  
  260.     PRINT_STRING win
  261.    
  262.  
  263.     call getChar
  264.  
  265.     cmp byte [input], 'y'
  266.     jne exit
  267.     mov byte [gameStatus], 0
  268.     call cleanBoard
  269.     jmp CMAIN
  270.  
  271.  
  272. gameFailed:
  273.  
  274.     PRINT_STRING fail
  275.    
  276.  
  277.     call getChar
  278.  
  279.     cmp byte [input], 'y'
  280.     jne exit
  281.     mov byte [gameStatus], 0
  282.     call cleanBoard
  283.     jmp CMAIN
  284.  
  285. gameTied:
  286.  
  287.     PRINT_STRING tie
  288.    
  289.  
  290.     call getChar
  291.  
  292.     cmp byte [input], 'y'
  293.     jne exit
  294.     mov byte [gameStatus], 0
  295.     call cleanBoard
  296.     jmp CMAIN
  297.  
  298.  
  299. getChar:
  300.     PRINT_STRING "Your choice is: "
  301.     GET_CHAR input
  302.  
  303.     cmp byte [input], 10
  304.     jne .L1
  305.     ret
  306.  
  307.     .L1:
  308.     GET_CHAR dummy
  309.  
  310.     cmp byte [dummy], 10
  311.     jne .L1
  312.     ret
  313.  
  314. ; expects base address in ecx, offset in ebx, and new val in al
  315. editByte:
  316.     push eax
  317.     push ebx
  318.     push ecx
  319.     push edx
  320.  
  321.     add ecx, ebx
  322.     mov byte [ecx], al
  323.  
  324.     pop edx
  325.     pop ecx
  326.     pop ebx
  327.     pop eax
  328.     ret
  329.  
  330. ; expects side ('X' or 'O') at al. returns 1=yes 0=no to ah.
  331. isGameOver:
  332.  
  333.     xor ah, ah
  334.     push ebx
  335.  
  336.     mov bl, byte [board+0]
  337.     cmp bl, al
  338.     jne .step2
  339.  
  340.     mov bl, byte [board+3]
  341.     cmp bl, al
  342.     jne .step2
  343.    
  344.     mov bl, byte [board+6]
  345.     cmp bl, al
  346.     jne .step2
  347.     jmp .yes
  348.  
  349.     .step2:
  350.     mov bl, byte [board+1]
  351.     cmp bl, al
  352.     jne .step3
  353.  
  354.     mov bl, byte [board+4]
  355.     cmp bl, al
  356.     jne .step3
  357.    
  358.     mov bl, byte [board+7]
  359.     cmp bl, al
  360.     jne .step3
  361.     jmp .yes
  362.  
  363.     .step3:
  364.     mov bl, byte [board+2]
  365.     cmp bl, al
  366.     jne .step4
  367.  
  368.     mov bl, byte [board+5]
  369.     cmp bl, al
  370.     jne .step4
  371.    
  372.     mov bl, byte [board+8]
  373.     cmp bl, al
  374.     jne .step4
  375.     jmp .yes
  376.  
  377.     .step4:
  378.     mov bl, byte [board+0]
  379.     cmp bl, al
  380.     jne .step5
  381.  
  382.     mov bl, byte [board+1]
  383.     cmp bl, al
  384.     jne .step5
  385.    
  386.     mov bl, byte [board+2]
  387.     cmp bl, al
  388.     jne .step5
  389.     jmp .yes
  390.  
  391.     .step5:
  392.     mov bl, byte [board+3]
  393.     cmp bl, al
  394.     jne .step6
  395.  
  396.     mov bl, byte [board+4]
  397.     cmp bl, al
  398.     jne .step6
  399.    
  400.     mov bl, byte [board+5]
  401.     cmp bl, al
  402.     jne .step6
  403.     jmp .yes
  404.  
  405.     .step6:
  406.     mov bl, byte [board+6]
  407.     cmp bl, al
  408.     jne .step7
  409.  
  410.     mov bl, byte [board+7]
  411.     cmp bl, al
  412.     jne .step7
  413.    
  414.     mov bl, byte [board+8]
  415.     cmp bl, al
  416.     jne .step7
  417.     jmp .yes
  418.  
  419.     .step7:
  420.     mov bl, byte [board+0]
  421.     cmp bl, al
  422.     jne .step8
  423.  
  424.     mov bl, byte [board+4]
  425.     cmp bl, al
  426.     jne .step8
  427.    
  428.     mov bl, byte [board+8]
  429.     cmp bl, al
  430.     jne .step8
  431.     jmp .yes
  432.  
  433.     .step8:
  434.     mov bl, byte [board+2]
  435.     cmp bl, al
  436.     jne .no
  437.  
  438.     mov bl, byte [board+4]
  439.     cmp bl, al
  440.     jne .no
  441.    
  442.     mov bl, byte [board+6]
  443.     cmp bl, al
  444.     jne .no
  445.     jmp .yes
  446.  
  447.     .no:
  448.     mov ah, 0
  449.     pop ebx
  450.     ret
  451.  
  452.     .yes:
  453.     mov ah, 1
  454.     pop ebx
  455.     ret
  456.  
  457.  
  458. cleanBoard:
  459.     push eax
  460.     mov eax, 0
  461.  
  462.     .loop:
  463.     mov byte [board+eax], ' '
  464.     inc eax
  465.     cmp eax, 9
  466.     jne .loop
  467.  
  468.     pop eax
  469.     ret
  470.  
  471. ; returns 1=yes 0=no to ah.
  472. areAnyMovesLeft:
  473.     mov eax, board
  474.  
  475.     .loop:
  476.     cmp byte [eax], ' '
  477.     je .yes
  478.     inc eax
  479.  
  480.     cmp eax, board+9
  481.     jne .loop
  482.     jmp .no
  483.  
  484.     .no:
  485.     mov ah, 0
  486.     ret
  487.  
  488.     .yes:
  489.     mov ah, 1
  490.     ret
  491.    
  492.  
  493.  
  494. cpuAlgorithm:
  495.  
  496.     mov ecx, 0
  497.  
  498.     .loop1:
  499.  
  500.     cmp ecx, 9
  501.     je .noWinningPositions
  502.  
  503.     cmp byte [board+ecx], ' '
  504.     je .cellIsEmpty
  505.     jne .cellIsFull
  506.  
  507.     .cellIsFull:
  508.     inc ecx
  509.     jmp .loop1
  510.  
  511.     .cellIsEmpty:
  512.     mov byte [board+ecx], 'O'
  513.     mov al, 'O'
  514.     call isGameOver
  515.     cmp ah, 1
  516.     jne .notWinningPosition
  517.     ret
  518.  
  519.     .notWinningPosition:
  520.     mov byte [board+ecx], ' '
  521.     inc ecx
  522.  
  523.     jmp .loop1
  524.  
  525.     .noWinningPositions:
  526.  
  527.     mov ecx, 0
  528.    
  529.     .loop2:
  530.     cmp ecx, 9
  531.     je .moveRandomly
  532.  
  533.     cmp byte [board+ecx], ' '
  534.     je .cellIsEmpty2
  535.     inc ecx
  536.     jmp .loop2
  537.  
  538.     .cellIsEmpty2:
  539.     mov byte [board+ecx], 'X'
  540.     mov al, 'X'
  541.     call isGameOver
  542.     cmp ah, 1
  543.     je .preventWin
  544.    
  545.     mov byte [board+ecx], ' '
  546.     inc ecx
  547.     jmp .loop2
  548.  
  549.     .preventWin:
  550.     mov byte [board+ecx], 'O'
  551.     ret
  552.    
  553.     .moveRandomly:
  554.  
  555.     ; srand( time(0) )
  556.     push dword 0
  557.     call time
  558.     add esp, 4
  559.     push eax
  560.     call srand
  561.     add esp, 4
  562.  
  563.     .loop3:
  564.  
  565.     ; offset = rand() / ( 2^32 / 9 )
  566.     call rand
  567.     mov ecx, 9
  568.     div ecx
  569.  
  570.     cmp byte [board+edx], ' '
  571.     jne .loop3
  572.  
  573.     mov byte [board+edx], 'O'
  574.     ret
  575.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement