[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 
all.

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):
    update_when('key_pressed')
    if key_pressed('escape'):
        return True
    elif key_pressed('4'): ...
    else:
        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)

ok


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:
            break
        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>
    play_game()
  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 
check_collisions
    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 
arguments.
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
http://www.alan-g.me.uk/




More information about the Tutor mailing list