Xte Schere, Sttein Papier Variante

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du abtsrahierst nicht im richtigen Umfang. KI bedeutet ja nicht, dass da höchst komplexe Algorithmen das Spielgeschehen beeinflussen, sonder nur, dass der Computer im Rahmen der Regeln eines Spiels einen gültigen Zug spielen kann. Insofern ist der Ansatz, die Lapalcewahrscheinlichkeit zu analysieren imho wesentlich einfacher als Deine Idee ;-)

Du hast meine aller erste Frage nicht beantwortet: Wie lauten die "Ordnungszahlen" für folgende Sequenzen:

Code: Alles auswählen

aaab
aaba
abaa
baaa
;-)

Du schreibst, dass Du keine Wahrscheinlichkeiten (oder sonstigen schwierigen Konstrukte benötigst). Andererseits willst Du "überdurchschnittlich" erfolgreiche Ketten spielen. "Überdurchschnittlich" beinhaltet jedoch, dass Du den Durchschnitt errechnest (bzw. bestimmst) und die tatsächliche Wahrscheinlichkeit ;-)

Wie willst Du die Ketten überhaupt zusammenstellen? Alleine das stelle ich mir schwierig vor und einen Ansatz dazu hast Du auch noch nicht präsentiert.

Ich will Deinen Ansatz nicht schlecht machen! Aber ich glaube Du schätzt die Schwierigkeit der Algorithmik hier falsch ein und hast für viele Probleme noch keine Lösung oder sogar noch keine Erkenntniss, dass etwas ein Problem ist (s. o. die Reihenfolge).

Laplacewahrscheinlichkeit ist übrigens sehr einfach. In Deinem Falle ist das 1/3 - Du hast drei Möglichkeiten und jede ist gleich wahrscheinlich. Dort eine Abweichung festzustellen ist folglich sehr einfach; ich beschrieb dazu ja einen Ansatz.

Zudem habe ich auch eher Deine Modellierung "kritisiert". "Spieler" ist eben keine Funktion. Natürlich kannst Du Deinen Ansatz in Code gießen, aber orientiere Dich da doch einfach an einer sinnvollen Bennenung und Struktur. Die Durchführung / Ermittlung eines Zuges sollte man eben in eine Funktion packen und sinnvoll benennen. Das war quasi der Hauptkritikpunkt ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

Deine erste Frage hatte ich als Scherz verstanden, endschuldige. Aber Du hast mich auch nicht richtig verstanden. Die kleinste Sequenz sind immer drei Zeichen! Das eben wegen grundlegenden Überlegungen zur Wahrscheinlichkeit.
Egal. Du zweifelst ja grundsätzlich, auch an meiner Fähigkeit das umzusetzen:
Hyperion hat geschrieben: Wie willst Du die Ketten überhaupt zusammenstellen? Alleine das stelle ich mir schwierig vor und einen Ansatz dazu hast Du auch noch nicht präsentiert.

Code: Alles auswählen

import random as ran
def snake():
    dic = {1 : 'abc',2 : 'acb',3 : 'bca',4 : 'bac',5 : 'cba',6 : 'cab',
          7 : 'aab', 8 : 'aba',9 : 'baa',10 : 'bba',11 : 'abb',12 : 'bab',
           13 :'cca',14 : 'acc',15 : 'cac',} # hier fehlen..
    snake = ''
    for z in range(15):
        x = ran.randint(1, 15)
        snake += dic[x]
    return(snake)
So zB :lol:
Da fehlt noch der Teil, der die Ordnungszahl der Schlange ermittelt, also wieviel a, b und c darin sind.

Wenn mein Ansatz falsch ist, dann wird mir das fertige Programm das 'sagen' können!
BlackJack

@wwwheimer: Mit Namen sieht das immer noch nicht gut aus. Lass das mit den Abkürzungen doch mal sein. `random` ist so ein schöner Name — was gewinnst Du denn dabei daraus ein unverständliches `ran` zu machen?

