while loop isn't working

I’m trying to use a while loop:
while 10==10:
testing = 4
obj[“playerInTurn”] = testing

When I run this, the property called “playerInTurn” isn’t 4.
Actually whatever I try to do inside this loop isn’t working.
Any idea?

the test at the start of the while loop, would mean that the loop would become infinite in nature, unless you stick a break upon some condition.


value = 7
testing = 4
while(value < 10):
   print("testing is", testing)
   value += 1
   testing += 2

ok, that seems logic,
but the condition was just one I tried because things weren’t working out.
I actually want the whole thing to repeat until a variable gameOver is true.
So it would bee
while (gameOver == false):

but that will still give me the same problem, not?

is it game engine ? I assume yes… + it works in bpy
if I’m not wrong, the values modified in a controller script are only updated when the script leave, “at the end of its tic”
so you need to check gameOver == false during several execution of the script

ok, I’m quit new to this, so maybe a question or 2:
Do you mean I need to start the script with “import bpy” before this will work?
And second, should I then repeat gameOver == false inside the while loop?

while (gameOver == false):
       testing = 4
       obj["playerInTurn"] = testing
       gameOver = false

if it’s BGE, there’s no BPY module. I meant the code of zeffii works in ‘normal’ Blender PYthon code.
in game, each script your link to a sensor is executed during a ‘tic’ (see the options in sensors. one defines an interval of tics = the number of execution compared to other sensors)
while a script is running, in a tic, the values you define won’t change. they will be updated AFTER ALL the code of the block text has been parsed by the BGE. I should check but I’m pretty sure it’s the same in the other way, if you change a value outside of the script during its execution, it won’t update immediately.
so no, while is useless unless. idea is smtg like.

if gameover : # ( means if gameover == True)
   # it's game over, do this
   obj["playerInTurn"] = 4
   if something_else :
       # this time it's really finished
else :
   # continue to play

gameOver = false is useless, gameover is already false

since the code is replayed every(tic) time, you should obtain your gameover of gameover state

also you should check the BGE section if you begin BGE. lots of usefull info link and scripts. hope this help a bit.

Sorry I’ve been out a while, but now I’m working on it again.
This is the code so far:

import bge

cont = bge.logic.getCurrentController()
obj = cont.owner

obj["playerInTurn"] = 10

gameOver = false

if gameOver :
    # game is over
    
else :
    testing = 4
    obj["playerInTurn"] = testing

Now I just get a value for playerInTurn which is 0 (standard value). When I remove the if and else, it shows 10. So why do things stop working when I add an if clause?

And one more thing I always get this error:
else:
^
indentationError: expected an indent block

Whay should I do about that?

because there’s no line code below gameOver, so python waits for a line at the tabulation level than the gameover line.

could you just explain what you want to do ?
also have a look to python and tutorialsforblender websites, and the game engine section here.

I wanted to make a game for multiple players.
So there are 6 diffrent characters and they can each play at their turn.
They are devided in 2 teams of 3 players. When 1 of the teams is completly lost the gameOver should turn to true and the game would end.
Now I wanted to make somekind of a loop system, because every player can do the same things in his turn. So I wanted to make a for loop which added from 1 to 6. And each time only the player with the number from playerInTurn can act (with the same controllers like mouse, buttons, …)

I don’t really know if this way is good. Maybe there is a more efficient way, but this is whay I came up with

you can begin to read papers about python lists and dictionnaries, as a way to store persistent datas for your game. properties are usefull for context variables and to store a few datas but that will become hard to manage for more complex things.
read python dictionnary documentation, then this :
http://www.tutorialsforblender3d.com/GameModule/GameLogicModule_20.html

below a suggestion of code. beware, this is normal python, it won’t work in the BGE. but in ‘normal blender python’ yes.

import random

players=[
  { 'name':'paul',  'energy':100, 'strength':100 },
  { 'name':'keith', 'energy':100, 'strength':10  },
  { 'name':'ringo', 'energy':100, 'strength':100 },
  { 'name':'john',  'energy':100, 'strength':100 },
  { 'name':'mick',  'energy':100, 'strength':100 },
  { 'name':'brian',  'energy':100, 'strength':100 }
]

print(players[0])
print(players[0].items()) # try player[0].keys() and also .values()
print('player 3 name is %s'%players[3]['name'])

id = 3
players[id]['energy'] -= 10
print("%s's energy is now %s"%(players[id]['name'],players[id]['energy']))

print()

teams=[ {'name':'red', 'playerlist':[0,3,2] }, {'name':'blue', 'playerlist':[1,5,4]} ]
looser = False

while looser == False : # in game engine you can't write this line.
    
    print('----------------')
    for team in teams :
        print('Team %s'%team['name'])
        teamcanplay = 0
        for pid in team['playerlist'] :
            if players[pid]['energy'] > 0 :
                players[pid]['energy'] = max( 0, players[pid]['energy'] - random.randint(-2,6) ) # self destructive game
                # player does something
                
                
            if players[pid]['energy'] == 0 :
                 status = 'dead'
            else : 
                status = 'alive'
                teamcanplay += 1
                
            print('  player %s : %s is %s : %s'%(pid,players[pid]['name'],status,players[pid]['energy']))

        if teamcanplay == 0 :
            looser = team
            break

