# TO DO: Benachritigung bei komplettem Schiff-Abschuss? import random, time matrixgr = 7 # Größe des Spielfeldes (7x7) def makeFeld (): feld = [[[0] for i in range(matrixgr)] for e in range(matrixgr)] # Erzeugt ein mit Nullen befülltes Feld, was bedeutet, dass dort weder ein (zerstörtes) Schiff ist, noch ein fehlgeschlagener Angriff stattgefunden hat return feld def printFelder(): # Von Feld1 werden nur die abgeschossenen Felder gezeigt, von Feld2 alle. output = [[gegnerFeld [matrixgr]],[' ' + eigenFeld [matrixgr]]] # In die Liste Output werden die auszugebenden Elemente eingetragen, damit sie am Ende alle gleichzeitig nebeneinander ausgegeben werden können for i in output: i+= [" 1 2 3 4 5 6 7 "] felder = [gegnerFeld, eigenFeld] for f in range (2): # f als erstes 0, dann 1 NZeile = 'A' # Bezeichner für die Zeile for i in felder[f]: zeile = '' for n in i: if n == [0]: if f == 1: # Zeige ALLE Felder an zeile+=' [ ] ' # Feld ist leer elif f==0: # Zeige NUR TREFFER an, ~ um vom eigenen Feld zu differenzieren zeile+=' [ ~ ] ' elif n== [1]: zeile+=' [ . ] ' # Feld wurde abgeschossen elif n==[2]: if f == 1: # Zeige ALLE Felder an zeile+=' [ ■ ] ' # Auf dem Feld ist ein ungetroffenes Schiff elif f== 0: # Zeige NUR TREFFER an zeile+=' [ ~ ] ' elif n==[3]: zeile+=' [ X ] ' # Das Schiff auf dem Feld wurde getroffen if ord(NZeile.lower())-97 < matrixgr: output [f] += [NZeile + ' ' + zeile] else: output [f] += [' ' + zeile] NZeile = chr(ord(NZeile)+1) for i in range (0,len(output[0])): print (output [0][i], ' ' + output [1][i]) print ("") def setFeld (spielerFeld, zeile, spalte, wert): #zeile = ord(zeile.lower())-97 # Weil die Zeilen traditionell nach Buchstaben benannt werden, muss erst der Buchstabe in seinen ASCII-Wert umgewandelt werden und dann um 97 verringer (ASCII 97 = 'a') #spielerFeld [zeile][spalte-1][0] = wert # Weil die Nummerierung der Spalten bei 1 anfangen soll hier -1 if wert == 5: wert = getFeld (spielerFeld, zeile, spalte) +1 # Um den Wert im Feld um eins zu erhöhen spielerFeld [zeile][spalte][0] = wert def getFeld (spielerFeld, zeile, spalte): #zeile = ord(zeile.lower())-97 #return spielerFeld [zeile][spalte-1][0] return spielerFeld [zeile][spalte][0] def summeFeld (spielerFeld): summe = 0 for i in spielerFeld: for e in i: for n in e: summe += n return summe def zweicheck (spielerFeld): for i in spielerFeld: for e in i: for n in e: if n == 2: return True def checkUmfeld (spielerFeld, zeile, spalte): if getFeld (spielerFeld, zeile, spalte) == 2: # Wenn auf dem Feld schon ein Schiff ist, kann der Check direkt abgebrochen werden return False summe = 0 if zeile < matrixgr and spalte = 0 and spalte >= 0: if zeile+1 < matrixgr: if getFeld (spielerFeld, zeile+1, spalte) != 2: summe += 1 else: summe+= 1 if spalte+1 < matrixgr: if getFeld (spielerFeld, zeile, spalte+1) !=2: summe += 1 else: summe+= 1 if zeile-1 >= 0: if getFeld (spielerFeld, zeile-1, spalte) !=2: summe += 1 else: summe+= 1 if spalte-1 >= 0: if getFeld (spielerFeld, zeile, spalte-1) !=2: summe += 1 else: summe+= 1 if summe < 4: return False else: return True def setSchiff (spielerFeld, groesse, belegFeld): feldsumme = summeFeld(spielerFeld) versuch = 0 while summeFeld(spielerFeld) != feldsumme + groesse*2 : if versuch < 25: spitze = [random.randint(0, matrixgr-1), random.randint(0, matrixgr-1)] if checkUmfeld(spielerFeld, spitze[0], spitze[1]): #spitze[0] ZEILE, spitze[1] SPALTE if groesse == 1: setFeld (spielerFeld, spitze[0], spitze[1], 2) setFeld (belegFeld, spitze [0], spitze [1], 1) # Damit später abgerufen werden kann, wie groß das Schiff auf dem Feld ist. else: reihe = [] counter = 0 #Jetzt wird entschieden, ob das Schiff vertikal oder horizontal ausgerichtet sein soll. orientierung = random.randint (0,1) #0: horizontal, 1: vertikal if orientierung == 0: orig = spitze [1] spitze [1] = counter counterind = 1 #damit der Counter noch bearbeitet werden kann else: orig = spitze [0] spitze [0] = counter counterind = 0 while spitze [counterind] < matrixgr: #Ab jetzt wird überprüft, ob in der ausgewählten Reihe überhaupt das Schiff hinpasst. if checkUmfeld(spielerFeld, spitze[0], spitze[1]): reihe += [spitze[counterind]] else: reihe = [] summe = 0 if len(reihe) >= groesse and reihe.count(orig)==1: #.count zählt, wie oft die mitgegebene Zahl in der Liste vorkommt. Wenn sie vorkommt und die Liste for i in range (len(reihe)-1, len(reihe)-groesse-1,-1): #mindestens so lang ist wie das Schiff sein soll, kann weitergemacht werden. if orientierung == 0: if checkUmfeld (spielerFeld, spitze[0], i): summe += 1 else: if checkUmfeld (spielerFeld, i, spitze[1]): summe += 1 if summe == groesse: for i in range (len(reihe)-1, len(reihe)-groesse-1,-1): if orientierung == 0: setFeld (spielerFeld, spitze[0], i, 2) setFeld (belegFeld, spitze[0], i, groesse) # Damit später abgerufen werden kann, wie groß das Schiff auf dem Feld ist. else: setFeld (spielerFeld, i, spitze[1], 2) setFeld (belegFeld, i, spitze[1], groesse) # Damit später abgerufen werden kann, wie groß das Schiff auf dem Feld ist. if summe != groesse: spitze [counterind] += 1 versuch += 1 else: spielerFeld = makeFeld () versuch = 0 if summeFeld(spielerFeld) != feldsumme + groesse*2 : spielerFeld = makeFeld () setSchiff (spielerFeld, groesse) def fuellFeld (Feld, belegFeld): for i in range (1): setSchiff (Feld, 4, belegFeld) for i in range (2): setSchiff (Feld, 3, belegFeld) for i in range (2): setSchiff (Feld, 2, belegFeld) for i in range (3): setSchiff (Feld, 1, belegFeld) def schiffVersenkt (spielerFeld, belegFeld, treffer): gr = getFeld (belegFeld, treffer [0], treffer [1]) schiff = [treffer] for i in range (-1, 2, 2): if 0 <= treffer [0] + i < matrixgr: if getFeld(belegFeld, treffer [0] + i, treffer [1]) == gr: e = 1 while getFeld (belegFeld, treffer [0] + e*i, treffer [1]) == gr: schiff += [[treffer[0]+e*i, treffer [1]]] e += 1 for i in range (-1, 2, 2): if 0 <= treffer [1] + i < matrixgr: if getFeld(belegFeld, treffer [0], treffer [1] + i) == gr: e = 1 while getFeld (belegFeld, treffer [0], treffer [1] + e*i) == gr: schiff += [[treffer[0], treffer [1]+e*i]] e += 1 for i in schiff: if getFeld (spielerFeld, i[0], i[1]) == 2: return False for i in schiff: for e in range (-1,2,2): if 0 <= i[0] + e < matrixgr: if getFeld (spielerFeld, i[0]+e, i[1]) != 3: setFeld (spielerFeld, i[0]+e, i[1], 1) for e in range (-1,2,2): if 0 <= i[1] + e < matrixgr: if getFeld (spielerFeld, i[0], i[1]+e) != 3: setFeld (spielerFeld, i[0], i[1]+e, 1) return True def feldWahl (spielerFeld, belegSpFeld): feld = str(input("Wähle das Feld, das abgeschossen werden soll! ")) feld.replace (" ", "") if (len(feld) != 2 ) or (not feld[0].isalpha ()) or (not feld[1].isdigit()): print ("Fehlerhafte Eingabe! \n Ein Feld wird beispielsweise folgendermaßen angegeben:\n A1 [Enter]") feldWahl (spielerFeld, belegSpFeld) return 0 # Rückgabe, damit die Funktion nicht mit falschem Wert weiterläuft feld = [ord(feld[0].lower())-97, int(feld[1])-1] # Weil die Zeilen traditionell nach Buchstaben benannt werden, muss erst der Buchstabe in seinen ASCII-Wert umgewandelt werden und dann um 97 verringert (ASCII 97 = 'a') if not (0 <= feld [0] <= matrixgr-1 and 0 <= feld [1] <= matrixgr-1): print ("Dieses Feld existiert nicht! Bitte ein anderes wählen!") feldWahl (spielerFeld) return 0 # Rückgabe, damit die Funktion nicht mit falschem Wert weiterläuft wert = getFeld (spielerFeld,feld[0],feld[1]) if wert == 1 or wert == 3: print ("Dieses Feld wurde schon abgeschossen! Bitte ein anderes wählen!") feldWahl (spielerFeld) return 0 # Rückgabe, damit die Funktion nicht mit falschem Wert weiterläuft setFeld (spielerFeld, feld[0],feld[1], 5) # Treffer wird eingetragen printFelder() if wert+1 == 3: if not zweicheck (spielerFeld): print ("GRATULATION! Du hast gewonnen!!!") return 0 vers = '' if schiffVersenkt (spielerFeld, belegSpFeld, feld): print ("\n\n\n") printFelder() vers = "Das ganze Schiffe wurde versenkt!" print ("["+chr(feld[0]+65)+str(feld[1]+1)+"]","TREFFER!", vers, "\nEs darf direkt ein neues Feld gewählt werden!") feldWahl (spielerFeld, belegSpFeld) else: print ("["+chr(feld[0]+65)+str(feld[1]+1)+"]","Leider kein Treffer! Der Bot zieht nun...") def Initialisiere (): # Erstellt die beiden Felder global gegnerFeld, eigenFeld global gegnerFeld, eigenFeld gegnerFeld= makeFeld () belegGegFeld = makeFeld () fuellFeld (gegnerFeld, belegGegFeld) while summeFeld (gegnerFeld) != 34: gegnerFeld= makeFeld () fuellFeld (gegnerFeld, belegGegFeld) gegnerFeld += ['Gegnerisches Feld:'] print ("Das gegnerische Feld wurde generiert!") eing = '' while eing.lower () != ('j'): eigenFeld = makeFeld () belegEigFeld = makeFeld () fuellFeld (eigenFeld, belegEigFeld) while summeFeld (eigenFeld) != 34: belegEigFeld = makeFeld () eigenFeld= makeFeld () fuellFeld (eigenFeld, belegEigFeld) eigenFeld += ['Eigenes Feld:'] printFelder() eing = str(input("Ist dieses Feld akzeptabel? [J: Ja / Irgendwas: Nein, Neues!] ")) print ("\n\n\n") def SchwierigkeitsWahl (): try: diff = float(input("Bitte wähle die Schwierigkeit von 0-sehr einfach bis 10-sehr schwer! [0-10] ")) except: print ("Keine valide Eingabe!") SchwierigkeitsWahl () return 0 if not (0<=diff<= 10): print ("Der Schwierigkeitsgrad muss zwischen 0 und 10 sein!") SchwierigkeitsWahl () return 0 return diff def botwahl (spielerFeld, belegSpFeld, diff): diff *= 10 wurf = random.randint (-5, 105) feld = [random.randint (0, matrixgr-1), random.randint (0, matrixgr-1)] treffer = False if diff >= wurf: while getFeld(spielerFeld, feld [0], feld [1]) != 2: feld = [random.randint (0, matrixgr-1), random.randint (0, matrixgr-1)] treffer = True else: while getFeld(spielerFeld, feld [0], feld [1]) != 0: feld = [random.randint (0, matrixgr-1), random.randint (0, matrixgr-1)] setFeld (spielerFeld, feld[0], feld[1], 5) printFelder() if treffer: if not zweicheck (spielerFeld): print ("Schade! Der Bot hat gewonnen!") return 0 if schiffVersenkt (spielerFeld, belegSpFeld, feld): print ("\n\n\n") printFelder () print ("["+chr(feld[0]+65)+str(feld[1]+1)+"]","Der Bot hat getroffen! Er darf noch ein Feld wählen!") time.sleep (1) botwahl (spielerFeld, diff/10.25) else: print ("["+chr(feld[0]+65)+str(feld[1]+1)+"]","Der Bot hat nicht getroffen! Du bist nun dran!") def start (): startzeit = time.time () level = SchwierigkeitsWahl () Initialisiere () printFelder () while True: feldWahl (gegnerFeld, belegGegFeld) if not zweicheck (gegnerFeld): break time.sleep (1) botwahl (eigenFeld, belegEigFeld, level) if not zweicheck (eigenFeld): break print ("Das Spiel hat", int((time.time()-startzeit)//60), "Minuten", int(((time.time()-startzeit)%60)//1), "Sekunden gedauert.") w = str (input ("Noch eine Runde? [J: Ja/Irgendwas: Nein] ")) if w == 'J': start () start ()