Last active
February 25, 2023 04:35
-
-
Save londarks/45ab5287320b0faa957c36e9be7b72b3 to your computer and use it in GitHub Desktop.
tic-tac-toe with AI
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
import tensorflow as tf | |
import numpy as np | |
# Definindo o modelo da rede neural | |
model = tf.keras.Sequential([ | |
tf.keras.layers.Dense(9, activation='relu', input_shape=(9,)), | |
tf.keras.layers.Dense(9, activation='relu'), | |
tf.keras.layers.Dense(1, activation='sigmoid') | |
]) | |
# Compilando o modelo | |
model.compile(optimizer='adam', | |
loss='binary_crossentropy', | |
metrics=['accuracy']) | |
# Definindo as posições iniciais do tabuleiro | |
initial_board = np.zeros((3, 3), dtype=np.int8) | |
# Função para obter os próximos movimentos possíveis | |
def get_next_moves(board): | |
empty_cells = np.argwhere(board == 0) | |
next_moves = [tuple(cell) for cell in empty_cells] | |
return next_moves | |
# Função para converter o tabuleiro em uma entrada para o modelo | |
def board_to_input(board): | |
input_board = np.zeros((1, 9), dtype=np.int8) | |
input_board[0, board.ravel() == 1] = 1 | |
input_board[0, board.ravel() == 2] = -1 | |
return input_board | |
# Função para converter a saída do modelo em um movimento | |
def output_to_move(output, next_moves): | |
sorted_indices = np.argsort(output)[::-1] | |
for i in sorted_indices: | |
move = next_moves[i] | |
if output[i] > 0.5: | |
return move | |
return None | |
# Treinando o modelo | |
for i in range(1000): | |
board = initial_board.copy() | |
moves = [] | |
while True: | |
# Obter os movimentos possíveis | |
next_moves = get_next_moves(board) | |
# Se não houver mais movimentos possíveis, o jogo termina em empate | |
if len(next_moves) == 0: | |
break | |
# Obter a entrada para o modelo | |
input_board = board_to_input(board) | |
# Obter a saída do modelo | |
output = model.predict(input_board) | |
# Converter a saída do modelo em um movimento | |
if len(next_moves) == 9: | |
move = (np.random.choice(3), np.random.choice(3)) | |
else: | |
move = output_to_move(output[0], next_moves) | |
if move is None: | |
break | |
# Fazer o movimento no tabuleiro | |
moves.append(move) | |
player = len(moves) % 2 + 1 | |
board[move] = player | |
# Verificar se o jogo terminou | |
if (board.sum(axis=0) == 3*player).any() or (board.sum(axis=1) == 3*player).any() or (np.trace(board) == 3*player) or (np.trace(np.fliplr(board)) == 3*player): | |
target = 1 | |
break | |
elif (board == 0).sum() == 1: | |
target = 0 | |
break | |
# Atualizar o modelo | |
if len(moves) > 0: | |
X = np.zeros((len(moves), 9), dtype=np.int8) | |
y = np.zeros((len(moves), 1), dtype=np.int8) | |
for j, move in enumerate(moves): | |
X[j] = board_to_input(board) | |
y[j] = target | |
model.train_on_batch(X, y) | |
# Função para imprimir o tabuleiro | |
def print_board(board): | |
print(" 0 1 2") | |
for i in range(3): | |
row_str = f"{i} " | |
for j in range(3): | |
if board[i, j] == 0: | |
row_str += "." | |
elif board[i, j] == 1: | |
row_str += "X" | |
elif board[i, j] == 2: | |
row_str += "O" | |
if j < 2: | |
row_str += "|" | |
print(row_str) | |
# Inicializando o tabuleiro | |
board = np.zeros((3, 3), dtype=np.int8) | |
# Jogando o jogo da velha com o algoritmo | |
while True: | |
# Movimento do jogador humano | |
print("Sua jogada:") | |
row = int(input("Linha: ")) | |
col = int(input("Coluna: ")) | |
if board[row, col] != 0: | |
print("Jogada inválida, tente novamente.") | |
continue | |
board[row, col] = 1 | |
print_board(board) | |
# Verificar se o jogador humano ganhou | |
if (board.sum(axis=0) == 3).any() or (board.sum(axis=1) == 3).any() or (np.trace(board) == 3) or (np.trace(np.fliplr(board)) == 3): | |
print("Parabéns, você ganhou!") | |
break | |
elif (board == 0).sum() == 0: | |
print("Empate!") | |
break | |
# Movimento do algoritmo | |
print("Jogada do algoritmo:") | |
input_board = board_to_input(board) | |
output = model.predict(input_board) | |
next_moves = get_next_moves(board) | |
move = output_to_move(output[0], next_moves) | |
board[move] = 2 | |
print_board(board) | |
# Verificar se o algoritmo ganhou | |
if (board.sum(axis=0) == 6).any() or (board.sum(axis=1) == 6).any() or (np.trace(board) == 6) or (np.trace(np.fliplr(board)) == 6): | |
print("O algoritmo ganhou!") | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment