Batalha Naval simples:
a. Monte um dicionário com os tipos de embarcações:
  • ‘S’: submarinos, 3 posições, pontos 30
  • ‘D’: destroyers, 5 posições, pontos 50
  • ‘C’: cruzadores, 7 posições, pontos 100
    b. Monte um dicionário com a localização das embarcações.
  • tupla da posição no mapa da embarcação: sigla da embarcação
Observação: Há apenas uma embarcação de cada tipo
Jogo:
  • O usuário digita as coordenadas separadas por virgula. ( -1,-1 ) para finalizar
  • Caso tenha acertado alguma embarcação, o programa exibe o nome da embarcação, caso contrário exibe ‘Água’.
  • Quando uma embarcação é totalmente destruída, o programa mostra os pontos obtidos.
    Término do programa:
  • quando o usuário desiste: coordenadas -1,-1
  • todas as embarcações foram destruídas.
Em ambos os casos, deve ser exibido o total de pontos

Passo 1

O que o enunciado pede e quais informações ele nos dá.
  • Precisamos montar um dicionário com os tipos de embarcações contendo para cada sigla: nome, número de posições e pontos. Os dados fornecidos são:
    • Sigla 'S': submarinos, 3 posições, 30 pontos.
    • Sigla 'D': destroyers, 5 posições, 50 pontos.
    • Sigla 'C': cruzadores, 7 posições, 100 pontos.
  • Precisamos montar um dicionário com a localização das embarcações onde a chave é uma tupla representando a posição no mapa e o valor é a sigla da embarcação. Observação: há apenas uma embarcação de cada tipo.
  • Regras do jogo a implementar:
    • O usuário digita coordenadas no formato x,y. A entrada especial (-1,-1) encerra o jogo por desistência.
    • Se o chute acertar alguma embarcação, o programa deve exibir o nome da embarcação; caso contrário, exibe Água.
    • Quando uma embarcação for totalmente destruída (todas as suas posições foram atingidas), o programa deve mostrar os pontos obtidos por destruir essa embarcação.
    • O jogo termina quando o usuário desiste (entrada (-1,-1)) ou quando todas as embarcações foram destruídas.
    • Ao terminar (em qualquer caso), exibir o total de pontos obtidos pelo jogador.

Passo 2

Escolhendo estruturas de dados (explicação didática).
  • Dicionário para tipos de embarcação: é natural usar um dicionário onde a chave é a sigla ('S', 'D', 'C') e o valor é outra estrutura com nome, tamanho e pontos. Isso facilita consultar nome e pontuação rapidamente dado a sigla.
    • Em Python um dicionário é criado como {chave: valor, ...}. As chaves podem ser strings; os valores podem ser tuplas ou outros dicionários.
  • Dicionário para localização: usar um dicionário onde cada chave é uma tupla que representa a coordenada (x,y) e o valor é a sigla da embarcação naquela posição. Por exemplo, positions[(0,0)] = 'S'.
    • Por que tupla? Porque tuplas são imutáveis e servem como chaves de dicionário.
  • Rastreio de células restantes por embarcação: vamos construir um dicionário ship_cells onde a chave é a sigla da embarcação e o valor é um conjunto (set) com todas as tuplas de coordenadas que ainda não foram atingidas. Um set permite remoção rápida e checagem de vazio para detectar destruição total.
  • Variáveis para pontuação: uma variável total_points para acumular a pontuação do jogador.
  • Conjunto already_shots para registrar coordenadas já chutadas e evitar contar o mesmo acerto duas vezes (evita pontuar duas vezes a mesma posição).

Passo 3

