[Tutor PyCZ] Livewires V - seznam a proměnné

Tomáš Bělonožník rebelme na gmail.com
Neděle Březen 5 21:04:25 CET 2006


Ahoj,
opět jsem se zasekl a potřeboval bych pomoct. Ke konci tutoriálu už
totiž potřebných a nových věcí přibývá a nápověd rapidně ubývá. Sice
se mi podařilo program napsat tak, aby jakž takž celý fungoval, ale je
tam spousta malých chybiček, je to rozvleklý a úplně jiný než to mělo
být. Vrátím se k počátku problému. Mám program, kde hráče posunovaného
stisky kláves honí "robot" a když ho dožene, hráč prohrál. Měl bych
přidělat další roboty. Autor tutoriálu dává rady:
    *   Vytvořte prázdný list robots.
    * Opakujte pro každého robota, kterého chceme:
          o Přidejte robota do seznamu robotů.
          o Vytvořte náhodně souřadnice místa, kde by se měl robot
narodit. Nezapomeňte nastavit atribut srot na 0.
          o Opakujte while "pokud se tento robot srazil s jiným":
                + Zkuste jiné místo.
          o Vytvořte tělo robota a uložte ho do jeho atributu telo.
Když jsem se to snažil dělat takto, třeba se mi i podařilo vyrobit pět
robotích těl, ale pohybovalo se pouze jedno a ostatní nereagovaly ani
na kontakt. Dejme tomu tedy, že mám tuto funkci pro tvorbu robotů:
def vyrobRobota(pocet_opakovani, seznam):
    robot = Robot()
    while pocet_opakovani < 5:
	# Budoucí souřadnice robota
        robot.x=random.randint(8, 631)
        robot.y=random.randint(8, 471)

        # Část funkce zajišťující, že hráč a robot nezačnou na sobě.
        robot_x_round = robot.x / 10
        hrac_x_round = hrac.x / 10
        robot_y_round = robot.y / 10
        hrac_y_round = hrac.y / 10
        while robot_x_round == hrac_x_round and robot_y_round == hrac_y_round:
            robot.x=random.randint(8, 631)
            robot.y=random.randint(8, 471)
            hrac.x=random.randint(8, 631)
            hrac.y=random.randint(8, 471)

        seznam.append(robot)
        robot.telo = box(robot.x-5,robot.y-5,robot.x+5,robot.y+5,
filled=1, colour=Colour.dark_blue)    # Popis těla robota

Toto mi vytvoří seznam s pěti instancemi robot třídy Robot. Jak ale
udělat, aby se v této funkci všichni hýbali?
def posunRobota(hrac):
    for robot in seznam:     #tahle řádka je tu navíc, tak jsem to zkoušel
        if robot.x < hrac.x:
            robot.x = robot.x + 5
        elif robot.x > hrac.x:
            robot.x = robot.x - 5
        if robot.y < hrac.y:
            robot.y = robot.y + 5
        elif robot.y > hrac.y:
            robot.y = robot.y - 5
        move_to(robot.telo, robot.x, robot.y)
        sleep(0.2)

Přijde mi, jako by si ti roboti v seznamu nedokázali pamatovat svoje
.x a .y nebo spíš za toho robota, kterým se má hýbat, byl pokládán
pořád jeden a ten samý, protože se hýbe mnohem rychleji než hráč. Tomu
by nasvědčovalo i to, že jsem kdesi četl, že jména v Pythonu jsou
prakticky jen odkazy na objekty.


Nakonec jsem to vyřešil metodami třídy Robot:
    #Metoda na výrobu robotů
	def vyrobRoboty(self):
        self.x = random.randint(8, 631)
        self.y = random.randint(8, 471)
        self.srot = 0
        hrac.xround = hrac.x / 10
        hrac.yround = hrac.y / 10
        self.telo = box(self.x-5, self.y-5, self.x+5, self.y+5,
filled=1, colour=Colour.dark_blue)
    # Metoda na posun roboty
    def posunRobota(self):
        if self.srot == 0:
            if self.x < hrac.x:
                self.x = self.x + 5
            elif self.x > hrac.x:
                self.x = self.x - 5
            if self.y < hrac.y:
                self.y = self.y + 5
            elif self.y > hrac.y:
                self.y = self.y - 5
            sleep(0.02)
            move_to(self.telo, self.x, self.y)

robot.vyrobRoboty()
robot2.vyrobRoboty()
robot3.vyrobRoboty()
robot4.vyrobRoboty()
robot5.vyrobRoboty()
robot.posunRobota()
robot2.posunRobota()
robot3.posunRobota()
robot4.posunRobota()
robot5.posunRobota()

Ale jak vidíte, už tohle je příšerně zdlouhavé a ještě  při běhu musím
volat další tři metody a funkce, která má zajišťovat, aby při narození
neskončil jeden robot na druhém je dlouhá pomalu jako epos o
Gilgamešovi. Ukázka:
        elif self == robot3:
            while self.xround == robot.xround and self.xround == robot.yround:
                self.x = random.randint(8, 631)
                self.y = random.randint(8, 471)
            while self.xround == robot2.xround and self.xround == robot2.yround:
                self.x = random.randint(8, 631)
                self.y = random.randint(8, 471)

V tutoriálech které jsem četl se při psaní o seznamech věnují spíše
textovým řetězcům. Věřím, že kdyby se dal v tomto případě použít
seznam, o něco by se to zkrátilo a navíc by to zjednodušilo přidávání
dalších robotů v dalších levelech atd. atd. Asi bych mohl ten program
sice dodělat tímto stylem, ale s výsledkem bych nemohl být spokojen.

Díky za jakékoliv rady.
Tomáš Bělonožník

--
"Any fool who would die for honor is better off dead." - Cabal Patriarch
"I don't know what the next World War will be fought with, but the
World War after that will be fought with sticks and stones." - Albert
Einstein


Další informace o konferenci Tutor