Skip to content

Instantly share code, notes, and snippets.

@londarks
Last active February 25, 2023 04:35
Show Gist options
  • Save londarks/45ab5287320b0faa957c36e9be7b72b3 to your computer and use it in GitHub Desktop.
Save londarks/45ab5287320b0faa957c36e9be7b72b3 to your computer and use it in GitHub Desktop.
tic-tac-toe with AI
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