[Tutor PyCZ] Roboti Přicházejí - Final(?)

geon geon na post.cz
Pátek Březen 24 18:35:45 CET 2006


Tomáš Bělonožník napsal(a):
> Ahoj,
> tak jsem se rozhodl že vám sem postnu link na dodělanou hru Roboti
> Přicházejí. 
 > # Funkce na výrobu robotova těla.
 > def vyrobRobota(hrac, seznam):
    > p = 0
    > for i in range(20):
        > robot = Robot()
        > robot.x=random.randint(1, 63)                  
        > robot.y=random.randint(1, 47)

Tyto (horní) dva řádky, se ti v programu minimálně dvakrát --> je 
vhodnější z toho udělat funkci


        > robot.xsrot = 0
        > robot.ysrot = 0

TO jsem moc nepochopil -- proc zjistujes a nastavujes x,y souradnice 
srotu? Vzdyt muzes pouzit poslední souradnice pred smrtí... (pak se již 
nehýbe)

        > robot.srot = 0
        > # Část funkce zajišťující, že hráč a robot nezačnou na sobě.
        > while robot.x == hrac.x and robot.y == hrac.y:
            > robot.x=random.randint(1, 63)
            > robot.y=random.randint(1, 47)
        > # Část, která by měla zajišťovat, že roboti nezačnou na sobě.
        > # Výsledek asi hodinového uvažování. Základ ostatních funkcí 
kontroly kolizí.
        > for n in range(p):
            > if robot.x == seznam[n].x and robot.y == seznam[n].y:
                > robot.x = random.randint(1, 63)
                > robot.y = random.randint(1, 47)

Jinými slovy - horní řádky kontrolují, jestli se robot nesrazil s jinými 
roboty.. ale to by mělo být velmi stejné jako při kontrole obyčejných 
srážek ---> funkce

        > p = p+1
        > seznam.append(robot)
 >           
        > robot.telo = 
box(robot.x*10-5,robot.y*10-5,robot.x*10+5,robot.y*10+5, filled=1, 
colour=Colour.dark_blue)    # Popis těla robota
    > return robot, seznam
 >    
 > # Mění hráčovy koordináty dle stisků kláves, ale nepohybuje jím.
 > # Je tu i možnost 5x se nechat přesunout na náhodné místo plochy - 
"teleportace".
 > def zmena_XY_hr(hrac, teleportace):
        > if "2" in klavesy:                     
            > hrac.y = hrac.y - 1   
        > elif "8" in klavesy:
            > hrac.y = hrac.y + 1
        > elif "4" in klavesy:
            > hrac.x = hrac.x - 1
        > elif "6" in klavesy:
            > hrac.x = hrac.x + 1
        > elif "1" in klavesy:
            > hrac.x = hrac.x - 1
            > hrac.y = hrac.y - 1
        > elif "3" in klavesy:
            > hrac.x = hrac.x + 1
            > hrac.y = hrac.y - 1
        > elif "7" in klavesy:
            > hrac.x = hrac.x - 1
            > hrac.y = hrac.y + 1
        > elif "9" in klavesy:
            > hrac.x = hrac.x + 1
            > hrac.y = hrac.y + 1
        > elif teleportace < 5:


moooc velký krok --- já jsem experimentálně určil krok=0.02 a pro roboty 
třetinový (aby se vždy vyhrálo ;-) )
Znám jednu poučku, která říká, že mnoho if/elif se dá řešit elegantněji 
nějakou datovou strukturou. Ale v tomto případě mě nic nenapadá. Věděl 
by někdo?

            > if "t" in klavesy:
                > hrac.x = random.randint(1, 63)
                > hrac.y = random.randint(1, 47)
                > teleportace = teleportace + 1
                > sleep(0.1)
        > return hrac, teleportace
 >
 > # Funkce, která posouvá robotem do osmi směrů tak, aby pronásledoval 
hráče.
 > # Dále kontroluje kolize robot-robot a vytváří šrot.
 > def posunRobota(robot):
    > p = 0
    > for robot in seznam:
        > if robot.srot == 0:
            > if robot.x < hrac.x:
                > robot.x = float(robot.x) + 0.5
            > elif robot.x > hrac.x:
                > robot.x = float(robot.x) - 0.5
            > if robot.y < hrac.y:
                > robot.y = float(robot.y) + 0.5
            > elif robot.y > hrac.y:
                > robot.y = float(robot.y) - 0.5
            > move_to(robot.telo, float(robot.x)*10, float(robot.y)*10)
            > for n in range(p):
                > if robot.x == seznam[n].x and robot.y == seznam[n].y:
                    > remove_from_screen(robot.telo)
                    > robot.xsrot = robot.x
                    > robot.ysrot = robot.y
                    > robot.srotelo = 
box(robot.xsrot*10-5,robot.ysrot*10-5,robot.xsrot*10+5,robot.ysrot*10+5, 
filled=0, colour=Colour.dark_blue)
                    > robot.x = 0
                    > robot.y = 0
                    > robot.srot = 1
                    > return robot

