Kann man so etwas wie Karol auch in Python programmieren? Bestimmt! Wenn man genug Zeit dazu hat…

Aber man kann ja zumindest mal damit anfangen und dieses Projekt nutzen, um Python zu lernen! Wer möchte, darf sich gerne beteiligen!

Version 0.0.1

Es gibt eine Klasse „Welt“ und eine Klasse „Roboter“. Der Roboter kann sich in der Welt bewegen und Ziegel hinlegen. Die Anzahl der Ziegel kann auch direkt festgelegt werden.

class Welt(object):
 
    # Konstruktor
    def __init__(self,laenge=10,breite=10,hoehe=10):
        self.Laenge = laenge
        self.Breite = breite
        self.Hoehe  = hoehe
 
        # eine zweidimensionale Liste anlegen und mit Nullen füllen
        self.Ziegel = []
        for j in range(laenge):
            reihe = []
            for i in range(breite):
                reihe.append(0)
            self.Ziegel.append(reihe)
 
    # Anzahl der Ziegel an einer bestimmten Position direkt eingeben
    def setZiegel(self,x,y,anzahl):
        self.Ziegel[x][y] = anzahl
 
    # Anzahl der Ziegel an einer bestimmten Position um 1 erhöhen
    def hinlegenZiegel(self,x,y):
        self.Ziegel[x][y] += 1
 
class Roboter(object):
 
    # Konstruktor
    def __init__(self,welt,posx=0,posy=0,richtung=1):
        self.Welt = welt            # Richtungen:    +1
        self.Posx = posx            #              -2  +2
        self.Posy = posy            #                -1
        self.Richtung = richtung
 
    # ein Feld nach vorne gehen
    def schritt(self):
        self.Posx += self.Richtung / 2
        self.Posy += self.Richtung % 2
 
    # nach rechts drehen
    def rechtsDrehen(self):
        if self.Richtung == 1:
            self.Richtung = 2
        elif self.Richtung == 2:
            self.Richtung = -1
        elif self.Richtung == -1:
            self.Richtung = -2
        else:
            self.Richtung = 1
 
    # nach links drehen
    def linksDrehen(self):
        self.rechtsDrehen()
        self.Richtung *= -1
 
    # einen Ziegel vor den Roboter legen
    def hinlegen(self):
        ziegelposx = self.Posx + self.Richtung / 2
        ziegelposy = self.Posy + self.Richtung % 2        
        self.Welt.hinlegenZiegel(ziegelposx,ziegelposy)

Die Ausgabe erfolgt zunächst über die Kommandozeile mit diesen Prozeduren:

from RobbiDaten import *
 
def weltausgeben(welt):
    print "Länge: ",welt.Laenge
    print "Breite:",welt.Breite
    print "Höhe:  ",welt.Hoehe
    for j in range(welt.Laenge-1,-1,-1):
        for i in range(welt.Breite):
            print welt.Ziegel[i][j],
        print
 
def roboterausgeben(roboter):
    print "Koordinaten:",roboter.Posx, roboter.Posy
    print "Richtung:   ",roboter.Richtung
 
def allesausgeben(welt,roboter):
    print "Länge: ",welt.Laenge
    print "Breite:",welt.Breite
    print "Höhe:  ",welt.Hoehe
    for j in range(welt.Laenge-1,-1,-1):
        for i in range(welt.Breite):
            if roboter.Posx == i and roboter.Posy == j:
                print "X",
            else:
                print welt.Ziegel[i][j],
        print

Testen von der Python-Shell aus:

>>> w=Welt()
>>> r=Roboter(w)
>>> r.hinlegen();r.schritt()
>>> r.hinlegen();r.schritt()
>>> r.hinlegen();r.schritt()
>>> r.rechtsDrehen()
>>> r.hinlegen();r.schritt()
>>> r.hinlegen();r.schritt()
>>> r.schritt()
>>> allesausgeben(w,r)
Länge:  10
Breite: 10
Höhe:   10
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 X 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Es fehlt eine Überprüfung, ob der Roboter am Rand der Welt angelangt ist sowie die Roboter-Methode „aufheben“.

Version 0.1.0

Die oben fehlende Überprüfung ist eingefügt: Der Roboter kennt nun seine Welt und kann vor jeder Aktion überprüfen, ob er sie durchführen kann. Die Koordinaten des Roboters wurden geändert und die Richtung des Roboters ist nun ein 2-dimensionaler Vektor.

