5. (Opcional) Jogada da IA

Recursos do Minicurso

Vamos fazer o computador pensar

Antes, usamos um objeto Random para gerar uma jogada aleatória para o computador. Por isso, o computador não era muito difícil de vencer.

Neste exercício, queremos aumentar a dificuldade do jogo fazendo o computador tomar decisões melhores.

Vamos fazer isso adicionando inteligência artificial ao nosso programa usando o algoritmo Minimax (um procedimento bem definido que permite aos computadores resolver problemas).

Algoritmo Minimax

Minimax é um algoritmo usado em jogos de dois jogadores para tomar decisões ótimas para um jogador.

Como o Minimax funciona no Jogo da Velha?

Veja o exemplo abaixo:

exemplo de opções para vencer o jogo da velha como descrito no texto acima.
  1. Na primeira linha, consideramos as 3 jogadas possíveis para o computador "O", que é o maximizador.

  2. Examinamos todos os estados do jogo até que todas as jogadas terminem com vitória do computador, vitória do jogador ou empate. Depois damos a pontuação correspondente.

    Por exemplo, no segundo tabuleiro da linha 1, o computador vence colocando "O" na posição 8. Esse estado recebe a pontuação 1 * (número de espaços livres no tabuleiro + 1) = 1 * (2+1) = 3.

  3. Nos estados que não têm vencedor ou empate, escolhemos a menor pontuação nas rodadas de minimização (quando "X" joga) e a maior pontuação nas rodadas de maximização (quando "O" joga).

  4. Se você seguir as rodadas de maximização/minimização na imagem acima, verá que a jogada ótima para o computador é colocar "O" na posição 8, permitindo que ele vença com 1 jogada a partir do tabuleiro inicial.

Estrutura do Código

Na atividade-3, você escreveu o método int getComputerMove(String[] curBoard) para gerar uma jogada aleatória para o computador. Agora, vamos escrever outro método chamado getComputerMoveAI(String[] curBoard) que retorna a jogada ótima para o computador chamando o método int minimax(String[] curBoard, boolean isMaximizing).

int getComputerMove(String[] curBoard){
    // 1. este método chama minimax() para todas as jogadas possíveis do computador
    // 2. pega o maior valor entre todas elas
    // 3. retorna a jogada ótima
}
int minimax(String[] curBoard, boolean isMaximizing){
    // 1. Na rodada de maximização, chama minimax() para todas as jogadas possíveis do computador, "O", retorna a maior pontuação
    // 2. Na rodada de minimização, chama minimax() para todas as jogadas possíveis do jogador, "X", retorna a menor pontuação
}

  • O método minimax() é uma função recursiva, ou seja, ela chama a si mesma dentro da sua própria implementação.
  • No nosso método, minimax() chama a si mesma com diferentes tabuleiros colocando "X" ou "O" em cada espaço livre. E, o método escolhe o maior ou menor valor dependendo se é uma rodada de maximização ou minimização.

Escreva o Método getComputerMoveAI()

  1. Para cada espaço livre no tabuleiro, coloque "O" naquele espaço e obtenha a pontuação desse tabuleiro chamando minimax().

  • Lembre-se de passar false como segundo argumento, pois será a vez do minimizador.
  • Você deve voltar o espaço para " " depois de obter a pontuação, assim mantém o estado original do tabuleiro para a próxima rodada.

  1. Guarde a maior pontuação e a posição correspondente do tabuleiro em cada rodada. Retorne a posição com a maior pontuação.

  • Tenha uma variável chamada bestScore que guarda a melhor pontuação atual e comece com o valor Integer.MIN_VALUE (menor valor possível de um inteiro).
  • Isso é útil para encontrar o maior valor em uma estrutura de dados. Por exemplo:
public int getLargestNum() {
    // o código abaixo encontra o maior valor no array "nums"
    int[] nums = {3, 5, -2, 10};
    int largestNum = Integer.MIN_VALUE;
    for(int i = 0; i < nums.length; i++){
        if(nums[i] > largestNum){
            largestNum = nums[i];
        }
    }
    return largestNum;
}

Escreva o Método minimax()

Como discutimos acima, o método minimax() tem o cabeçalho int minimax(String[] curBoard, boolean isMaximizing).

  1. Chame getWinner() no tabuleiro para verificar se há um vencedor. Se sim, retorne a pontuação correspondente.

    (Pontuação: computador vence (1 * número de espaços livres no tabuleiro + 1), jogador vence (-1 * número de espaços livres no tabuleiro + 1), empate (0)).

  2. Obtenha a Pontuação Minimax

  1. Retorne a Maior Pontuação

Teste seus métodos

Copie e cole seus dois métodos abaixo do main().

Clique em Executar para testar seus métodos. Nós fornecemos um teste do exemplo da imagem acima.

Você pode testar diferentes tabuleiros para ver se o resultado está correto. Abrir no Replit

Lembre-se de testar seus métodos!

Atualize o Programa

Depois de testar os métodos, troque todas as chamadas do método getComputerMove() por getComputerMoveAI() no seu programa de Jogo da Velha.

Vai ficar muito mais difícil vencer o computador agora😀!


Você conseguiu!
Minicurso concluído