„Snake” heisst zwar auf deutsch „Schlange” aber im englischen ist dabei nur das Tier gemeint. Du suchst eher `queue` oder `chain` als englische Übersetzung von „Schlange”.

`dic` ist auch ein nichtssagender Name. Üblich ist es den Namen so zu wählen, dass er die Bedeutungen von Schlüssel/Wert-Paaren beschreibt. Also zum Beispiel `name2address` oder hier vielleicht `number2triple`. Was fehlt denn in dem Wörterbuch noch? Sollen da alle 27 Möglichkeiten von 'aaa' bis 'ccc' hinein? Falls ja, warum dann nicht einfach 15*3 einzelne Züge generieren statt 15-mal aus allen Möglichkeiten wählen? Warum ein Wörterbuch das aufsteigende, zusammenhängende Zahlen auf Werte abbildet? Die könnte man auch in eine Liste stecken. Und dann daraus mit `random.choice()` wählen.

Du fängst mit der Zählung schon wieder bei 1 an — bei Rechnern ist es üblich bei 0 anzufangen. Das macht es oft einfacher.

Wiederholtes erweitern eine Zeichenkette mit ``+`` oder ``+=`` kann sehr ineffizient werden. Üblicherweise sammelt man die Teilzeichenketten deshalb in einer Liste und verwendet dann am Ende einmal die `join()`-Methode von Zeichenketten um daraus eine Zeichenkette zu machen.

``return`` ist keine Funktion, darum sollte man es auch nicht so hinschreiben als wäre es eine.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

wwwheimer hat geschrieben:Deine erste Frage hatte ich als Scherz verstanden, endschuldige. Aber Du hast mich auch nicht richtig verstanden. Die kleinste Sequenz sind immer drei Zeichen! Das eben wegen grundlegenden Überlegungen zur Wahrscheinlichkeit.
Nee, Du hast es nicht richtig dargestellt ;-) Du hast ja keine kleinste und größte Sequenz, sondern offensichtlich immer exakt drei Zeichen lange Sequenzen!

Zudem hast Du immer noch nicht beschrieben, wie Du die Sequenzen aus einem laufenden Spiel heraus analysierst!

Beispiel:

Code: Alles auswählen

Spieler 1: aabaaccabba
Spieler 2: bbbccababac
Wie teilst Du das nun in 3-er Sequenzen, um zu analysieren, welche Sequenz am besten gewinnt? Gehst Du vom Gegenspieler aus, was der spielt, oder was Du spielst?

Genau das stelle ich mir kompliziert vor.

Das was Du da gezeigt hast, ist ja nur das in kompliziert:

Code: Alles auswählen

In [13]: list(product("abc", repeat=3))
Out[13]:
[('a', 'a', 'a'),
 ('a', 'a', 'b'),
 ('a', 'a', 'c'),
 ('a', 'b', 'a'),
 ('a', 'b', 'b'),
 ('a', 'b', 'c'),
 ('a', 'c', 'a'),
 ('a', 'c', 'b'),
 ('a', 'c', 'c'),
 ('b', 'a', 'a'),
 ('b', 'a', 'b'),
 ('b', 'a', 'c'),
 ('b', 'b', 'a'),
 ('b', 'b', 'b'),
 ('b', 'b', 'c'),
 ('b', 'c', 'a'),
 ('b', 'c', 'b'),
 ('b', 'c', 'c'),
 ('c', 'a', 'a'),
 ('c', 'a', 'b'),
 ('c', 'a', 'c'),
 ('c', 'b', 'a'),
 ('c', 'b', 'b'),
 ('c', 'b', 'c'),
 ('c', 'c', 'a'),
 ('c', 'c', 'b'),
 ('c', 'c', 'c')]
Das hat ja noch null Bezug zu irgend welcher Wahrscheinlichkeit!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

Hallo Ihr Lieben!
Ich denke, dass es gut wäre das Ganze bis zum fertigen Programm zu entwickeln, das mit Eurer Hilfe dann auch aller (Eurer) Kritik standhält. :wink:
Doch vorher was anderes:
@BlackJack,
ich glaube, ich habe auch das Forum sehr schlecht gewählt. :(
Wie gesagt, ich würde das gern zu ende bringen, bin mir aber nicht sicher ob das überhaupt hier das dafür richtige Forum ist?

Grüße!
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

Hyperion hat geschrieben: Nee, Du hast es nicht richtig dargestellt ;-) Du hast ja keine kleinste und größte Sequenz, sondern offensichtlich immer exakt drei Zeichen lange Sequenzen!

Zudem hast Du immer noch nicht beschrieben, wie Du die Sequenzen aus einem laufenden Spiel heraus analysierst!

Beispiel:

Code: Alles auswählen

Spieler 1: aabaaccabba
Spieler 2: bbbccababac
Hi Hyperion,
finde ich gut, dass Dich das Thema interessiert. Du hast auch recht, dass das Ganze doch komplexer ist, als ich mir das scheinbar vorstelle. Doch das scheint wirklich nur so. Es geht mir hier ja überhaupt erst eimal um die grundlegende Funktion, die nicht mehr können muß, als zwei Zeichenketten zu erzeugen, zu spielen und die Ergebnisse auszugeben.
Eine Teillösung zur Frage der Auswertung habe ich mit Hilfe von 'iter(x)' gefunden. Ein paar Beispielausgaben:

Code: Alles auswählen

>>> 
Aset: ababbccbcaacbababcacbcacabcbbc , Awin: 7
Bset: cbbccbbccbacccbcbbbabcbcbaccca , Bwin: 13
weightA: 9 , 11 , 10
weightB: 4 , 12 , 14
>>> ====================== RESTART ======================
>>> 
Aset: bcbccbbbbbacbbbccccbbaabbcbcba , Awin: 9
Bset: aabcabababccbcbbaabccabbaccbab , Bwin: 10
weightA: 4 , 16 , 10
weightB: 10 , 12 , 8
>>> ====================== RESTART ======================
>>> 
Aset: bcbbbbbbbacccacbbacabcaabbbaaa , Awin: 13
Bset: aacbaaaacaacaabcacbaacabacbacc , Bwin: 8
weightA: 9 , 14 , 7
weightB: 16 , 5 , 9
>>> ====================== RESTART ======================
>>> 
Aset: acbbaccbbbbacccaacaababaacbbca , Awin: 9
Bset: abcbccbaaccaccccccabcabcacbccc , Bwin: 6
weightA: 11 , 10 , 9
weightB: 7 , 6 , 17
>>> 
Da sind solche Sequenzen/abc-Schlangen mit einer Auswertung. Die Zeichezahl ist beliebig, außer, dass ihre Summe ohne Rest durch drei teilbar sein muß.
Grüße!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Das kannst Du auch einfach per ``collections.Counter`` lösen:

Code: Alles auswählen

>>> Counter("ababbccbcaacbababcacbcacabcbbc")
Counter({'b': 11, 'c': 10, 'a': 9})
>>> Counter("cbbccbbccbacccbcbbbabcbcbaccca")
Counter({'c': 14, 'b': 12, 'a': 4})
(schrieb ich schon weiter oben ;-) )

Per ``Counter.update(aktuelle_wahl)`` kannst Du die Zähler aktualisieren.

Ich kapiere nur den Zusammenhang zu Deiner "3er"-Block-Idee noch nicht. Das hier gezeigte erinnert mich eher an meine Laplace-Idee :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

Hi Hyperion,
der Counter-Tip war schon gut, und ich werde den sicher auch verwenden. :)

Die 27 'Dreier' sind die kürzesten Sequenzen aus denen sich beliebig lange Sequenzen erzeugen lassen, die sich von Sequenzen aus einzeln erzeugten Ziffern nicht unterscheiden.
Aber das allein war nicht der Grund, sondern mehr die Überlegung, dass sich einer ungeordneten, 'zufälligen' Folge, vielleicht mit Ordnung begegnen lässt.
Also, um auch 'ordentliche' abc-Schlangen (zB: aaabbbccccccbbbaaa) ins Rennen schicken zu können, schien mir die Dreierteilung ideal. Da jeder Dreier über einen festen Index ansprechbar ist, kann ich das nutzen, um relativ einfach solche 'ordentlichen' abc-Schlangen zu erzeugen.

Hoffe, ich konnte Dir die Frage nach dem Sinn der 'Dreier' ausreichend beantworten.

Dank und Gruß!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

wwwheimer hat geschrieben: Also, um auch 'ordentliche' abc-Schlangen (zB: aaabbbccccccbbbaaa) ins Rennen schicken zu können, schien mir die Dreierteilung ideal. Da jeder Dreier über einen festen Index ansprechbar ist, kann ich das nutzen, um relativ einfach solche 'ordentlichen' abc-Schlangen zu erzeugen.
Um ehrlich zu sein: Nein, ich habe das noch nicht verstanden. Evtl. zeigst Du es mal ohne Code; also einfach den Ablauf, wie Du Die das Erzeugen vorstellst - und wieso überhauot etwas erzeugt werden soll (worauf beruht diese Sequenz?).
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

Hyperion,
da weiss ich im Moment auch nicht wie ich es noch anders erklären könnte. Vielleicht später.

Eigentlich gehört das auch nicht zu den Kernfunktionen, um die es mir geht.
Was jetzt noch fehlt, das ist ein 'SpeicherWerk' für die erfolgreichen abc-Schlangen, und Methoden diese miteinander zu verknüpfen - zu Riesenschlangen;)
Bin selbst gespannt, wie ich das löse. Denn mehr Treffer sind nur ein Kriterium für Erfolg. Das andere Kriterium ist das Gewicht (Ordnungszahl), das auch stimmen muss. Für eine Sortierung nach Unter-, Ideal- und Über-Gewicht braucht es, was ich oben mit 'Speicherwerk' umschreibe. Welche tollen Objekte/Methoden mir Python hier wohl bietet?
Eines ist mir aber jetzt schon klar, der schwerste Akt wird es sein, richtig sprechende Namen für die neun SpeicherObjekte zu finden. :wink:

Grüße!
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

Aber vielleicht helfen doch ein paar Ausgaben weiter:

Code: Alles auswählen

>>> 
>>> from asim import start as s
>>> s(1)
Aset: bca , Awin: 0
Bset: bcb , Bwin: 1
weightA: 1 , 1 , 1
weightB: 0 , 2 , 1
>>> s(7)
Aset: bccccabbacbcabcaacabb , Awin: 6
Bset: abbaacccabccbbcabbabc , Bwin: 8
weightA: 6 , 7 , 8
weightB: 6 , 8 , 7
>>> s(12)
Aset: bbaabcbcbabaacbbcaacaaaaabcbaabcabbb , Awin: 16
Bset: cccbcbaabcabccbaccabcaabbcaaccaccbab , Bwin: 10
weightA: 15 , 14 , 7
weightB: 11 , 10 , 15
>>> s(1000)
Aset: aaabccaababcbabbcbbcb..............# 2 * 3000! B hat gewonnen ;-)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

wwwheimer hat geschrieben: da weiss ich im Moment auch nicht wie ich es noch anders erklären könnte. Vielleicht später.
Tja, ich denke mal, dann wirst Du von uns hier erst wieder etwas hören, wenn Du uns Code vorlegst ;-)
wwwheimer hat geschrieben: Bin selbst gespannt, wie ich das löse. Denn mehr Treffer sind nur ein Kriterium für Erfolg. Das andere Kriterium ist das Gewicht (Ordnungszahl), das auch stimmen muss. Für eine Sortierung nach Unter-, Ideal- und Über-Gewicht braucht es, was ich oben mit 'Speicherwerk' umschreibe. Welche tollen Objekte/Methoden mir Python hier wohl bietet?
Ich kann Dir leider überhaupt nicht mehr folgen. Wenn Du die Strategie und den Ablauf nicht irgend wie besser erklären kannst, ist es mit Tipps hier schwer :-)

Es fängt schon dabei an, dass mir immer noch nicht klar ist, was Du unter erfolgreichen Schlangen verstehst (was ist hier das Maß?) und inwiefern diese mit Deinen "Ordnungszahlen" in Zusammenhang stehen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

Hyperion, Treffer und Gewicht definieren zusammen die Kategorie 'Erfolg'.
Eine abcSchlange kann auch überdurchschnittliche Treffer erzielen, wenn sie zB. auf 'a' starkes Untergewicht hat, was als Ordnungszahl dann in etwa so aussieht: 6,12,12. Die hat zwar zufällig gut gewonnen, aber hat bei mehreren Durchläufen schlechte Chancen, weil da die fehlenden 'a' sich bemerkbar machen.
Sie wird deshalb unter der Kategorie der aUntergewichtigen abgelegt.
Dann gibt es natürlich auch eine Kategorie für aÜbergewichtige. So kann man dann eine aUntergewichtige mit einer aÜbergewichtigen kombinieren und bekommt eine Idealgewichtige.;-)
Als Ordnungszahlen:
6, 12, 12. = aUnterg.
plus
14, 8, 8. = aÜberg.
ergibt
20, 20, 20 = Idealg.
Das sollte nun wirklich leicht zu verstehen sein.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Mir gehts wie Hyperion. Warum muessen die Sequenzen durch 3 teilbar sein? Man hat zwar 3 Gegenstaende, das hat aber erstmal nichts mit der Laenge der gespielten Sequenzen/Runden zu tun. Die Analyse auf Basis von 3er Tupeln innerhalb einer Sequenz halte ich erstmal nicht fuer so sinnvoll. Die Namen a, b, c erleichtern auch nicht gerade die Interpretation der Ausgabe. Da finde ich r, p, s (fuer (R)ock, (P)aper, (S)cissor)) eingaengiger, oder "o", "-", "<" :-), oder auschreiben...

Mein erstes Beispiel kann man natuerlich auch dahingegend erweitern, darueber Buch zu fuehren, wer was gespielt hat. Da ich vermute, das du es anders geloest hast, hier nochmal meine Version: (Da ich geistig und installationsmaeesig noch bei 2.6 bin, ohne collections.Counter)
http://paste.pocoo.org/show/458640/

Zunaechst einmal wuerde ich mir ein Programmgeruest bauen, mit dem ich mir unterschiedliche Playerstrategien definieren kann, die dann gegeneinander antreten. Diese koennen auch vollkommen trivial sein, z.B. Player spielt nur "Rock" oder das, was der Gegner zuletzt gespielt hat. Danach kann man diese dann immer mehr verfeinern. Oh, sehe gerade, ich bin nicht mehr aktuell, mmh... tappe immer noch im Dunkeln, wie deine Strategie funktionieren soll.

:wink:
yipyip
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

wwwheimer hat geschrieben:Hyperion, Treffer und Gewicht definieren zusammen die Kategorie 'Erfolg'.
Und was sind `Treffer` und `Gewicht`? ;-)
wwwheimer hat geschrieben: Eine abcSchlange kann auch überdurchschnittliche Treffer erzielen, wenn sie zB. auf 'a' starkes Untergewicht hat, was als Ordnungszahl dann in etwa so aussieht: 6,12,12. Die hat zwar zufällig gut gewonnen, aber hat bei mehreren Durchläufen schlechte Chancen, weil da die fehlenden 'a' sich bemerkbar machen.
Ok, aber woher willst Du wissen, ob die nur zufällig gewonnen hat? Evtl. ist die Gegner KI ja anfällig dafür, bei vielen gespielten `a`s zu versagen. Damit wäre es eine gute Strategie auf `a` zu setzen! Oder aber, wenn das die Sequenz des Gegners ist, spielt er wenig a, daher wäre es dann wohl sinnvoll etwas zu spielen, was gegen `b` und `c` gewinnt!

Hinzu kommt noch: Du ignorierst die Reihenfolge. Evtl. ist eine Gegner-KI einfach alternierend. Damit spielt sie zwar in einer Laplace-Wahrscheinlichkeit, aber berechenbar. Wenn Du nun zufällig einen Wert dagegen setzt, gewinnt Deine KI sicherlich besser als ohne irgend eine Analyse.
wwwheimer hat geschrieben: ...
Das sollte nun wirklich leicht zu verstehen sein.
Ja. Aber was bringt das? Wie kommt es denn zu solchen "Schlangen"? Das habe ich schon vor zig Postings einmal gefragt ;-)

Wie werden daraus

Code: Alles auswählen

aaabbbcacbbaaabbbccccbaaabccc
eine oder mehrere "Schlangen"? Nach welchen Regeln wird da zerstückelt? Und mit welchem Ziel? (das kann natürlich auch implizit in den Regeln stehen - aber ich würde es doch gerne auch mal explizit hören)

Und was ist das Ziel Deiner Analyse? Du zerstückelst ein laufendes Spiel in Sequenzen (bei Dir Schlangen) und zählst darin das Auftreten der einzelnen Möglichkeiten. Dann gewichtest Du diese bezüglich der Laplace-Wahrscheinlichkeit. Und nun? Wie willst Du diese Erkenntnisse nutzen? Und wo liegt der Zusammenhang zwischen zwei Sequenzen? Wozu überhaupt mehrere Sequenzen? Wo liegt da der Vorteil gegenüber einer globalen Betrachtung der gesamten bisher gespielten Sequenz? Und vor allem: Welche Sequenz betrachtest Du überhaupt? Die des Gegners, um daraus Schlüsse zu ziehen, oder Deine eigene, um diese ausgeglichen zu gestalten bezüglich der Laplace-Wahrscheinlichkeit? Mir kommt es an diesem Punkt so vor, als vermischt Du das ein wenig. Insofern wäre es aus meiner Sicht sinnvoll, wenn Du Deine Idee einmal präzise global beschreibst!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

@yipyip,
Code lesen macht mehr Spass, als Löcher in Bauch gefragt bekommen :-) Danke!

Hyperion,
mit der Lapace-Wahrscheinlichkeit hatte ich anfangs fälschlich was anderes assoziiert.
Habe nachgeschaut.
Klar, das ist sozusagen die Richtschnur, an der sich Abweichungen nach oben wie nach
unten messen lassen. Praktisch braucht es also eine Zahl, die diese Wahrscheinlichkeit
repräsentiert. Und eben genau diese Zahl erhalte ich durch die Dreiergruppierung!
Die Zahl der Dreier repräsentiert die Laplace-Wahrscheinlichkeit. Womit ich in der Folge
diese LW nicht mehr extra berechnen muss. Und bei notwendigen Berechnungen lassen
sich Dezimalbrüche gut vermeiden - was wohl auch nicht ganz unwichtig ist.

Beispiel:
Um eine 30 Zeichen lange Sequenz zu erhalten, mussen 10 Dreier aneinandergehängt/erzeugt
werden. Die Zahl '10' steht für die jeweiligen Chancen dieser Sequenz 10 mal zu gewinnen,
10 mal zu verlieren und 10 mal unentschieden zu spielen. Erfolgreich ist eine Sequenz, wenn
sie mehr als 10 plus x Treffer erzielt hat.
Der Witz bei der Geschichte ist doch, dass in dem eigentlichen Spiel schon die Drittellung
vorgegeben ist und es darum auch Sinn macht die Regeln danach auszurichten.

Ich habe auch nicht, wie Du anzunehmen scheinst, eine andere KI, sondern allein die nackte
Random-Funktion zum 'Gegner'. Was Du andenkst ist eine andere 'Baustelle' und sehr
viel komplexer als ich bei diesem Beispiel im Sinne habe. Zu allererst will ich ja an einem
überschaubarem Projekt das Programmieren mit Python lernen, und nicht etwa ein tolles
KI-Script schreiben.
Die eigentliche Spiel-Funktion ist soweit klar. Da spielt es auch keine Rolle wie die Sequenzen
entstehen, weil die Zeichen der Funktion einzeln übergeben werden und sie auch
Einzelergebnisse liefert. Auch die Erzeugung der Sequenzen ist soweit klar. Hier noch einmal
beide Funktionen zusammen:

Code: Alles auswählen

import random
def sim(inp):
    a = inp
    if a == "a":
        a = 1
    if a == "b":
        a = 2
    if a == "c":
        a = 3
    aplay = 0; bplay = 0
    b = random.randint(1,3)
    if a == b:
        pass
    else:
        if a > b:
            z = a - b
            if z == 1:
                aplay = 1
            else:
                bplay = 1
        else:
            z = b - a
            if z == 1:
                bplay = 1
            else:
                aplay = 1
                
    if a == 1:  
        ap = 'a'
    if a == 2:
        ap = 'b'
    if a == 3:
        ap = 'c'
       
    if b == 1:
        bp = 'a'
    if b == 2:
        bp = 'b'
    if b == 3:
        bp = 'c'
        
    return aplay, ap, bplay, bp
Beispielaufrufe:

Code: Alles auswählen

>>> from sim3 import sim
>>> sim('a')
(1, 'a', 0, 'c')
>>> sim(1)
(1, 'a', 0, 'c')
>>> sim(3)
(0, 'c', 1, 'a')
>>> sim('c')
Zufallssequenzen bekommt man mit dieser Funktion:

Code: Alles auswählen

def snake(anz3er):
    a = anz3er
    dic = {1 : 'abc',2 : 'acb',3 : 'bca',4 : 'bac',
           5 : 'cba',6 : 'cab',7 : 'aab', 8 : 'aba',
           9 : 'baa',10 : 'bba',11 : 'abb',12 : 'bab',
          13 :'cca',14 : 'acc',15 : 'cac', 16 : 'aaa',
          17 : 'bbb', 18 : 'ccc', 19 :  'aac', 20 : 'ccb',
          21 : 'cbc',  22 : 'bcc', 23 : 'bbc', 24 : 'cbb',
          25 : 'bcb', 26 : 'aca', 27 : 'caa'}
    snake = ""
    for z in range(a):
        x = random.randint(1, 27)
        snake += dic[x]

    return snake
Testausgabe:

Code: Alles auswählen

>>> 
>>> from abc1 import snake
>>> snake(1)
'cca'
>>> snake(3)
'aaababaca'
>>> snake(1000)
'abbacacbbacacccbbcabcbaabccbbabbcbcaabbbcbbcbcbbbaaacbbbbbcbaaacb
acbcbccbbbbbabbabbaaccccccccbbbbabaabcbaacaccbbacaccaa....'
Danke fürs Mitdenken!
BlackJack

@wwwheimer: Du hast irgendwie immer noch nicht erklärt *warum* Du diese komischen 3er-Grüppchen brauchst!? Die blosse Behauptung das Spiel gebe eine Drittelung vor reicht da nicht, Du musst schon erklären *warum* das so sein soll. Dem ist nämlich nicht so. Du kannst Deine umständliche `snake()`-Funktion durch eine ersetzen die einfach 3mal so oft einen Einzelbuchstaben auswürfelt, ohne dass man von aussen einen Unterschied feststellen könnte:

Code: Alles auswählen

def snake(anz3er):
    return ''.join(random.choice('abc') for _ in xrange(anz3er * 3))
Die so erzeugten Ketten haben die gleichen Wahrscheinlichkeiten, als welche wo `anz3er` mal aus allen dreistelligen Möglichkeiten ausgewählt wird. Genau *das* ist wohl der Punkt an dem wir alle nicht so recht verstehen was Du da eigentlich bezwecken willst.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich habe grad keine Zeit (und Lust) den Code zu kommentieren, daher beschränke ich mich noch mal aufs wesentliche:

Ich habe immer noch nicht kapiert, was Du eigentlich machen willst!

Erst hieß es, eine KI schreiben, nun doch keine KI. Welchen Sinn haben diese 3er-Sequenzen? Ja, klar, man kann aus den Kombinationen alle möglichen abc-Schlangen zusammenbauen. Aber mit welchem Ziel? Das habe ich noch nicht kapiert!

Dein Gegner ist einfach eine "dumme" KI, die per Zufall aus "abc" wählt. Ok.

Wann / wie kommen jetzt diese "Schlangen" ins Spiel?

Edit: Hey, außer mir kann wohl noch jemand nicht schlafen? ;-) @BlackJack: bei Dir auch grad Gewitter?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Und wo ist jetzt der Beleg, dass die Dreiergruppierung sinnvoll ist? Für mich sieht das nach einer vollkommen willkürlich gewählten Zahl aus, da du dich mit Wahrscheinlichkeitstheorie und Statistik nicht gut genug auskennst. Dir mag 3 hier zwar intuitiv richtig vorkommen, aber Intuition und Wahrscheinlichkeit sind nicht gerade gute Freunde. Das Brüche vermieden werden sollte finde ich ehrlich gesagt ein etwas abwegiges Argument.

Vielleicht zu deinem Code, da du etws lernen möchtest:
- Benutze richtige Namen; `sim` und `inp` sind nichtssagend.
- Die Zuweisung `a = inp` tut genau gar nichts außer einen neuen Namen zu erstellen.
- `elif` existiert
- Das ganze Mapping von a,b,c auf 1,2,3 kann man mit einem Dictionary geschickter lösen.
- `aplay = 0; bplay = 0` kannst du in zwei Zeilen schreiben; und natürlich richtige Namen vergeben
- `if a == b: pass else: ...` ist sehr umständlich. Benutze `if not a == b` oder in diesem Fall direkt `if a != b`
- Das Mapping von 1,2,3 nach a,b,c geht natürlich auch wieder einfacher
- Warum schreibst du das Mapping doppelt hin? Einmal für `a` und einmal für `b`? Benutze Funktionen.
- Es wurde dir glaube ich schon einmal gesagt "snake" ist das Tier. Du suchst "chain", "queue" oder in diesem Fall wahrscheinlich eher "sequence".
- Warum benutzt du `dic` als Dictionary, wenn du offensichtlich Indizes verwendest? Das sollte eine Liste sein oder ein Tupel. Außedem ist es in der Informatik üblich beginnend ab 0 zu zählen.
- Strings solltest du nicht mit `+` zusammensetzen, sondern sie alle in eine Liste packen und am Ende darauf `"".join` anwenden

Sebastian
Hyperion hat geschrieben:Edit: Hey, außer mir kann wohl noch jemand nicht schlafen? ;-) @BlackJack: bei Dir auch grad Gewitter?
Ich habe mich auch gerade gewundern, dass es noch zwei Posts gab ^^ Hier in Berlin ist noch kein Gewitter, bei mir ist es nur noch der Rest vom Jetlag. Danach schiebe ich es dann aufs Wetter ...
Das Leben ist wie ein Tennisball.
Benutzeravatar
wwwheimer
User
Beiträge: 25
Registriert: Sonntag 17. Juli 2011, 16:35

Was haben Euch meine Dreier bloss angetan? :roll:
Ich hatte es weiter oben schon angeesprochen und gesagt, dass ich die Dreier brauche, um auch Sequenzen konstruieren zu können, die ein sich wiederholendes Muster ergeben: (aaabbbcccaaabbbccc).
Das geht nicht per Zufall, sondern da muss ich schon die einzelnen Dreier aneinanderreihen und diese auch über einen eindeutigen Index auswählen können.

Warum Muster, bzw. Symetrien?
Weil ich davon ausgehe, dass auch Zufallsgeneratoren nach Regeln funktionieren und diese Regeln auch Spuren in Form von Mustern hinterlassen. Und darum finde ich den Gedanken gar nicht so abwegig, mit Hilfe von Mustern nach den vermuteten Mustern der Random-Fuktion zu suchen.
Uff!
Grüße!
Antworten