Created
July 4, 2020 18:17
-
-
Save Krymancer/30e725ff54947e0c291634ec6867994d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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