Eine große Änderung besteht in der Bedienung durch eine grafische Benutzeroberfläche. Diese wurde mit dem Modul Tkinter geschrieben.

Darüber hinaus lässt sich der Roboter mit folgenden Befehlen programmieren:

  • schritt
  • rechtsdrehen
  • linksdrehen
  • hinlegen
  • aufheben
  • wiederhole n mal

    *wiederhole

Das Robbie-Programm kann gespeichert und wieder geladen werden.

So sieht das Programm bisher aus:

class Welt(object):
 
    # Konstruktor
    def __init__(self,laenge=10,breite=10,hoehe=10):
        self.Laenge = laenge
        self.Breite = breite
        self.Hoehe  = hoehe
 
        # eine zweidimensionale Liste anlegen und mit Nullen füllen
        self.Ziegel = [[0 for i in range(breite)] for j in range(laenge)]
 
    # Anzahl der Ziegel an einer bestimmten Position direkt eingeben
    def setZiegel(self,x,y,anzahl):
        self.Ziegel[x][y] = anzahl
 
    # Anzahl der Ziegel an einer bestimmten Position um 1 erhöhen
    def hinlegenZiegel(self,x,y):
        if self.Ziegel[x][y] < self.Hoehe:
            self.Ziegel[x][y] += 1
 
    # Anzahl der Ziegel an einer bestimmten Position um 1 erniedrigen
    def aufhebenZiegel(self,x,y):
        if self.Ziegel[x][y] > 0:
            self.Ziegel[x][y] -= 1
 
 
class Roboter(object):
 
    # Konstruktor
    def __init__(self,welt,posx=0,posy=0,richtung=[1,0]):
        self.Welt = welt            
        self.Posx = posx            
        self.Posy = posy            
        self.Richtung = richtung
 
    # ein Feld nach vorne gehen, falls möglich
    def schritt(self):
        self.Posx += self.Richtung[0]
        if self.Posx < 0: self.Posx = 0
        if self.Posx > self.Welt.Laenge - 1:
            self.Posx = self.Welt.Laenge - 1
        self.Posy += self.Richtung[1]
        if self.Posy < 0: self.Posy = 0
        if self.Posy > self.Welt.Breite - 1:
            self.Posy = self.Welt.Breite - 1
 
    # nach rechts drehen
    def rechtsDrehen(self):
        if self.Richtung == [1,0]:
            self.Richtung = [0,1]
        elif self.Richtung == [0,1]:
            self.Richtung = [-1,0]
        elif self.Richtung == [-1,0]:
            self.Richtung = [0,-1]
        else:
            self.Richtung = [1,0]
 
    # nach links drehen
    def linksDrehen(self):
        if self.Richtung == [1,0]:
            self.Richtung = [0,-1]
        elif self.Richtung == [0,1]:
            self.Richtung = [1,0]
        elif self.Richtung == [-1,0]:
            self.Richtung = [0,1]
        else:
            self.Richtung = [-1,0]
 
    # einen Ziegel vor den Roboter legen falls möglich
    def hinlegen(self):
        ziegelposx = self.Posx + self.Richtung[0]
        ziegelposy = self.Posy + self.Richtung[1]
        if 0 <= ziegelposx < self.Welt.Laenge and 0<= ziegelposy < self.Welt.Breite:
            self.Welt.hinlegenZiegel(ziegelposx,ziegelposy)
            return True
        else:
            return False
 
    # einen Ziegel vor dem Roboter aufheben falls möglich
    def aufheben(self):
        ziegelposx = self.Posx + self.Richtung[0]
        ziegelposy = self.Posy + self.Richtung[1]        
        if 0 <= ziegelposx < self.Welt.Laenge and 0<= ziegelposy < self.Welt.Breite:
            self.Welt.aufhebenZiegel(ziegelposx,ziegelposy)
            return True
        else:
            return False

Dies war der Daten-Teil. Jetzt folgt die GUI. Was noch überhaupt nicht schön ist: der Robbi-Interpreter steht noch in der GUI, wo er eigentlich nicht hingehört.

from RobbiDaten import *
#from RobbiShell import *
#from RobbiInter import *
#from tkFileDialog   import askopenfilename
 
