Naloge - dedovanje (Želva)

Začnite z razredom Turtle, ki ste ga definirali na predavanjih. Naloge rešujte tako, da ustvarite nove razrede. Razreda Turtle ne smete spreminjati.

Želva z imenom

Napiši razred ZelvaZImenom, ki je izpeljan iz razreda Turtle. ZelvaZImenom se obnaša kot vsaka druga želva, le da ima, poleg vseh svojih atributov, še atribut ime, ki ga nastavimo v konstruktorju in metodo pozdrav.

i = ZelvaZImenom('Jožica') # Ustvari želvo z imenom Jožica
i.forward(100)
i.pozdrav() # izpiše 'Jaz sem želva Jožica'

Rešitev

class ZelvaZImenom(Turtle):
    def __init__(self, ime):
        super().__init__()
        self.ime = ime

    def pozdrav(self):
        print('Jaz sem želva', self.ime)

Čveka

Želva čveka je zelo glasna želva -- preden se premakne ali obrne, nas o tem obvesti. Želva čveka ima tudi ime in metodo pozdrav.

c = Cveka('Jožica') # Ustvari želvo čveko z imenom Jožica
c.forward(20) # izpiše 'Jožica gre 20 korakov naprej'
c.turn(60) # izpiše 'Jožica se obrača za 60 stopinj'
c.forward(20) # izpiše 'Jožica gre 20 korakov naprej'
c.pozdrav() # izpiše 'Jaz sem želva Jožica'

Rešitev

class Cveka(ZelvaZImenom):
    def forward(self, l):
        super().forward(l)
        print(self.ime, 'gre naprej', l)

    def turn(self, angle):
        super().turn(angle)
        print(self.ime, 'se obrača', angle)

Rdečevratka

Želva rdečevratka nima imena. Ima pa vse ostale lastnosti navadne želve. Poleg tega:

  • ima rdeč vrat.

    zelva

    Krogu, ki je že narisan lahko spremenite barvo tako, da na vrhu programa napišete

    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    

    Krog pa pobarvate z ukazom

    self.head.setPen(QPen(QBrush(risar.rdeca), 3))
    
  • se premika dvakrat počasneje kot navadna želva.

    # Zelva Rdecevratka je počasna zelva
    r = Rdecevratka()
    r.forward(40)
    r.turn(90)
    r.forward(50)
    t = Turtle()
    t.forward(40)
    t.turn(90)
    t.forward(50)
    

    zelva

  • se ne zna dobro skriti -- skrije se tako, da glavo povleče v oklep.

    r = Rdecevratka()
    r.hide()
    

    zelva

Rešitev

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Rdecevratka(Turtle):
    def __init__(self):
        super().__init__()
        self.head.setPen(QPen(QBrush(risar.rdeca), 3))

    def forward(self, l):
        super().forward(l // 2)

    def hide(self):
        self.head.hide()

Vojska Želv

Definirajte razred VojskaZelv. Konstruktor naj sprejme število želv v vojski in naj jih razporedi tako kot je prikazano na sliki.

vojska = VojskaZelv(5)

army1

Želeli bi, da bi se vse želve v vojski premikale enako. Razredu VojskaZelv dodajte metodo forward, ki pokliče metodo forward vseh želv v vojski. Na enak način razredu VojskaZelv dodajte metodo turn.

vojska = VojskaZelv(5)
vojska.forward(50)
vojska.turn(30)
vojska.forward(50)

army2

Rešitev

# Razred VojskaZelv ni izpeljan iz razreda Turtle.
class VojskaZelv:
    def __init__(self, n):
        self.vojaki = []
        for i in range(n):
            t = Turtle()
            t.fly(t.x + i * 20, t.y, t.angle)
            self.vojaki.append(t)

    def forward(self, n):
        for t in self.vojaki:
            t.forward(n)

    def turn(self, angle):
        for t in self.vojaki:
            t.turn(angle)

Pijanka

Želva pijanka je vesela želva -- pred vsakim premikom se želva pijanka zmede in naključno spremeni svoj kot. Velikost naključne spremembe je seveda sorazmerna s številom popitih kozarcev. Po prvem kozarcu je velikost spremembe od -5 do 5 stopinj, po drugem kozarcu od -10 do 10 stopinj, itd. Po petih popitih kozarcih želva pijanka obleži, zato se ne premika več.

# Zelva pijanka po stirih popitih kozarcih
p = Pijanka()
p.drink()
p.drink()
p.drink()
p.drink()
for i in range(20):
    p.forward(10)

zelva

# Zelo pijana zelva pijanka se ne premika
p = Pijanka()
p.drink()
p.drink()
p.drink()
p.drink()
p.drink()
p.turn(45)
p.forward(100)

zelva

Rešitev

import random

class Pijanka(Turtle):
    def __init__(self):
        super().__init__()
        self.drinks = 0

    def drink(self):
        self.drinks += 1

    def forward(self, l):
        if self.drinks < 5:
            self.angle += random.randint(-self.drinks * 5, self.drinks * 5)
            super().forward(l)

    def turn(self, angle):
        if self.drinks < 5:
            super().turn(angle)

Pravokotnica

Želva pravokotnica je posebna želva -- premika se lahko le v vodoravni in navpični smeri. Če ji ukažemo drugače, bo premik opravila v dveh korakih: najprej v navpični, nato v vodoravni smeri.

p = Pravokotnica()
p.turn(30)
p.forward(20)
p.forward(20)
p.forward(20)
p.forward(20)
p.turn(100)
p.forward(100)

zelva

Rešitev

import math

class Pravokotnica(Turtle):
    def forward(self, l):
        angle = math.radians(90 - self.angle)
        nx, ny = l*math.cos(angle), l*math.sin(angle)

        angle_old = self.angle
        self.angle = 0
        super().forward(ny)
        self.angle = 90
        super().forward(nx)
        self.angle = angle_old
        self.update()

Množenje

Želve se lahko množijo -- ko se dve želvi zmnožita, ustvarita novo želvo na koordinatah (0, 0). Želvi se lahko množita le če sta dovolj blizu (manj kot 10 pikslov narazen). Pri tej nalogi lahko izjemoma spremenite razred Turtle tako, da mu dodate ustrezno metodo.

oce = Turtle()
mati = Turtle()
sin = oce * mati

oce.forward(20)
oce.turn(30)
oce.forward(20)

mati.forward(20)
mati.turn(-30)
mati.forward(20)

zelva

oce = Turtle()
oce.forward(100)
mati = Turtle()
sin = oce * mati # Zelvi nista dovolj blizu. Program naj vrze napako.

Rešitev

# Razredu Turtle dodajte metodo __mul__
    def __mul__(self, other):
        if (self.x - other.x)**2 + (self.y - other.y)**2 > 10**2:
            raise ConnectionRefusedError()
        return Turtle()

Last modified: Friday, 15 January 2021, 1:13 PM