[Tutor] robots question

Alan Gauld alan.gauld at btinternet.com
Fri Sep 17 02:14:32 CEST 2010

"Roelof Wobben" <rwobben at hotmail.com> wrote

# robots.py

This is pretty weird code, there are several odd things in it.

def place_player():
    # x = random.randint(0, GRID_WIDTH)
    # y = random.randint(0, GRID_HEIGHT)
    x, y = GRID_WIDTH/2 + 3, GRID_HEIGHT/2
    return {'shape': Circle((10*x+5, 10*y+5), 5, filled=True), 'x': x, 
'y': y}

So this returns a dictionary which always contains the same data.

def place_robot(x,y, junk):
    x = random.randint(0, GRID_WIDTH)
    y = random.randint(0, GRID_HEIGHT)
    return {'shape': Box((10*x, 10*y), 10, 10), 'x': x, 'y': y}

This returns a similar dict but with random data.
It ignores the values of x and y passed in and does not use junk at 

def place_robots(numbots):
    robots = []
    # for i in range(numbots):
    #    x = random.randint(0, GRID_WIDTH)
    #    y = random.randint(0, GRID_HEIGHT)
    #    robots.append(place_robot(x, y))
    robots.append(place_robot(GRID_WIDTH/2 - 4, GRID_HEIGHT/2 + 2, 
junk= False))
    robots.append(place_robot(GRID_WIDTH/2 - 4, GRID_HEIGHT/2 - 2, 
junk = False))
    print type(robots)
    return robots

This returns a list of 2 dictionaries. The x,y parameters are ignored 
by the function.

def move_player(player):
    if key_pressed('escape'):
        return True
    elif key_pressed('4'): ...
        return False
    move_to(player['shape'], (10*player['x']+5, 10*player['y']+5))
    return False

This seems OK, it returns True for escape otherwise False.

def collided(thing1, thing2):
    return thing1['x'] == thing2['x'] and thing1['y'] == thing2['y']

This returns a boolean

def check_collisions(robots, junk, player):
    # check whether player has collided with anything
    for thing in robots + junk:
        if collided(thing, player):
            return True
    return False

Could be simplified to just

for thing in robots + junk:
     return collided(thing, player)

It requires that robots and junk are capable of being added together
and the result being iterable.

def move_robot(robot, player):
    if robot['x'] < player['x']: robot['x'] += 1
    elif robot['x'] > player['x']: robot['x'] -= 1

    if robot['y'] < player['y']: robot['y'] += 1
    elif robot['y'] > player['y']: robot['y'] -= 1

    move_to(robot['shape'], (10*robot['x'], 10*robot['y']))

I don't see move_to so assume its part of the module you imported?

def move_robots(robots, player):
    for robot in robots:
        move_robot(robot, player)


def play_game():
    begin_graphics(SCREEN_WIDTH, SCREEN_HEIGHT)
    player = place_player()
    robot = place_robots(4)
    junk = [ place_robot(GRID_WIDTH/2, GRID_HEIGHT/2, junk="true" )]
    robots = []
    defeated = False

So at this point
player is a dict
robot is a list of 2 dicts
junk is a list of one dict
robots is an empty list

    while not defeated:
        quit =  move_player(player)
        if quit:
        move_robots(robots, player)
        print "type robots", type(robots)
        print "type junk", type(junk)
        print "type player", type(player)
        defeated = check_collisions(robots, player, junk)

You now call check_collisions passing an empty list and a dict and a 
list of a dict
The order in the definition is:

def check_collisions(robots, junk, player):

so it looks like you swapped the last two arguments

And now Im getting this message :

** Message: pygobject_register_sinkfunc is deprecated (GtkWindow)
** Message: pygobject_register_sinkfunc is deprecated (GtkInvisible)
** Message: pygobject_register_sinkfunc is deprecated (GtkObject)
<type 'list'>

Not sure where that lot came from...

type robotsTraceback (most recent call last):
 <type 'list'>
type junk <type 'list'>
type player <type 'dict'>
  File "/root/workspace/test2/src/test.py", line 125, in <module>
  File "/root/workspace/test2/src/test.py", line 111, in play_game
    defeated = check_collisions(robots, player, junk)
  File "/root/workspace/test2/src/test.py", line 74, in 
    for thing in robots + junk:
TypeError: can only concatenate list (not "dict") to list

But this is valid because of the swapped arguments.

> So far I can see the problem is that player is a dict and the rest 
> is a list.
> Is this the correct conclusion ?

Yes, but you missed the fact that you changed the order of the 
When you get type errors check the types at your interfaces(functions, 
classes etc)
match the definitions.

Alan Gauld
Author of the Learn to Program web site

More information about the Tutor mailing list