print("Team %s can't play anymore"%team['name'])

some pieces of what it could be in BGE but ok, I should write my own code I’ll let you search :wink:

dictionnaries allow you to SHARE variables between all the script of your game.
you can’t make just one big script with while loops else the game will freeze. you need to check TIC by TIC the values of your game.

beware, not tested…


<b># INIT SCRIPT</b>
import GameLogic

game={'players':{}, 'teams':{}}
players=game['players']
teams=game['teams']

players=[
  { 'name':'paul',  'energy':100, 'strength':100 },
  { 'name':'keith', 'energy':100, 'strength':10  },
  { 'name':'ringo', 'energy':100, 'strength':100 },
  { 'name':'john',  'energy':100, 'strength':100 },
  { 'name':'mick',  'energy':100, 'strength':100 },
  { 'name':'brian',  'energy':100, 'strength':100 }
]

print(players[0])
print(players[0].items()) # try player[0].keys() and also .values()
print('player 3 name is %s'%players[3]['name'])

id = 3
players[id]['energy'] -= 10
print("%s's energy is now %s"%(players[id]['name'],players[id]['energy']))

print()

teams=[ {'name':'red', 'playerlist':[0,3,2] }, {'name':'blue', 'playerlist':[1,5,4]} ]


GameLogic.globalDict['game'] = game
<b># SCRIPT THAT CHECK IF GAME OVER OR NOT</b>

game = GameLogic.globalDict.get("game")
players=game['players']
teams=game['teams']
looser = False

  
print('----------------')
for team in teams :
    print('Team %s'%team['name'])
    teamcanplay = 0
    for pid in team['playerlist'] :
        if players[pid]['energy'] &gt; 0 :

            # player can play. team is not deaddoes something
            # players[pid]['energy'] = max( 0, players[pid]['energy'] - random.randint(-2,6) ) # self destructive game 
            # update a property value with the id of the player that is allowed to play
            
        if players[pid]['energy'] == 0 :
             status = 'dead'
        else : 
            status = 'alive'
            teamcanplay += 1
            
        print('  player %s : %s is %s : %s'%(pid,players[pid]['name'],status,players[pid]['energy']))

    if teamcanplay == 0 :
        looser = team
        break

###

if looser :
    print("Team %s can't play anymore"%team['name'])
    # update a property value with the game status OVER
<b># SCRIPT FOR PLAYER x DOING SOMETHING</b>
[...]

game = GameLogic.globalDict.get("game")
players=game['players']
teams=game['teams']
pid = ow['playerid'] # playerid is the prop that has been updated with an integer representing the player

player=players[pid] # the current player

for team in teams :
    if pid in team['playerlist'] :
        team = team['name']
    else :
        otherteam = team['name']
        ennemies = team['playerlist']

for ennemy in ennemies :
    players[ennemy]['energy'] = max( 0, players[pid]['energy'] - random.randint(-2,6) ) # self destructive game

[...]

Ok, it’s a bit complicated, but I think I got most of it.
Only one question. In your script first the three players of one team play, then the players of the other team play.
I actually wanted first a player from team 1, then a player from team 2, then again team 1, …
Any idea for that?

And shouldn’t that be import bge instead of GameLogic? or are the both possible?

And I also tried this:

if gameOver == True :
    # game is over
    actuator = cont.actuators["Property"]
    cont.activate(actuator)
    
    
else :
    actuator2 = cont.actuators["Property2"]
    cont.activate(actuator2)

And it didn’t work. So apperently nothing which I type inside of the if clause is executed?
If find that very strange.

mmm it should work almost the way you want as is, but the script that tells ‘your turn player x’ is missing :wink:
in fact in the # SCRIPT THAT CHECK IF GAME OVER OR NOT
you should only have a if players[pid][‘energy’] == 0 test.
(you’re right I missed that)
the yourturn script could read the energy left of each player then enable him I suppose.
a property can store which is the player that plays (with its id, 0 <-> 5), test if energy > 0, does something or not, add 1 to the id property…

the property changed sensor can be usefull.

to update a property :


# ob = owner or any object in the scene
if teamcanplay == False :
    # game is over
    ob['gameover'] = True


add a game property to your object like gamevoer (string type…)
and enable debug mode

I don’t really understand the # SCRIPT FOR PLAYER x DOING SOMETHING.
Could you perhapse explain it a little bit more detailed?

Hi again,
I kind of thought out my own algorithm for this situation.
It is based partley on what has been posted previously, but on the other hand there were parts that I didn’t understand at all, so I had to do something about it.
Now I completly know what does what, and that’s easier to work with.
I’d like some comments and tips, because I’m pretty sure that it won’t be correct (both algorithmic as syntaxis mistakes).

