Moin Leute,
es hat sich zwar etwas gezogen, aber das ist eine andere Geschichte...
Da ich Probleme mit meinem LMDE hatte, habe ich zwischenzeitlich auf Mint16, gleiche Probleme und dann Mint13 (Maya) gewechselt. Da ich damit dann aber auch nicht zufrieden war, und 46x Updates seit Erscheinen mir auch nicht "zuviel" vorkamen, bin ich mittlerweile wieder auf LMDE umgestiegen.
Einen font-config-Fehler (Monospace) habe ich zwar immernoch, aber mit dem komme ich zurecht.
Mit dem "Umsteigen" war das auch nicht immer soo einfach...jedes mal musste ich die Partitionen nach Windoof (ab SDA4 - primäre extended Partition mit / , swap & /home per GPartedLive wieder runterhauen usw usf...DAS! war mal eine for-Schleife
Naja, jetzt läufts soweit.
Das Problem mit der Nicht-Ausführbarkeit von python-Scripts habe ich mittlerweile auch gelöst, weiß leider nicht mehr wie - eher durch Zufall als durch Wissen. Lag aber glaub ich entweder an geany oder an einem fehlerhaften Ausführbar-machen durch mich, wobei mir das immernoch nicht erklärt, wieso das Terminal dann env nicht finden konnte, bzw. im Script nicht. env selber hat im Terminal einwandfrei funktioniert...bzw tut es jetzt zumindest. Das ist jetzt aber ne andere Baustelle...
Zum Thema zurück.
Ich werde hier heute die Funktion zur Ermittlung der maximal nötigen Schritte (f_bisektion - by BSA
) veröffentlichen.
Ich musste sie für mein Spiel jedoch leicht modifizieren, da ich für mein Spiel eine andere Angabe aus der Funktion brauchte, was ihr aber selber anhand der beiden Codes ablesen könnt.
Für die Ermittlung der maximal nötigen Schritte musste ich (für mich...) erstmal eine Funktion entwickeln, die zuverlässig die richtigen Rechenschritte ausübt, ohne dabei zu viele Fehler zu produzieren.
Für mein Spiel brauchte ich jedoch eine Funktion, die mir am Ende auch den entsprechenden Wert der benötigten Schritte für eine entsprechend zu übergebende Variable lieferte, oder anders gesagt:
ich wollte die Funktion nochmal speziell auf das Spiel anpassen.
Vorneweg sage ich, dass beide nicht hundert Prozent fehlerfrei arbeiten.
Es gibt vereinzelt Zahlen, bei denen der Rechner rechnet und auf kein Ergebnis kommt. Diese sind jedoch verschwindend gering und wenn ich mal etwas mehr Zeit über habe, werde ich das auch noch in Angriff nehmen.
Ich denke ich weiß sogar schon, woran genau es liegt. Die Ergebnisse der Einzelschritte werden ständig auf INT degradiert, was aller Wahrscheinlichkeit nach zu eben jenem Phänomen führt.
Das ist für mich aber momentan nicht so wichtig, da ich das Spiel etwas umgemodelt habe...man könnte auch sagen, ich hab es angepasst. Ein HighScore ist noch nicht implementiert, das kommt dann aber auch noch irgendwann und zwar als Übung, da ich die Datei "highscore" auslagern werde, und zwar einmal in eine .txt, einmal in eine .csv und wenn es mir die Zeit erlaubt evtl. auch noch mal in eine .bin - aber letzteres hat auf jeden Fall erstmal noch Zeit...
Wie gesagt, das Spiel ist leicht modifiziert und eigentlich auch noch lange nicht fertig...
Z.B. lässt es sich jetzt aktuell nicht mehr sauber beenden, ich habe dafür einen Fehler einbauen müssen, durch den es aber erstmal abbricht.
Außer dem sind noch etliche andere Sachen zu machen, etwa Verbesserungen am Code, am Style, an den Funktionen und am gesamt-Umfeld, die da wären:
- Sound (per pygame - müsste ich mir erst noch kompilieren oder warten bis es für 3.3 released wird)
- GUI (evtl. per tkinter oder Qt oder sonst irgendwas womit sich umgehen lässt...hier kein pygame)
- und noch so einige andere Sachen, die mir im Kopf rumschwirren
Die Codes stelle ich dann am Ende ein.
@Hyperion
Hui... ``time.sleep`` zum Verfolgen von Rechenfehlern... sitzt Du vor der Ausgabe und willst "live" mitrechnen?
Jupp, ziemlich genau so lief das da ab
Wenn ich dir die div. Stationen meiner (vor-)Funktions-Findung zeigen würde, würdest du bestimmt mit den Ohren schlackern
@EyDu
``math.log`` und ``math.ceil``. Hast du dir zur Bestimmung der Anzahl keine Gleichung aufgestellt? Dann wären dir die benötigten Funktionen sofort aufgefallen.
Hm...mit denen hab ich mich noch gar nicht befasst, könnt ich aber nochmal tun!
Nee, bzw. so halbwegs. Anfangs hatte ich soviele Ideen die alle nur bei XY-Prozent geklappt haben, und kein mathematisch greifbares Verfahren zur Hand, dass ich mir meine Zeit recht zwiespältig (Frust&Freude) vertrieben hab.
Nachdem ich dann den Tipp mit dem "Bisektion"s-Verfahren von BlackJack bekommen hab, ging es dann aber doch recht fix von der Hand - weniger als einen Tag hat es gedauert, bis die erste Funktion fertig war und lief.
Danach war erstmal stillstand in Sachen python...
Du müsstest dich nicht in dein Modul einarbeiten, jeder andere schon
Nee, mag sein, dass es nicht allzu funktionsreich sein sollte, aber es ist echt einfach zu benutzen.
Siehst du nachher im Code, aber auch im Spiel.
Als Modul hab ich das ganze bisher noch nicht gemacht, kommt aber vielleicht auch noch, wenn es dann fehlerfrei läuft.
Aktuell ruft man die Funktion im game folgendermaßen auf
Wobei MIN eigentlich rausfallen könnte, da ich gemerkt habe, dass ein Bereich von Bspw. 100 - 200 wie der Bereich von 1 - 200 behandelt wird, was zur Folge hätte, das man einen Versuch zuviel zugestanden bekommen hätte.
Das ist aber nur noch Feinjustierung die ich beizeiten nachholen werde. Aktuell habe ich das Thema anders gelöst, siehst du dann im Spiel-Code
(der untere Bereich ist fest -> globale Variable MIN = 1 -> keine Auswahl mehr von MIN durch den Anwender)
Das wird mit der Zeit besser. Viele Dinge lassen sich irgendwann sehr intuitiv lösen und komplexere Sachverhalte wirst du schneller erkennen.
Wollen wir's hoffen
@BlackJack
@BSA: Die `log`-Funktion steht doch im Wikiartikel, nur auf das Aufrunden muss man noch selber kommen. Also als Formel ⌈log₂ n⌉ mit n = Anzahl der Zahlen.
Ja, ich hab mir das angeschaut und es kam mir irgendwie zu komplex rüber, aber ich werde, allein schon um es mal gemacht zu haben, versuchen, eine kleine entsprechende Funktion per "math.log" und "math.ceil" zu schreiben. Bisher muss ich gestehen, hab ich mich mit den Dokumenten auf python.org und in den Wikis noch nicht wirklich viel beschäftigt - das kommt (muss ja) aber auch noch!
Außerdem hatte ich ganz zu Beginn schon angefangen, noch bevor mir Bisektion überhaupt ein Begriff war, das ganze über if/else-Anweisungen zu schaffen...das gab aber nur elendig lange Verschachtelungen, null Struktur und keine Übersichtlichkeit - *ironie=1* die Funktionalität nahm dafür
proportional zum geschriebenen Code zu
*ironie=0*
So. Nun ist aber Zeit für die Codes.
Und schlafen muss ich auch noch schnell, kurz & bündig...
Als erstes kommt der leicht überarbeitete Code der Funktion f_bisektion, im Grunde sind nur unnötige Variablen rausgeflogen, die keine erkennbare Funktion hatten (im Spiel ursprünglich: f_bisect, aktuell selbst nicht mehr implementiert).
Code: Alles auswählen
#!/usr/bin/env python3
########################################
# Diese Funktion zum Modul umarbeiten. #
# BSA | 13.12.2013 | 01:45 Uhr #
# überarbeitet am 18.11.2013 #
########################################
import random
import time
def main():
# MIN,MAX durch Eingabe des Nutzers definieren _ hier testing
MIN,MAX = 1,1000
x = random.randint(MIN,MAX)
# x = 512 # Testing
print("x = ", x) # Testing
obergrenze = MAX
untergrenze = MIN
trial_count = 1
y = obergrenze / 2 # erste Lokalisierung, Ausgabe für
print('Versuch: ', trial_count, 'y = ', y) # testing
seek = True
while True:
if y == x:
print("MATCH! x = ", y) # testing
print("COUNTER: ", trial_count) # testing
time.sleep(1) # testing
seek = False
break
if x < y:
obergrenze = int(y)
y = int(((obergrenze - untergrenze) / 2) + untergrenze)
l = range(0,y)
l_len = int(len(l))
l_mw = len(l) / 2
r = range(y,obergrenze)
r_len = int(len(r))
r_mw = r_len / 2
trial_count = trial_count+1
# Ausgabe für testing
print("Versuch: ", trial_count, "55 | y = ", y)
seek = True
if x > y:
untergrenze = int(y)
y = int(untergrenze + ((obergrenze - untergrenze) / 2))
l = range(untergrenze,obergrenze + (obergrenze - untergrenze))
l_len = int(len(l))
l_mw = len(l) / 2
r = range(untergrenze,obergrenze)
r_len = int(len(r))
r_mw = len(r) / 2
trial_count = trial_count+1
# Ausgabe für testing
print("Versuch: ", trial_count, "75 | y = ", y)
seek = True
if __name__ == '__main__':
main()
Wie ihr seht, hab ich wirklich für's Testing Ausgaben erzeugt, sogar mit ungefährer Zeilenangabe (später verrutscht), um zu sehen, wo es zeitweise noch hakte bzw. haken könnte.
Nachdem der Code funktionierte, habe ich die "time.sleep()"-Anweisungen rausgenommen, da war dann nur noch das Endergebnis interessant.
_____________________________________________________________________
Hier dann noch der etwas abgewandelte und besser auf das Spiel abgestimmte Code.
Code: Alles auswählen
#!/usr/bin/env python3
########################################
# Diese Funktion zum Modul umarbeiten. #
# BSA | 13.12.2013 | 01:45 Uhr #
# überarbeitet am 18.11.2013 #
########################################
import random
import time
def main():
# MIN,MAX durch Eingabe des Nutzers definieren _ hier testing
MIN,MAX = 198,200 # falsche Ausgabe bei höherem Einstieg durch MIN
for i in range(MIN,MAX):
x = i
obergrenze = MAX
untergrenze = MIN
trial_count = 1
y = obergrenze / 2 # !!! trotz y = ((obergrenze - untergrenze) / 2) + untergrenze falsches Ergebnis... ?
while True:
if y == x:
print("MATCH! x = ", y)
print("COUNTER: ", trial_count)
break
else:
if x < y:
obergrenze = int(y)
y = int(((obergrenze - untergrenze) / 2) + untergrenze)
l = range(0,y)
l_len = int(len(l))
l_mw = len(l) / 2
r = range(y,obergrenze)
r_len = int(len(r))
r_mw = r_len / 2
trial_count = trial_count+1
elif x > y:
untergrenze = int(y)
y = int(untergrenze + ((obergrenze - untergrenze) / 2))
l = range(untergrenze,obergrenze + (obergrenze - untergrenze))
l_len = int(len(l))
l_mw = len(l) / 2
r = range(untergrenze,obergrenze)
r_len = int(len(r))
r_mw = len(r) / 2
trial_count = trial_count+1
else:
continue
trials_needed = trial_count + trial_count # + t_c nötig ?
trials_max = int(trials_needed / 2)
# print('Höchste Anzahl benötigter Versuche: ', trials_max)
if __name__ == '__main__':
main()
___________________________________________________________________________
So. Und zu guter letzt natürlich noch das Spiel. Zum Spiel weiter unten vielleicht noch ein paar Kleinigkeiten.
Aber erstmal der Code...
Code: Alles auswählen
#!/usr/bin/env python3
import random
import time
import sys
MIN = 1
# Divisionsoperator range / Liste f.range-Begrenzungsregel MAX (STEP_50)
div_op_range = []
# 50 / 1 = 1, 100 / 2 = 2 ... 2000 / 50 = 40
for i in range(1,41):
div_op_range.insert(i,i)
def f_bisection(player_name,MIN,MAX):
for i in range(MIN,MAX):
x = i
obergrenze = MAX
untergrenze = MIN
trial_count = 1
y = obergrenze / 2
while True:
if y == x:
break
else:
if x < y:
obergrenze = int(y)
y = int(((obergrenze - untergrenze) / 2) + untergrenze)
l = range(0,y)
l_len = int(len(l))
l_mw = len(l) / 2
r = range(y,obergrenze)
r_len = int(len(r))
r_mw = r_len / 2
trial_count = trial_count+1
elif x > y:
untergrenze = int(y)
y = int(untergrenze + ((obergrenze - untergrenze) / 2))
l = range(untergrenze,obergrenze + (obergrenze - untergrenze))
l_len = int(len(l))
l_mw = len(l) / 2
r = range(untergrenze,obergrenze)
r_len = int(len(r))
r_mw = len(r) / 2
trial_count = trial_count+1
else:
continue
trials_needed = trial_count + trial_count
trials_max = int(trials_needed / 2)
set_difficulty(player_name,MIN,MAX,trials_max)
def main():
print('Willkommen bei _guess_!')
time.sleep(1)
print('In diesem kleinen Spiel geht es darum...')
time.sleep(0.5)
print('die gesuchte Zahl zu finden.')
time.sleep(0.5)
print('Du bekommst Hinweise darauf ob die gesuchte Zahl...')
time.sleep(0.5)
print('größer oder kleiner ist als die Zahl...')
time.sleep(0.5)
print('die du eingetippt hast.')
time.sleep(0.5)
print('Viel Spaß!\n\
Und natürlich auch ein wenig Glück...')
player_name = input('>> Wie ist dein Name? ')
if player_name == 'TEST': # testing
set_range(player_name) #
print('Hallo', player_name, '!')
print('********************GUESS********************')
time.sleep(2)
print('...')
time.sleep(0.5)
print('Es war einmal, vor langer Zeit...')
time.sleep(1.5)
print('eine Zahl, versteckt seit langer Zeit...')
time.sleep(1.5)
print('sie trollte allein so vor sich hin...')
time.sleep(1.5)
print('da sah sie auf einmal eine Tafel und ein Kind...')
time.sleep(1.5)
print('die Tafel war so voll mit tollen Zahlen...')
time.sleep(3)
print('da musste sie und rollte sofort hin.')
time.sleep(1.5)
print('Und an der Tafel angekommen, sah sie viele von sich...')
time.sleep(1.5)
print('und empfand eine Freude, ganz neu für sich...')
time.sleep(1.5)
print('und sie dachte sich, doch verriet natürlich nicht: "Hey! ')
time.sleep(1.5)
print('Wer mich findet, mit dem spiele ich!" ')
time.sleep(5)
print('Die Zeit verging und es ward´ dunkel...')
time.sleep(1.5)
print('Da sammelten sich viele nette Leute, ja man munkelt...')
time.sleep(1.5)
print('vor dieser riesen Tafel standen sie und dachten sich...')
time.sleep(1.5)
print('"Mensch, die ist aber gut versteckt! Na, die find´ doch ich!'
'"')
time.sleep(3)
print('... und so begann vor langer Zeit dieses Spiel ...')
time.sleep(4)
print('... und {0}, denke daran, du bist nun mitten drin !'\
.format(player_name))
time.sleep(4)
print('*********************************************')
print('******************* GUESS *******************')
print('*********************************************')
time.sleep(4)
print('')
print('*****************EINLEITUNG******************')
time.sleep(2)
print('In diesem kleinen Spiel geht es darum...')
time.sleep(1.5)
print('die gesuchte Zahl zu finden.')
time.sleep(1.5)
print('Abhängig vom festgelegten Zahlenbereich...')
time.sleep(1.5)
print('und abhängig vom gewählten Schwierigkeitsgrad...')
time.sleep(1.5)
print('stehen dir eine bestimmte Anzahl an Versuchen frei...')
time.sleep(1.5)
print('um "Guessy" zu finden, die sich versteckt hält.')
time.sleep(2)
print('"Guessy" ist die Zahl, mit der du spielen willst...')
time.sleep(1.5)
print('du kannst den Zahlenbereich selber festlegen...')
time.sleep(1.5)
print('das heißt, du kannst zwischen 1 und 50, 1 und 100...')
time.sleep(1.5)
print('oder aber auch zwischen 1 und 2000 nach ihr suchen.')
time.sleep(1.5)
print('Die Anzahl deiner Versuche passt sich entsprechend an...')
time.sleep(1.5)
print('doch sei gewarnt...\n\
hier wirkt sich auch der Schwierigkeitsgrad aus!')
time.sleep(3)
print('...')
time.sleep(5)
print('Bereit? Dann kommst du jetzt ins Konfigurationsmenü ...')
set_range(player_name)
def set_range(player_name):
print('')
print('**************EINSTELLUNGSMENÜ***************')
time.sleep(2)
print('Du kannst den Zahlenbereich selbst auswählen.')
time.sleep(0.5)
print('Für den Anfang empfehle ich dir den Bereich von 1 - 100.')
time.sleep(0.5)
print('Du kannst aber natürlich auch im Bereich bis 10 anfangen...')
time.sleep(0.5)
print('und den Bereich im Konfigurationsmenü schrittweise'
' erhöhen.')
time.sleep(0.5)
print('Du kannst den Zahlenbereich nach jedem Durchlauf...')
time.sleep(0.5)
print('in 50er Schritten ändern, nach oben wie nach unten.')
time.sleep(0.5)
print('Du kannst zum Beispiel im Bereich von 1 - 50, 1 - 100...')
time.sleep(0.5)
print('aber auch im Bereich von maximal 1 - 2000 suchen.')
time.sleep(0.5)
print('Die größte Zahl ist aus Gründen der Kompatibilität 2000!')
while True:
try:
sett_max = int(input('>> Wähle jetzt die größte Zahl'
' deines Suchbereichs: '))
if sett_max >= 50 and sett_max <= 2000:
MAX = sett_max
div_op = float(MAX / 50)
if div_op in div_op_range:
break
else:
print('Denke bitte daran, nur in 50er'
' Schritten vorzugehen.')
else:
if sett_max < 50:
print('Bitte wähle einen etwas größeren Bereich...')
elif sett_max > 2000:
print('Denke daran: Die größte Zahl ist 2000 !')
except ValueError:
print('Gib ruhig eine vernünftige, also natürliche Zahl'
' ein...')
f_bisection(player_name,MIN,MAX)
def set_difficulty(player_name,MIN,MAX,trials_max):
print('Also {}, es gibt drei'
'Schwierigkeitsgrade.'.format(player_name))
time.sleep(0.5)
print('Fange am besten klein an, und steigere dich mit der Zeit.')
time.sleep(0.5)
print('Für die leichteste Stufe, bestätige die [1]')
time.sleep(0.5)
print('Für einen etwas höheren Nervenkitzel, bestätige die [2]')
time.sleep(0.5)
print('Und für ein wenig Kopfzerbrechen bestätige die [3]...')
time.sleep(0.5)
print('Doch denke daran: Je erhöhter Schwierigkeitsstufe\n\
gibst du einen möglichen Versuch ab !')
while True:
difficulty = input('>> Wähle eine Schwierigkeitsstufe aus: ')
if difficulty == '1':
MAX_TRIAL_COUNTS = trials_max
break
elif difficulty == '2':
MAX_TRIAL_COUNTS = trials_max - 1
break
elif difficulty == '3':
print('PREPARING THRILLMODE...')
time.sleep(0.5)
print('ENTERING THRILLMODE...')
time.sleep(0.5)
print('YOU HAVE ENTERED THRILLMODE !')
time.sleep(2)
MAX_TRIAL_COUNTS = trials_max - 2
break
else:
print('Bitte treffe eine gültige Auswahl...')
break
play_game(player_name,MIN,MAX,MAX_TRIAL_COUNTS)
def play_game(player_name,MIN,MAX,MAX_TRIAL_COUNTS):
while True:
start_time = time.time()
secret_number = random.randint(MIN, MAX)
print('*********************************************')
print('******************* GUESS *******************')
print('*********************************************')
time.sleep(2)
for trial_count in range(1, MAX_TRIAL_COUNTS + 1):
print('Versuch ', trial_count, 'von', MAX_TRIAL_COUNTS)
while True:
try:
guessed_number = int(input('>> Deine Zahl: '))
break
except ValueError:
print('Ungültige Eingabe. Bitte wiederhole deine'
' Eingabe...')
if secret_number != guessed_number:
print(
'Die gesuchte Zahl ist {0} als {1}'.format(
'größer' if secret_number > guessed_number else 'kleiner',
guessed_number
)
)
else:
time_used = time.time() - start_time
print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print('+ Herzlichen Glückwunsch! Die gesuchte Zahl war {0}. +'.format(guessed_number))
print('+ Benötigte Versuche: ', trial_count, " +")
print('+ Deine Zeit: {0:.2f} Sekunden oder ({0:.2f}/60) Minuten. +'.format(time_used))
print('+ Ergebnis erzielt:', time.strftime("%d.%m.%Y %H:%M:%S +"))
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
break
else:
print('-----------------------------------')
print(player_name, ', du hast es leider nicht geschafft.')
time.sleep(0.5)
print('Versuche es am besten gleich nochmal!')
time.sleep(0.5)
print('\n\
Bestätige mit [1] um fortzufahren.\n\
Bestätige mit [2] um ins Konfigurationsmenü zu gelangen.\n\
Bestätige mit [0] um das Programm zu beenden.')
while True:
response = input('>> Deine Auswahl: ')
if response == '0':
raise SystemExit
elif response == '2':
set_range(player_name)
elif response == '1':
play_game(player_name,MIN,MAX,MAX_TRIAL_COUNTS)
if __name__ == '__main__':
main()
Also erstens, wer Lust und Zeit hat, und das Spiel mal ausprobieren möchte, sollte sich natürlich auch einmal das Spiel komplett anschauen, wer danach etwas "cheaten" mag, kann bei seinem Namen "TEST" eingeben und überspringt somit etwa 30 "print()"-Ausgaben und ca.(!) 120 Sekunden Programmdauer.
Desweiteren hab ich, da ich gemerkt hab, dass es bei einzelnen, wenigen Zahlen noch zu Endlos-Berechnungen (s.o.) kommen kann, vorerst erstmal alles auf 50er-Schritte ausgelegt.
Und da sind noch so EINIGE andere Kleinigkeiten, die mir nicht gefallen, die ich aber auch alle später noch in Angriff nehmen kann. Denn dadurch dass ich noch ganz am Anfang stehe, lerne ich ständig was neues hinzu und wenn ich hier dann erst was vorlegen möchte, wenn ich auch hundert prozentig mit zufrieden bin, dann dauert das wahrscheinlich noch ewig...
Ich muss leider schon längst wieder in der Falle sein, sonst würd ich jetzt noch auf einige Sachen eingehen, aber vielleicht noch kurz das wichtigste:
Für Tipps und Kritik bin ich wie immer offen!
Hier auch nochmal ein großer Dank an Dich, BlackJack, denn dadurch dass du meinen vorigen chaos-Code mal ordentlich verpackt hast, und ich das ganze abgetippt hab, hab ich nochmal ne ganze Menge in Sachen Style und im Weglassen unnötiger Fehlerbehandlungen durch try/except INT() - Behandlungen gelernt -> einfach als str() '0' und die entsprechend if/elif/else-Anweisungen in eine while-Schleife packen! Schon spart man sich das ganze Drumrum.
(wo ist hier eigentlich der DaumenHochButton?
)
(im Code oben sind beide Vorgehensweisen noch vorhanden, wird aber natürlich noch gefixt - ist im nächsten Update dann verschwunden)
Edit: "import sys" und "raise SystemExit" eingefügt.