Definindo as posições das embarcações (escolha de exemplo) e criando os dicionários iniciais.
  • O enunciado pediu que montássemos o dicionário com a localização. Como não foram dadas posições, vou escolher uma configuração válida (sem sobreposição) em um mapa discreto. Essa escolha é arbitrária, mas consistente com as regras (cada embarcação ocupa o número correto de posições).
  • Exemplo simples (coordenadas inteiras):
    • Submarino 'S' (tamanho 3), na horizontal: (0,0), (0,1), (0,2).
    • Destroyer 'D' (tamanho 5), na vertical: (2,0), (3,0), (4,0), (5,0), (6,0).
    • Cruzador 'C' (tamanho 7), na horizontal: (9,2), (9,3), (9,4), (9,5), (9,6), (9,7), (9,8).
  • A partir dessas posições constrói-se positions (mapeando cada tupla para a sigla) e ship_cells (mapeando cada sigla para o conjunto de suas coordenadas).
  • Observação: escolhi coordenadas que não se sobrepõem; em provas ou exercícios concretos poderia ser pedido para aceitar qualquer configuração, mas aqui fixamos uma para implementar e testar o jogo.

Passo 4

Lógica do jogo passo a passo (o que precisa acontecer a cada interação do usuário).
  1. Repetir:
    • Ler uma linha do usuário no formato x,y.
    • Tratar espaços em branco e entradas inválidas (por exemplo, não numéricas ou formato errado).
    • Se a entrada for exatamente (-1,-1), terminar o loop por desistência.
    • Converter os valores para inteiros; formar a tupla coord = (x, y).
  2. Verificar se coord já foi chutada (usar already_shots):
    • Se já foi chutada, informar que a posição já foi chutada e tratar como Água (não pontua de novo).
  3. Se coord não foi chutada:
    • Adicionar coord em already_shots.
    • Verificar se coord está presente em positions:
      • Se estiver: é um acerto. Recuperar a sigla ship = positions[coord]. Mostrar o nome da embarcação (ex.: Submarino).
        • Remover coord do conjunto ship_cells[ship].
        • Se ship_cells[ship] ficar vazio, a embarcação foi totalmente destruída: somar os pontos correspondentes à embarcação a total_points e informar o jogador (ex.: Cruzador destruído! +100 pontos).
      • Se não estiver: exibir Água.
  4. Encerrar o laço se todas as embarcações forem destruídas (ou seja, todos os conjuntos em ship_cells estiverem vazios).
  5. Ao final (término por desistência ou por destruição de todas embarcações), exibir Total de pontos: X.

Passo 5

Tratamento de casos especiais e detalhes importantes para a prova.
  • Validação de entrada: sempre envolver a conversão em int com try/except para capturar entradas inválidas e pedir nova entrada sem quebrar o programa.
  • Evitar pontuar várias vezes a mesma célula: por isso usamos already_shots.
  • Evitar pontuar várias vezes o mesmo navio quando ele é destruído: pontuação deve ser adicionada apenas na transição de “ainda tinha células” para “foi para vazio” — ou seja, quando ship_cells[ship] se torna vazio pela primeira vez.
  • Mensagens ao usuário: manter simples conforme solicitado — exibir apenas o nome do navio quando acertar e Água quando errar; em destruição total também exibir os pontos daquela embarcação.
  • Simplicidade para a prova: o programa é todo em terminal, sem necessidade de interface gráfica, e roda com input() e print().

Passo 6

Exemplo de execução imaginada (fluxo) — para entender o que o usuário vê.
  • Suponha que o usuário chute (0,0):
    • O programa verifica positions; encontra 'S' → imprime Submarino.
    • Remove (0,0) de ship_cells['S']. Se ainda restarem outras posições do submarino, não pontua ainda.
  • O usuário chute (0,1), depois (0,2):
    • Cada acerto imprime Submarino.
    • Quando o último pedaço (0,2) é atingido, ship_cells['S'] fica vazio → programa imprime Submarino destruído! +30 pontos e soma 30 a total_points.
  • Se o usuário chutou (1,1) (posição vazia), o programa imprime Água.
  • Se o usuário digitar (-1,-1), o programa imprime Total de pontos: X e encerra.

