Links und Funktionen
Sprachumschaltung

Navigationspfad
Sie sind hier: Startseite / Probestudium / 2013 / WS I: 3D-Programmierung / Arbeitsgruppen 2013 / Mensch-Ärgere-Dich-Nicht SP


Inhaltsbereich

Mensch-Ärgere-Dich-Nicht SP

Python Source icon fertigSp.py — Python Source, 17 KB (18407 bytes)

Dateiinhalt

from visual import *
import copy
# Colormap: rot = 0, blau = 1, gruen = 2, gelb = 3

#Wichtigste Klasse, initalisiert Graphik und macht Bewegungen
class Spielfeld():
    def __init__(self): 
        self.boxMain = box(pos=(0,-0.25,0),length=11,height=0.5, width=11)  #Spielfeld
        
        self.goal = [0,0,0,0]   #Spielstand        
        self.colorStartField = [0,10,20,30] #Startfeld fuer Figuren einer Farbe die aus dem Haus kommen
        self.colorEndField = [39,9,19,29] #Endfeld fuer Figuren einer Farbe die aus dem Haus kommen
        
        # Array der Spieler: self.p[x][y] mit x = color und y = Nummer des Spielers eines Teams
        self.p = [[Player((1,0,0)),Player((1,0,0)),Player((1,0,0)),Player((1,0,0))],[Player((0,0,1)),Player((0,0,1)),Player((0,0,1)),Player((0,0,1))],[Player((0,1,0)),Player((0,1,0)),Player((0,1,0)),Player((0,1,0))],[Player((1,1,0)),Player((1,1,0)),Player((1,1,0)),Player((1,1,0))]]
        # Setzt die Startposition der Figuren
        self.p[0][0].pos = (-5,0,-4)
        self.p[0][1].pos = (-5,0,-5)
        self.p[0][2].pos = (-4,0,-4)
        self.p[0][3].pos = (-4,0,-5)
        self.p[1][0].pos = (5,0,-4)
        self.p[1][1].pos = (5,0,-5)
        self.p[1][2].pos = (4,0,-4)
        self.p[1][3].pos = (4,0,-5)
        self.p[2][0].pos = (5,0,4)
        self.p[2][1].pos = (5,0,5)
        self.p[2][2].pos = (4,0,4)
        self.p[2][3].pos = (4,0,5)
        self.p[3][0].pos = (-5,0,4)
        self.p[3][1].pos = (-5,0,5)
        self.p[3][2].pos = (-4,0,4)
        self.p[3][3].pos = (-4,0,5)

        #Kopiert die Startpositionen in posCopy, damit die Ursprungsposition einer Figur gespeichert ist
        self.p[0][0].posCopy = (-5,0,-4)
        self.p[0][1].posCopy = (-5,0,-5)
        self.p[0][2].posCopy = (-4,0,-4)
        self.p[0][3].posCopy = (-4,0,-5)
        self.p[1][0].posCopy = (5,0,-4)
        self.p[1][1].posCopy = (5,0,-5)
        self.p[1][2].posCopy = (4,0,-4)
        self.p[1][3].posCopy = (4,0,-5)
        self.p[2][0].posCopy = (5,0,4)
        self.p[2][1].posCopy = (5,0,5)
        self.p[2][2].posCopy = (4,0,4)
        self.p[2][3].posCopy = (4,0,5)
        self.p[3][0].posCopy = (-5,0,4)
        self.p[3][1].posCopy = (-5,0,5)
        self.p[3][2].posCopy = (-4,0,4)
        self.p[3][3].posCopy = (-4,0,5)

        #Array der "Haus"-Felder: self.pRoot[x][y] mit x = color und y = Nummer des Hausfeldes eines Teams
        self.pRoot = [[PosFeld((1,0,0)),PosFeld((1,0,0)),PosFeld((1,0,0)),PosFeld((1,0,0))],None,None,None]
        self.pRoot[1] = [PosFeld((0,0,1)),PosFeld((0,0,1)),PosFeld((0,0,1)),PosFeld((0,0,1))]
        self.pRoot[2] = [PosFeld((0,1,0)),PosFeld((0,1,0)),PosFeld((0,1,0)),PosFeld((0,1,0))]
        self.pRoot[3] = [PosFeld((1,1,0)),PosFeld((1,1,0)),PosFeld((1,1,0)),PosFeld((1,1,0))]
        # Setzt die Position der "Haus"-Felder
        self.pRoot[0][0].pos = (-5,0,-4)
        self.pRoot[0][1].pos = (-5,0,-5)
        self.pRoot[0][2].pos = (-4,0,-4)
        self.pRoot[0][3].pos = (-4,0,-5)                
        self.pRoot[1][0].pos = (5,0,-4)
        self.pRoot[1][1].pos = (5,0,-5)
        self.pRoot[1][2].pos = (4,0,-4)
        self.pRoot[1][3].pos = (4,0,-5)
        self.pRoot[2][0].pos = (5,0,4)
        self.pRoot[2][1].pos = (5,0,5)
        self.pRoot[2][2].pos = (4,0,4)
        self.pRoot[2][3].pos = (4,0,5)
        self.pRoot[3][0].pos = (-5,0,4)
        self.pRoot[3][1].pos = (-5,0,5)
        self.pRoot[3][2].pos = (-4,0,4)
        self.pRoot[3][3].pos = (-4,0,5)

        #Array der "End"-Felder: self.pEnd[x][y] mit x = color und y = Nummer dse Endfeldes eines Teams
        self.pEnd = [[PosFeld((1,0,0)),PosFeld((1,0,0)),PosFeld((1,0,0)),PosFeld((1,0,0))],[PosFeld((0,0,1)),PosFeld((0,0,1)),PosFeld((0,0,1)),PosFeld((0,0,1))],[PosFeld((0,1,0)),PosFeld((0,1,0)),PosFeld((0,1,0)),PosFeld((0,1,0))],[PosFeld((1,1,0)),PosFeld((1,1,0)),PosFeld((1,1,0)),PosFeld((1,1,0))]]              
        # Setzt die Position der "End"-Felder
        self.pEnd[0][0].pos = (-4,0,0)
        self.pEnd[0][1].pos = (-3,0,0)
        self.pEnd[0][2].pos = (-2,0,0)
        self.pEnd[0][3].pos = (-1,0,0) 
        self.pEnd[1][0].pos = (0,0,-4)
        self.pEnd[1][1].pos = (0,0,-3)
        self.pEnd[1][2].pos = (0,0,-2)
        self.pEnd[1][3].pos = (0,0,-1)
        self.pEnd[2][0].pos = (4,0,0)
        self.pEnd[2][1].pos = (3,0,0)
        self.pEnd[2][2].pos = (2,0,0)
        self.pEnd[2][3].pos = (1,0,0)
        self.pEnd[3][0].pos = (0,0,4)
        self.pEnd[3][1].pos = (0,0,3)
        self.pEnd[3][2].pos = (0,0,2)
        self.pEnd[3][3].pos = (0,0,1)

        #Array der "neutralen"-Felder: self.pEnd[x] mit x = Nummer des Feldes startend beim roten Startfeld
        self.fieldNeutral = []
        for x in range(40):
            if x == 0:
                self.fieldNeutral.append(PosFeld((1,0,0)))  #rotes Startfeld
            elif x == 10:
                self.fieldNeutral.append(PosFeld((0,0,1)))  #blaues Startfeld
            elif x == 20:
                self.fieldNeutral.append(PosFeld((0,1,0)))  #gruenes Startfeld
            elif x == 30:
                self.fieldNeutral.append(PosFeld((1,1,0)))  #gelbes Startfeld
            else:
                self.fieldNeutral.append(PosFeld()) #schwarzes Feld
        # Setzt die Position der "neutralen"-Felder        
        self.fieldNeutral[0].pos= (-5,0,-1)
        self.fieldNeutral[1].pos= (-4,0,-1)
        self.fieldNeutral[2].pos= (-3,0,-1)
        self.fieldNeutral[3].pos= (-2,0,-1)
        self.fieldNeutral[4].pos= (-1,0,-1)
        self.fieldNeutral[5].pos= (-1,0,-2)
        self.fieldNeutral[6].pos= (-1,0,-3)
        self.fieldNeutral[7].pos= (-1,0,-4)
        self.fieldNeutral[8].pos= (-1,0,-5)
        self.fieldNeutral[9].pos= (0,0,-5)
        self.fieldNeutral[10].pos= (1,0,-5)
        self.fieldNeutral[11].pos= (1,0,-4)
        self.fieldNeutral[12].pos= (1,0,-3)
        self.fieldNeutral[13].pos= (1,0,-2)
        self.fieldNeutral[14].pos= (1,0,-1)
        self.fieldNeutral[15].pos= (2,0,-1)
        self.fieldNeutral[16].pos= (3,0,-1)
        self.fieldNeutral[17].pos= (4,0,-1)
        self.fieldNeutral[18].pos= (5,0,-1)
        self.fieldNeutral[19].pos= (5,0,0)
        self.fieldNeutral[20].pos= (5,0,1)
        self.fieldNeutral[21].pos= (4,0,1)
        self.fieldNeutral[22].pos= (3,0,1)
        self.fieldNeutral[23].pos= (2,0,1)
        self.fieldNeutral[24].pos= (1,0,1)
        self.fieldNeutral[25].pos= (1,0,2)
        self.fieldNeutral[26].pos= (1,0,3)
        self.fieldNeutral[27].pos= (1,0,4)
        self.fieldNeutral[28].pos= (1,0,5)
        self.fieldNeutral[29].pos= (0,0,5)
        self.fieldNeutral[30].pos= (-1,0,5)
        self.fieldNeutral[31].pos= (-1,0,4)
        self.fieldNeutral[32].pos= (-1,0,3)
        self.fieldNeutral[33].pos= (-1,0,2)
        self.fieldNeutral[34].pos= (-1,0,1)
        self.fieldNeutral[35].pos= (-2,0,1)
        self.fieldNeutral[36].pos= (-3,0,1)
        self.fieldNeutral[37].pos= (-4,0,1)
        self.fieldNeutral[38].pos= (-5,0,1)
        self.fieldNeutral[39].pos= (-5,0,0)
        

    #Methode, die berechnet ob playerFrame um die Anzahl field bewegt werden kann (return bool)
    def calcPossible(self,playerFrame,field):
        newField = playerFrame.fieldPos + field #neue Position der Figur
        
        #wenn im Endbereich
        if playerFrame.isEndZone:
            #wenn neue Position innerhalb des Endbereich
            if newField < 4:
                #wenn keine eigene Figur blockiert
                if self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color:
                    return True
            return False
        
        #wenn im Haus
        elif playerFrame.fieldPos == -1:   
            #wenn keine eigene Figur blockiert
            if (self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color) and field == 6:
                return True
            else:
                return False

        #wenn kommt in den Endbereich    
        elif newField > self.colorEndField[playerFrame.color]and (playerFrame.fieldPos < self.colorStartField[playerFrame.color] or playerFrame.color == 0):
            if newField < self.colorEndField[playerFrame.color] + 5:
                newField -= (self.colorEndField[playerFrame.color] +1)#neue Position auf das korrekte Endfeld setzten
                #wenn keine eigene Figur blockiert
                if self.pEnd[playerFrame.color][newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color:
                    return True
                else:
                    return False
            else:
                return False

        #wenn Overflow im Array    
        elif newField > 39:
            newField -= 40 #Overflow beheben
            #wenn keine eigene Figur blockiert
            if (self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color):
                return True
            else:
                return False

        #sonst, wenn keine eigene Figur blockiert
        elif self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color:        
            return  True
        return False


    #Methode, die playerFrame um die Anzahl field bewegt, wenn moeglich (return bool)
    def movePlayer(self,playerFrame,field):
        newField = playerFrame.fieldPos + field #neue Position der Figur
        #wenn im Endbereich
        if playerFrame.isEndZone:
            #wenn neue Position innerhalb des Endbereich
            if newField < 4:
                #wenn keine eigene Figur blockiert
                if self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color:
                    self.pEnd[playerFrame.color][playerFrame.fieldPos] = None #Spieler im alten Feld entfernen
                    playerFrame.fieldPos = newField #neue Position des Spielers intern setzten
                    self.pEnd[playerFrame.color][newField].player = playerFrame #Spieler im neuen Feld anmelden
                    playerFrame.pos = self.pEnd[playerFrame.color][newField].pos #neue Position des Spielers graphisch setzten
                    return True
            return False

        #wenn im Haus   
        elif playerFrame.fieldPos == -1:
            newField = self.colorStartField[playerFrame.color]
            #wenn keine eigene Figur blockiert
            if (self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color) and field == 6:
                #wenn anderer Spieler wird geschlagen
                if not self.fieldNeutral[newField].player == None and not self.fieldNeutral[newField].player.color == playerFrame.color:
                    self.fieldNeutral[newField].player.pos = self.fieldNeutral[newField].player.posCopy #geschlagenen Spieler zuruecksetzen
                    self.fieldNeutral[newField].player.fieldPos = -1 #neue Position des geschlagenen Spielers auf im Haus setzten
                    
                playerFrame.fieldPos = newField #neue Position des Spielers intern setzten
                self.fieldNeutral[newField].player = playerFrame #Spieler im neuen Feld anmelden
                playerFrame.pos = self.fieldNeutral[newField].pos #neue Position des Spielers graphisch setzten
                return True
            return False

        #wenn kommt in den Endbereich
        elif newField > self.colorEndField[playerFrame.color]and (playerFrame.fieldPos < self.colorStartField[playerFrame.color] or playerFrame.color == 0):
            if newField < self.colorEndField[playerFrame.color] + 5:
                newField -= self.colorEndField[playerFrame.color]
                newField -= 1 #neue Position auf das korrekte Endfeld setzten
                #wenn keine eigene Figur blockiert
                if (self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color):
                    self.goal[playerFrame.color] += 1 #der Farbe einem Punkt geben
                    playerFrame.isEndZone = True #Zustand des Spielers intern auf im Ziel setzten
                    self.fieldNeutral[playerFrame.fieldPos].player = None #Spieler im alten Feld entfernen
                    playerFrame.fieldPos = newField #neue Position des Spielers intern setzten
                    self.pEnd[playerFrame.color][newField].player = playerFrame #Spieler im neuen Feld anmelden
                    playerFrame.pos = self.pEnd[playerFrame.color][newField].pos #neue Position des Spielers graphisch setzten
                    return True
                else:
                    return False
            else:
                return False

        #wenn Overflow im Array     
        elif newField > 39:
            newField -= 40 #Overflow beheben
            #wenn keine eigene Figur blockiert
            if (self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color):
                #wenn anderer Spieler wird geschlagen
                if not self.fieldNeutral[newField].player == None and not self.fieldNeutral[newField].player.color == playerFrame.color:
                    self.fieldNeutral[newField].player.pos = self.fieldNeutral[newField].player.posCopy #geschlagenen Spieler zuruecksetzen
                    self.fieldNeutral[newField].player.fieldPos = -1 #neue Position des geschlagenen Spielers auf im Haus setzten
                
                self.fieldNeutral[playerFrame.fieldPos].player = None #Spieler im alten Feld entfernen
                playerFrame.fieldPos = newField #neue Position des Spielers intern setzten
                self.fieldNeutral[newField].player = playerFrame #Spieler im neuen Feld anmelden
                playerFrame.pos = self.fieldNeutral[newField].pos #neue Position des Spielers graphisch setzten
                return True
            return False

        #sonst, wenn keine eigene Figur blockiert    
        elif self.fieldNeutral[newField].player == None or not self.fieldNeutral[newField].player.color == playerFrame.color:
            #wenn anderer Spieler wird geschlagen
            if not self.fieldNeutral[newField].player == None and not self.fieldNeutral[newField].player.color == playerFrame.color:
                self.fieldNeutral[newField].player.pos = self.fieldNeutral[newField].player.posCopy #geschlagenen Spieler zuruecksetzen
                self.fieldNeutral[newField].player.fieldPos = -1 #neue Position des geschlagenen Spielers auf im Haus setzten
                
            self.fieldNeutral[playerFrame.fieldPos].player = None #Spieler im alten Feld entfernen
            playerFrame.fieldPos = newField #neue Position des Spielers intern setzten
            self.fieldNeutral[newField].player = playerFrame #Spieler im neuen Feld anmelden
            playerFrame.pos = self.fieldNeutral[newField].pos #neue Position des Spielers graphisch setzten
            return True
        return False

    def allOfColorInHouse(self,color):
        for i in range(4):
            if field.p[color][i].fieldPos <> -1 and field.p[color][i].isEndZone == False:
                return False
        return True

#Klasse Player, erbt von Frame
class Player(frame):
    def __init__(self,color = (1,1,1)):
        frame.__init__(self) #super-Konstruktor
        self.bottom = cone(frame = self,axis=(0,1,0), radius=0.35,color = color) #graphischer Rumpf
        self.head = sphere(frame = self, radius=0.3,pos=(0,0.8,0),color = color) #graphischer Kopf
        self.fieldPos = -1 #aktuelle Position (Startposition = -1)
    
        if color == (1,0,0): #Farbcode in Colormap (siehe Anfang der Datei)
            self.color = 0
        elif color == (0,0,1):
            self.color = 1
        elif color == (0,1,0):
            self.color = 2
        elif color == (1,1,0):
            self.color = 3
            
        self.isEndZone= False #Zustand(im Ziel, oder nicht)
        self.posCopy = None #Kopie der Startposition



#Klasse PosFeld (Spielfeld), erbt von Frame               
class PosFeld(frame):
    def __init__(self,color= (0,0,0)):
        frame.__init__(self) #super-Konstruktor
        self.feld = ring(frame = self,axis=(0,1,0),radius=0.4,thickness= 0.05, color = color) #graphischer Kreis
        self.player = None #Spieler der auf dem Feld steht



#Hauptthread
scene.title = "Mensch aergere dich nicht!" #Fenstertitel
scene.forward = (0,-0.5,-1) #Kamerawinkel
scene.background = (1,1,1) #Hintergrund
field = Spielfeld() #Spielfeld (Hauptobjekt)

random.seed() #Wuerfel
curPlayer = 0 #aktueller Spieler
            
while True: #Spiel startet
    isAgain = True
    allInHouseCount = 0

    #Zug beginnt
    
    while isAgain:
        endTurn = False
        
        #Wuerfeln        
        print "Spieler Nummer "+ str(curPlayer) + " ist an der Reihe:"
        result = random.randint(1,7)
        print "Er wuerfelt " + str(result)
        if result == 6:
            isAgain = True
        else:
            isAgain = False

        if field.allOfColorInHouse(curPlayer) and allInHouseCount <2:
            isAgain = True
            allInHouseCount += 1
            
        #testet Moeglichkeit zu ziehen
        for i in range(4):
            if field.calcPossible(field.p[curPlayer][i],result):
                #Mauseingabe: wartet auf korrekten Zug
                while not endTurn:
                    rate(30)
                    if scene.mouse.events:
                        m1 = scene.mouse.getclick()
                        #wenn Spieler angeklickt
                        if type(m1.pick) == cone or type(m1.pick) == sphere:
                            #wenn Farbe des Spielers stimmt
                            if m1.pick.frame.color == curPlayer:
                                #bewege Spieler und setzte ob der Zug korrekt war (je nach Ergebnis von movePlayer)
                                endTurn = field.movePlayer(m1.pick.frame,result)
                                
        #wenn Sieger 
        if field.goal[curPlayer] > 3:
            print str(curPlayer) + "wins!"
            
    #Spieler wechseln
    if curPlayer == 0:
        curPlayer = 1
    else:
        curPlayer = 0

Funktionsleiste