Reversi KI
Übersicht

Gehe zu Seite 1, 2, 3, 4 Weiter
neoleinBetreff: Reversi KI |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo,
seit Langem bin ich dabei ein Reversi zu programmieren, das Brett besteht aus 8x8 Feldern, auf denen 4 vorgegeben sind, d.h. 60 Steine fehlen noch. Schließt eine Farbe die andere ein (ein oder mehrere Steine) so werden alle Steine dazwischen zu eigenen. Im Code z.B. Schwarz auf e6 dreht weiß auf e5 zu schwarz. Es geht horitontal, vertikal, und diagonal, es fängt IMMER Schwarz an. Am Ende hat der gewonnen, der die meisten Steine seiner Farbe hat. Edit: Hier wird nun regelmäßig der aktuelle Code präsentiert Code: [AUSKLAPPEN] Graphics 640, 480, 16, 2 Dim Feld% (64,9,9) Dim Methode%(2) Methode(1)=0 Methode(2)=1 Type LeerTyp Field X% Field Y% End Type Global GibtWasZuMalen%, Spieler%, AnzahlLeere%, ZufallX%, ZufallY%, RotX%, RotY% Global MausX%, MausY%, SpielerKonnteNicht%, Immer%, Zeit%, SpielEnde%, WieOft% Global AnzahlSchwarze%, AnzahlWeisse%, SchwarzGewinnt%, WeissGewinnt% Global SchwarzBeginntGewinnt%, WeissBeginntGewinnt%, WerBeginnt% Global Schwarz Schwarz = CreateImage (36,36) SetBuffer ImageBuffer (Schwarz) Color 5,5,5 Oval 5,5,30,30 Global Weiss Weiss = CreateImage (36,36) SetBuffer ImageBuffer (Weiss) Color 223,223,223 Oval 5,5,30,30 Global Rot Rot = CreateImage (36,36) SetBuffer ImageBuffer (Rot) Color 223,3,3 Oval 5,5,30,30,0 SetBuffer BackBuffer() FeldReset() Spieler=1 SeedRnd MilliSecs() Repeat SpielerSetzt() MaleSpielFeld() Until KeyHit(1) End Function SpielerSetzt() ZugFestlegen Methode(Spieler) MausX=ZufallX MausY=ZufallY If EsIstHierErlaubt(MausX,MausY,Spieler) Feld(Ebene,MausX,MausY)=Spieler DebugLog "Spieler " + Spieler + " setzt auf " + MausX + "/" + MausY AllesDrehen(MausX,MausY,Spieler) Spieler=3-Spieler DebugLog "bald ist Spieler " + Spieler + " dran" ; dieser Teil stellt später fest, ob der gegner im anschluss überhaupt ziehen kann FindeAlleLeeren If AnzahlLeere=0 DebugLog "(SpielerSetzt) Gegner " + Spieler + " kann nicht" Spieler=3-Spieler FindeAlleLeeren If AnzahlLeere=0 DebugLog "(SpielerSetzt) Auch Gegner " + Spieler + " kann nicht" SpielEnde=1 EndIf WaitKey EndIf EndIf End Function Function FindeAlleLeeren() For Such.LeerTyp = Each LeerTyp Delete Such Next For X=1 To 8 For Y=1 To 8 If EsIstHierErlaubt(X%,Y%,Spieler) Neu.LeerTyp= New LeerTyp Neu\X= X Neu\Y= Y AnzahlLeere% = AnzahlLeere + 1 EndIf Next Next ;For Such.LeerTyp = Each LeerTyp ; RotX=Such\X ; RotY=Such\Y ;....entscheiden, ob dies der nächste Zug wird. ;Next End Function Function ZugFestlegen(Methode%) Select Methode Case 0 ; ziehen durch MausKlick RotX=MouseX()/50 RotY=MouseY()/50 If MouseHit(1) Then ZufallX=RotX ZufallY=RotY Else ZufallX=0 EndIf Case 1 RotX=Rand(1,8) RotY=Rand(1,8) ZufallX=RotX ZufallY=RotY End Select End Function Function EsIstHierErlaubt%(X%,Y%,Ich%) Local Ergebnis%, Summe%, i%, j% If Feld(Ebene,X,Y)=0 Then For i=-1 To 1 For j=-1 To 1 Ergebnis = ScanneEineRichtung(X, Y, i, j, Ich) Summe =Summe + Ergebnis Next Next EndIf Return summe End Function Function ScanneEineRichtung%(X%, Y%, RichtungX%, RichtungY%, Ich%) Local Erfolg% Repeat X=X+RichtungX Y=Y+RichtungY If (X>8) Or (X<1) Or (Y>8) Or (Y<1) Then Return 0 EndIf If Feld(Ebene,X,Y)=0 Then ; leeres Feld gefunden Return 0 ElseIf Feld(Ebene,X,Y)<>Ich Then ; Gegner-Feld gefunden Erfolg=Erfolg+1 ElseIf Feld(Ebene,X,Y)=Ich Then ; eigenes Feld gefunden Return Erfolg EndIf Forever End Function Function DreheEineRichtung (X%, Y%, RichtungX%, RichtungY%, Ich%) Repeat X=X+RichtungX Y=Y+RichtungY If Feld (Ebene,X,Y)=Ich Then Return EndIf Feld(Ebene,X,Y)=Ich Forever End Function Function AllesDrehen(X%,Y%,Ich%) Local Ergebnis%, Summe%, i%, j% For i=-1 To 1 For j=-1 To 1 If ScanneEineRichtung(X, Y, i, j, Ich)>0 Then DreheEineRichtung (X%, Y%, i, j, Ich%) EndIf Next Next End Function Function MaleSpielFeld() Local X%, Y% Cls Color 50, 100, 50 ;grün Rect 0,0,640,480,1 ;grüner Hintergrund Color 255, 255, 255 font = LoadFont("Arial",20,1) SetFont font Xpos = 70 For i = 65 To 72 Text Xpos,25,Chr$(i) Xpos = Xpos + 50 Next For Ypos=68 To 418 Step 50 Reihe = Reihe + 1 Text 30,Ypos,Reihe Next For x = 1 To 8 For y = 1 To 8 Rect x*50, Y*50, 50, 50, 0 If Feld (Ebene,X,Y) = 1 Then DrawImage Schwarz, X*50+2,Y*50+2 ElseIf Feld (Ebene,X,Y) = 2 Then DrawImage Weiss, X*50+2, Y*50+2 EndIf Next Next DrawImage Rot, rotX*50+2, rotY*50+2 Flip 0 ;Delay 50 End Function Function FeldReset() Local E%, X%, Y% For E = 1 To 60 For X = 1 To 8 For Y = 1 To 8 Feld (E,X,Y)= 0 Next Next Next ; 4 Start-Steine Feld(0,4,5)=1 Feld(0,5,4)=1 Feld(0,4,4)=2 Feld(0,5,5)=2 End Function |
||
- Zuletzt bearbeitet von neolein am Fr, Feb 12, 2010 11:08, insgesamt 8-mal bearbeitet
![]() |
Goodjee |
![]() Antworten mit Zitat ![]() |
---|---|---|
warum ist dein feld noch 60 tief? | ||
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
3D dimensional?
Aber erst mal: Feld$ definiert ein Array für Strings - du willst aber Zahlen darin speichern. Das Feld ist zu Anfang leer, also musst du es nicht mit Nullen füllen. Wenn du das Spielfeld Leeren willst, kannst du Code: [AUSKLAPPEN] Dim Feld(8,8,60) schreiben - neu dimensionieren in der selben Größe füllt es auch wieder mit Nullen.
Ich glaub' um ellenlange Abfragen kommt man dabei nicht wirklich herum... |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
SpionAtom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ausgehend von dem Stein, der gerae gesetzt wurde muss man in alle Himmelsrichtungen + Zwischenrichtungen prüfen (also N NO O SO S SW W NW), wieviele andersfarbige Steine auf dem Weg liegen - bevor wieder ein gleichfarbener Stein kommt. Das geht recht gut mit einigen while-Schleifen. | ||
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080 |
![]() |
Eingeproggt |
![]() Antworten mit Zitat ![]() |
---|---|---|
Äh Moment mal... Hab ich grad n paar schief gewickelte Hirnwindungen zuviel oder hat bis jetzt noch niemand bemerkt dass neolein gar keine Hauptschleife hat? Was er auch tut, er wird nichts davon sehen denn WaitMouse is sein programm zuEnd![]() Daher meine Empfehlung: Grundlegende Tutorials zum Programmaufbau / Codestruktur durchstöbern! mfG, Christoph. |
||
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9 |
neolein |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo,
danke für die Tips, der vorliegende Code ist nicht das eigentliche Programm, sondern dient nur der Darstellung des Brettes und der Dimensionierung, ich habe 2007 damit angefangen und musste das Projekt aus krankheitsgründen aufgeben. Hier benutzte ich auch die Idee mit den Himmelsrichtungen, das sind 8 und ich mußte quasi für jede Richtung den Code neu schreiben, es war schon ein riesen Aufwand nur die Regel hinzubekommen, das mit dem Drehen, als es dann an die Vorausberechnung ging (daher die 60 Ebenen, man kann das Spiel z.B. bis zur 4. Ebene alle Züge durchspielen lassen und den "besten" nimmt er sich dann. An der Bestimmung des "besten" Zuges bin ich dann mental verzweifelt. Der Check, welche Züge überhaupt gehen, geschah immer von links oben bis rechts unten, sodaß das Spiel immer nach links driftete. Wenn ihr der Meinung seid, daß es nur mit den Schleifen geht und Zahlen OK sind für die Variablen weiß, schwarz und leer dann bin ich vielleicht auf dem richtige Weg, dachte es könnte vielleicht irgendwie einfacher gehen. Chris |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Schritt 1:
Du schreibst eine einzige Funktion, die ausgehend vom akt. Stein in eine einzige Richtung nsch rechts voranschreitet. Bei jedem Schritt testest du, ob bereits eine Bedingung erreicht ist, die das Setzen des Stein wegen dieser Richtung untersagen würde. Kommt endlich dein eigener Stein, dann ist sogar eine Bedingung erreicht, die für das Setzen des Steins sprechen würde. Teste diese Funktion. Schritt 2: Nun führtst du in der Funktion zwei Variablen XMove%=1 und YMove%=0 ein. Jetzt änderst du die Funktion so ab, dass dort wo in xAkt% +1 stand jetzt XAkt+XMove% steht und dort wo YAkt stand YAkt+Ymove% steht. Damit sollte die Funktion jetzt wieder funktionieren. Schritt 3: Nun rufst du diese Funktion 8x mit jeweils den Parameternpaaren (-1,0) (-1,-1) (0,-1) (1,-1) (1,0) (1,1) (0,1) (-1,1) auf. Die Parameter stehen da für XMove%,YMove%. Schon genügt eine Funktion um alle 8 Himmelsrichtungen zu testen. |
||
neolein |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo,
vielen Dank, das mit XMove kannte ich noch gar nicht, das Abfragen habe ich durch Schleifen abgefragt. Hier ist mein vollständiger Code Code: [AUSKLAPPEN] Graphics 640, 480, 16, 2 Color 50, 100, 50 ;grün Rect 0,0,640,480,1 ;grüner Hintergrund Arial = LoadFont("Arial",15) SetFont Arial ;SetBuffer BackBuffer() Global Schwarz Schwarz = LoadImage ("schwarz.bmp") Global Weiss Weiss = LoadImage ("weiss.bmp") Function SchwarzM() DrawImage Schwarz,Mx*50+2,My*50+2 End Function Global Mx Mx = MouseX()/50 Global My My = MouseY()/50 ;weißes Felder malen Color 255, 255, 255 x=0 y=0 For n = 1 To 8 Repeat x=x+50 Rect 0+x, 50+y, 50, 50, 0 Until x>350 x=0 y=y+50 Next ;Feld dimensionieren Dim feld (64,9,9) ;alle Felder auf 0 For e = 1 To 60 For b = 1 To 8 For h = 1 To 8 feld (e,b,h) = 0 Next Next Next ; erste 4 Felder (Runde 1 bis 4) x = 0 For e = 1 To 60 ; ab erster Ebene For b = 4 To 5 For h = 4 To 5 x = 1-x feld (e,b,h) = x+1 Select x Case 1 DrawImage Weiss, b*50+2,h*50+2 Case 0 DrawImage Schwarz, b*50+2,h*50+2 End Select Next x = 1 Next x = 0 Next Flip e = 2 ; zweite Ebene fx = 1 S=0 Gosub ft ;f1=schwarz For R = 1 To 30 ;macht 58+2 Ebenen z = 0 em1 = 0 If f1=2 Gosub proof b=bz : h=hz Delay 250 EndIf ;Mausfarbe If f1=1 ;And em1>0 Repeat Until MouseHit(1) b=MouseX()/50 h=MouseY()/50 EndIf e=e+1;Ebene 3 If feld (e,b,h) = 0 Gosub Matrix Gosub copy Gosub bh ;Steine malen If z=0 ; wenn Aussetzer e=e-1 R=R-1 EndIf z = 0 em1 = 0 Gosub Proof b=bz : h=hz Delay 250 If f1=1 ;And em1>0 Repeat Until MouseHit(1) b=MouseX()/50 h=MouseY()/50 EndIf e=e+1 If feld (e,b,h) = 0 Gosub Matrix Gosub copy Gosub bh ;Steine malen ;Print em Gosub ft If e>55 Text (R-35)*20,10,e If z=0 ; wenn Aussetzer e=e-1 R=R-1 EndIf S=S+1 Text S*15,460,e Text 0+S*15,450,z ;Print R If e=30 Exit Next bl=0 wh=0 For b = 1 To 8 For h = 1 To 8 If feld (e,b,h) = 1 bl = bl+1 If feld (e,b,h) = 2 wh = wh+1 Next Next Text 500,40,"Schwarz: " + bl Text 500,60,"Weiss: " + wh Text 500,80,"Ebene: "+e Repeat Until MouseHit(1) End ;Return .Proof Gosub ft;weiss d1=16 z=0 For b1 = 1 To 8 ; setzt Steine For h1 = 1 To 8 b=b1 : h=h1 If feld (e,b,h) = 0 e=e+1;2 Gosub Matrix If z>0 Gosub Proof2 e=e-1;1 EndIf If d>0 And d<d1 d1 = d EndIf Gosub copy Next Next Return .Proof2 Gosub ft;schwarz em=0 em1=17 z=0 For b2 = 1 To 8 ; setzt Steine For h2 = 1 To 8 b=b2 : h=h2 If feld (e,b,h) = 0 e=e+1;3 Gosub Matrix ;If z>0 Gosub Proof3 e=e-1;2 EndIf If em<em1 ; immer das größte em auswählen em1=em bz=b1 hz=h1 EndIf ;Print em Gosub copy Next Next If em=0 f1=2 ;Print f1 Gosub ft;weiss Return .Proof3 Gosub ft z=0 em=0 For b3 = 1 To 8 ; setzt Steine For h3 = 1 To 8 b=b3 : h=h3 If feld (e,b,h) = 0 e=e+1;4 Gosub Matrix e=e-1;3 EndIf If em > em1 ; immer das größte z auswählen em1 = em bz=b1 hz=h1 EndIf Gosub copy ;e=e5 Next Next Gosub ft ;Print z Return .Matrix d=0:z=0 If feld (e,b,h-1) = f2 Gosub N If feld (e,b+1,h) = f2 Gosub O If feld (e,b,h+1) = f2 Gosub S If feld (e,b-1,h) = f2 Gosub W If feld (e,b+1,h-1) = f2 Gosub NO If feld (e,b+1,h+1) = f2 Gosub SO If feld (e,b-1,h+1) = f2 Gosub SW If feld (e,b-1,h-1) = f2 Gosub NW If z>0 em=em+1 EndIf Return .ft fx = 1-fx f1 = 1+fx f2 = 2-fx Return .bh For b = 1 To 8 ; setzt Steine For h = 1 To 8 If feld (e,b,h) = 1 DrawImage Schwarz, b*50+2,h*50+2 If feld (e,b,h) = 2 DrawImage Weiss, b*50+2,h*50+2 Next Next Flip Return .copy For ba = 1 To 8 For ha = 1 To 8 feld (e+1,ba,ha) = feld (e,ba,ha) Next Next Return .N For y1 = h-1 To 1 Step -1 ; Schleife, bis schwarz kommt If feld (e,b,y1) = f1 Exit Next n = 0 I = 0 For y2 = h-1 To y1+1 Step -1 ; überprüft, ob alle Felder weiß I = I+1 If feld (e,b,y1) <> f1 Exit ; falls die ganze Reihe bis y1(1) = 2 ist If feld (e,b,y2) <> f2 Exit ; falls Nachbar von f1 nicht f2 ist n = n+1 Next For y3 = h-1 To y1+1 Step -1 ; wandelt die Farbe If n = I feld (e,b,y3) = f1 ;alle zwischen Maus und Ende feld (e,b,h) = f1 ;Maus d=d+1 EndIf ;Gosub V Next If n = I z = z+1 Return .O For x1 = b+1 To 8 ; Schleife, bis schwarz kommt If feld (e,x1,h) = f1 Exit Next n = 0 I = 0 For x2 = b+1 To x1-1 ; überprüft, ob alle Felder weiß I = I+1 If feld (e,x1,h) <> f1 Exit ; falls die ganze Reihe bis x1(8) = 2 ist If feld (e,x2,h) <> f2 Exit n = n+1 Next For x3 = b+1 To x1-1 ; wandelt die Farbe If n = I feld (e,x3,h) = f1 feld (e,b,h) = f1 d=d+1 EndIf ;Gosub H Next If n = I z = z+1 Return .S For y1 = h+1 To 8 ; Schleife, bis schwarz kommt If feld (e,b,y1) = f1 Exit Next n = 0 I = 0 For y2 = h+1 To y1-1 ; überprüft, ob alle Felder weiß I = I+1 If feld (e,b,y1) <> f1 Exit ; falls die ganze Reihe bis y1(8) = 2 ist If feld (e,b,y2) <> f2 Exit n = n+1 Next For y3 = h+1 To y1-1 ; wandelt die Farbe If n = I feld (e,b,y3) = f1 ;alle zwischen Maus und Ende feld (e,b,h) = f1 ;Maus d=d+1 EndIf ;Gosub V Next If n = I z = z+1 Return .W For x1 = b-1 To 1 Step -1 ; Schleife, bis schwarz kommt If feld (e,x1,h) = f1 Exit Next n = 0 I = 0 For x2 = b-1 To x1+1 Step -1 ; überprüft, ob alle Felder weiß I = I+1 If feld (e,x1,h) <> f1 Exit ; falls die ganze Reihe bis x1(1) = 2 ist If feld (e,x2,h) <> f2 Exit n = n+1 Next For x3 = b-1 To x1+1 Step -1 ; wandelt die Farbe If n = I feld (e,x3,h) = f1 feld (e,b,h) = f1 d=d+1 EndIf ;Gosub H Next If n = I z = z+1 Return .NO y1 = h For x1 = b+1 To 8 ; Schleife, bis schwarz kommt y1 = y1-1 If y1 < 1 Exit If feld (e,x1,y1) = f1 Exit ; wenn die andere Farbe kommt, weiter Next n = 0 I = 0 y2 = h For x2 = b+1 To x1-1 ; überprüft, ob alle Felder weiß y2 = y2-1 I = I+1 If y1 < 1 Exit If feld (e,x1,y1) <> f1 Exit ; falls die ganze Reihe bis zum Rand die andere Farbe nicht kommt, weiter If feld (e,x2,y2) <> f2 Exit n = n+1 Next y3 = h For x3 = b+1 To x1-1 ; wandelt die Farbe If y1 < 1 Exit y3 = y3-1 If n = I feld (e,x3,y3) = f1 feld (e,b,h) = f1 d=d+1 EndIf ;Gosub D Next If n = I z = z+1 Return .SO y1 = h For x1 = b+1 To 8 ; Schleife, bis schwarz kommt y1 = y1+1 If y1 > 8 Exit If feld (e,x1,y1) = f1 Exit Next n = 0 I = 0 y2 = h For x2 = b+1 To x1-1 ; überprüft, ob alle Felder weiß y2 = y2+1 I = I+1 If y1 > 8 Exit If feld (e,x1,y1) <> f1 Exit ; falls die ganze Reihe bis x1(8) = 2 ist If feld (e,x2,y2) <> f2 Exit n = n+1 Next y3 = h For x3 = b+1 To x1-1 ; wandelt die Farbe If y1 > 8 Exit y3 = y3+1 If n = I feld (e,x3,y3) = f1 feld (e,b,h) = f1 d=d+1 EndIf ;Gosub D Next If n = I z = z+1 Return .SW y1 = h For x1 = b-1 To 1 Step -1; Schleife, bis schwarz kommt y1 = y1+1 If y1 > 8 Exit If feld (e,x1,y1) = f1 Exit Next n = 0 I = 0 y2 = h For x2 = b-1 To x1+1 Step -1; überprüft, ob alle Felder weiß y2 = y2+1 I = I+1 If y1 > 8 Exit If feld (e,x1,y1) <> f1 Exit ; falls die ganze Reihe bis x1(1) = 2 ist If feld (e,x2,y2) <> f2 Exit n = n+1 Next y3 = h For x3 = b-1 To x1+1 Step -1 ; wandelt die Farbe If y1 > 8 Exit y3 = y3+1 If n = I feld (e,x3,y3) = f1 feld (e,b,h) = f1 d=d+1 EndIf ;Gosub D Next If n = I z = z+1 Return .NW y1 = h For x1 = b-1 To 1 Step -1 ; Schleife, bis schwarz kommt y1 = y1-1 If y1 < 1 Exit If feld (e,x1,y1) = f1 Exit Next n = 0 I = 0 y2 = h For x2 = b-1 To x1+1 Step -1 ; überprüft, ob alle Felder weiß y2 = y2-1 I = I+1 If y1 < 1 Exit If feld (e,x1,y1) <> f1 Exit ; falls die ganze Reihe bis y1(1) = 2 ist If feld (e,x2,y2) <> f2 Exit n = n+1 Next y3 = h For x3 = b-1 To x1+1 Step -1 ; wandelt die Farbe If y1 < 1 Exit y3 = y3-1 If n = I feld (e,x3,y3) = f1 feld (e,b,h) = f1 d=d+1 EndIf ;Gosub D Next If n = I z = z+1 Return |
||
neolein |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo,
erwähnen wollt ich noch: .Matrix ist die primäre Abfrage (ob der Nachbar einer Farbe die andrer Farbe ist, also Nachbar von weiß muß schwarz sein), von dort aus geht es dann zu den Richtungen (N,W,O,S,NO,SO,SW,NW) |
||
![]() |
D2006Administrator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bitte vermeide Doppelposts und benutze den EDIT-Button rechts über deinem Beitrag, wenn du noch etwas hinzufügen möchstest! | ||
Intel Core i5 2500 | 16 GB DDR3 RAM dualchannel | ATI Radeon HD6870 (1024 MB RAM) | Windows 7 Home Premium
Intel Core 2 Duo 2.4 GHz | 2 GB DDR3 RAM dualchannel | Nvidia GeForce 9400M (256 MB shared RAM) | Mac OS X Snow Leopard Intel Pentium Dual-Core 2.4 GHz | 3 GB DDR2 RAM dualchannel | ATI Radeon HD3850 (1024 MB RAM) | Windows 7 Home Premium Chaos Interactive :: GoBang :: BB-Poker :: ChaosBreaker :: Hexagon :: ChaosRacer 2 |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mit XMove meinte ich auch nur eine Variable. Die Idee ist die acht Richtungen mit einer einzigen Funktion abzudecken. Das sollte möglich sein.
Das ganze sieht jetzt schon sehr unübersichtlich aus. Ich glaub du hast dich da grundsätzlich verheddert. Eigentlich müsste die Feldabfrage incl aller Spielregeln mit ca 30 Zeilen möglich sein. Aber beantworte mir bitte mal zunächst, was du mit den 60 Ebenen anstellen willst? Möglicherweise reden wir ja grad aneinander vorbei... [Nachtrag] Ich habe mir deinen Code jetzt einmal genau angesehen. Er läuft ja schon einigermaßen korrekt abr noch nicht sehr stabil, außerdem ist sehr undurchsichtig und langatmig. Nun hast du zwei Möglichkeiten. Zum einen könnte ich dir kurz sagen, warum der Computer das Spiel immer in eine Richtung entwickelt und auch wie du das verbessern kannst. Zum anderen könntest du den gesamten Code besser strukturieren. Damit würde der Code wesentlich kürzer (ca 70% weg) und leichter pflegbar. Dabei würdest du auch alle Fehler finden, die noch enthalten sind. So, wie er jetzt ist, wird es auch schwierig z.b. eine KI einzubauen (Bisher gewinnt man ja jedes Spiel gegen den Computer). Ich würde dich dabei Schritt für Schritt begleiten und dir alle Änderungen genau erklären. Es bliebe also "Dein Code". Du würdest eine Menge lernen. |
||
neolein |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi,
du hast recht, unbersichtlich ist er, besonders jetzt, nach 2 Jahren habe ich wieder so einiges vergessen, den Aufbau, den Gedankengang. Zu den Ebenen: Da ja am Anfang immer 4 Steine liegen fehlen noch 60; die Idee ist (aber eigentlich halte ich das sogar für notwendig) eine Vorausberechnung, d.h. das Spiel muß "wissen" wie alle Möglichkeiten der Züge (sind ein paar Millionen) es z.B. in Ebene 10 aussieht, um in Ebene 6 meinetwegen den richtigen Zug auszuführen. Das sind die Teile des Codes mit .Proof 2. mchte ich Zugrücknahme einbauen und Spielspeicherung, d.h. das ganze Spiel kann von hinten bis vorne zurückgespielt werden, deshalb habe ich die 3. Dimension aufgebaut, man kann es sich sogar bildlich vorstellen, wie ein Quader. Falls wir das machen könnten wäre ich froh, das Projekt möchte ich eh nicht kommerzielisieren, es gibt schon sehr sehr gute Freewareprogramme (das bekannteste ist WZebra), das bis zu 24 im Voraus berechnet und mehr. Letzten Endes ist mir die KI am wichtigsten, so gibt es z.B. folgendes zu bedenken: keine Maximumstrategie am Anfang möglichst wenig Steine des Gegners umdrehen, d.h. möglichst wenig Steine eigener Farbe haben, damit verbunden ist die Mobilität, je weniger ich habe, desto mehr Zugmöglichkeiten hat man. Vermeiden, daß der Gegner die Ecken besetzt, denn das sind stabile Steine und man hat die besten Voraussetzungen das Spiel zu gewinnen. Parität beachten (d.h. wer spielt den letzten Zug=Vorteil), wenn beide in einem nromalen Spiel immer abwechselnd ziehen, dann setzt weiß immer zuletzt, es sei denn weiß kann in einem oder einer Menge ungerader Züge nicht ziehen. Es gint noch einen Haufen mehr an KI, es ist so komplex wie bei Schach, aber darauf würde ich dann später kommen. Da ich wirklich wenig Zeit habe (meine Tochter ist mit Mama ausnahmsweise für 3 Tage ausser Haus) wird das nicht von heute auf morgen gehen, aber vielleicht ist das ein Anfang und dann gehts eben etwas langsamer. |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ok, dann handelt es sich bei den Ebenen nicht um ein 3D-Reversi... gut! Deine Ideen zu KI sind zwar nett, aber dafür ist es noch viel zu früh. Ich werde dir zunächst helfen, den Code lesbar zu machen.
Zunächst zu deinem Problem, warum es immer in eine bestimmte Richtung läuft: Du solltest den Gegner die möglichen Felder nicht von links oben zeilenweise nach rechts unten durchforsten lassen sondern ruhig mit zufall arbeiten.Das Spiel des Gegners wirkt dann lebendiger. Ich schlage folgende Strategie vor: 1. beliebiges Zufallsfeld aus allen 64 auswählen 2. Ist es noch frei? 3. Ist es erlaubt? 4. Ist es sinnvoll? 5. Ziehen Damit bekommst du einen (Computer-)Gegner, der zwar völlig unintelligent, aber schon absolut regelkonform zieht. Quasi eine "Anfänger-Stufe" gegen die Kinder spielen könnten. Später werden wir dann Punkt 4 immer weiter ausbauen und mehrere verschiedene "Intelligenz-Grade" einfügen. Bevor dies aber in Angriff genommen werden kann, muss aus dem Spaghetti-Code ein strukturiertes Programm werden. Dazu MUSST du dich mit Funktionen anfreunden. Das ist fast wie die GOSUBs, die du bereits im Code hast, bietet aber sehr viel mehr Vorteile. Lies dazu das Kapitel III aus meinem Programmablauf-Tutorial https://www.blitzforum.de/foru...hp?t=33584 und das Kapitel I aus dem Funktionen-Tutorial: https://www.blitzforum.de/foru...hp?t=33468 Das Ordnen der Zeilen Zunächst kapseln wir einige Routine-Aufgaben in jeweils eine eigene Funktion. Den Code in den Funktionen habe ich immer 1:1 aus deinem Code genommen. Du müsstest ihn eigentlich erkennen: BlitzBasic: [AUSKLAPPEN] Function MaleSpielFeld() Hier habe ich einmal alles das untergebracht, was für einen Neustart zu tun ist. Bei dir war es auf viele Stellen verstreut: BlitzBasic: [AUSKLAPPEN] Function FeldReset() |
||
- Zuletzt bearbeitet von Midimaster am Di, Feb 02, 2010 2:15, insgesamt einmal bearbeitet
neolein |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das mit dem Zufall ist sehr gut, die Zufallsabfrage hätte ich auch reingenommen, aber erstens wußte ich nicht wie, und zweitens, das ist der Knackpunkt, wenn die KI irgendwann steht, wird es völlig egal sein, von wo die Abfrage startet.
Da sie in meinem Code nicht vorhanden war, hat er natürlich sofort das erste mögliche Feld genommen, darum die Ausrichtung nach rechts. Die Funcitions hatte ich auch benutzt, aber vielleicht nicht ausgiebig genug. Mit dem Zufall ist aber für den Anfang eine sehr gute Sache, denn viele Anfänger spielen "zufällig". Achso, Grundfunktionen sind vorhanden, ich habe hier das Spiel Pong 1.0 hochgeladen, fix und fertig gezipt mit readme, code und exe, ich weiß nur nicht, auf welcher Seite im Archiv es liegt. |
||
- Zuletzt bearbeitet von neolein am Mo, Feb 01, 2010 20:00, insgesamt einmal bearbeitet
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ok, dann kommt jetzt hier der erste harte Brocken für dich. Die Funktion zum Erfassen, was in den 8 Himmelsrichtungen los ist:
Diese Funktion untersucht von einem Feld in eine best. Richtung. Damit du den Code zunächst wiedererkennst, untersucht sie erst einmal nur Richtung Osten. Später wollen wir mit dieser Funktion alle 8 Himmelsrichtungen mit dem gleichen Code beherschen: BlitzBasic: [AUSKLAPPEN] Function ScanneEineRichtung%(X%, Y%, RichtungX%=1, Ich%=1) Verstehtst du, was passiert? In den Variablen X und Y erhält sie die gewünschte Position für den nächsten Stein: BlitzBasic: [AUSKLAPPEN] Function ScanneEineRichtung%(X%, Y%, RichtungX%=1, Ich%=1) Durch das Ich% erfährt sie, wer gerade fragt: schwarz(=1) oder weiß(=2). Nun läuft sie bedingt durch das RichtungX=1 stein für stein in die X-Richtung (Osten) BlitzBasic: [AUSKLAPPEN] X=X+RichtungX Triff sie auf ein leeres Feld, dann bricht sie sofort ab. trifft sie auf einen Gegner, findet sie das gut und erhöht den Erfolg. Trifft sie auf die eigene Farbe, dann beendet sie die Routine und meldet, wie groß der Erfolg war (sprich, wieviele Gegner dazwischen lagen) Es fehlen noch zwei Dinge: Die Sicherheitsabfrage, ob der Spielfeldrand erreicht wurde.... BlitzBasic: [AUSKLAPPEN] If (X>8) Or (X<1) Or (Y>8) Or (Y<1) Then hier wird immer wie erfolglos abgebrochen! ...und jetzt zu der Universalität für alle 8 Richtungen... Wir legen uns einfach nicht bei RichtungX% fest. Und außerdem gibt es auch eine RichtungY%: BlitzBasic: [AUSKLAPPEN] Function ScanneEineRichtung%(X%, Y%, RichtungX%, RichtungY%, Ich%) Alle Werte im "Header" einer Funktion lassen sich ja "von außen" manipulieren. Aufgerufen werden die 8 Richtungen dann mit diesen Parametern: Hier Beispiel Richtung Nord, schwarz ist dran (xxx und yyy sind beliebige Feldkoordinate): BlitzBasic: [AUSKLAPPEN] Print ScanneEineRichtung( xxx, yyy, 0, -1, 1) Hier Beispiel Richtung Südwest, weiß ist dran: BlitzBasic: [AUSKLAPPEN] Print ScanneEineRichtung( xxx, yyy, -1, 1, 2) ok? Frag, wenn Du hier etwas nicht verstehst. Denn das wird DIE zentrale Routine deines Prgramms. Sie ist praktisch schon alles was wir überhaupt brauchen werden. Der Rest baut komplett auf Ihr auf. jetzt nochmals die gesamte Funktion: BlitzBasic: [AUSKLAPPEN] Function ScanneEineRichtung%(X%, Y%, RichtungX%, RichtungY%, Ich%) |
||
neolein |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ok, also ein paar Fragen habe ich:
Code: [AUSKLAPPEN] Function ScanneEineRichtung% (X%, Y%, RichtungX%=1, Ich%=1) Local Erfolg% Repeat X=X+RichtungX Y=Y+RichtungY If (X>8) Or (X<1) Or (Y>8) Or (Y<1) Then Return 0 If Feld(Ebene,X,Y)=0 Then ; leeres Feld gefunden Return 0 ElseIf Feld (Ebene,X,Y)<>Ich Then ; Gegner-Feld gefunden Erfolg=Erfolg+1 ElseIf Feld (Ebene,X,Y)=Ich Then ; eigenes Feld gefunden Return Erfolg EndIf Forever End Function Ist die Integer Funktion (%) wirklich nötig? weil schneller? Wie ist die Variable "Erfolg" definiert? Wenn Erfolg = Erfolg+1 ist, was ist der Anfangswert von Erfolg? Müßte dafür nich am Anfang "Local Erfolg = 1" stehen? Was bewirkt die Variable Erfolg überhaupt? Achso und Feld (Ebene,X,Y)<>Ich kann doch auch 0 sein und nicht nur 1 oder 2 |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Diese Funktion scannt nicht nur die Steine in eine bestimmte Richtung sondern sie liefert auch gleich am Ende die Anzahl der gegn. Steine als Wert zurück. Daher verhält sie sich wie eine INTEGER-Zahl. Die Definition muss also INTEGER lauten. Was wäre Dein Gedanke dazu gewesen?
Die Variable Erfolg% dient nur LOKAL während der Funktion zum Zusammenzählen der gefundenen gegn. Steine. Am Anfang unmittelbar nach dem Local Erfolg% hat sie zunächst den Wert 0. Findet die Funktion einen gegnerischen Stein, erhöht sie Erfolg immer um 1. Am Ende des Durchscannens gibt Erfolg seinen Wert möglicherweise als Funktions-Ergebnis zurück. Beispiel: Die Funktion findet 3 gegnerische Steine, aber keinen Abschlussstein der eigenen Farbe. Hier hat zwar Erfolg den Wert 3, die Funktion liefert aber 0 zurück. ( RETURN 0) Beispiel 2: Die Funktion findet 3 gegnerische Steine, und glücklicherweise dahinter noch einen Abschlussstein der eigenen Farbe. Hier hat die Erfolg den Wert 3, die Funktion liefert auch 3 zurück. ( RETURN Erfolg) Es sind zwei Scenarien denkbar: 1. Die Funktion findet irgendwann auf dem Weg ein leeres Feld (oder Rand). Dann bricht sie sofort ab und meldet 0, egal wieviele Gegner bis dahin gefunden waren. Eine Gegner-Kette mit leeren Feld am anderen Ende nützt uns ja nichts. 2. Die Funktion findet irgendwann auf dem Weg einen eigenen Stein. Dann bricht sie sofort ab und meldet die Anzahl der dazwischen gefundenen Gegner. Möglicherweise meldet sie aber auch 0, weil auf diesem Weg direkt neben uns sofort ein eigener Stein lag. Ja, die Feld(Ebene,X,Y) kann drei Zustände haben: 0= Feld ist leer Ich= Feld hat die gleiche Farbe wie ich Weder Ich noch 0 = Feld gehört dem Gegner |
||
neolein |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Zu
0= Feld ist leer Ich= Feld hat die gleiche Farbe wie ich Weder Ich noch 0 = Feld gehört dem Gegner müsste es dann nicht heißen: ElseIf Feld (Ebene,X,Y)<>Ich or (Ebene,X,Y)<>0 Then Erfolg=Erfolg+1 Zu der Funktion, ich habe mich nur gefragt warum hinter jeder Variablen ein % steht, ich dachte, weil es immer ganze Zahlen sind und dadurch vielleicht schneller läuft. Die Frage ist, ob es wichrtig ist wieviele Steine umgedreht wurden, da die Verteilung schwarz:weiß ja kein Qualitätsmerkmal für die eine oder andere Seite ist. In vielen Reversi Spielen wird oft der Spielstand angezeigt, was eigentlich nur am Ende beim Auszählen interessant ist, aber für den Verlauf überhaupt keine Bedeutung hat. |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
...Or Feld(Ebene,X,Y)<>0
das mußt du in diesem Fall nicht abchecken, weil du ja zwei zeilen vorher schon alle Fälle =0 in die erste IF verzweigt hast. Bei einer IF/ELSE/ENDIF springt eine zutreffende Bedingung nach Abarbeitung des Blocks immer an das ENDIF und arbeitet die anderen IFs gar nicht mehr ab: BlitzBasic: [AUSKLAPPEN] A%=Rand(1,100) Wichtigkeit wieviele.... Zunächst scheint es noch nicht wichtig. Da wir ja nur feststellen wollen, ob dort überhaupt mind 1 Gelegenheit besteht etwas umzudrehen, ignorieren wir tatsächlich das Ergebnis der Funktion. Aber vielleicht brauchen wir es ja später noch ... ![]() Warum das %? Hinter jeder Variablen steht %, weils so ordentlich ist. Siehe 2 Kapitel aus mein Variablen-Tutorial: https://www.blitzforum.de/foru...037#354037 https://www.blitzforum.de/foru...050#354050 |
||
neolein |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ok, das mit dem Check habe ich verstanden.
Ich wollte nur mal schon etwas wegen der KI vorweggreifen, bevor du dir den Code weiter überlegst: Es ist vorrangige Strategie des Spiels das Bewegungsfeld des Gegners einzuschränken, und die eigene zu erhöhen. Das heißt, in den Ebenen, wo man selbst spielt (z.B. Schwarz 2, 4, 6 usw.) setze ich so, daß der Gegner im nächsten Zug (Weiß Ebene 3, 5, 7) möglichst wenig Felder zum setzen hat und ich im übernächsten Zug möglichst viele. Das heißt bildlich gesprochen: Man sollte versuchen sich im Zentrum zu bewegen, sich einmauern zu lassen, den Gegner dazu zu bewegen sich umzingeln zu lassen. Vielleicht läßt sich da mit einem einfachen Befehl schon etwas machen am Anfang, ach mir brennts unter den Nägeln mit der KI anzufangen ![]() |
||
Gehe zu Seite 1, 2, 3, 4 Weiter
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group