Passo 7

Implementação prática em Python (descrição antes de mostrar o código).
  • A implementação combina todos os passos anteriores: definição dos dicionários iniciais, loop principal que lê e valida entradas, verificação de acertos, atualização de estruturas e pontuação, impressão de mensagens e encerramento.
  • Atenção: como o enunciado pediu que montássemos os dicionários (tipos e posições), o código abaixo já contém essas construções iniciais prontas com a configuração de exemplo escolhida no Passo 3.

Resposta

# Batalha Naval simples - implementação em Python

# Dicionário com os tipos de embarcações:
# chave: sigla, valor: (nome, tamanho, pontos)
ship_types = {
    'S': ('Submarino', 3, 30),
    'D': ('Destroyer', 5, 50),
    'C': ('Cruzador', 7, 100)
}

# Dicionário com a localização das embarcações:
# chave: (x, y) -> valor: sigla da embarcação
# Configuração escolhida (exemplo sem sobreposição):
positions = {
    # Submarino 'S' (tamanho 3): (0,0), (0,1), (0,2)
    (0, 0): 'S', (0, 1): 'S', (0, 2): 'S',
    # Destroyer 'D' (tamanho 5): (2,0), (3,0), (4,0), (5,0), (6,0)
    (2, 0): 'D', (3, 0): 'D', (4, 0): 'D', (5, 0): 'D', (6, 0): 'D',
    # Cruzador 'C' (tamanho 7): (9,2) a (9,8)
    (9, 2): 'C', (9, 3): 'C', (9, 4): 'C', (9, 5): 'C', (9, 6): 'C', (9, 7): 'C', (9, 8): 'C'
}

# Construir ship_cells: mapa de sigla -> conjunto das coordenadas ainda não atingidas
ship_cells = {}
for coord, sig in positions.items():
    ship_cells.setdefault(sig, set()).add(coord)

# Inicializar pontuação e conjunto de tiros já dados
total_points = 0
already_shots = set()

# Função auxiliar para verificar se todas as embarcações foram destruídas
def all_destroyed(cells_dict):
    return all(len(cells) == 0 for cells in cells_dict.values())

# Loop principal do jogo
while True:
    # Ler entrada do usuário
    line = input().strip()
    # Tolerar linhas vazias pulando para próxima leitura
    if line == '':
        continue

    # Tentar parsear "x,y"
    try:
        parts = line.split(',')
        if len(parts) != 2:
            raise ValueError("Formato inválido")
        x = int(parts[0].strip())
        y = int(parts[1].strip())
    except Exception:
        print("Entrada inválida. Use o formato x,y (por exemplo: 3,4) ou -1,-1 para sair.")
        continue

    # Caso de desistência
    if (x, y) == (-1, -1):
        print(f"Total de pontos: {total_points}")
        break

    coord = (x, y)

    # Se já foi chutado antes, tratar como 'Água' (sem pontuar)
    if coord in already_shots:
        print("Água")
        # Verificar condição de término: se todas destruídas, encerrar
        if all_destroyed(ship_cells):
            print(f"Total de pontos: {total_points}")
            break
        continue

    already_shots.add(coord)

    # Verificar se acertou alguma embarcação
    if coord in positions:
        sig = positions[coord]
        name, size, points = ship_types[sig]
        print(name)
        # Remover a célula atingida do conjunto do navio (se ainda estava lá)
        if coord in ship_cells.get(sig, set()):
            ship_cells[sig].remove(coord)
            # Se o navio foi totalmente destruído agora, somar pontos e informar
            if len(ship_cells[sig]) == 0:
                total_points += points
                print(f"{name} destruído! +{points} pontos")
    else:
        print("Água")

    # Se todas as embarcações foram destruídas, encerrar informando total de pontos
    if all_destroyed(ship_cells):
        print(f"Total de pontos: {total_points}")
        break

Exercícios relacionados