Files
SchiffeVersenken/schiffe-versenken.py
2023-07-02 17:53:19 +02:00

298 lines
11 KiB
Python

## TO DO: AUSGABE VERBESSERN
import random, time
matrixgr = 7
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]]]
for i in output:
i+= [" 1 2 3 4 5 6 7 "]
if len (gegnerFeld) != len(eigenFeld):
return ("Error: Listen nicht gleich lang!!")
felder = [gegnerFeld, eigenFeld]
for f in range (2):
NZeile = 'A'
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): #Super dumm, kann optimiert werden
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) != 0:
return False
summe = 0
if zeile < matrixgr and spalte <matrixgr and zeile >= 0 and spalte >= 0:
if zeile+1 < matrixgr:
if getFeld (spielerFeld, zeile+1, spalte) == 0:
summe += 1
else:
summe+= 1
if spalte+1 < matrixgr:
if getFeld (spielerFeld, zeile, spalte+1) == 0:
summe += 1
else:
summe+= 1
if zeile-1 >= 0:
if getFeld (spielerFeld, zeile-1, spalte) == 0:
summe += 1
else:
summe+= 1
if spalte-1 >= 0:
if getFeld (spielerFeld, zeile, spalte-1) == 0:
summe += 1
else:
summe+= 1
if summe < 4:
return False
else:
return True
def setSchiff (spielerFeld, groesse):
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)
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)
else:
setFeld (spielerFeld, i, spitze[1], 2)
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):
for i in range (1):
setSchiff (Feld, 4)
for i in range (2):
setSchiff (Feld, 3)
for i in range (2):
setSchiff (Feld, 2)
for i in range (3):
setSchiff (Feld, 1)
def feldWahl (spielerFeld):
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)
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:
print ("TREFFER!\nEs darf direkt ein neues Feld gewählt werden!")
feldWahl (spielerFeld)
else:
print ("Leider kein Treffer! Der Bot zieht nun...")
def Initialisiere ():
global gegnerFeld, eigenFeld
gegnerFeld= makeFeld ()
fuellFeld (gegnerFeld)
while summeFeld (gegnerFeld) != 34:
gegnerFeld= makeFeld ()
fuellFeld (gegnerFeld)
gegnerFeld += ['Gegnerisches Feld:']
print ("Das gegnerische Feld wurde generiert!")
akzeptiert = False
eing = ''
while eing != ('J' or 'j'):
eigenFeld = makeFeld ()
fuellFeld (eigenFeld)
while summeFeld (eigenFeld) != 34:
eigenFeld= makeFeld ()
fuellFeld (eigenFeld)
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, diff):
print (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:
print ("Der Bot hat getroffen! Er darf noch ein Feld wählen!")
time.sleep (2)
botwahl (spielerFeld, diff/10.25)
else:
print ("Der Bot hat nicht getroffen! Du bist nun dran!")
def start ():
level = SchwierigkeitsWahl ()
Initialisiere ()
printFelder ()
while zweicheck (eigenFeld) and zweicheck (gegnerFeld):
feldWahl (gegnerFeld)
time.sleep (2)
botwahl (eigenFeld, level)
start ()