The break
has limited utility for cases like these: it comes out of a single loop in the same function.
You are creating the game with a good separation of what does what, but apparently the desperation to do break
work messed up your code.
Every game will have an excerpt that is what we call the main loop - "mainloop": the excerpt that has to be repeated each frame, or with each interaction with the player, for the game to work. In this code it is easy to notice that the part that does this is in its function andar
, updating positions, calling update and verification functions, and printing the current status of the game. For this code to make sense, it is the walking function that is the main loop, which needs to be executed every interaction of the game.
Updating - I only realized after I wrote that you will actually have several "players". In case, you will get a "main loop" at another point of the program, which calls the function andar
in every interaction: that’s where the block should be try...except
which I describe at the end. If you choose the variable, it has to be a global variable, not an attribute then.
So the while True
which ended up in function victory
should be covering the whole block that is on andar
. And yes, hence, we need a mechanism for that function victory
can break that bond, and that is your doubt.
There are two ways: you can keep a variable with the overall state of the game (in this case, simply an attribute of the Player class): while
in andar
checks this variable, and the function victory
updates the same:
...
def __init__(...):
...
self.vitoria_aconteceu = False
...
self.andar()
...
def andar(self):
while not self.vitoria_aconteceu:
self.passos_parcial = random.randint(1,60)
self.passos+=self.passos_parcial
self.checknivel()
self.victory()
print self.nome, "Andou mais", self.passos_parcial, "e está a", (120 - self.passos), "do próximo nível"
...
def victory(self):
if self.nivel == 3:
...
vitoria_aconteceu = True
Now, imagine that this is a complex game, with several instances of Jogador
, and several tests to stop the game: a player may die, or find the treasure, or even reach a point where there is a phase shift to another map.
The functions could have more levels - in another type of game, the death of a player can happen in the position update of a class object Tiro
, in his method atualizar
(and this method would not have access to the attribute in the main class of the game).
So a common way to treat the problem is to create custom exceptions, and put the main loop block inside a try...except
.
Creating a custom exception may sound complicated, but it’s the simplest thing in the world: it’s empty classes that inherit from Exception
.
You can even create an exception for each type of event that would result in an exit from loop main, and there, a block of except
appropriate to each:
class GameException(Exception): pass
class VicrotyException(GameException): pass
class LostException(GameException): pass
...
def andar(self):
try:
while True:
self.passos_parcial = random.randint(1,60)
self.passos+=self.passos_parcial
self.checknivel()
self.victory()
print self.nome, "Andou mais", self.passos_parcial, "e está a", (120 - self.passos), "do próximo nível"
except VictoryException:
print(self.nome, "ganhou")
...
...
def victory(self):
if self.nivel == 3:
# Levanta uma excelççao de vitória,
# que dsvia o código para o except correspondente:
raise VitctoryException
The exceptions are by no means something bad, as it may seem - for more information see my reply on exceptions:
Why make use of Python exceptions using raise?
Two more general tips for your code:
Why are you sweating Python 2? It’s a language from last millennium, with less and less support - try to use Python 3.6
Try to maintain a consistency of nomenclature: you are using variables and methods with names in Portuguese and English half at random. Ideally use in English: you never know when your project will be cool, and you’ll want to put it on github and have international contributors.
When you call the method
andar
, the player will walk an amount less than 60 steps and after is called the methodvictory
, which has an infinite loop: thewhile
will be running forever as the player has not walked 60 steps and continues to level 0. What is the function of thiswhile
?– Woss
Actually I tried to put this 'while' because there is no way to break the 'if' loop. But the real question is this... do when the 'self.nivel == 3' stop the loop. I tried to do this in the 'Victory'
– Marcos Vinícius
That’s the point: you don’t need the tie, so you don’t need the
break
. Try to leave only theif
. In advance, the method names are a bit strange. It is not a good practice to mix names in Portuguese and English.– Woss
But when I call the class downstairs, it will happen that the only one will call downstairs. Being that it is to call until the level is equal to 3. Ai then it is to zero the dice pq finished the game.
– Marcos Vinícius
who downvoted this question? is perfectly responsive and good.
– jsbueno