from Tkinter import *
import tkFileDialog     
 
#from tkMessageBox import *
#from tkColorChooser import askcolor              
 
 
class GUI:
 
    def __init__(self,roboter):
 
        # Daten-Objekte
        self.Roboter = roboter
        self.Ziegel = [[0 for i in range(10)] for j in range(10)]
 
        # GUI-Objekte definieren
        self.fenster = Tk()
        self.fenster.title("Robbi Roboter")
        self.frame1 = Frame(master=self.fenster)
        self.frame2 = Frame(master=self.fenster)
        self.welt2d = Canvas(master=self.frame1, width=511, height=511, bg="white")
        self.eingabe = Text(master=self.frame1, width=40, height=36, bg = "#f0f0f0")
        self.buttonQuit = Button(master=self.frame2, text="Quit", command=self.fenster.quit)
        self.buttonNeueWelt = Button(master=self.frame2, text="Neue Welt", command=self.welt2dzeichnen)
        self.buttonSchritt = Button(master=self.frame2, text="Schritt", command=self.schritt)
        self.buttonLinks = Button(master=self.frame2, text="Linksdrehen", command=self.linksdrehen)
        self.buttonRechts = Button(master=self.frame2, text="Rechtsdrehen", command=self.rechtsdrehen)
        self.buttonHinlegen = Button(master=self.frame2, text="Hinlegen", command=self.hinlegen)
        self.buttonAufheben = Button(master=self.frame2, text="Aufheben", command=self.aufheben)
        self.buttonAusfuehren = Button(master=self.frame1, text ="Ausführen", command=self.ausfuehrenclick)
        self.buttonLaden = Button(master=self.frame1, text ="Laden", command=self.laden)
        self.buttonSpeichern = Button(master=self.frame1, text ="Speichern", command=self.speichern)
 
 
        # GUI-Objekte anordnen
        self.frame1.pack()
        self.frame2.pack()
        self.welt2d.pack(expand=YES, fill=BOTH, side=LEFT)
        self.eingabe.pack(side=TOP)
        self.buttonNeueWelt.pack(side=RIGHT)
        self.buttonQuit.pack(side=LEFT)
        self.buttonSchritt.pack(side=LEFT)
        self.buttonLinks.pack(side=LEFT)
        self.buttonRechts.pack(side=LEFT)
        self.buttonHinlegen.pack(side=LEFT)
        self.buttonAufheben.pack(side=LEFT)
        self.buttonAusfuehren.pack(side=LEFT)
        self.buttonLaden.pack(side=LEFT)
        self.buttonSpeichern.pack(side=LEFT)
 
 
    # Gitter zeichnen
    def welt2dzeichnen(self):
        self.welt2d.create_rectangle(10,10,510,510)
        for i in range(10,510,50):
            self.welt2d.create_line(10,i,510,i)
        for i in range(10,510,50):
            self.welt2d.create_line(i,10,i,510)
 
    # Alle Ziegel zeichnen (Zahl oder leerer String)
    def ziegelzeichnen(self):
        for j in range(10):
            for i in range(10):
                te=str(self.Roboter.Welt.Ziegel[i][j])
                if te =="0":te=""
                self.Ziegel[i][j]=self.welt2d.create_text(i*50+35,j*50+35,text=te)
 
    # Roboter (Dreieck) zeichnen)
    def roboterzeichnen(self):
        robx = 50*self.Roboter.Posx + 35
        roby = 50*self.Roboter.Posy + 35
        if self.Roboter.Richtung == [0,1]:
            self.dreieck=self.welt2d.create_polygon(robx-25,roby-25,robx+25,roby-25,robx,roby+25)    
        elif self.Roboter.Richtung == [0,-1]:
            self.dreieck=self.welt2d.create_polygon(robx-25,roby+25,robx+25,roby+25,robx,roby-25)    
        elif self.Roboter.Richtung == [1,0]:
            self.dreieck=self.welt2d.create_polygon(robx-25,roby-25,robx-25,roby+25,robx+25,roby)    
        elif self.Roboter.Richtung == [-1,0]:
            self.dreieck=self.welt2d.create_polygon(robx+25,roby+25,robx+25,roby-25,robx-25,roby)    
 
    # Roboter bewegen und neu zeichnen
    def schritt(self):
        self.welt2d.delete(self.dreieck)
        self.Roboter.schritt()
        self.roboterzeichnen()
 
    # Roboter nach links drehen und neu zeichnen
    def linksdrehen(self):
        self.welt2d.delete(self.dreieck)
        self.Roboter.linksDrehen()
        self.roboterzeichnen()
 
    # Roboter nach links drehen und neu zeichnen
    def rechtsdrehen(self):
        self.welt2d.delete(self.dreieck)
        self.Roboter.rechtsDrehen()
        self.roboterzeichnen()
 
    # Ziegel hinlegen und veränderten Ziegel neu zeichnen
    def hinlegen(self):
        if self.Roboter.hinlegen():
            neuziegelx = self.Roboter.Posx + self.Roboter.Richtung[0]
            neuziegely = self.Roboter.Posy + self.Roboter.Richtung[1]
            te=str(self.Roboter.Welt.Ziegel[neuziegelx][neuziegely])
            if te =="0":te=""
            self.welt2d.itemconfig(self.Ziegel[neuziegelx][neuziegely],text=te)
 
    # Ziegel aufheben und veränderten Ziegel neu zeichnen
    def aufheben(self):
        if self.Roboter.aufheben():
            neuziegelx = self.Roboter.Posx + self.Roboter.Richtung[0]
            neuziegely = self.Roboter.Posy + self.Roboter.Richtung[1]
            te=str(self.Roboter.Welt.Ziegel[neuziegelx][neuziegely])
            if te =="0":te=""
            self.welt2d.itemconfig(self.Ziegel[neuziegelx][neuziegely],text=te)
 
    def ausfuehrenclick(self):
        eingabe = self.eingabe.get("1.0",END)
        programm = eingabe.split()
        for i in range(len(programm)):
            if   programm[i] == "wiederhole": programm[i] = "w"
            elif programm[i] == "*wiederhole": programm[i] = "*w"
            elif programm[i] == "schritt": programm[i] = "s"
            elif programm[i] == "rechtsdrehen": programm[i] = "r"
            elif programm[i] == "linksdrehen": programm[i] = "l"
            elif programm[i] == "aufheben": programm[i] = "a"
            elif programm[i] == "hinlegen": programm[i] = "h"
 
        self.ausfuehren(programm)
 
    def ausfuehren(self,liste):
        print liste
        merke = [0,0,0,0]
        schleifenzaehler = [0,0,0,0]
        schleife = -1
 
        i = 0
        while i < len(liste):
            if liste[i] == "w":
                schleife += 1
                i += 1
                schleifenzaehler[schleife] = int(liste[i])
                merke[schleife]=(i+1)
            elif liste[i] == "*w":
                if schleifenzaehler[schleife] > 1:
                    schleifenzaehler[schleife] -= 1
                    i = merke[schleife] - 1
                else:
                    schleife -=1
            elif liste[i] == "s":
                self.schritt()
            elif liste[i] == "r":
                self.rechtsdrehen()
            elif liste[i] == "l":
                self.linksdrehen()
            elif liste[i] == "h":
                self.hinlegen()
            elif liste[i] == "a":
                self.aufheben()
            i += 1
 
    def laden(self):
        filename = tkFileDialog.askopenfilename()
        programmdatei = open(filename,"r")
        self.eingabe.delete("1.0",END)
        for zeile in programmdatei:
            self.eingabe.insert(END,zeile)
        programmdatei.close()
 
 
    def speichern(self):
        filename = tkFileDialog.asksaveasfilename()
        programmdatei = open(filename,"w")
        programmdatei.write(self.eingabe.get("1.0",END))
        programmdatei.close()
 
 
w=Welt()                    # Welt der Größe 10x10
r=Roboter(w)                # Roboter in dieser Welt
gui = GUI(r)                # Grafische Oberfläche initialisieren
gui.roboterzeichnen()       # Den Roboter einzeichnen
gui.ziegelzeichnen()        # Die Ziegel einzeichnen
gui.welt2dzeichnen()        # Das Gitter zeichnen
gui.fenster.mainloop()      # Auf Buttonklick warten
Cookies helfen bei der Bereitstellung von Inhalten. Durch die Nutzung dieser Seiten erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Rechner gespeichert werden. Weitere Information
Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht: CC Attribution-Noncommercial-Share Alike 4.0 International