Programador Leigo
Projetos 9 min leitura 16 MAR 2026

Como fazer um jogo da velha em Python

Crie o clássico jogo da velha para dois jogadores no terminal, com tabuleiro visual e detecção de vitória.


O que vamos construir?

O jogo da velha (tic-tac-toe) para dois jogadores no terminal. O tabuleiro aparece desenhado na tela, cada jogador escolhe uma posição, e o programa detecta automaticamente quando alguém venceu ou deu velha (empate).

É o projeto mais completo desta trilha: usa listas, funções, loops e lógica condicional de forma integrada.

Representando o tabuleiro

O tabuleiro é uma grade 3x3. Vamos representá-lo como uma lista de 9 posições, numeradas de 1 a 9:

tabuleiro = [" "] * 9

Cada posição começa vazia (espaço). Quando um jogador escolhe a posição 1, preenchemos tabuleiro[0] (lembre-se: listas começam no índice 0).

Desenhando o tabuleiro

Para exibir o tabuleiro de forma visual:

def desenhar_tabuleiro(tab):
    print()
    print(f" {tab[0]} | {tab[1]} | {tab[2]} ")
    print("---+---+---")
    print(f" {tab[3]} | {tab[4]} | {tab[5]} ")
    print("---+---+---")
    print(f" {tab[6]} | {tab[7]} | {tab[8]} ")
    print()

O resultado fica assim:

 X | O |
---+---+---
   | X |
---+---+---
 O |   | X

Verificando vitória

Um jogador vence quando preenche uma linha, coluna ou diagonal completa. São 8 combinações possíveis:

def verificar_vitoria(tab, jogador):
    combinacoes = [
        [0, 1, 2],  # linha superior
        [3, 4, 5],  # linha do meio
        [6, 7, 8],  # linha inferior
        [0, 3, 6],  # coluna esquerda
        [1, 4, 7],  # coluna do meio
        [2, 5, 8],  # coluna direita
        [0, 4, 8],  # diagonal principal
        [2, 4, 6],  # diagonal secundaria
    ]

    for combo in combinacoes:
        if tab[combo[0]] == tab[combo[1]] == tab[combo[2]] == jogador:
            return True

    return False

A comparação encadeada a == b == c == jogador verifica se as três posições têm o mesmo símbolo.

Verificando empate

O jogo empata quando todas as posições estão preenchidas e ninguém venceu:

def tabuleiro_cheio(tab):
    return " " not in tab

Se não houver mais espaços vazios na lista, o tabuleiro está cheio.

Pedindo a jogada

O jogador escolhe um número de 1 a 9. Precisamos validar se a posição existe e está vazia:

def pedir_jogada(tab, jogador):
    while True:
        try:
            posicao = int(input(f"Jogador {jogador}, escolha (1-9): "))
            if posicao < 1 or posicao > 9:
                print("Escolha entre 1 e 9.")
                continue
            if tab[posicao - 1] != " ":
                print("Posicao ocupada! Escolha outra.")
                continue
            return posicao - 1
        except ValueError:
            print("Digite um numero.")

Montando o jogo completo

O loop principal alterna entre os jogadores X e O:

def jogar():
    tabuleiro = [" "] * 9
    jogador_atual = "X"

    print("=== JOGO DA VELHA ===")
    print("Posicoes:")
    print(" 1 | 2 | 3 ")
    print("---+---+---")
    print(" 4 | 5 | 6 ")
    print("---+---+---")
    print(" 7 | 8 | 9 ")

    while True:
        desenhar_tabuleiro(tabuleiro)
        posicao = pedir_jogada(tabuleiro, jogador_atual)
        tabuleiro[posicao] = jogador_atual

        if verificar_vitoria(tabuleiro, jogador_atual):
            desenhar_tabuleiro(tabuleiro)
            print(f"Jogador {jogador_atual} venceu!")
            break

        if tabuleiro_cheio(tabuleiro):
            desenhar_tabuleiro(tabuleiro)
            print("Empate! Deu velha.")
            break

        # Alternar jogador
        if jogador_atual == "X":
            jogador_atual = "O"
        else:
            jogador_atual = "X"

A alternância de jogador usa um if/else simples. Outra forma seria: jogador_atual = "O" if jogador_atual == "X" else "X".

Código completo

def desenhar_tabuleiro(tab):
    print()
    print(f" {tab[0]} | {tab[1]} | {tab[2]} ")
    print("---+---+---")
    print(f" {tab[3]} | {tab[4]} | {tab[5]} ")
    print("---+---+---")
    print(f" {tab[6]} | {tab[7]} | {tab[8]} ")
    print()


def verificar_vitoria(tab, jogador):
    combinacoes = [
        [0, 1, 2], [3, 4, 5], [6, 7, 8],
        [0, 3, 6], [1, 4, 7], [2, 5, 8],
        [0, 4, 8], [2, 4, 6],
    ]
    for combo in combinacoes:
        if tab[combo[0]] == tab[combo[1]] == tab[combo[2]] == jogador:
            return True
    return False


def tabuleiro_cheio(tab):
    return " " not in tab


def pedir_jogada(tab, jogador):
    while True:
        try:
            posicao = int(input(f"Jogador {jogador}, escolha (1-9): "))
            if posicao < 1 or posicao > 9:
                print("Escolha entre 1 e 9.")
                continue
            if tab[posicao - 1] != " ":
                print("Posicao ocupada! Escolha outra.")
                continue
            return posicao - 1
        except ValueError:
            print("Digite um numero.")


def jogar():
    tabuleiro = [" "] * 9
    jogador_atual = "X"

    print("=== JOGO DA VELHA ===")
    print("Posicoes:")
    print(" 1 | 2 | 3 ")
    print("---+---+---")
    print(" 4 | 5 | 6 ")
    print("---+---+---")
    print(" 7 | 8 | 9 ")

    while True:
        desenhar_tabuleiro(tabuleiro)
        posicao = pedir_jogada(tabuleiro, jogador_atual)
        tabuleiro[posicao] = jogador_atual

        if verificar_vitoria(tabuleiro, jogador_atual):
            desenhar_tabuleiro(tabuleiro)
            print(f"Jogador {jogador_atual} venceu!")
            break

        if tabuleiro_cheio(tabuleiro):
            desenhar_tabuleiro(tabuleiro)
            print("Empate! Deu velha.")
            break

        jogador_atual = "O" if jogador_atual == "X" else "X"


jogar()

O que você aprendeu

  • Representar uma grade 2D com uma lista simples
  • Funções que trabalham juntas em um programa maior
  • Validação de entrada com múltiplas condições
  • Lógica de verificação com combinações predefinidas

Dicas para ir além

  • Jogar contra o computador: faça o computador escolher posições aleatórias com random.choice()
  • Placar: conte vitórias de cada jogador em várias partidas
  • Tabuleiro colorido: use códigos ANSI para colorir X e O no terminal

Conclusão

O jogo da velha é um ótimo exercício porque envolve lógica, estrutura de dados e interação com o usuário — tudo ao mesmo tempo. No próximo artigo, vamos explorar o módulo Turtle para criar desenhos visuais com Python.

Continue lendo

Compartilhar