1
0
Fork 0
cdpython01/PY03.1-Projetos.ipynb

11 KiB

Projeto: Capturando um robô

Como seria o programa que faz a captura de um robô?

Para responder essa pergunta precisamos ter em mente um princípio de design muito importante na criação de programas de computador. Esse princípio diz o seguinte:

É bom que os dados de um programa sejam independentes do modo como eles são apresentados para o usário do programa.

Em outras palavras, é bom que os os dados e tudo o que o programa faz com eles seja programado separado da parte da interface do programa, que é a parte do programa que apresenta os dados, seja em modo texto ou gráfico.

Isso é bom porque assim podemos ter várias formas de apresentar os dados, ou seja, várias interfaces, sem precisar mudar a parte do programa que manipula os dados. Por exemplo, as listas de robôs que estamos usando estão guardando dados importantes para o nosso jogo. Esses dados podem ser exibidos para o jogador de diversas formas. Vamos ver algumas.

Mostrar que robôs estão atacando

Mostrar para o usuário o quê está acontecendo no programa é uma tarefa da interface do programa. Para poder mostrar isso, a interface precisa de dados. Esses dados estão na lista de robôs chamada robos_atacando. Com essa lista, podemos mostrar de diversas formas que esses robôs estão atacando (podemos ter várias versões de interface).

In [1]:
# Dados
robos_atacando= ['robô 1', 'robô 2', 'robô 3', 'robô 4', 'robô 5']

# Diversas interfaces possíveis
# para mostrar os dados para o
# jogador

print('Apresentação dos dados - versão 1')
print(robos_atacando)
print()

print('Apresentação dos dados - versão 2')
print('Robôs atacando = %s' % len(robos_atacando))
print()

print('Apresentação dos dados - versão 3')
print('\N{robot face}' * len(robos_atacando))
print()

print('Apresentação dos dados - versão 4')
from IPython.display import HTML
HTML('<img src=img/robof-64px.png />' * len(robos_atacando))
Apresentação dos dados - versão 1
['robô 1', 'robô 2', 'robô 3', 'robô 4', 'robô 5']

Apresentação dos dados - versão 2
Robôs atacando = 5

Apresentação dos dados - versão 3
🤖🤖🤖🤖🤖

Apresentação dos dados - versão 4
Out[1]:

Observe que em qualquer dos casos os dados são sempre os mesmos. É sempre a mesma lista de strings, chamada robos_atacando que está sendo usada para criar essas 4 interfaces diferentes. E muitas outras formas são possíveis. Para todas elas a lista robos_atacando pode continuar a mesma - não é preciso mudar os dados para ter uma nova interface!

Então, pensando nessa separação entre dados e interface, o que seria a ação de capturar um robô do ponto-de-vista dos dados? Em outras palavras, se não nos preocuparmos com a interface, quais dados e quais operações sobre eles são efetuadas quando vamos "capturar um robô"?

Primeiro, quais são os dados que precisamos conhecer para poder realizar essa ação?

  1. quais robôs estão atacando (porque sem isso não sabemos o que temos para capturar)
  2. qual desses robôs será o robô capturado (porque temos que ter um "alvo" definido)
  3. onde colocar esse robô que capturamos, porque não faz sentido capturar um dos robôs e ele continuar junto dos robôs que estão atacando

lembrando que "capturar" não é "destruir", por isso vamos colocar o robô em algum lugar e não simplesmente excluir ele do jogo.

Essas dados serão os seguintes:

  1. A lista robos_atacando
  2. Há várias formas de escolher o robô que será nosso alvo. Podemos pegar sempre o primeiro da lista, ou sempre o último, ou pegar sempre um aleatório. O importante aqui é que precisamos guardar esse robô (que da perspectiva dos dados é só uma string comum) em alguma variáveil, porque depois vamos precisar dela para colocar esse robô nos robôs capturados.
  3. E vamos colocar o robô capturado na lista robos_capturados

Ora, nós praticamente já escrevemos esse código na sessão anterior!

Da perspectiva dos dados, capturar um robô pode ser algo simples, como:

  • escolher um robô da lista de robôs que estão atacando
  • retirar esse robô da lista
  • colocar esse robô na lista de robôs capturados

Assim:

In [2]:
# Dados
robos_atacando= ['robô 1', 'robô 2', 'robô 3', 'robô 4', 'robô 5']
robos_capturados =[]

# Ação: capturar robô

# 1. Escolher um robô da lista de robôs que estão atacando
robo = robos_atacando[-1] # aqui, escolhemos o último da lista

# 2. retirar esse robô da lista
del robos_atacando[-1]

# 3. colocar esse robô na lista de robôs capturados
robos_capturados.append(robo)

Fica agora faltando mostrar para o jogador o que aconteceu após a execução dessa ação de capturar robô. Agora é que entra a interface.

O jogador não sabe o que aconteceu com os dados do jogo porque isso aconteceu só na memória do computador. Ninguém viu! A interface deve mostrar para o jogador quais foram as mudanças que ocorreram no jogo após a sua ação.

In [3]:
# Interface que mostra para o jogador
# as mudanças que ocorrem nos dados do jogo

print('Robôs atacando')
print('\N{robot face}' * len(robos_atacando))
print('Robôs capturados')
print('\N{robot face}' * len(robos_capturados))

print()
Robôs atacando
🤖🤖🤖🤖
Robôs capturados
🤖

Mostrar a mudança dos dados

Vamos mostrar para o jogador um antes e depois do nosso programa quando a ação de capturar robô for executada. Isso é para o jogador entender melhor o que está acontecendo. Se mostramos penas a situação final (o depois, como fizemos acima) sem ter mostrado como tudo estava antes de da ação de captura acontecer, a informação apresentada fica meio enigmática, porque o jogador precisa "deduzir" quais robôs estavam atacando após ver o tamanho da sua lista de robôs capturados e entender que aqueles "robôs atacando" que aparecem para ele continham 1 robô a mais no momento anterior. Por isso, mostrar esse momento anterior facilita a compreensão do que aconteceu.

Vamos juntar tudo o que fizemos em uma só trecho de código e vamos escrever no final esse antes e depois mostrando a mudança nos dados.

In [4]:
# Dados
robos_atacando= ['robô 1', 'robô 2', 'robô 3', 'robô 4', 'robô 5']
robos_capturados =[]

# ANTES
# Interface que mostra para o jogador
# as mudanças que ocorrem nos dados do jogo

print('Robôs atacando')
print('\N{robot face}' * len(robos_atacando))
print('Robôs capturados')
print('\N{robot face}' * len(robos_capturados))

print()


# Ação: capturar robô

# 1. Escolher um robô da lista de robôs que estão atacando
robo = robos_atacando[-1] # aqui, escolhemos o último da lista

# 2. retirar esse robô da lista
del robos_atacando[-1]

# 3. colocar esse robô na lista de robôs capturados
robos_capturados.append(robo)


# DEPOIS
# Interface que mostra para o jogador
# as mudanças que ocorrem nos dados do jogo

print('Robôs atacando')
print('\N{robot face}' * len(robos_atacando))
print('Robôs capturados')
print('\N{robot face}' * len(robos_capturados))

print()
Robôs atacando
🤖🤖🤖🤖🤖
Robôs capturados


Robôs atacando
🤖🤖🤖🤖
Robôs capturados
🤖

Agora sim! Podemos ver muito melhor que começamos sem ter capturado nenhum robô e que 5 robôs estavam atacando. Depois da ação capturar robô vemos claramente que 1 robô foi capturado e que restam 4 robôs atacando.