And please remember this (apart from some earlier symplistic experiments) is the first game I’m trying to make with blender using python.
So please explain everything like i would be a noob. :stuck_out_tongue:

So here it is:


The Empty object

First of all I would set an empty object with this logic
always sensor — python: startingData.py
|–> (Should set only one positive pulse, so I think I have to mark “Tap”? please correct)

property sensor (if prop “checkGameOver” equal to 1) — python: gameOver.py

(ofcourse this implicates that the empty object should have a property called checkGameOver which is default set to 0)

startingData.py (a script which just sets the basic variables on the start)



import GameLogic

players=[
  { 'name':'paul',  'energy':100, },
  { 'name':'keith', 'energy':100, },
  { 'name':'ringo', 'energy':100, },
  { 'name':'john',  'energy':100, },
  { 'name':'mick',  'energy':100, },
  { 'name':'brian', 'energy':100, }
]

activePlayer = 1

GameLogic.globalDict['players'] = players
GameLogic.globalDict['activePlayer'] = activePlayer


gameOver.py (only at certain points in the game there should be a check if the game isn’t over yet)



import GameLogic

players = GameLogic.globalDict.get("players")
activePlayer = GameLogic.globalDict.get("activePlayer")
looser = "none"

team1Energy = players[0]['energy'] + players[2]['energy'] + players[4]['energy']
team2Energy = players[1]['energy'] + players[3]['energy'] + players[5]['energy']

if team1Energy == 0 :
     looser = "team1"
elif team2Energy == 0 :
     looser = "team2"
else :
     looser = none

     if activePlayer == 5 :
          activePlayer = 0
          GameLogic.globalDict['activePlayer'] = activePlayer
     else :
          activePlayer = activePlayer + 1
          GameLogic.globalDict['activePlayer'] = activePlayer

Now that was it for the empty.


The game characters

Now we have the gamecharacters. They all have these properties:
pID (int) = 0-5 (depending on which character)
partOfTurn (int) = 1
ammo (int) = 1

now for the logic setup:

You should know my intentions for the game for this: I want that each player can (in his turn) move for 5 seconds, and afterwards aim to shoot once (and by that trying to hit the enemy)


Always   ---  python: action.py     --- property checkGameOver == 1 
  |                                                          |
(should send constant true pulses)        (this is a property of the empty object, so it needs to be connected to the empty object)

property (if prop "partOfTurn" is equal to 1)                         ---  And                   ---  weapon is inVisible
                                                                  \
                                                                   \-----  And                   ---  Movement
                                                                        /
keyboard (all the diffrent keys you can press (up,down,left,right))  --/

property (if prop "partOfTurn" is equal to 2)                         ---  And                   --- weapon is Visbile
                                                                     \
clicking the mouse                                                    ---  And                   --- Shooting (don't know exactly yet how I'm going to do that, but that's just a matter of time)
                                                                      /                         \--- property ammo == 0
property (if prop "ammo" is equal to 1)                              /


That’s the logic setup. I know this is maybe confusion to type it with all the ASCII, but if it’s not clear just ask me.

Now for the script:

action.py



import GameLogic
ow = GameLogic.getCurrentController()

if ow['partOfTurn'] == 1

    # set a time.
    # i don't know how to set a timer, but I will look it up if someone knows a helpfull link :p
    # anyhow, after 5 seconds this should happen:

    ow['partOfTurn'] = 2

elif ow['partOfTurn'] == 2

    if ow['ammo'] == 0  # means the end of the turn

         # reset everything
         ow['ammo'] = 1
         ow['partOfTurn'] = 1

         # change the checkGameOver
         actuator = ow.actuators["gameOverProp"]
         activate(actuator)


That’s it so far. I know it’s not complete yet (the shooting, the creation of damage, the ending and beginning of the game,…) I’m going to think about that now.
But I would appreciate some help with this so far, because it’s certainly not correct.

Now that I have typed it all out, I see that it is a bit confusing like that. Maybe I’ll add a screenshot from the logic setups, or something like that.
Anyhow you can always ask more explenation about something.

Thanks in advance for all the tips and helpfull information.

Note: maybe I should start a new threard? because it’s not really anymore about a while loop is it?

in the game property of an object, you can add a timer property :wink:
also for ‘init state’, ‘running state’, ‘gameover state’ you can read some doc about game engine state usage.
and yes maybe the thread is out of scope now (good thing for you !) you should post in game engine section, visit tutorialsforblender etc…

isn’t tutorialsforblender a bit outdated, for correct syntaxis and so on?

Ok, I think I got the principals of states :stuck_out_tongue:
The first place I’m going to try this out will probably be the partofturn thing.
So I don’t have to work with the property and it’s easier to overview.
But actually isn’t it kind of the same principal? the use of this property and the use of states?
Or am I missing something about the states?

you are missing something :slight_smile: ok in a way it can work as a if or a while test, but this has nothing to do with props.
here’s a file that could help :
http://jerome.le.chat.free.fr/tmp/states.blend
the BGE api is not really updated a lot, it works exactly the same way but faster with different module names, print()… there’s a thread from mogury about that.