[1] myslím, že když se srazí dva roboti, tak jeden musí zmizet a z 
druhého se stane srot. Musí zmizet ze seznamu a z druhého je srot (bez 
ohledu na to, jestli jiz srotem byl), který v seznamu zůstává. 

            > p = p+1
        > sleep(0.0025)

to bych dal pryč, protože jsme zjemnili krok

 >        
 > # Tato funkce pohne hráčem podle koordinátů upravených ve funkci 
zmena_XY       
 > def posunHrace():                              
    > move_to(hrac.telo, hrac.x*10, hrac.y*10)
 >
 > # Funkce znemožňující hráčův pohyb za okraj hrací plochy
 > def kontrola_plochy(hrac):
    > if hrac.x < 1:
       > hrac.x = 1
 >       
    > elif hrac.x > 63:
       > hrac.x = 63
 >       
    > if hrac.y < 1:
       > hrac.y = 1
 >       
    > elif hrac.y > 47:
       > hrac.y = 47
    > move_to(hrac.telo, hrac.x*10, hrac.y*10)
    > return hrac
 >    
 > # Kontrola srážky hráče s robotem
 > def kontrola_srazky(konec_sub):
    > for robot in seznam:
        > if float(robot.x) == float(hrac.x)  and float(robot.y) == 
float(hrac.y):

tady si myslím že je největší chyba - takto se souřadnice musí shodovat 
absolutně přesně - proto často "očividné" srážky nezpůsobí nic. Je lepší 
použít nepřesnější, zato přirozenější funkci round()
            > konec_sub = 1
            > return konec_sub
        > elif robot.xsrot == hrac.x and robot.ysrot == hrac.y:
            > konec_sub = 1
            > return konec_sub
 >
 > # Kontrola srážky robota se šrotem
 > def kontrola_srazky_robotu(robot):
    > p = 0
    > for robot in seznam:
        > for n in range(10):
            > if robot.x == seznam[n].xsrot and robot.y == seznam[n].ysrot:
                > remove_from_screen(robot.telo)
                > robot.x = 800
                > robot.y = 800
                > robot.srot = 2
                > return robot

tak nevím,  - -já myslel že tohle testování je už tam nahoře [1]- 
připadá mi to tu dvojité

        > p = p+1
 >
 > # Funkce kontrolující, jestli hráč nezvítězil.
 > def vyhra():
    > check = 0
    > vyhra_seznam = []
    > for robot in seznam:
        > if robot.srot != 0:
            > vyhra_seznam.append("yes")
        > else:
            > vyhra_seznam.append("no")
    > for n in range(20):
        > if vyhra_seznam[n] == "yes":
            > check = check + 1
    > if check == 20:
        > vyhra_v = 1
        > return vyhra_v

pokud se hrac srazi s robotem (at zivim nebo mrtvým), tak to je jasné, 
to řešíš jinde. tady se řeší jak poznat, jestli tam již není žádný 
"živý" robot, že jo? nedá se to nějak jednodušeji?např. při posunu 
robotů počítat, kolik jsme jich posunuly (kolik jeich není srotem). No a 
pokud je to číslo 0, tak huuuurrrrááááá!

 >    
 >        
 > ###################   
 > # SAMOTNÝ PROGRAM #
 > ###################
 >
 > # Vytváří okraj hrací plochy
 > box(4,4,636,476)
 > box(5,5,635,475)                       
 > # Výroba objektů
 > hrac = vyrobHrace()       
 > robot, seznam = vyrobRobota(hrac, seznam)
 > # Počátek herního cyklu
 > while konec != 2:
    > klavesy = keys_pressed()
    > # Spuštení hráčovy posunové dvoj-funkce
    > hrac, teleportace = zmena_XY_hr(hrac, teleportace)
    > posunHrace()
    > # Kontrola, jestli není hráč za okrajem plochy, posunutí robotem a 
případné vyhodnocení kolize
    > hrac = kontrola_plochy(hrac)
    > # Posun robotem a kontrola kolizi
    > robot = posunRobota(robot)
    > konec_sub = kontrola_srazky(konec_sub)
    > robot = kontrola_srazky_robotu(robot)
    > # Funkce kontrolující, jestli hráč nezvítězil.
    > vyhra_v = vyhra()
    > # Ukončení hry v případě srážky.
    > if konec_sub == 1:
        > print "Prohrál jsi!"
        > konec = 2
    > # Ukončení hry v případě výhry.
    > elif vyhra_v == 1:
        > print "Vyhrál jsi!"
        > konec = 2
    > # Přerušení hry uživatelem.
    > if "q" in klavesy:
        > konec = 2
 >        
 > end_graphics()  # Tjádadýdadá...to je konec.          


nebylo by to přehlednější nějak takto?


while not koncime:
    posunHrace()
    posunRobota()
    kontrolaSrazek()


Pokud budeš chtít, pošlu ti mé řešení, ale radši to sem nedávám rovnou, 
abych ti nekazil radost.

Ahoj!!!

-- 
geon
volume doprava.



Další informace o konferenci Tutor