Skip to content

Instantly share code, notes, and snippets.

@Krymancer
Created July 4, 2020 18:17
Show Gist options
  • Save Krymancer/30e725ff54947e0c291634ec6867994d to your computer and use it in GitHub Desktop.
Save Krymancer/30e725ff54947e0c291634ec6867994d to your computer and use it in GitHub Desktop.
(defvar *jogador* 1) ;espaço do jogador
(defvar *computador* 10) ;espaço do comptador
(defun make-board ()
(list 'board 0 0 0 0 0 0 0 0 0)) ;tabuleiro
(defun convert-to-letter (v) ;funçao pra converter o input na letra
(cond ((eql v 1) "O")
((eql v 10) "X")
(t " ")))
(defun print-row (x y z) ;funcao auxiliar para uma linha do tabuleiro
(format t "~& ~A | ~A | ~A"
(convert-to-letter x)
(convert-to-letter y)
(convert-to-letter z)))
(defun print-board (board) ;funcao pra printar o tabuleiro
(format t "~%")
(print-row (nth 1 board) (nth 2 board) (nth 3 board))
(format t "~& -----------")
(print-row (nth 4 board) (nth 5 board) (nth 6 board))
(format t "~& -----------")
(print-row (nth 7 board) (nth 8 board) (nth 9 board))
(format t "~%~%"))
(defun make-move (player pos board) ;funcao responsavel por fazer a jogada
(setf (nth pos board) player)
board)
(defvar *triplets* ;variavel que mostra as linhas e diagonais para ganhar
'((1 2 3) (4 5 6) (7 8 9) ; Horizontal
(1 4 7) (2 5 8) (3 6 9) ; Vertical
(1 5 9) (3 5 7))) ; Diagonal
(defun sum-triplet (board triplet) ;soma as linhas/diagonais para ganhar
(+ (nth (first triplet) board)
(nth (second triplet) board)
(nth (third triplet) board)))
(defun compute-sums (board) ;avalia se e possivel ganhar com as linhas/diagonais
(mapcar #'(lambda (triplet)
(sum-triplet board triplet))
*triplets*))
(defun winner-p (board) ; verifica se algum jogador venceu o jogo
(let ((sums (compute-sums board)))
(or (member (* 3 *jogador*) sums)
(member (* 3 *computador*) sums))))
(defun board-full-p (board) ;verifica se o tabuleiro esta cheio/deu velha
(not (member 0 board)))
(defun read-a-legal-move (board) ;le da entrada uma jogada
(format t "~&Sua vez: ")
(let ((pos (read)))
(cond ((not (and (integerp pos)
(<= 1 pos 9)))
(format t "~&Erro, input fora de formato.")
(read-a-legal-move board))
((not (zerop (nth pos board)))
(format t "~&Espaco ja ocupado.")
(read-a-legal-move board))
(t pos))))
(defun pick-random-empty-position (board) ; metodo de jogar em um local aleatorio
(let ((pos (+ 1 (random 9))))
(if (zerop (nth pos board))
pos(pick-random-empty-position board))))
(defun find-empty-position (board squares) ;achar uma posicao vazia no tabuleiro
(find-if #'(lambda (pos)
(zerop (nth pos board)))
squares))
(defun win-or-block (board target-sum) ;verificar se tenta bloquear o jogador ou tentar ganhar
(let ((triplet (find-if
#'(lambda (trip)
(equal (sum-triplet board trip) target-sum)) ;usa a variavel da soma das linhas/diagonais para verificar vantagem
*triplets*)))
(when triplet
(find-empty-position board triplet))))
(defun random-move-strategy (board) ;usa a estrategia de colcoar num local aleatorio
(list (pick-random-empty-position board)
"Movimento aleatorio"))
(defun make-three-in-a-row (board) ;usa a estrategia de fazer 3 numa linha/diagonal
(let ((pos (win-or-block board (* 2 *computador*))))
(and pos (list pos "Tentar fazer 3 numa linha/diagonal"))))
(defun block-player-win (board) ;usa a estrategia de bloquear a vitoria do jogador
(let ((pos (win-or-block board (* 2 *jogador*))))
(and pos (list pos "Impedir vitoria do jogador"))))
(defun choose-best-move (board) ;funcao pra escolher a melhor estrategia
(or (make-three-in-a-row board)
(block-player-win board)
(random-move-strategy board)))
(defun player-move (board) ;executa a jogada do jogador
(format t "~&Sua vez: ")
(let* ((pos (read-a-legal-move board))
(new-board (make-move *jogador* pos board)))
(print-board new-board)
(cond ((winner-p new-board) (format t "~&Venceu!"))
((board-full-p new-board) (format t "~&Deu velha."))
(t (computer-move new-board)))))
(defun computer-move (board) ;executa de fato o movimento do computador
(let* ((best-move (choose-best-move board))
(pos (first best-move))
(strategy (second best-move))
(new-board (make-move *computador* pos board)))
(format t "~&Jogada do PC: ~S" pos)
(format t "~&Estrategia: ~S" strategy)
(print-board new-board)
(cond ((winner-p new-board) (format t "~&Perdeu!"))
((board-full-p new-board) (format t "~&Deu velha."))
(t (player-move new-board)))))
(defun play () ;funcao para jogar
(if (y-or-n-p "Quer fazer a primeira jogada? ")
(player-move (make-board))
(computer-move (make-board))))
(play)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment