#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    23
    Rep Power
    0

    [SOLVED] List.remove(x): x not in list Knowledge problem....


    Hello Python Forum,

    I'm new here and i hope to get more knowledge while im here.
    I'm fairly new to Python but did rrogram in Java briefly but this is now 5 years ago.

    I try to code a simple Game: Some zombies walk against a wall and you can shoot them with the mouse.....

    So i got my zombie calss with health and everything and then i make a list of the Zombies and fill the list with zombie-objects. So when i shot one of them, i want to remove the object out of the list. After the removal this happens:

    Code:
    0 <zombie sprite(in 1 groups)>
    0 <zombie sprite(in 1 groups)>
    Traceback (most recent call last):
      File "/home/manuel/Python/GoF2/src/myGoF2.py", line 244, in <module>
        delete_Deadguys()
      File "/home/manuel/Python/GoF2/src/myGoF2.py", line 93, in delete_Deadguys
        waveArray.remove(i)
    ValueError: list.remove(x): x not in list
    The complete game code:

    Code:
    '''
    Created on 12 Apr 2013
    
    @author: manuel
    '''
    # Import a library of functions called 'pygame'
    
    import pygame
    import os, sys
    from pygame.locals import *
    import time
    from logilab.astng.node_classes import Print
    
    # ## VARS
    
    # Define some colors
    black = (0, 0, 0)
    white = (255, 255, 255)
    green = (0, 255, 0)
    red = (255, 0, 0)
    
    # Set the width and height of the screen
    size = (800, 600)
    # The title and version of this program
    title, version = "The Game of Life", "1.0"
    
    # Loop until the user clicks the close button.
    done = False
    
    
    waveCount = 1
    waveArray = []
    # ## VARS
    
    # ## INIT Stuff
    
    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()
    
    screen = pygame.display.set_mode(size)
    # Initialize the game engine
    pygame.init()
    
    # Set the title string of the root window
    pygame.display.set_caption(title + " " + version)
    
    # hide normal mouse
    pygame.mouse.set_visible(0)
    
    # ## INIT Stuff
    
    # ## DEFS
    
    def load_image(name, colorkey=None):
        fullname = os.path.join('data', name)
        try:
            image = pygame.image.load(fullname)
        except: pygame.error('Cannot load image:', name)
    
        image = image.convert_alpha()
        if colorkey is not None:
            if colorkey is -1:
                colorkey = image.get_at((0, 0))
            image.set_colorkey(colorkey)
        return image, image.get_rect()
    
    def collide(name):
    
        return
    
    def delete_Deadguys():
        print(len(waveArray))
    #     a = 0
    #     while a < len(waveArray):
    #         if waveArray:
    #             print("List is NOT empty")
    #             if waveArray[a].get_health() <= 0:
    #                 waveArray.remove(a)
    #                 break
    #             a = a + 1
    #         else:
    #             print("List ist empty")
        if len(waveArray) >= 1:
            print("lengt bogger than 1")
            print(len(waveArray))
            for i in range(len(waveArray))[:]:
    
                print(i, waveArray[i])
    
                if waveArray[i].get_health() <= 0:
    
                  print(i, waveArray[i])
                  waveArray.remove(i)
                  print("tdst")
    
            else:
                print("why")
               # print(i, waveArray[i])
    
    #     for count in range(len(waveArray)):
    #         a = 1
    #         print(range(len(waveArray)))
    #         print("llk")
    #         print(len(waveArray))
    #         print(count, a + 1)
    #         if waveArray[count].get_health() <= 0:
    #             print(count, waveArray[count])
    #             waveArray.remove(count)
    #             print(count, waveArray[count])
    
    
    
    
    # # ## DEFS
    
    # ## CLASSES
    
    
    class crosshair(pygame.sprite.Sprite):
        # moves a clenched fist on the screen, following the mouse"""
        # create a sprite object and load the image into it
        def __init__(self):
            pygame.sprite.Sprite.__init__(self)  # call Sprite initializer
            self.image, self.rect = load_image('cross64.png', -1)
    
        def update(self):
            # move the fist based on the mouse position"
    
            # put the crosshair picture where the mouse is
            pos = pygame.mouse.get_pos()
            # offsets the picture so the crosshair middle is the
            self.rect.center = pos
    
    
    class wall(pygame.sprite.Sprite):
        # moves a clenched fist on the screen, following the mouse"""
        # create a sprite object and load the image into it#
        global health
        health = 50
        def __init__(self):
            pygame.sprite.Sprite.__init__(self)  # call Sprite initializer
            self.image, self.rect = load_image('wall64.png', -1)
    
            self.rect.x = 350
            self.rect.y = 350
    
        def update(self):
            # move the fist based on the mouse position"
    
            # put the crosshair picture where the mouse is
            pass
            # pos = pygame.mouse.get_pos()
            # offsets the picture so the crosshair middle is the
            # self.rect.center = pos
    
    
    class zombie(pygame.sprite.Sprite):
        # moves a clenched fist on the screen, following the mouse"""
        # create a sprite object and load the image into it
        global zombie_speed
        global health
        health = 50
        zombie_speed = 5
    
        def __init__(self):
            pygame.sprite.Sprite.__init__(self)  # call Sprite initializer
            self.image, self.rect = load_image('wall64.png', -1)
    
            self.rect.x = 50
            self.rect.y = 350
    
    
        def update(self):
            # move the fist based on the mouse position"
    
            # put the crosshair picture where the mouse is
            # print("do something here later")
            pass
            self.rect.x = self.rect.x + zombie_speed
    
            # self.rect.x = self.rect.x + zombie_speed
            # pos = pygame.mouse.get_pos()
            # offsets the picture so the crosshair middle is the
            # self.rect.center = pos
    
        def get_x(self):
            # move the fist based on the mouse position"
            return self.rect.x
        def get_y(self):
            # move the fist based on the mouse position"
            return self.rect.y
        def get_height(self):
            # move the fist based on the mouse position"
            return self.rect.height
        def get_width(self):
            # move the fist based on the mouse position"
            return self.rect.width
        def set_health(self, health_arg):
            # move the fist based on the mouse position"
            global health
            health = health - health_arg
        def get_health(self):
            # move the fist based on the mouse position"
            return health
    # ## CLASSES
    
    # generate all the objects
    
    cshr = crosshair()
    wall1 = wall()
    waveArray.append(zombie())
    
    
    # render all the sprites in the background fisrt time!
    zombiesprites = pygame.sprite.RenderPlain((waveArray[0]))
    
    allsprites = pygame.sprite.RenderPlain((cshr, wall1))
    
    # -------- Main Program Loop -----------
    while done == False:
    
    
        # ALL GAME LOGIC SHOULD GO BELOW THIS COMMENT
    
        # calls the update method in the sprite class (defined by me)
    
        # spped see clock (30 fps)
        allsprites.update()
    
    
        zombiesprites.update()
        # ALL GAME LOGIC SHOULD GO ABOVE THIS COMMENT
    
        # ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
    
        # Clear the screen and set the screen background
        screen.fill(white)
    
        pygame.draw.rect(screen, red, [55, 200, 100, 50])
    
        allsprites.draw(screen)
        zombiesprites.draw(screen)
        # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
        delete_Deadguys()
        # Go ahead and update the screen with what we've drawn.
        # screen.blit(background, (0, 0))
        pygame.display.flip()
    
        # ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENT
        for event in pygame.event.get():  # User did something
            if event.type == pygame.QUIT:  # If user clicked close
                done = True  # Flag that we are done so we exit this loop
                break
                pygame.quit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                # mousecoords = pygame.mouse.get_pos()
                mouse_x, mouse_y = pygame.mouse.get_pos()
    
                # Test for 'collision'
                # print(len(waveArray))
                for count in range(len(waveArray)):
                    # print(count)
                    # print(waveArray[count])
                    # print(waveArray[count].get_x())
                    # print("lol")
    
                    # print(a, b, c, d)
                    # if waveArray[count].get_x() < mouse_x:
                    #    print("ruscha")
    
                    if waveArray[count].get_x() < mouse_x < waveArray[count].get_x() + waveArray[count].get_width() and waveArray[count].get_y() < mouse_y < waveArray[count].get_y() + waveArray[count].get_height():
                        print("crosshair works")
                        waveArray[count].set_health(27)
                        print(waveArray[count].get_health())
    
    
        # ALL EVENT PROCESSING SHOULD GO ABOVE THIS COMMENT
    
        # Limit to 20 frames per second
        clock.tick(30)
    Ok. I understand that the list is somehow out of entries and the index is to high. What i not understand is why the index is to high because the function deleteDeadguys deletes them and then should not run again because it has only one entry.

    Also on this why does range display [0,1] ? there is only one object in the list!Not two..

    Secondly even if the delete routine would start again it should not because of the if who checks id the list is not empty. But still it does it and seems to ignore the if.

    I do'nt know what is happening hopefully someone here does.....

    Here is some info:

    Coding in : Python3.2 with the help of pygame
    ON: Suse Linux 12.3
    Pygame cloned from source and manually installed.

    Thanks for making my day :-D

    Manuel

    EDIT: You can download the sources here:

    http://www.file-upload.net/download-7461056/GoF2.zip.html

    Start: python3 myGoF2.py.

    Try to shoot the moving zombie (the wall picture).
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    for i in range(len(waveArray))[:]:

    python evaluates the range arguments once, and the size of your array changes. The [:] is unhelpful, but irrelevant otherwise, I believe. I can't seem to test your code. I made a data directory and stuck some .png files therein but they still wouldn't load as images.

    Loop over the list backward.

    for i in range(len(waveArray),-1,-1):

    Seems like it would work.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    23
    Rep Power
    0
    Hello b49P23TIvg,

    Ok first Thank you very much for the quick reply. i tried your suggestion with
    for i in range(len(waveArray),-1,-1):

    and the only thing thats happens is that i get the error in an instant and the game/graphics does not even load.

    Code:
    Traceback (most recent call last):
      File "/home/manuel/Python/GoF2/src/myGoF2.py", line 245, in <module>
        delete_Deadguys()
      File "/home/manuel/Python/GoF2/src/myGoF2.py", line 89, in delete_Deadguys
        print(i, waveArray[i])
    IndexError: list index out of range

    the list seems to be still out of range so it must think it is still one element more in it right ?

    You can download the source code with data in the first post :-D

    Also when python does evaluate may array only one time does that mean i cant change in while in runtime ?

    Why is range saying there are 0 and 1 inside of the array but there should be only one?

    Thanks for the Help

    Originally Posted by b49P23TIvg
    for i in range(len(waveArray))[:]:

    python evaluates the range arguments once, and the size of your array changes. The [:] is unhelpful, but irrelevant otherwise, I believe. I can't seem to test your code. I made a data directory and stuck some .png files therein but they still wouldn't load as images.

    Loop over the list backward.

    for i in range(len(waveArray),-1,-1):

    Seems like it would work.
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    I've never used list.remove .
    Originally Posted by help(list.remove)
    remove(...)
    L.remove(value) -- remove first occurrence of value.
    Raises ValueError if the value is not present.
    Sorry.

    how about

    del waveArray[i]
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    23
    Rep Power
    0
    Hey

    Thank you very much that did the trick.

    Unfortunately it is still renderd to the screen. Even when the object is destoyed. I dont understand. How can this be ?

    Zombiespriites.Update() should not be executed because there is no zombie sprite any more. Also the zombiesprites.draw(screen) should trow an error because it is not existant anymore. I have the feeling that the objects are still exist in RAM.

    How do i delete them from there ?

    Thanks

    EDIT: Got it. sprite.kill() is the answer to that....
  10. #6
  11. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    Start a new thread? I know little about pygame.

    If the gui runs in a separate process or otherwise maintains it's own copies you'd need a way to synchronize.
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo