Matroids Matheplanet Forum Index
Moderiert von Bilbo
Informatik » Angewandte Informatik » Wer gewinnt beim Spiel Isola
Thema eröffnet 2018-08-23 22:12 von Delastelle
Seite 3   [1 2 3]   3 Seiten
Autor
Kein bestimmter Bereich Wer gewinnt beim Spiel Isola
NoraB
Aktiv Letzter Besuch: im letzten Monat
Dabei seit: 29.12.2022
Mitteilungen: 40
  Beitrag No.80, eingetragen 2023-01-03

Bisher nur eine Partie gespielt - und verloren 1: A3 to B3 removing D3 - E3 to D2 removing C4 2: B3 to C3 removing C2 - D2 to E3 removing B4 3: C3 to D2 removing D4 - E3 to E2 removing B1 4: D2 to D1 removing D2 - E2 to E1 removing B2 5: D1 to E2 removing D1 - 1:0 Have fun - ich muss los...


   Profil
gonz
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 16.02.2013
Mitteilungen: 4636
Wohnort: Harz
  Beitrag No.81, eingetragen 2023-01-03

Hmmmmpf... Ich glaube mein Programm ist noch fehlerhaft, ich ziehe meine obige Aussage erstmal zurück und prüfe das mal genauer...


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.82, vom Themenstarter, eingetragen 2023-01-03

@gonz: Ist Dein Program auf Basis von Alpha-Beta mit Suchbaumtechniken?


   Profil
gonz
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 16.02.2013
Mitteilungen: 4636
Wohnort: Harz
  Beitrag No.83, eingetragen 2023-01-03

Alpha-Beta Suche, ja. Ich bin jetzt mal auf die Idee gekommen, das Ganze für 3x3 auszuprobieren, um es einfacher nachverfolgen zu können. Allerdings hält das Programm - im Gegensatz zu der Tabelle von tactac, 3x3 für den Anziehenden für gewonnen, und zwar durch den Zug A2-A1 und Wegnahme von C3. Vielleicht könnte tt mal gucken, was Schwarz seiner Meinung nach (oder nach seinem Programm :) ) dann entgegnen sollte?


   Profil
tactac
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 15.10.2014
Mitteilungen: 2712
  Beitrag No.84, eingetragen 2023-01-07

Ich hab's jetzt nochmal neu programmiert und die Ergebnisse, die ich bisher erhalten habe, stimmen mit der damaligen Tabelle überein. Insbesondere verliert der Anziehende auf einem 3x3-Brett und er gewinnt auf einem 2x2-Brett (ja, auch mit Diagonalbewegung). Eine Antwort von Schwarz auf den Zug von Weiß in #83 wäre zum Beispiel C2-B1 mit Wegnahme von B2. Ich schätze mal, in gonz' Startkonfiguration ist alles mit Plättchen belegt. Nach #0 sollen die Startfelder der Spielfiguren aber nicht mit Plättchen belegt sein.


   Profil
tactac
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 15.10.2014
Mitteilungen: 2712
  Beitrag No.85, eingetragen 2023-01-07

\(\begingroup\)\(\newcommand{\sem}[1]{[\![#1]\!]} \newcommand{\name}[1]{\ulcorner#1\urcorner} \newcommand{\upamp}{\mathbin {⅋}} \newcommand{\monus}{\mathbin {∸}}\) Zum Zweck der Prüfung, ob wir in der Interpretation der Regeln übereinstimmen, hier mal mein (bisher extrem ineffizienter, aber leicht verständlicher) Code, mit ein paar Auswertungen: \sourceon Haskell {-# LANGUAGE OverloadedRecordDot, DuplicateRecordFields #-} import qualified Data.Set as S import Control.Monad -- Generic stuff data Game s m = Game { moves :: s -> [m], move :: s -> m -> s } isWin :: Game s m -> s -> Bool isWin g = not . isLoose g isLoose :: Game s m -> s -> Bool isLoose g = null . winningMoves g winningMoves :: Game s m -> s -> [m] winningMoves g s = filter (isLoose g . g.move s) $ g.moves s -- Isola specific type Vec = (Int, Int) type Pos = Vec type Dir = Vec type Dim = Vec (#+) :: Pos -> Dir -> Pos (a,b) #+ (c,d) = (a+c,b+d) data State = State { ply :: Pos, opp :: Pos, chips :: S.Set Pos } deriving (Eq, Ord, Show) type Move = (Dir, Pos) iMove :: State -> Move -> State iMove s (d, p) = State {chips = S.delete p s.chips, ply = s.opp, opp = s.ply #+ d } iMoves :: State -> [Move] iMoves s = do dx <- [-1..1] dy <- [-1..1] guard $ dx /= 0 || dy /= 0 let d = (dx,dy) let ply' = s.ply #+ d guard $ ply' /= s.opp && ply' `S.member` s.chips p <- S.toList s.chips guard $ p /= s.opp && p /= ply' return (d, p) start :: Dim -> State start (w,h) | w == 1 && odd h = error "Geht nicht" | otherwise = State ply opp chips where chips = S.fromList $ do x <- [1..w] y <- [1..h] let c = (x,y) guard $ c /= ply && c /= opp return c oppy = (h+1)`div`2 ply = (1,h+1-oppy) opp = (w,oppy) game :: Game State Move game = Game iMoves iMove -- >>> start (3,1) -- State {ply = (1,1), opp = (3,1), chips = fromList [(2,1)]} -- >>> start (2,2) -- State {ply = (1,2), opp = (2,1), chips = fromList [(1,1),(2,2)]} -- >>> game.moves (start (3,1)) -- [] -- >>> isWin game $ start (3,1) -- False -- >>> isWin game $ start (2,2) -- True -- >>> winningMoves game $ start (2,2) -- [((0,-1),(2,2)),((1,0),(1,1))] -- >>> isWin game $ start (3,3) -- False -- >>> game.moves $ start (3,3) -- [((0,-1),(1,3)),((0,-1),(2,1)),((0,-1),(2,2)),((0,-1),(2,3)),((0,-1),(3,1)),((0,-1),(3,3)),((0,1),(1,1)),((0,1),(2,1)),((0,1),(2,2)),((0,1),(2,3)),((0,1),(3,1)),((0,1),(3,3)),((1,-1),(1,1)),((1,-1),(1,3)),((1,-1),(2,2)),((1,-1),(2,3)),((1,-1),(3,1)),((1,-1),(3,3)),((1,0),(1,1)),((1,0),(1,3)),((1,0),(2,1)),((1,0),(2,3)),((1,0),(3,1)),((1,0),(3,3)),((1,1),(1,1)),((1,1),(1,3)),((1,1),(2,1)),((1,1),(2,2)),((1,1),(3,1)),((1,1),(3,3))] gonzSituation = game.move (start (3,3)) ((0,-1),(3,3)) -- >>> gonzSituation -- State {ply = (3,2), opp = (1,1), chips = fromList [(1,1),(1,3),(2,1),(2,2),(2,3),(3,1)]} -- >>> winningMoves game gonzSituation -- [((-1,-1),(2,2)),((-1,0),(2,1)),((-1,0),(3,1))] \sourceoff \(\endgroup\)


   Profil
tactac
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 15.10.2014
Mitteilungen: 2712
  Beitrag No.86, eingetragen 2023-01-08

Zu den Regeln. Da heute im Schwätz mokiert worden ist, dass die Regeln in #0 nicht "dem Original" entsprechen, hier mal ein Vorschlag, der dem wahren Geist des Spiels entsprechen sollte, und beliebig oft betretbare Startfelder enthält: 0) Alle Felder, bis auf die Startfelder, sind am Anfang mit Plättchen belegt. 1) Ein Zug besteht aus: - Bewegung der eigenen Spielfigur auf eines der (bis zu acht) betretbaren Nachbarfelder. Dabei ist ein Feld betretbar, wenn es keine Spielfigur enthält und entweder ein Plättchen enthält oder eines der beiden Startfelder ist. - Optionales(!) Entfernen eines Plättchens (auf dem keine Spielfigur stehen darf). 2) Wer keinen Zug ausführen kann, verliert. Dass die Entfernung eines Plättchens optional ist, soll bewirken, dass man nicht dadurch verlieren kann, dass kein Plättchen zum Entfernen verfügbar ist. Dies widerspräche m.E. dem Grundgedanken des Spiels, der auch zum Namen geführt hat. Möglicherweise ist aber besser (und näher an #0): Falls ein entfernbares Plättchen vorhanden ist, muss eines entfernt werden, ansonsten nicht.


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.87, vom Themenstarter, eingetragen 2023-01-08

Ich persönlich interessiere mich für die Lösung (a) 8x6 Isola mit 2 Startfeldern nicht drückbar. Aber auch für (b) 8x6 Isola mit 2 Startfeldern drückbar (c) 7x7 Isola (englischer Titel "Isolation")


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.88, vom Themenstarter, eingetragen 2023-01-09

! Strategien Isola nach Internet Kory Becker ! (1) Zufall ! (2) Defensiv (2*Spieler 1-Züge)-Spieler 2-Züge als Bewertungsfunktion ! (3) Offensiv (Spieler 1-Züge)-2*Spieler 2-Züge als Bewertungsfunktion ! (4) variabel 1.Hälfte des Spieles Defensiv (2), dann Offensiv (3) ! (5) variabel2 1.Hälfte des Spieles Offensiv (3), dann Defensiv (2) Dabei wurde ein Alpha-Beta-Algorithmus für das 7x7 Brett (Isolation) genutzt. Spieler 1 ist am Zug. Edit: das Programm aus Beitrag 85 verstehe ich nicht so gut - Haskell kann ich bisher nicht. Edit2: Die Strategien von oben (1) bis (5) getestet für Isola 8x6 (der Einfachheit halber können die Startfelder auch gedrückt werden). Hier Tiefe 1 - also noch kein richtiges Alpha-Beta. Noch mal überarbeitet: ein Matt in 1 Zug wird erkannt. Spieler 1 (Rot) gewinnt bei 1000 Versuchen mit Strategie: ! * B 1 / 2 / 3 / 4 / 5(Spieler 2 = Blau) !R1 // 476 / 44 / 57 / 62 / 44 ! 2 // 960 / 383 / 568 / 569 / 362 ! 3 // 950 / 437 / 507 / 536 / 415 ! 4 // 933 / 433 / 498 / 518 / 396 ! 5 // 951 / 424 / 553 / 589 / 415 (Spieler 1 - Rot) Fortran 90 File mit 449 Zeilen \showon \sourceon Fortran 90 program Isola2023Tiefe1V2 ! Isola 2023 mit Tiefe 1 ! !(V2 Matt in 1 wird erkannt) ! * B 1 / 2 / 3 / 4 / 5(Spieler 2 = Blau) !R1 // 476 / 44 / 57 / 62 / 44 ! 2 // 960 / 383 / 568 / 569 / 362 ! 3 // 950 / 437 / 507 / 536 / 415 ! 4 // 933 / 433 / 498 / 518 / 396 ! 5 // 951 / 424 / 553 / 589 / 415 ! https://de.wikipedia.org/wiki/Minimax-Algorithmus ! https://de.wikipedia.org/wiki/Alpha-Beta-Suche integer brett(80),zug8(8),zug(2) integer i,laeufe,rot,blau,roterg,blauerg,rotstrategie,blaustrategie integer ende,ausgabe real t0,t1 call cpu_time(t0) call random_seed() laeufe = 1000 rotstrategie = 5 blaustrategie = 5 ausgabe = 0 rotgewinn = 0 blaugewinn = 0 azspiele = 0 DO i = 1,laeufe call init(brett,zug8,rot,blau,zugnr) ende = 0 while (ende == 0) do call rotmatt(brett,zug8,rot,blau,roterg) if (roterg == 0) then call rotzug(brett,zug8,rot,blau,zug,zugnr,rotstrategie) if (ausgabe == 1) then ! print *,'rotzug ',zug call ausgabebrett(brett,rot,blau) endif else blaugewinn = blaugewinn + 1 azspiele = azspiele + 1 ende = 1 endif if (roterg == 0) then call blaumatt(brett,zug8,rot,blau,blauerg) if (blauerg == 0) then call blauzug(brett,zug8,rot,blau,zug,zugnr,blaustrategie) if (ausgabe == 1) then ! print *,'blauzug ',zug call ausgabebrett(brett,rot,blau) endif else rotgewinn = rotgewinn + 1 azspiele = azspiele + 1 ende = 1 endif endif end do ! print *,brett end do print *,'rotgewinn ',rotgewinn print *,'blaugewinn ',blaugewinn print *,'von ',azspiele call cpu_time(t1) print *,'Zeit = ',t1 end ! ********** ! Initialiserung ! brett(1..80) = 1 (Plaetchen) oder 100 (Rand) ! rot = 31 // Startfeld ! blau = 49 // Startfeld ! spielzuege // 42x (von,nach,plaetchen gedrueckt aktuell) ! ********** subroutine init(Grundstellung,zug8,rot,blau,zugnr) integer Grundstellung(80),zug8(8) integer i,rot,blau DO i = 1,80 GrundStellung(i) = 1 ! Plaettchen END DO Grundstellung(1) = 100 Grundstellung(2) = 100 Grundstellung(3) = 100 Grundstellung(4) = 100 Grundstellung(5) = 100 Grundstellung(6) = 100 Grundstellung(7) = 100 Grundstellung(8) = 100 Grundstellung(9) = 100 Grundstellung(10) = 100 Grundstellung(11) = 100 Grundstellung(20) = 100 Grundstellung(21) = 100 Grundstellung(30) = 100 Grundstellung(31) = 100 Grundstellung(40) = 100 Grundstellung(41) = 100 Grundstellung(50) = 100 Grundstellung(51) = 100 Grundstellung(60) = 100 Grundstellung(61) = 100 Grundstellung(70) = 100 Grundstellung(71) = 100 Grundstellung(72) = 100 Grundstellung(73) = 100 Grundstellung(74) = 100 Grundstellung(75) = 100 Grundstellung(76) = 100 Grundstellung(77) = 100 Grundstellung(78) = 100 Grundstellung(79) = 100 Grundstellung(80) = 100 ! spaeter vielleicht mit 2 fixen Feldern (Isola Original) !Grundstellung(31) = 50 !Grundstellung(49) = 50 rot = 31 blau = 49 zug8(1) = -11 zug8(2) = -10 zug8(3) = -9 zug8(4) = -1 zug8(5) = 1 zug8(6) = +9 zug8(7) = +10 zug8(8) = +11 zugnr = 0 end ! ***************************************************************** ! drucken des Bretts auf Bildschirm (Isola) ! ***************************************************************** subroutine ausgabebrett(brett,rot,blau) integer brett(80) integer rot,blau,i,j,nr character(len=30) merk print *,'Brett' print *,'------------' nr = 0 do i = 1,8 merk = " " do j = 1,10 nr = nr + 1 if (rot == nr) then merk((j-2)*3+2:(j-2)*3+2) = "R" else if (blau == nr) then merk((j-2)*3+2:(j-2)*3+2) = "B" else if (brett(nr) == 0) then merk((j-2)*3+2:(j-2)*3+2) = "." else if (brett(nr) == 1) then merk((j-2)*3+2:(j-2)*3+2) = "x" endif endif endif endif end do print *,merk end do print *,'------------' ! print *,'rot blau ',rot,blau end !*********** ! rotmatt // ist rot Matt? ! erg = 0 // rot nicht Matt ! erg = 1 // rot ist Matt !*********** subroutine rotmatt(brett,zug8,rot,blau,roterg) integer brett(80),zug8(8) integer rot,blau,roterg,i,lala roterg = 1 do i = 1,8 lala = rot+zug8(i) if (brett(lala) == 1.and.lala.ne.blau) then roterg = 0 exit endif end do end !*********** ! blaumatt // ist blau Matt? ! erg = 0 // blau nicht Matt ! erg = 1 // blau ist Matt !*********** subroutine blaumatt(brett,zug8,rot,blau,blauerg) integer brett(80),zug8(8) integer rot,blau,blauerg,i,lala blauerg = 1 do i = 1,8 lala = blau+zug8(i) if (brett(lala) == 1.and.lala.ne.rot) then blauerg = 0 exit endif end do end ! ********** ! berechne Anzahl der Rotfelder (Felder auf die Rot ziehen kann) ! ********** subroutine rotbewegtfelder(brett,zug8,rot,blau,rotfelder) integer brett(80),zug8(8) integer rot,blau,rotfelder,i,lala rotfelder = 0 do i = 1,8 lala = rot+zug8(i) if (brett(lala) == 1.and.lala.ne.blau) then rotfelder = rotfelder + 1 endif end do end ! ********** ! berechne Anzahl der Blaufelder (Felder auf die Blau ziehen kann) ! ********** subroutine blaubewegtfelder(brett,zug8,rot,blau,blaufelder) integer brett(80),zug8(8) integer rot,blau,blaufelder,i,lala blaufelder = 0 do i = 1,8 lala = blau+zug8(i) if (brett(lala) == 1.and.lala.ne.rot) then blaufelder = blaufelder + 1 endif end do end ! ********** ! Zug von Rot ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! ********** subroutine rotzug(brett,zug8,rot,blau,zug,zugnr,rotstrategie) integer feld(352,3),feld2(352) integer brett(80),zug8(8),zug(2) integer rot,blau,rotneu,zugnr,rotstrategie,rotfelder,blaufelder,rotmax integer i,j,merk,r integer azzuege,azzuege2,gedrueckt ! (1) berechne und bewerte Zuege azzuege = 0 !do i = 1,352 ! feld(i,1) = 0 ! feld(i,2) = 0 ! feld(i,3) = 0 !end do do i = 1,8 !print *,'i ',i rotneu = rot+zug8(i) if (brett(rotneu) == 1.and.rotneu.ne.blau) then do j = 12,69 !print *,'j ',j gedrueckt = j if (brett(gedrueckt) == 1.and.rotneu.ne.gedrueckt.and.blau.ne.gedrueckt) then ! zug zulaessig azzuege = azzuege + 1 feld(azzuege,1) = rotneu feld(azzuege,2) = gedrueckt brett(gedrueckt) = 0 call rotbewegtfelder(brett,zug8,rotneu,blau,rotfelder) call blaubewegtfelder(brett,zug8,rotneu,blau,blaufelder) !print *,rotfelder,blaufelder !print *,'rs ',rotstrategie if (rotstrategie == 1) then feld(azzuege,3) = 0 else if (rotstrategie == 2) then feld(azzuege,3) = 2*rotfelder-blaufelder else if (rotstrategie == 3) then feld(azzuege,3) = rotfelder-2*blaufelder else if (rotstrategie == 4) then if (zugnr < 21) then feld(azzuege,3) = 2*rotfelder-blaufelder else feld(azzuege,3) = rotfelder-2*blaufelder endif else if (zugnr < 21) then feld(azzuege,3) = rotfelder-2*blaufelder else feld(azzuege,3) = 2*rotfelder-blaufelder endif endif endif endif endif if (blaufelder == 0) then feld(azzuege,3) = 1000 endif ! mache Zug rueckgaengig brett(gedrueckt) = 1 endif end do endif end do ! (2) jetzt suche besten Zug aus feld von eben rotmax = -1000 azzuege2 = 0 ! finde besten Zug do i = 1,azzuege if (feld(i,3) >= rotmax) then rotmax = feld(i,3) endif end do ! erstelle Liste mit allen besten Zuegen do i = 1,azzuege ! print *,'i feld(i,3) ',i,feld(i,3) if (feld(i,3) == rotmax) then azzuege2 = azzuege2 + 1 feld2(azzuege2) = i ! print *,'rotmax azzuege2 i ',rotmax,azzuege2,i endif end do ! waehle Zug aus if (azzuege2 == 1) then merk = feld2(azzuege2) else call random_number(zwi) r = floor(zwi*azzuege2)+1 merk = feld2(r) endif zug(1) = feld(merk,1) zug(2) = feld(merk,2) rot = zug(1) brett(zug(2)) = 0 zugnr = zugnr + 1 ! print *,'zugnr ',zugnr end ! ********** ! Zug von Blau ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! ********** subroutine blauzug(brett,zug8,rot,blau,zug,zugnr,blaustrategie) integer feld(352,3),feld2(352) integer brett(80),zug8(8),zug(2) integer rot,blau,blauneu,zugnr,blaustrategie,rotfelder,blaufelder,blaumax integer i,j,merk,r integer azzuege,azzuege2,gedrueckt azzuege = 0 !do i = 1,352 ! feld(i,1) = 0 ! feld(i,2) = 0 ! feld(i,3) = 0 !end do ! (1) berechne und bewerte Zuege do i = 1,8 blauneu = blau+zug8(i) if (brett(blauneu) == 1.and.blauneu.ne.rot) then do j = 12,69 gedrueckt = j if (brett(gedrueckt) == 1.and.blauneu.ne.gedrueckt.and.rot.ne.gedrueckt) then ! zug zulaessig azzuege = azzuege + 1 feld(azzuege,1) = blauneu feld(azzuege,2) = gedrueckt brett(gedrueckt) = 0 call blaubewegtfelder(brett,zug8,rot,blauneu,blaufelder) call rotbewegtfelder(brett,zug8,rot,blauneu,rotfelder) if (blaustrategie == 1) then feld(azzuege,3) = 0 else if (blaustrategie == 2) then feld(azzuege,3) = 2*blaufelder-rotfelder else if (blaustrategie == 3) then feld(azzuege,3) = blaufelder-2*rotfelder else if (blaustrategie == 4) then if (zugnr < 21) then feld(azzuege,3) = 2*blaufelder-rotfelder else feld(azzuege,3) = blaufelder-2*rotfelder endif else if (zugnr < 21) then feld(azzuege,3) = blaufelder-2*rotfelder else feld(azzuege,3) = 2*blaufelder-rotfelder endif endif endif endif endif if (rotfelder == 0) then feld(azzuege,3) = 1000 endif ! mache Zug rueckgaengig brett(gedrueckt) = 1 endif end do endif end do ! (2) jetzt suche besten Zug aus feld von eben azzuege2 = 0 blaumax = -1000 ! finde besten Zug do i = 1,azzuege if (feld(i,3) >= blaumax) then blaumax = feld(i,3) endif end do ! erstelle Liste mit allen besten Zuegen do i = 1,azzuege if (feld(i,3) == blaumax) then azzuege2 = azzuege2 + 1 feld2(azzuege2) = i endif end do ! waehle Zug aus if (azzuege2 == 1) then merk = feld2(azzuege2) else call random_number(zwi) r = floor(zwi*azzuege2)+1 merk = feld2(r) endif zug(1) = feld(merk,1) zug(2) = feld(merk,2) blau = zug(1) brett(zug(2)) = 0 zugnr = zugnr + 1 end \sourceoff \showoff


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.89, vom Themenstarter, eingetragen 2023-01-17

Ich habe jetzt ein Programm fertig, das Rot (Spieler 1) mit Tiefe 3 gegen Blau (Spieler 2) mit Tiefe 1 spielen kann. Auch Blau Tiefe 3 gegen Rot Tiefe 1 oder 3. Das Programm ist nicht besonders schön, ich muss mir noch überlegen, wie ich einen Suchbaum am besten im Computer speichere. Im Moment habe ich 3 Routinen für - Tiefe 1 / feld -> Züge der Tiefe 1 - Tiefe 2 / feld2 -> Züge der Tiefe 2 - Tiefe 3 / feld3 -> Züge der Tiefe 3 Hinweis: ich habe hier die Isola 8x6 Version verwendet, bei der man alle Felder drücken kann - auch die Startfelder. Das Programm ist nicht besonders schön. Ich habe das Programm jetzt noch mal überarbeitet. Jetzt ist das Programm bei gleicher Spielstärke noch schneller. \showon \sourceon Fortran 90 program Isola2023Tiefe3V3 implicit none ! Isola 2023 mit Tiefe 1, (2,) 3 ! ! https://de.wikipedia.org/wiki/Minimax-Algorithmus ! https://de.wikipedia.org/wiki/Alpha-Beta-Suche ! ! Rot 3 / T 3 // Blau 1 / T 1 -> Rot 999 von 1000 gewonnen / 36,6 Sekunden ! Rot 2 / T 3 // Blau 2 / T 1 -> Rot 767 von 1000 gewonnen / 40,7 Sekunden ! Rot 3 / T 3 // Blau 3 / T 1 -> Rot 862 von 1000 gewonnen / 37,6 Sekunden ! Rot 4 / T 3 // Blau 4 / T 1 -> Rot 825 von 1000 gewonnen / 41,2 Sekunden ! Rot 5 / T 3 // Blau 5 / T 1 -> Rot 797 von 1000 gewonnen / 38,8 Sekunden ! ! Rot 4 / T 3 // Blau 3 / T 1 -> Rot 832 von 1000 gewonnen / 39,9 Sekunden ! Rot 5 / T 3 // Blau 3 / T 1 -> Rot 806 von 1000 gewonnen / 38,8 Sekunden ! Rot 4 / T 3 // Blau 5 / T 1 -> Rot 833 von 1000 gewonnen / 40,3 Sekunden ! Rot 5 / T 3 // Blau 4 / T 1 -> Rot 810 von 1000 gewonnen / 40,0 Sekunden ! Rot 1 / T 1 // Blau 3 / T 3 -> Blau 999 von 1000 gewonnen / 38,2 Sekunden ! Rot 2 / T 1 // Blau 2 / T 3 -> Blau 767 von 1000 gewonnen / 41,3 Sekunden ! Rot 3 / T 1 // Blau 3 / T 3 -> Blau 854 von 1000 gewonnen / 37,6 Sekunden ! Rot 4 / T 1 // Blau 4 / T 3 -> Blau 800 von 1000 gewonnen / 41,8 Sekunden ! Rot 5 / T 1 // Blau 5 / T 3 -> Blau 817 von 1000 gewonnen / 39,4 Sekunden ! ! Rot 2 / T 3 // Blau 2 / T 3 -> Rot 475 von 1000 gewonnen / 79,2 Sekunden ! Rot 3 / T 3 // Blau 3 / T 3 -> Rot 468 von 1000 gewonnen / 70,1 Sekunden ! Rot 4 / T 3 // Blau 4 / T 3 -> Rot 452 von 1000 gewonnen / 80,7 Sekunden ! Rot 5 / T 3 // Blau 5 / T 3 -> Rot 458 von 1000 gewonnen / 74,1 Sekunden ! ! max1 336 / max2 336 / max3 82668 (3 T 3 vs 1 T 1 1000x) integer brett(80),brett2(80),zug8(8),zug(2) integer i,j,laeufe,rot,blau,roterg,blauerg,rotstrategie,blaustrategie integer rot2,blau2,zugnr,azspiele,rotgewinn,blaugewinn integer ende,ausgabe,suchtieferot,suchtiefeblau integer max1,max2,max3 real t0,t1 common /isola1/ max1 common /isola2/ max2 common /isola3/ max3 call cpu_time(t0) call random_seed() laeufe = 1000 rotstrategie = 3 suchtieferot = 3 blaustrategie = 1 suchtiefeblau = 1 ausgabe = 0 rotgewinn = 0 blaugewinn = 0 azspiele = 0 max1 = 0 max2 = 0 max3 = 0 DO i = 1,laeufe call init(brett,zug8,rot,blau,zugnr) ende = 0 do while (ende == 0) ! while (ende == 0) do call rotmatt(brett,zug8,rot,blau,roterg) if (roterg == 0) then call rotzug(brett,zug8,rot,blau,zug,zugnr,rotstrategie,suchtieferot) !print *,zug if (ausgabe == 1) then ! print *,'rotzug ',zug call ausgabebrett(brett,rot,blau) endif else blaugewinn = blaugewinn + 1 azspiele = azspiele + 1 ende = 1 endif if (roterg == 0) then ! spiegele Brett do j = 1,80 brett2(j) = brett(81-j) end do rot2 = 81-blau blau2 = 81-rot ! call blaumatt(brett,zug8,rot,blau,blauerg) call rotmatt(brett2,zug8,rot2,blau2,blauerg) if (blauerg == 0) then ! call blauzug(brett,zug8,rot,blau,zug,zugnr,blaustrategie,suchtiefeblau) call rotzug(brett2,zug8,rot2,blau2,zug,zugnr,blaustrategie,suchtiefeblau) ! spiegele Brett do j = 1,80 brett(j) = brett2(81-j) end do rot = 81-blau2 blau = 81-rot2 if (ausgabe == 1) then ! print *,'blauzug ',zug call ausgabebrett(brett,rot,blau) endif else rotgewinn = rotgewinn + 1 azspiele = azspiele + 1 ende = 1 endif endif end do ! print *,brett end do print *,'rotgewinn ',rotgewinn print *,'blaugewinn ',blaugewinn print *,'von ',azspiele print *,' ' print *,'feldmax 1 2 3 ',max1,max2,max3 call cpu_time(t1) print *,'Zeit = ',t1 end ! ********** ! Initialiserung ! brett(1..80) = 1 (Plaetchen) oder 100 (Rand) ! rot = 31 // Startfeld ! blau = 49 // Startfeld ! spielzuege // 42x (von,nach,plaetchen gedrueckt aktuell) ! ********** subroutine init(Grundstellung,zug8,rot,blau,zugnr) implicit none integer Grundstellung(80),zug8(8) integer i,rot,blau,zugnr DO i = 1,80 GrundStellung(i) = 1 ! Plaettchen END DO Grundstellung(1) = 100 Grundstellung(2) = 100 Grundstellung(3) = 100 Grundstellung(4) = 100 Grundstellung(5) = 100 Grundstellung(6) = 100 Grundstellung(7) = 100 Grundstellung(8) = 100 Grundstellung(9) = 100 Grundstellung(10) = 100 Grundstellung(11) = 100 Grundstellung(20) = 100 Grundstellung(21) = 100 Grundstellung(30) = 100 Grundstellung(31) = 100 Grundstellung(40) = 100 Grundstellung(41) = 100 Grundstellung(50) = 100 Grundstellung(51) = 100 Grundstellung(60) = 100 Grundstellung(61) = 100 Grundstellung(70) = 100 Grundstellung(71) = 100 Grundstellung(72) = 100 Grundstellung(73) = 100 Grundstellung(74) = 100 Grundstellung(75) = 100 Grundstellung(76) = 100 Grundstellung(77) = 100 Grundstellung(78) = 100 Grundstellung(79) = 100 Grundstellung(80) = 100 ! spaeter vielleicht mit 2 fixen Feldern (Isola Original) !Grundstellung(31) = 50 !Grundstellung(49) = 50 rot = 31 blau = 49 zug8(1) = -11 zug8(2) = -10 zug8(3) = -9 zug8(4) = -1 zug8(5) = 1 zug8(6) = +9 zug8(7) = +10 zug8(8) = +11 zugnr = 0 end ! ***************************************************************** ! drucken des Bretts auf Bildschirm (Isola) ! ***************************************************************** subroutine ausgabebrett(brett,rot,blau) implicit none integer brett(80) integer rot,blau,i,j,nr character(len=30) merk print *,'Brett' print *,'------------' nr = 0 do i = 1,8 merk = " " do j = 1,10 nr = nr + 1 if (rot == nr) then merk((j-2)*3+2:(j-2)*3+2) = "R" else if (blau == nr) then merk((j-2)*3+2:(j-2)*3+2) = "B" else if (brett(nr) == 0) then merk((j-2)*3+2:(j-2)*3+2) = "." else if (brett(nr) == 1) then merk((j-2)*3+2:(j-2)*3+2) = "x" endif endif endif endif end do print *,merk end do print *,'------------' ! print *,'rot blau ',rot,blau end !*********** ! rotmatt // ist rot Matt? ! erg = 0 // rot nicht Matt ! erg = 1 // rot ist Matt !*********** subroutine rotmatt(brett,zug8,rot,blau,roterg) implicit none integer brett(80),zug8(8) integer rot,blau,roterg,i,lala roterg = 1 do i = 1,8 lala = rot+zug8(i) if (brett(lala) == 1.and.lala.ne.blau) then roterg = 0 exit endif end do end !*********** ! blaumatt // ist blau Matt? ! erg = 0 // blau nicht Matt ! erg = 1 // blau ist Matt !*********** subroutine blaumatt(brett,zug8,rot,blau,blauerg) implicit none integer brett(80),zug8(8) integer rot,blau,blauerg,i,lala blauerg = 1 do i = 1,8 lala = blau+zug8(i) if (brett(lala) == 1.and.lala.ne.rot) then blauerg = 0 exit endif end do end ! ********** ! berechne Anzahl der Rotfelder (Felder auf die Rot ziehen kann) ! ********** subroutine rotbewegtfelder(brett,zug8,rot,blau,rotfelder) implicit none integer brett(80),zug8(8) integer rot,blau,rotfelder,i,lala rotfelder = 0 do i = 1,8 lala = rot+zug8(i) if (brett(lala) == 1.and.lala.ne.blau) then rotfelder = rotfelder + 1 endif end do end ! ********** ! berechne Anzahl der Blaufelder (Felder auf die Blau ziehen kann) ! ********** subroutine blaubewegtfelder(brett,zug8,rot,blau,blaufelder) implicit none integer brett(80),zug8(8) integer rot,blau,blaufelder,i,lala blaufelder = 0 do i = 1,8 lala = blau+zug8(i) if (brett(lala) == 1.and.lala.ne.rot) then blaufelder = blaufelder + 1 endif end do end ! ********** ! sortiere Zuege aus feld(azzuege) ! feld(i,1) = rotneu ! feld(i,2) = gedrueckt ! feld(i,3) = Bewertung (hoch am besten) ! ********** subroutine sortiere(feld,azzuege) implicit none integer feld(352,3) integer i,j,azzuege,merk,merk2 integer lala,lala2,lala3 ! sortiere gesamtes Feld do i = 1,azzuege-1 do j = i+1,azzuege merk = feld(i,3) merk2 = feld(j,3) if (merk < merk2) then ! tausche lala = feld(i,1) lala2 = feld(i,2) lala3 = feld(i,3) feld(i,1) = feld(j,1) feld(i,2) = feld(j,2) feld(i,3) = feld(j,3) feld(j,1) = lala feld(j,2) = lala2 feld(j,3) = lala3 endif end do end do !print *,feld(:,3) !stop end ! ********** ! Zug von Rot ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! Strategie 5: variabel2 ! Baum Tiefe 1 in feld ! feld(:,1) = rotneu ! feld(:,2) = gedrueckt ! feld(:,3) = Bewertung des Zuges ! ********** subroutine rotzug(brett,zug8,rot,blau,zug,zugnr,rotstrategie,suchtieferot) implicit none integer feld(352,3),feld2(352,3) ! feld2(352*8*43) integer feld3(250000,4) ! feld3(40685568,6) integer brett(80),zug8(8),zug(2),zug1(2),zug3(2),feld99(352) integer rot,blau,rotneu,zugnr,rotstrategie,rotfelder,blaufelder,rotmax integer i,j,merk,r integer azzuege,azzuege2,azzuege3,azzuege99,gedrueckt,suchtieferot integer max1,max2,max3 real zwi common /isola1/ max1 ! (1) berechne und bewerte Zuege azzuege = 0 !do i = 1,352 ! feld(i,1) = 0 ! feld(i,2) = 0 ! feld(i,3) = 0 !end do do i = 1,8 !print *,'i ',i rotneu = rot+zug8(i) if (brett(rotneu) == 1.and.rotneu.ne.blau) then do j = 12,69 !print *,'j ',j gedrueckt = j if (brett(gedrueckt) == 1.and.rotneu.ne.gedrueckt.and.blau.ne.gedrueckt) then ! zug zulaessig azzuege = azzuege + 1 feld(azzuege,1) = rotneu feld(azzuege,2) = gedrueckt brett(gedrueckt) = 0 call rotbewegtfelder(brett,zug8,rotneu,blau,rotfelder) call blaubewegtfelder(brett,zug8,rotneu,blau,blaufelder) !print *,rotfelder,blaufelder !print *,'rs ',rotstrategie if (rotstrategie == 1) then feld(azzuege,3) = 0 else if (rotstrategie == 2) then feld(azzuege,3) = 2*rotfelder-blaufelder else if (rotstrategie == 3) then feld(azzuege,3) = rotfelder-2*blaufelder else if (rotstrategie == 4) then if (zugnr < 21) then feld(azzuege,3) = 2*rotfelder-blaufelder else feld(azzuege,3) = rotfelder-2*blaufelder endif else if (zugnr < 21) then feld(azzuege,3) = rotfelder-2*blaufelder else feld(azzuege,3) = 2*rotfelder-blaufelder endif endif endif endif endif if (blaufelder == 0) then feld(azzuege,3) = 1000 endif ! mache Zug rueckgaengig brett(gedrueckt) = 1 endif end do endif end do if (azzuege > 0) then if (azzuege > max1) then max1 = azzuege endif endif ! (2) jetzt suche besten Zug aus feld von eben rotmax = -1000 azzuege99 = 0 ! finde besten Zug do i = 1,azzuege if (feld(i,3) >= rotmax) then rotmax = feld(i,3) endif end do ! erstelle Liste mit allen besten Zuegen do i = 1,azzuege ! print *,'i feld(i,3) ',i,feld(i,3) if (feld(i,3) == rotmax) then azzuege99 = azzuege99 + 1 feld99(azzuege99) = i ! print *,'rotmax azzuege2 i ',rotmax,azzuege2,i endif end do ! waehle Zug aus if (azzuege99 == 1) then merk = feld99(azzuege99) else call random_number(zwi) r = floor(zwi*azzuege99)+1 merk = feld99(r) endif zug1(1) = feld(merk,1) zug1(2) = feld(merk,2) !rot = zug(1) !brett(zug(2)) = 0 if (rotmax.ne.1000.and.suchtieferot == 3) then ! sortiere Zuege Tiefe 1 call sortiere(feld,azzuege) ! jetzt erzeuge Zuege von Blau (Tiefe 2) azzuege2 = 0 azzuege3 = 0 call rotblauzug(brett,zug8,feld,azzuege,feld2,azzuege2,rot,blau,zug,zugnr,rotstrategie,suchtieferot) ! falls blau keinen Zug hat waehle besten Zug aus Tiefe 1(rot) call rotblaurotzug(brett,zug8,feld,azzuege,feld2,azzuege2,feld3,azzuege3,rot,blau,zug3,zugnr,rotstrategie,suchtieferot) zug(1) = zug3(1) zug(2) = zug3(2) else zug(1) = zug1(1) zug(2) = zug1(2) endif rot = zug(1) brett(zug(2)) = 0 zugnr = zugnr + 1 ! print *,'zugnr ',zugnr end ! ********** ! Zug von Rot/Blau ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! Strategie 5: variabel2 ! in feld2 wird die Bauminformation der Tiefe 2 gespeichert ! dabei wird zum Zug feld(kkk,:) nur der beste Antwortzug feld2(kkk,:) gespeichert ! sollte es mehrere beste Antwortzuege geben, wird der 1.gefundene Zug gespeichert ! feld2(:,1) = blauneu ! feld2(:,2) = gedrueckt ! feld2(:,3) = Bewertung des Zuges ! ********** subroutine rotblauzug(brett,zug8,feld,azzuege,feld2,azzuege2,rot,blau,zug,zugnr,rotstrategie,suchtieferot) implicit none integer feld(352,3),feld2(352,3) ! feld2(352*8*43) integer brett(80),zug8(8),zug(2) integer rot,blau,rotneu,blauneu,zugnr integer rotstrategie,blaustrategie,rotfelder,blaufelder,blaumax integer i,j,kkk,wert,merk,r,marke,marke2 integer azzuege,azzuege2,gedrueckt,gedrueckt2,suchtieferot integer minimum,maximum,max2 integer tempblau,tempgedrueckt,tempbewertung real zwi common /isola2/ max2 azzuege2 = 0 do kkk = 1,azzuege ! marke = azzuege2 ! print *,'kkk ',kkk rotneu = feld(kkk,1) gedrueckt = feld(kkk,2) wert = feld(kkk,3) brett(gedrueckt) = 0 !zugnr = zugnr + 1 ! (1) berechne und bewerte Zuege feld2(kkk,1) = -1 feld2(kkk,2) = -1 feld2(kkk,3) = -2000 tempblau = -1 tempgedrueckt = -1 tempbewertung = -1000 do i = 1,8 blauneu = blau+zug8(i) if (brett(blauneu) == 1.and.blauneu.ne.rotneu) then do j = 12,69 gedrueckt2 = j if (brett(gedrueckt2) == 1.and.blauneu.ne.gedrueckt2.and.rot.ne.gedrueckt2) then ! zug zulaessig !azzuege2 = azzuege2 + 1 !feld2(azzuege2,1) = kkk tempblau = blauneu !feld2(azzuege2,2) = blauneu tempgedrueckt = gedrueckt2 !feld2(azzuege2,3) = gedrueckt2 brett(gedrueckt2) = 0 call blaubewegtfelder(brett,zug8,rotneu,blauneu,blaufelder) call rotbewegtfelder(brett,zug8,rotneu,blauneu,rotfelder) if (rotstrategie == 1) then tempbewertung = 0 else if (rotstrategie == 2) then tempbewertung = 2*blaufelder-rotfelder else if (rotstrategie == 3) then tempbewertung = blaufelder-2*rotfelder else if (rotstrategie == 4) then if (zugnr < 21) then tempbewertung = 2*blaufelder-rotfelder else tempbewertung = blaufelder-2*rotfelder endif else if (zugnr < 21) then tempbewertung = blaufelder-2*rotfelder else tempbewertung = 2*blaufelder-rotfelder endif endif endif endif endif if (rotfelder == 0) then tempbewertung = 1000 endif if (tempbewertung > feld2(kkk,3)) then feld2(kkk,1) = tempblau feld2(kkk,2) = tempgedrueckt feld2(kkk,3) = tempbewertung endif ! mache Zug rueckgaengig brett(gedrueckt2) = 1 !zugnr = zugnr - 1 endif end do endif end do brett(gedrueckt) = 1 ! print *,'marke marke2 ',marke,marke2 ! suche min,max von feld2 eines Zuges kkk !stop end do azzuege2 = azzuege if (azzuege > max2) then max2 = azzuege endif !print *,'azzuege2 ',azzuege2 !do i = 1,azzuege2 ! print *,i ! print *,feld2(i,:) !end do !stop end ! ********** ! Zug von Rot/Blau/Rot ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! Strategie 5: variabel2 ! in feld3 wird die Bauminformation der Tiefe 3 gespeichert ! feld3(:,1) = kkk // Information welcher Zug Tiefe 1 gespielt wurde ! feld3(:,2) = blauneu ! feld3(:,3) = gedrueckt ! feld3(:,4) = Bewertung des Zuges ! ********** subroutine rotblaurotzug(brett,zug8,feld,azzuege,feld2,azzuege2,feld3,azzuege3,rot,blau,zug,zugnr,rotstrategie,suchtieferot) implicit none integer feld(352,3),feld2(352,3) ! feld2(352*8*43) integer feld3(250000,4) ! feld3(40685568,6) integer brett(80),zug8(8),zug(2),feld99(100000) integer rot,blau,rotneu,blauneu,rotneuneu integer zugnr,rotstrategie,rotfelder,blaufelder,rotmax integer i,j,kkk,merk,merk2,merk3,r integer azzuege,azzuege2,azzuege3,azzuege99 integer gedrueckt,gedrueckt2,gedrueckt3,suchtieferot integer max3 real zwi common /isola3/ max3 ! (1) berechne und bewerte Zuege !azzuege = 0 !azzuege2 = 0 azzuege3 = 0 !do i = 1,352 ! feld(i,1) = 0 ! feld(i,2) = 0 ! feld(i,3) = 0 !end do !print *,'azzzuege2 ',azzuege2 do kkk = 1,azzuege2 merk = kkk rotneu = feld(merk,1) gedrueckt = feld(merk,2) blauneu = feld2(kkk,1) gedrueckt2 = feld2(kkk,2) if (feld2(kkk,1).ne.-1) then brett(gedrueckt) = 0 brett(gedrueckt2) = 0 !zugnr = zugnr + 2 !print *,merk,rotneu,blauneu,gedrueckt,gedrueckt2 do i = 1,8 !print *,'i ',i rotneuneu = rotneu+zug8(i) if (brett(rotneuneu) == 1.and.rotneuneu.ne.blauneu) then do j = 12,69 !print *,'j ',j gedrueckt3 = j if (brett(gedrueckt3) == 1.and.rotneuneu.ne.gedrueckt3.and.blauneu.ne.gedrueckt3) then ! zug zulaessig azzuege3 = azzuege3 + 1 feld3(azzuege3,1) = kkk feld3(azzuege3,2) = rotneuneu feld3(azzuege3,3) = gedrueckt3 brett(gedrueckt3) = 0 call rotbewegtfelder(brett,zug8,rotneuneu,blauneu,rotfelder) call blaubewegtfelder(brett,zug8,rotneuneu,blauneu,blaufelder) !print *,rotfelder,blaufelder !print *,'rs ',rotstrategie if (rotstrategie == 1) then feld3(azzuege3,4) = 0 else if (rotstrategie == 2) then feld3(azzuege3,4) = 2*rotfelder-blaufelder else if (rotstrategie == 3) then feld3(azzuege3,4) = rotfelder-2*blaufelder else if (rotstrategie == 4) then if (zugnr < 21) then feld3(azzuege3,4) = 2*rotfelder-blaufelder else feld3(azzuege3,4) = rotfelder-2*blaufelder endif else if (zugnr < 21) then feld3(azzuege3,4) = rotfelder-2*blaufelder else feld3(azzuege3,4) = 2*rotfelder-blaufelder endif endif endif endif endif if (blaufelder == 0) then feld3(azzuege3,4) = 1000 endif ! mache Zug rueckgaengig brett(gedrueckt3) = 1 endif end do endif end do brett(gedrueckt) = 1 brett(gedrueckt2) = 1 endif !zugnr = zugnr - 2 end do !print *,'Hurz' !do i = 1,100 ! print *,i ! print *,feld3(i,:) !end do if (azzuege3 > 0) then ! (2) jetzt suche besten Zug aus feld von eben rotmax = -1000 azzuege99 = 0 ! finde besten Zug do i = 1,azzuege3 if (feld3(i,4) >= rotmax) then rotmax = feld3(i,4) endif end do ! erstelle Liste mit allen besten Zuegen do i = 1,azzuege3 ! print *,'i feld(i,3) ',i,feld(i,3) if (feld3(i,4) == rotmax) then azzuege99 = azzuege99 + 1 feld99(azzuege99) = i ! print *,'rotmax azzuege2 i ',rotmax,azzuege2,i endif end do ! waehle Zug aus if (azzuege99 == 1) then merk = feld99(azzuege99) else call random_number(zwi) r = floor(zwi*azzuege99)+1 merk = feld99(r) endif merk2 = feld3(merk,1) !merk3 = feld2(merk2,1) zug(1) = feld(merk2,1) zug(2) = feld(merk2,2) rot = zug(1) brett(zug(2)) = 0 else ! print *,'Hurz99' ! nimm ersten Zug zug(1) = feld(1,1) zug(2) = feld(1,2) rot = zug(1) brett(zug(2)) = 0 endif if (azzuege3 > max3) then max3 = azzuege3 endif zugnr = zugnr + 1 ! print *,'zugnr ',zugnr !print *,'azzuege3 ',azzuege3 ! print *,zug !do i = 1,100 ! print *,i ! print *,feld3(i,:) !end do ! stop end \sourceoff \showoff


   Profil
NoraB
Aktiv Letzter Besuch: im letzten Monat
Dabei seit: 29.12.2022
Mitteilungen: 40
  Beitrag No.90, eingetragen 2023-01-18

Hallo Delastelle Welchen Fortran Compiler benutzt du? Ich würde das gerne bei mir hier mal laufen lassen - oder ist Fortran 90 überall gleich implementiert? und/ "Schön" sind meine Programme auch nicht. Aber wenn es funktioniert... Grüße Nora


   Profil
zippy
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 24.10.2018
Mitteilungen: 4407
  Beitrag No.91, eingetragen 2023-01-18

\quoteon(2023-01-18 09:39 - NoraB in Beitrag No. 90) oder ist Fortran 90 überall gleich implementiert? \quoteoff Es gibt einen Standard für Fortran 90, aber das Programm hält sich nicht daran: 1. Die "while"-Schleife müsste eine "do while"-Schleife sein. 2. Es gibt Variablen, die nicht deklariert werden und daher ihren Typ implizit erhalten. Das führt zu diversen Fehlern wie "Type mismatch in argument ‘azzuege3’ at (1); passed REAL(4) to INTEGER(4)". Diese beiden Punkte führen zu Problemen, wenn man versucht, das Programm mit einem standardkonformen Compiler zu übersetzen. --zippy


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.92, vom Themenstarter, eingetragen 2023-01-18

Das Programm läuft mit dem Compiler von Salford. ftn95 -link programm programm.f90 und programm Bei Fortran 77 - Programmen wurde mir immer angezeigt, ob alle Variablen deklariert sind.


   Profil
zippy
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 24.10.2018
Mitteilungen: 4407
  Beitrag No.93, eingetragen 2023-01-18

\quoteon(2023-01-18 11:02 - Delastelle in Beitrag No. 92) Bei Fortran 77 - Programmen wurde mir immer angezeigt, ob alle Variablen deklariert sind. \quoteoff Verwende einfach "implicit none", um das Problem undeklarierter Variablen zu vermeiden.


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.94, vom Themenstarter, eingetragen 2023-01-18

Stimmt - früher hatte ich auch immer implicit none verwendet. Wenn man in meinem Programm die Stellung und die Position von Rot und Blau spiegelt, dann kann man auch mit Blau in Tiefe 3 rechnen. Ich habe jetzt das Programm aus Nr.89 noch mal überarbeitet. Es läuft ganz gut, stürzt aber manchmal noch ab - da muss ich mal schauen, ob ich gelegentlich auf ein Feldelement zugreife das es nicht gibt oder so. zugnr scheint nicht immer zu stimmen, damit kann es Probleme bei des Strategien 4 und 5 geben - mal sehen...


   Profil
zippy
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 24.10.2018
Mitteilungen: 4407
  Beitrag No.95, eingetragen 2023-01-18

\quoteon(2023-01-18 11:43 - Delastelle in Beitrag No. 94) Ich habe jetzt das Programm aus Nr.89 noch mal überarbeitet. \quoteoff Die "type mismatch"-Probleme sind damit beseitgt. Wenn du jetzt auch noch while (ende == 0) do durch do while (ende == 0) ersetzt, lässt sich das Programm beispielsweis auch mit GNU Fortran übersetzen. \quoteon(2023-01-18 11:43 - Delastelle in Beitrag No. 94) Es läuft ganz gut, stürzt aber manchmal noch ab - da muss ich mal schauen, ob ich gelegentlich auf ein Feldelement zugreife das es nicht gibt oder so. \quoteoff Wenn man mit der Option "-fcheck=bounds" von GNU Fortran übersetzt, sieht man immer wieder folgenden Fehler: At line 672 Fortran runtime error: Index '2000001' of dimension 1 of array 'feld3' above upper bound of 2000000


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.96, vom Themenstarter, eingetragen 2023-01-18

Danke für die Hinweise! Bei mir ist das Programm noch experimentell, da ich das 1.Mal mit Suchbäumen arbeite und selbst erst mal einiges probiere! Edit: ich habe das Programm aus Nr.89 noch beschleunigt. Jetzt sollte Tiefe 3 für Rot/Blau gut funktionieren.


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.97, vom Themenstarter, eingetragen 2023-01-22

Mein Programm aus Nr.89 arbeitet wohl noch nicht korrekt. Ich habe noch mal in das Buch "Schach am PC" von 1995 geschaut. Darin gibt es 2,5 Seiten zu Alpha-Beta-Suche: https://www.matheplanet.de/matheplanet/nuke/html/uploads/c/15578_A_L1020190_beschnitten_33_Prozent.jpg https://www.matheplanet.de/matheplanet/nuke/html/uploads/c/15578_B_L1020192_beschnitten_33_Prozent.jpg https://www.matheplanet.de/matheplanet/nuke/html/uploads/c/15578_C_L1020193_beschnitten_33_Prozent.jpg Das muss ich noch richtig umsetzen! Edit: bei mir funktioniert ein Spielbaum der Tiefe 3 noch nicht richtig - ich werde wohl erst mal ein ganz simples Spiel wie Tic Tac Toc mit Spielbaum (Tiefe 3) probieren. Edit2: vielleicht kann ein Isola-Programm aus dem Internet das 5x5 Problem lösen. Siehe hier: https://github.com/on2valhalla/Isola/blob/master/README.txt


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.98, vom Themenstarter, eingetragen 2023-01-30

Ich habe jetzt ein Programm mit Suchtiefe 3 (Rot/Blau/Rot). Es scheint ein leichter Vorteil von Blau (Spieler 2) zu sein. Hoffentlich keine Fehler mehr! Zwar kein Alpha-Beta, aber auch recht schnell. Der Fortran 90-Code enthält keine besonderen Tricks, müsste also in Java etc. ähnlich funktionieren. \showon \sourceon Fortran 90 program Isola2023Tiefe3V6 implicit none ! Isola 2023 mit Tiefe 1, (2,) 3 ! ! https://de.wikipedia.org/wiki/Minimax-Algorithmus ! https://de.wikipedia.org/wiki/Alpha-Beta-Suche // spaeter ! ! ohne Alpha-Beta: Isola2023Tiefe3V6 ! Rot 3 / T 3 // Blau 1 / T 1 -> Rot 100 von 100 gewonnen / 364,4 Sekunden ! Rot 2 / T 3 // Blau 2 / T 1 -> Rot 33(38) von 100 gewonnen / 604,2 Sekunden ! Rot 3 / T 3 // Blau 3 / T 1 -> Rot 58 von 100 gewonnen / 574,5 Sekunden ! Rot 4 / T 3 // Blau 4 / T 1 -> Rot 52 von 100 gewonnen / 642,3 Sekunden ! Rot 5 / T 3 // Blau 5 / T 1 -> Rot 41 von 100 gewonnen / 574,4 Sekunden ! ! Rot 2 / T 3 // Blau 3 / T 1 -> Rot 66 von 100 gewonnen / 581,8 Sekunden ! Rot 3 / T 3 // Blau 2 / T 1 -> Rot 47 von 100 gewonnen / 578,7 Sekunden ! ! Rot 4 / T 3 // Blau 3 / T 1 -> Rot 52 von 100 gewonnen / 579,7 Sekunden ! Rot 4 / T 3 // Blau 2 / T 1 -> Rot 30 von 100 gewonnen / 597,0 Sekunden ! ! Rot 2 / T 1 // Blau 2 / T 3 -> Rot 32 von 100 gewonnen / 620,3 Sekunden ! ! Rot 2 / T 3 // Blau 2 / T 3 -> Rot 0 von 100 gewonnen / 1081,2 Sekunden ! ! Rot "6T3" (rf-bf) // Blau 2T1 -> Rot 35 von 100 gewonnen / 611,3 Sekunden ! Rot "6T3" (3*rf-bf) // Blau 2T1 -> Rot 36 von 100 gewonnen / 616,7 Sekunden ! ! max1 336 / max2 107648 (3T3 vs 1T1) ! integer brett(80),brett2(80),zug8(8),zug(2) integer i,j,laeufe,rot,blau,roterg,blauerg,rotstrategie,blaustrategie integer rot2,blau2,zugnr,azspiele,rotgewinn,blaugewinn integer ende,ausgabe,suchtieferot,suchtiefeblau integer max1,max2,max3 real t0,t1 common /isola1/ max1 common /isola2/ max2 common /isola3/ max3 call cpu_time(t0) call random_seed() laeufe = 100 rotstrategie = 2 suchtieferot = 1 blaustrategie = 2 suchtiefeblau = 3 ausgabe = 0 rotgewinn = 0 blaugewinn = 0 azspiele = 0 max1 = 0 max2 = 0 max3 = 0 DO i = 1,laeufe call init(brett,zug8,rot,blau,zugnr) ende = 0 !call ausgabebrett(brett,rot,blau) do while (ende == 0) ! while (ende == 0) do call rotmatt(brett,zug8,rot,blau,roterg) if (roterg == 0) then !call ausgabebrett(brett,rot,blau) if (suchtieferot == 1) then call rotzugTiefe1(brett,zug8,rot,blau,zug,zugnr,rotstrategie,suchtieferot) else call rotzugTiefe3(brett,zug8,rot,blau,zug,zugnr,rotstrategie,suchtieferot) endif !print *,zug ! print *,zug,rot,blau if (ausgabe == 1) then ! print *,'rotzug ',zug call ausgabebrett(brett,rot,blau) endif else blaugewinn = blaugewinn + 1 azspiele = azspiele + 1 ende = 1 endif if (roterg == 0) then ! spiegele Brett do j = 1,80 brett2(j) = brett(81-j) end do rot2 = 81-blau blau2 = 81-rot ! call blaumatt(brett,zug8,rot,blau,blauerg) call rotmatt(brett2,zug8,rot2,blau2,blauerg) if (blauerg == 0) then ! call blauzug(brett,zug8,rot,blau,zug,zugnr,blaustrategie,suchtiefeblau) !print *,suchtiefeblau if (suchtiefeblau == 1) then call rotzugTiefe1(brett2,zug8,rot2,blau2,zug,zugnr,blaustrategie,suchtiefeblau) else call rotzugTiefe3(brett2,zug8,rot2,blau2,zug,zugnr,blaustrategie,suchtiefeblau) endif ! spiegele Brett do j = 1,80 brett(j) = brett2(81-j) end do rot = 81-blau2 blau = 81-rot2 if (ausgabe == 1) then ! print *,'blauzug ',zug call ausgabebrett(brett,rot,blau) endif else rotgewinn = rotgewinn + 1 azspiele = azspiele + 1 ende = 1 endif endif end do ! print *,brett end do print *,'rotgewinn ',rotgewinn print *,'blaugewinn ',blaugewinn print *,'von ',azspiele print *,' ' print *,'feldmax 1 2 3 ',max1,max2,max3 call cpu_time(t1) print *,'Zeit = ',t1 end ! ********** ! Initialiserung ! brett(1..80) = 1 (Plaetchen) oder 100 (Rand) ! rot = 31 // Startfeld ! blau = 49 // Startfeld ! spielzuege // 42x (von,nach,plaetchen gedrueckt aktuell) ! ********** subroutine init(Grundstellung,zug8,rot,blau,zugnr) implicit none integer Grundstellung(80),zug8(8) integer i,rot,blau,zugnr DO i = 1,80 GrundStellung(i) = 1 ! Plaettchen END DO Grundstellung(1) = 100 Grundstellung(2) = 100 Grundstellung(3) = 100 Grundstellung(4) = 100 Grundstellung(5) = 100 Grundstellung(6) = 100 Grundstellung(7) = 100 Grundstellung(8) = 100 Grundstellung(9) = 100 Grundstellung(10) = 100 Grundstellung(11) = 100 Grundstellung(20) = 100 Grundstellung(21) = 100 Grundstellung(30) = 100 Grundstellung(31) = 100 Grundstellung(40) = 100 Grundstellung(41) = 100 Grundstellung(50) = 100 Grundstellung(51) = 100 Grundstellung(60) = 100 Grundstellung(61) = 100 Grundstellung(70) = 100 Grundstellung(71) = 100 Grundstellung(72) = 100 Grundstellung(73) = 100 Grundstellung(74) = 100 Grundstellung(75) = 100 Grundstellung(76) = 100 Grundstellung(77) = 100 Grundstellung(78) = 100 Grundstellung(79) = 100 Grundstellung(80) = 100 ! spaeter vielleicht mit 2 fixen Feldern (Isola Original) !Grundstellung(31) = 50 !Grundstellung(49) = 50 rot = 31 blau = 49 zug8(1) = -11 zug8(2) = -10 zug8(3) = -9 zug8(4) = -1 zug8(5) = 1 zug8(6) = +9 zug8(7) = +10 zug8(8) = +11 zugnr = 0 end ! ***************************************************************** ! drucken des Bretts auf Bildschirm (Isola) ! ***************************************************************** subroutine ausgabebrett(brett,rot,blau) implicit none integer brett(80) integer rot,blau,i,j,nr character(len=30) merk print *,'Brett' print *,'------------' nr = 0 do i = 1,8 merk = " " do j = 1,10 nr = nr + 1 if (rot == nr) then merk((j-2)*3+2:(j-2)*3+2) = "R" else if (blau == nr) then merk((j-2)*3+2:(j-2)*3+2) = "B" else if (brett(nr) == 0) then merk((j-2)*3+2:(j-2)*3+2) = "." else if (brett(nr) == 1) then merk((j-2)*3+2:(j-2)*3+2) = "x" endif endif endif endif end do print *,merk end do print *,'------------' ! print *,'rot blau ',rot,blau end !*********** ! rotmatt // ist rot Matt? ! erg = 0 // rot nicht Matt ! erg = 1 // rot ist Matt !*********** subroutine rotmatt(brett,zug8,rot,blau,roterg) implicit none integer brett(80),zug8(8) integer rot,blau,roterg,i,lala roterg = 1 do i = 1,8 lala = rot+zug8(i) if (brett(lala) == 1.and.lala.ne.blau) then roterg = 0 exit endif end do end !*********** ! blaumatt // ist blau Matt? ! erg = 0 // blau nicht Matt ! erg = 1 // blau ist Matt !*********** subroutine blaumatt(brett,zug8,rot,blau,blauerg) implicit none integer brett(80),zug8(8) integer rot,blau,blauerg,i,lala blauerg = 1 do i = 1,8 lala = blau+zug8(i) if (brett(lala) == 1.and.lala.ne.rot) then blauerg = 0 exit endif end do end ! ********** ! berechne Anzahl der Rotfelder (Felder auf die Rot ziehen kann) ! ********** subroutine rotbewegtfelder(brett,zug8,rot,blau,rotfelder) implicit none integer brett(80),zug8(8) integer rot,blau,rotfelder,i,lala rotfelder = 0 do i = 1,8 lala = rot+zug8(i) if (brett(lala) == 1.and.lala.ne.blau) then rotfelder = rotfelder + 1 endif end do end ! ********** ! berechne Anzahl der Blaufelder (Felder auf die Blau ziehen kann) ! ********** subroutine blaubewegtfelder(brett,zug8,rot,blau,blaufelder) implicit none integer brett(80),zug8(8) integer rot,blau,blaufelder,i,lala blaufelder = 0 do i = 1,8 lala = blau+zug8(i) if (brett(lala) == 1.and.lala.ne.rot) then blaufelder = blaufelder + 1 endif end do end ! ********** ! sortiere Zuege aus feld(azzuege) ! feld(i,1) = rotneu ! feld(i,2) = gedrueckt ! feld(i,3) = Bewertung (hoch am besten) ! ********** subroutine sortiere(feld,azzuege) implicit none integer feld(352,3) !,feld2(121088,4) integer i,j,azzuege,merk,merk2 integer lala,lala2,lala3,lala4 ! sortiere gesamtes Feld do i = 1,azzuege-1 do j = i+1,azzuege merk = feld(i,3) merk2 = feld(j,3) if (merk < merk2) then ! tausche lala = feld(i,1) lala2 = feld(i,2) lala3 = feld(i,3) !lala4 = feld(i,4) feld(i,1) = feld(j,1) feld(i,2) = feld(j,2) feld(i,3) = feld(j,3) !feld(i,4) = feld(j,4) feld(j,1) = lala feld(j,2) = lala2 feld(j,3) = lala3 !feld(j,4) = lala4 endif end do end do !print *,feld(:,3) !stop end ! ********** ! Zug von Rot ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! Strategie 5: variabel2 ! Baum Tiefe 1 in feld ! feld(:,1) = rotneu ! feld(:,2) = gedrueckt ! feld(:,3) = Bewertung des Zuges ! ********** subroutine rotzugTiefe1(brett,zug8,rot,blau,zug,zugnr,rotstrategie,suchtieferot) implicit none integer feld(352,3),feld2(352,3) ! feld2(352*8*43) integer feld3(250000,4) ! feld3(40685568,6) integer brett(80),zug8(8),zug(2),zug1(2),zug3(2),feld99(352) integer rot,blau,rotneu,zugnr,rotstrategie,rotfelder,blaufelder,rotmax integer i,j,merk,r integer azzuege,azzuege2,azzuege3,azzuege99,gedrueckt,suchtieferot integer max1,max2,max3,bewert real zwi common /isola1/ max1 ! (1) berechne und bewerte Zuege azzuege = 0 !do i = 1,352 ! feld(i,1) = 0 ! feld(i,2) = 0 ! feld(i,3) = 0 !end do do i = 1,8 !print *,'i ',i rotneu = rot+zug8(i) if (brett(rotneu) == 1.and.rotneu.ne.blau) then do j = 12,69 !print *,'j ',j gedrueckt = j if (brett(gedrueckt) == 1.and.rotneu.ne.gedrueckt.and.blau.ne.gedrueckt) then ! zug zulaessig azzuege = azzuege + 1 feld(azzuege,1) = rotneu feld(azzuege,2) = gedrueckt brett(gedrueckt) = 0 call bewertestellung(brett,zug8,rotstrategie,zugnr,rotneu,blau,bewert) feld(azzuege,3) = bewert ! mache Zug rueckgaengig brett(gedrueckt) = 1 endif end do endif end do if (azzuege > 0) then if (azzuege > max1) then max1 = azzuege endif endif ! (2) jetzt suche besten Zug aus feld von eben rotmax = -1000 azzuege99 = 0 ! finde besten Zug do i = 1,azzuege if (feld(i,3) >= rotmax) then rotmax = feld(i,3) endif end do ! erstelle Liste mit allen besten Zuegen do i = 1,azzuege ! print *,'i feld(i,3) ',i,feld(i,3) if (feld(i,3) == rotmax) then azzuege99 = azzuege99 + 1 feld99(azzuege99) = i ! print *,'rotmax azzuege2 i ',rotmax,azzuege2,i endif end do ! waehle Zug aus if (azzuege99 == 1) then merk = feld99(azzuege99) else call random_number(zwi) r = floor(zwi*azzuege99)+1 merk = feld99(r) endif zug1(1) = feld(merk,1) zug1(2) = feld(merk,2) zug(1) = zug1(1) zug(2) = zug1(2) rot = zug(1) brett(zug(2)) = 0 zugnr = zugnr + 1 !print *,'zugnr ',zugnr end ! ********** ! Zug von Rot ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! Strategie 5: variabel2 ! Baum Tiefe 1 in feld ! feld(:,1) = rotneu ! feld(:,2) = gedrueckt ! feld(:,3) = Bewertung des Zuges ! ********** subroutine rotzugTiefe3(brett,zug8,rot,blau,zug,zugnr,rotstrategie,suchtieferot) implicit none integer feld(352,3),feld2(121088,4) ! feld2(352*8*43) integer feld3(121088,3) ! feld3(40685568,6) integer brett(80),zug8(8),zug(2),zug1(2),zug3(2),feld99(352) integer rot,blau,rotneu,zugnr,rotstrategie,rotfelder,blaufelder,rotmax integer i,j,merk,r integer azzuege,azzuege2,azzuege3,azzuege99,gedrueckt,suchtieferot integer max1,max2,max3,bewert real zwi common /isola1/ max1 ! (1) berechne und bewerte Zuege azzuege = 0 do i = 1,8 !print *,'i ',i rotneu = rot+zug8(i) if (brett(rotneu) == 1.and.rotneu.ne.blau) then do j = 12,69 !print *,'j ',j gedrueckt = j if (brett(gedrueckt) == 1.and.rotneu.ne.gedrueckt.and.blau.ne.gedrueckt) then ! zug zulaessig azzuege = azzuege + 1 feld(azzuege,1) = rotneu feld(azzuege,2) = gedrueckt brett(gedrueckt) = 0 call bewertestellung(brett,zug8,rotstrategie,zugnr,rotneu,blau,bewert) feld(azzuege,3) = bewert ! mache Zug rueckgaengig brett(gedrueckt) = 1 endif end do endif end do if (azzuege > 0) then if (azzuege > max1) then max1 = azzuege endif endif ! (2) jetzt suche besten Zug aus feld von eben rotmax = -1000 azzuege99 = 0 ! finde besten Zug do i = 1,azzuege if (feld(i,3) >= rotmax) then rotmax = feld(i,3) endif end do ! erstelle Liste mit allen besten Zuegen do i = 1,azzuege ! print *,'i feld(i,3) ',i,feld(i,3) if (feld(i,3) == rotmax) then azzuege99 = azzuege99 + 1 feld99(azzuege99) = i ! print *,'rotmax azzuege2 i ',rotmax,azzuege2,i endif end do ! waehle Zug aus if (azzuege99 == 1) then merk = feld99(azzuege99) else call random_number(zwi) r = floor(zwi*azzuege99)+1 merk = feld99(r) endif zug1(1) = feld(merk,1) zug1(2) = feld(merk,2) !rot = zug(1) !brett(zug(2)) = 0 if (rotmax.ne.1000.and.suchtieferot == 3) then ! sortiere Zuege Tiefe 1 call sortiere(feld,azzuege) ! jetzt erzeuge Zuege von Blau (Tiefe 2) azzuege2 = 0 azzuege3 = 0 !print *,'vor rbz' call rotblauzug(brett,zug8,feld,azzuege,feld2,azzuege2,rot,blau,zug,zugnr,rotstrategie,suchtieferot) ! falls blau keinen Zug hat waehle besten Zug aus Tiefe 1(rot) !print *,brett !print *,'vor rbrz' call rotblaurotzug(brett,zug8,feld,azzuege,feld2,azzuege2,feld3,azzuege3,rot,blau,zug3,zugnr,rotstrategie,suchtieferot) !print *,'nach rbrz' zug(1) = zug3(1) zug(2) = zug3(2) else zug(1) = zug1(1) zug(2) = zug1(2) endif rot = zug(1) brett(zug(2)) = 0 !print *,brett !print *,rot,blau zugnr = zugnr + 1 ! print *,'zugnr ',zugnr end ! ********** ! Zug von Rot/Blau ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! Strategie 5: variabel2 ! in feld2 wird die Bauminformation der Tiefe 2 gespeichert ! dabei wird zum Zug feld(kkk,:) nur der beste Antwortzug feld2(kkk,:) gespeichert ! sollte es mehrere beste Antwortzuege geben, wird der 1.gefundene Zug gespeichert ! feld2(:,1) = kkk // Nr in "feld" -> um zu wissen, wie der 1.Zug war ! feld2(:,2) = blauneu ! feld2(:,3) = gedrueckt ! feld2(:,4) = Bewertung des Zuges ! ********** subroutine rotblauzug(brett,zug8,feld,azzuege,feld2,azzuege2,rot,blau,zug,zugnr,rotstrategie,suchtieferot) implicit none integer feld(352,3),feld2(121088,4) ! feld2(352*8*43) integer brett(80),zug8(8),zug(2) integer rot,blau,rotneu,blauneu,zugnr integer rotstrategie,blaustrategie,rotfelder,blaufelder,blaumax integer i,j,kkk,wert,merk,r,marke,marke2 integer azzuege,azzuege2,gedrueckt,gedrueckt2,suchtieferot integer minimum,maximum,max2,bewert integer tempblau,tempgedrueckt real zwi common /isola2/ max2 azzuege2 = 0 do kkk = 1,azzuege ! marke = azzuege2 ! print *,'kkk ',kkk rotneu = feld(kkk,1) gedrueckt = feld(kkk,2) wert = feld(kkk,3) brett(gedrueckt) = 0 !zugnr = zugnr + 1 ! (1) berechne und bewerte Zuege do i = 1,8 blauneu = blau+zug8(i) if (brett(blauneu) == 1.and.blauneu.ne.rotneu) then do j = 12,69 gedrueckt2 = j if (brett(gedrueckt2) == 1.and.blauneu.ne.gedrueckt2.and.rot.ne.gedrueckt2) then ! zug zulaessig !azzuege2 = azzuege2 + 1 !feld2(azzuege2,1) = kkk !feld2(azzuege2,3) = gedrueckt2 brett(gedrueckt2) = 0 call bewertestellung(brett,zug8,rotstrategie,zugnr,rotneu,blauneu,bewert) !if (blaufelder == 0) then ! tempbewertung = -1000 !endif azzuege2 = azzuege2 + 1 feld2(azzuege2,1) = kkk feld2(azzuege2,2) = blauneu feld2(azzuege2,3) = gedrueckt2 feld2(azzuege2,4) = bewert brett(gedrueckt2) = 1 !zugnr = zugnr - 1 endif end do endif end do brett(gedrueckt) = 1 end do !azzuege2 = azzuege if (azzuege2 > max2) then max2 = azzuege2 endif ! sortierte Zug der Tiefe 2 (besten Zug=[hoher Wert] von blau nach oben) ! call sortiere(feld2,azzuege2) !print *,azzuege2 !do i = 1,100 ! print *,i ! print *,feld2(i,:) !end do !stop end ! ********** ! Zug von Rot/Blau/Rot ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! Strategie 5: variabel2 ! in feld3 wird die Bauminformation der Tiefe 3 gespeichert ! feld3(:,1) = rotneuneu ! feld3(:,2) = gedrueckt3 ! feld3(:,3) = Bewertung des Zuges ! ********** subroutine rotblaurotzug(brett,zug8,feld,azzuege,feld2,azzuege2,feld3,azzuege3,rot,blau,zug,zugnr,rotstrategie,suchtieferot) implicit none integer feld(352,3),feld2(121088,4) ! feld2(352*8*43) integer feld3(121088,3) ! feld3(40685568,6) integer brett(80),zug8(8),zug(2),feld99(100000) integer rot,blau,rotneu,blauneu,rotneuneu integer zugnr,rotstrategie,rotfelder,blaufelder,rotmax integer i,j,kkk,merk,merk2,merk3,r integer azzuege,azzuege2,azzuege3,azzuege99 integer gedrueckt,gedrueckt2,gedrueckt3,suchtieferot integer max3,wert integer bestbewert,bestkkk integer bestrot1,bestrot3,bestgedrueckt1,bestgedrueckt3 integer blockmax,zaehler,bewert real zwi common /isola3/ max3 ! (1) berechne und bewerte Zuege !azzuege = 0 !azzuege2 = 0 azzuege3 = 1 !do i = 1,352 ! feld(i,1) = 0 ! feld(i,2) = 0 ! feld(i,3) = 0 !end do !print *,'azzzuege2 ',azzuege2 do kkk = 1,azzuege2 merk = kkk merk2 = feld2(kkk,1) rotneu = feld(merk2,1) gedrueckt = feld(merk2,2) blauneu = feld2(kkk,2) gedrueckt2 = feld2(kkk,3) wert = feld2(kkk,4) !beta = feld2(1,4) !if (feld2(kkk,1).ne.-1) then brett(gedrueckt) = 0 brett(gedrueckt2) = 0 !zugnr = zugnr + 2 !print *,merk,rotneu,blauneu,gedrueckt,gedrueckt2 zaehler = 0 do i = 1,8 !print *,'i ',i rotneuneu = rotneu+zug8(i) if (brett(rotneuneu) == 1.and.rotneuneu.ne.blauneu) then do j = 12,69 !print *,'j ',j gedrueckt3 = j if (brett(gedrueckt3) == 1.and.rotneuneu.ne.gedrueckt3.and.blauneu.ne.gedrueckt3) then ! zug zulaessig brett(gedrueckt3) = 0 zaehler = zaehler + 1 call bewertestellung(brett,zug8,rotstrategie,zugnr,rotneuneu,blauneu,bewert) if (zaehler == 1) then blockmax = bewert endif ! selber Block if (bewert > blockmax) then !im selben Block besseren Wert gefunden ! print *,blockmax blockmax = bewert bestkkk = kkk bestrot3 = rotneuneu bestgedrueckt3 = gedrueckt3 ! bestbewert = blockmax ! tempbewert bestrot1 = rotneu bestgedrueckt1 = gedrueckt !print *,bestrot1,bestgedrueckt1,bestrot3,bestgedrueckt3,bewert endif ! mache Zug rueckgaengig brett(gedrueckt3) = 1 endif end do endif end do ! spaeter beta schnitt 9999 brett(gedrueckt) = 1 brett(gedrueckt2) = 1 !endif !zugnr = zugnr - 2 !altkkk = kkk feld3(kkk,1) = bestrot3 feld3(kkk,2) = bestgedrueckt3 feld3(kkk,3) = blockmax end do ! jetzt suche besten Zug bestbewert = -2000 do kkk = 1,azzuege2 if (feld3(kkk,3) > bestbewert) then !print *,kkk,bestbewert bestbewert = feld3(kkk,3) merk = feld2(kkk,1) bestrot1 = feld(merk,1) bestgedrueckt1 = feld(merk,2) endif end do ! merk = bestkkk !merk2 = feld3(merk,1) !merk2 = feld2(merk,1) !zug(1) = feld(merk2,1) !zug(2) = feld(merk2,2) zug(1) = bestrot1 zug(2) = bestgedrueckt1 !print *,bestrot1,bestgedrueckt1,bestbewert end ! ********** ! bewerte die Stellung auf dem Brett bei Strategie 1 bis 5 ! ********** subroutine bewertestellung(brett,zug8,rotstrategie,zugnr,rot,blau,bewert) implicit none integer brett(80),zug8(8) integer rot,blau,rotfelder,blaufelder,rotstrategie,bewert,zugnr call rotbewegtfelder(brett,zug8,rot,blau,rotfelder) call blaubewegtfelder(brett,zug8,rot,blau,blaufelder) !print *,rotfelder,blaufelder !print *,'rs ',rotstrategie select case (rotstrategie) case (1) bewert = 0 case (2) bewert = 2*rotfelder-blaufelder case (3) bewert = rotfelder-2*blaufelder case (4) if (zugnr < 21) then bewert = 2*rotfelder-blaufelder else bewert = rotfelder-2*blaufelder endif case (5) if (zugnr < 21) then bewert = rotfelder-2*blaufelder else bewert = 2*rotfelder-blaufelder endif !case (6) ! bewert = 3*rotfelder-blaufelder end select bewert = bewert + 20 if (blaufelder == 0) then bewert = 1000 endif end \sourceoff \showoff


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.99, vom Themenstarter, eingetragen 2023-02-01

Noch etwas zu Bäumen und wie man sie implementiert. (aus einem Java Buch zu Datenstrukturen "Data Structures and Algorithms in Java") Ich habe oben in Isola (Beitrag 98) mit mehreren Feldern gearbeitet. https://www.matheplanet.de/matheplanet/nuke/html/uploads/c/15578_1_Java_allgemeiner_Baum_als_bin_rer_Baum_33_Prozent.jpg (1 ein allgemeiner Baum umgewandelt in einen binären Baum) https://www.matheplanet.de/matheplanet/nuke/html/uploads/c/15578_2_Java_allgemeiner_Baum_als_Container_33_Prozent.jpg (2 ein Baum Darstellung -2-)


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.100, vom Themenstarter, eingetragen 2023-02-07

Mittlerweile habe ich einen Minimax-Algorithmus zum Lösen von Isola. (bei mir aktuell 8x6 Feld mit alle Felder drückbar) Nachteil: ein zufälliger Lauf von Strategie 3 mit Tiefe 3 (Rot/Blau/Rot) gegen Zufall mit Tiefe 1 hat 27,9 Sekunden gedauert. Minimax mit Tiefe 5 müsste zwar laufen, aber noch mal um dem Faktor 300+ pro Halbzug langsamer sein. Also ca. ein Faktor von 300+*300+ = 90000+ langsamer als Tiefe 3. Nützlich war dabei auch der Versuch Tic Tac Toe mit Minimax zu lösen: https://www.matheplanet.de/matheplanet/nuke/html/viewtopic.php?topic=261555&start=0&lps=1899546#v1899546 Edit: noch einen kleinen Fehler für Spieler 2 (blau) und Suchtiefe 3 behoben. /Edit Edit2: geändert: das Startfeld von rot ist 32 nicht 31 (31 wäre auf dem Rand)./Edit2 Edit3: noch einen Fehler im Minimax gefunden und behoben./Edit3. Code in Fortran 90 \showon \sourceon Fortran 90 program Isola2023MinMax implicit none ! Isola 2023 mit Tiefe 1, (2,) 3 (Minimax-Algorithmus) ! ! https://de.wikipedia.org/wiki/Minimax-Algorithmus ! https://de.wikipedia.org/wiki/Alpha-Beta-Suche // spaeter ! ! Rechenzeit 3T3 vs 3T1 -> 1 Lauf 27,9 Sekunden ! ! ohne Alpha-Beta: Isola2023MinMax ! Rot 3 / T 3 // Blau 1 / T 1 -> Rot 97 von 100 gewonnen / 2183,9 Sekunden ! Rot 2 / T 3 // Blau 2 / T 1 -> Rot 48 von 100 gewonnen / 3105,9 Sekunden ! Rot 3 / T 3 // Blau 3 / T 1 -> Rot 59 von 100 gewonnen / 2887,5 Sekunden ! Rot 4 / T 3 // Blau 4 / T 1 -> Rot 60 von 100 gewonnen / 3092,4 Sekunden ! Rot 5 / T 3 // Blau 5 / T 1 -> Rot 54 von 100 gewonnen / 2946,8 Sekunden ! ! Rot 3 / T 3 // Blau 2 / T 1 -> Rot 61 von 100 gewonnen / 2628,4 Sekunden ! integer brett(80),brett2(80),zug8(8),zug(2) integer i,j,laeufe,rot,blau,roterg,blauerg,rotstrategie,blaustrategie integer rot2,blau2,zugnr,azspiele,rotgewinn,blaugewinn integer ende,ausgabe,suchtieferot,suchtiefeblau integer max1 integer spieler,bestMove real t0,t1 common /isola1/ max1 common /isola4/ rotstrategie common /isola5/ suchtieferot common /isola6/ zugnr call cpu_time(t0) call random_seed() laeufe = 1 rotstrategie = 3 suchtieferot = 3 blaustrategie = 3 suchtiefeblau = 1 ausgabe = 0 rotgewinn = 0 blaugewinn = 0 azspiele = 0 max1 = 0 DO i = 1,laeufe call init(brett,zug8,rot,blau,zugnr) ende = 0 !call ausgabebrett(brett,rot,blau) do while (ende == 0) ! while (ende == 0) do call rotmatt(brett,zug8,rot,blau,roterg) if (roterg == 0) then !call ausgabebrett(brett,rot,blau) if (suchtieferot == 1) then call rotzugTiefe1(brett,zug8,rot,blau,zug,zugnr,rotstrategie,suchtieferot) else spieler = 1 call Minimax_Decision(brett,zug8,rot,blau,zug,zugnr,spieler) ! print *,'nach Minimax (rot) ',zug rot = zug(1) brett(zug(2)) = 0 endif !print *,zug ! print *,zug,rot,blau if (ausgabe == 1) then ! print *,'rotzug ',zug call ausgabebrett(brett,rot,blau) call cpu_time(t1) print *,'Zeit = ',t1 endif else blaugewinn = blaugewinn + 1 azspiele = azspiele + 1 ende = 1 endif if (roterg == 0) then ! spiegele Brett do j = 1,80 brett2(j) = brett(81-j) end do rot2 = 81-blau blau2 = 81-rot ! call blaumatt(brett,zug8,rot,blau,blauerg) call rotmatt(brett2,zug8,rot2,blau2,blauerg) if (blauerg == 0) then ! call blauzug(brett,zug8,rot,blau,zug,zugnr,blaustrategie,suchtiefeblau) !print *,suchtiefeblau if (suchtiefeblau == 1) then call rotzugTiefe1(brett2,zug8,rot2,blau2,zug,zugnr,blaustrategie,suchtiefeblau) else spieler = 1 call Minimax_Decision(brett2,zug8,rot2,blau2,zug,zugnr,spieler) rot2 = zug(1) brett2(zug(2)) = 0 endif ! spiegele Brett do j = 1,80 brett(j) = brett2(81-j) end do rot = 81-blau2 blau = 81-rot2 if (ausgabe == 1) then ! print *,'blauzug ',zug call ausgabebrett(brett,rot,blau) endif else rotgewinn = rotgewinn + 1 azspiele = azspiele + 1 ende = 1 endif endif end do ! print *,brett end do print *,'rotgewinn ',rotgewinn print *,'blaugewinn ',blaugewinn print *,'von ',azspiele print *,' ' print *,'feldmax 1 ',max1 call cpu_time(t1) print *,'Zeit = ',t1 end ! ********** ! Initialiserung ! brett(1..80) = 1 (Plaetchen) oder 100 (Rand) ! rot = 31 // Startfeld ! blau = 49 // Startfeld ! spielzuege // 42x (von,nach,plaetchen gedrueckt aktuell) ! ********** subroutine init(Grundstellung,zug8,rot,blau,zugnr) implicit none integer Grundstellung(80),zug8(8) integer i,rot,blau,zugnr DO i = 1,80 GrundStellung(i) = 1 ! Plaettchen END DO Grundstellung(1) = 100 Grundstellung(2) = 100 Grundstellung(3) = 100 Grundstellung(4) = 100 Grundstellung(5) = 100 Grundstellung(6) = 100 Grundstellung(7) = 100 Grundstellung(8) = 100 Grundstellung(9) = 100 Grundstellung(10) = 100 Grundstellung(11) = 100 Grundstellung(20) = 100 Grundstellung(21) = 100 Grundstellung(30) = 100 Grundstellung(31) = 100 Grundstellung(40) = 100 Grundstellung(41) = 100 Grundstellung(50) = 100 Grundstellung(51) = 100 Grundstellung(60) = 100 Grundstellung(61) = 100 Grundstellung(70) = 100 Grundstellung(71) = 100 Grundstellung(72) = 100 Grundstellung(73) = 100 Grundstellung(74) = 100 Grundstellung(75) = 100 Grundstellung(76) = 100 Grundstellung(77) = 100 Grundstellung(78) = 100 Grundstellung(79) = 100 Grundstellung(80) = 100 ! spaeter vielleicht mit 2 fixen Feldern (Isola Original) !Grundstellung(31) = 50 !Grundstellung(49) = 50 rot = 32 blau = 49 zug8(1) = -11 zug8(2) = -10 zug8(3) = -9 zug8(4) = -1 zug8(5) = 1 zug8(6) = +9 zug8(7) = +10 zug8(8) = +11 zugnr = 0 end ! ***************************************************************** ! drucken des Bretts auf Bildschirm (Isola) ! ***************************************************************** subroutine ausgabebrett(brett,rot,blau) implicit none integer brett(80) integer rot,blau,i,j,nr character(len=30) merk print *,'Brett' print *,'------------' !print *,rot,blau !print *,brett nr = 0 do i = 1,8 merk = " " do j = 1,10 nr = nr + 1 if (rot == nr) then merk((j-2)*3+2:(j-2)*3+2) = "R" else if (blau == nr) then merk((j-2)*3+2:(j-2)*3+2) = "B" else if (brett(nr) == 0) then merk((j-2)*3+2:(j-2)*3+2) = "." else if (brett(nr) == 1) then merk((j-2)*3+2:(j-2)*3+2) = "x" endif endif endif endif end do print *,merk end do print *,'------------' ! print *,'rot blau ',rot,blau end !*********** ! rotmatt // ist rot Matt? ! erg = 0 // rot nicht Matt ! erg = 1 // rot ist Matt !*********** subroutine rotmatt(brett,zug8,rot,blau,roterg) implicit none integer brett(80),zug8(8) integer rot,blau,roterg,i,lala roterg = 1 do i = 1,8 lala = rot+zug8(i) if (brett(lala) == 1.and.lala.ne.blau) then roterg = 0 exit endif end do end !*********** ! blaumatt // ist blau Matt? ! erg = 0 // blau nicht Matt ! erg = 1 // blau ist Matt !*********** subroutine blaumatt(brett,zug8,rot,blau,blauerg) implicit none integer brett(80),zug8(8) integer rot,blau,blauerg,i,lala blauerg = 1 do i = 1,8 lala = blau+zug8(i) if (brett(lala) == 1.and.lala.ne.rot) then blauerg = 0 exit endif end do end ! ********** ! berechne Anzahl der Rotfelder (Felder auf die Rot ziehen kann) ! ********** subroutine rotbewegtfelder(brett,zug8,rot,blau,rotfelder) implicit none integer brett(80),zug8(8) integer rot,blau,rotfelder,i,lala rotfelder = 0 do i = 1,8 lala = rot+zug8(i) if (brett(lala) == 1.and.lala.ne.blau) then rotfelder = rotfelder + 1 endif end do end ! ********** ! berechne Anzahl der Blaufelder (Felder auf die Blau ziehen kann) ! ********** subroutine blaubewegtfelder(brett,zug8,rot,blau,blaufelder) implicit none integer brett(80),zug8(8) integer rot,blau,blaufelder,i,lala blaufelder = 0 do i = 1,8 lala = blau+zug8(i) if (brett(lala) == 1.and.lala.ne.rot) then blaufelder = blaufelder + 1 endif end do end ! ********** ! sortiere Zuege aus feld(azzuege) ! feld(i,1) = rotneu ! feld(i,2) = gedrueckt ! feld(i,3) = Bewertung (hoch am besten) ! ********** subroutine sortiere(feld,azzuege) implicit none integer feld(352,3) !,feld2(121088,4) integer i,j,azzuege,merk,merk2 integer lala,lala2,lala3,lala4 ! sortiere gesamtes Feld do i = 1,azzuege-1 do j = i+1,azzuege merk = feld(i,3) merk2 = feld(j,3) if (merk < merk2) then ! tausche lala = feld(i,1) lala2 = feld(i,2) lala3 = feld(i,3) !lala4 = feld(i,4) feld(i,1) = feld(j,1) feld(i,2) = feld(j,2) feld(i,3) = feld(j,3) !feld(i,4) = feld(j,4) feld(j,1) = lala feld(j,2) = lala2 feld(j,3) = lala3 !feld(j,4) = lala4 endif end do end do !print *,feld(:,3) !stop end ! ********** ! Zug von Rot ! Strategie 1: Zufall ! Strategie 2: Defensiv ! Strategie 3: Offensiv ! Strategie 4: variabel ! Strategie 5: variabel2 ! Baum Tiefe 1 in feld ! feld(:,1) = rotneu ! feld(:,2) = gedrueckt ! feld(:,3) = Bewertung des Zuges ! ********** subroutine rotzugTiefe1(brett,zug8,rot,blau,zug,zugnr,rotstrategie,suchtieferot) implicit none integer feld(352,3),feld2(352,3) ! feld2(352*8*43) integer feld3(250000,4) ! feld3(40685568,6) integer brett(80),zug8(8),zug(2),zug1(2),zug3(2),feld99(352) integer rot,blau,rotneu,zugnr,rotstrategie,rotfelder,blaufelder,rotmax integer i,j,merk,r integer azzuege,azzuege2,azzuege3,azzuege99,gedrueckt,suchtieferot integer max1,bewert real zwi common /isola1/ max1 ! (1) berechne und bewerte Zuege azzuege = 0 !do i = 1,352 ! feld(i,1) = 0 ! feld(i,2) = 0 ! feld(i,3) = 0 !end do do i = 1,8 !print *,'i ',i rotneu = rot+zug8(i) if (brett(rotneu) == 1.and.rotneu.ne.blau) then do j = 12,69 !print *,'j ',j gedrueckt = j if (brett(gedrueckt) == 1.and.rotneu.ne.gedrueckt.and.blau.ne.gedrueckt) then ! zug zulaessig azzuege = azzuege + 1 feld(azzuege,1) = rotneu feld(azzuege,2) = gedrueckt brett(gedrueckt) = 0 call bewertestellung(brett,zug8,rotstrategie,zugnr,rotneu,blau,bewert) feld(azzuege,3) = bewert ! mache Zug rueckgaengig brett(gedrueckt) = 1 endif end do endif end do if (azzuege > 0) then if (azzuege > max1) then max1 = azzuege endif endif ! (2) jetzt suche besten Zug aus feld von eben rotmax = -1000 azzuege99 = 0 ! finde besten Zug do i = 1,azzuege if (feld(i,3) >= rotmax) then rotmax = feld(i,3) endif end do ! erstelle Liste mit allen besten Zuegen do i = 1,azzuege ! print *,'i feld(i,3) ',i,feld(i,3) if (feld(i,3) == rotmax) then azzuege99 = azzuege99 + 1 feld99(azzuege99) = i ! print *,'rotmax azzuege2 i ',rotmax,azzuege2,i endif end do ! waehle Zug aus if (azzuege99 == 1) then merk = feld99(azzuege99) else call random_number(zwi) r = floor(zwi*azzuege99)+1 merk = feld99(r) endif zug1(1) = feld(merk,1) zug1(2) = feld(merk,2) zug(1) = zug1(1) zug(2) = zug1(2) rot = zug(1) brett(zug(2)) = 0 zugnr = zugnr + 1 !print *,'zugnr ',zugnr end ! ********** ! bewerte die Stellung auf dem Brett bei Strategie 1 bis 5 ! ********** subroutine bewertestellung(brett,zug8,rotstrategie,zugnr,rot,blau,bewert) implicit none integer brett(80),zug8(8) integer rot,blau,rotfelder,blaufelder,rotstrategie,bewert,zugnr !print *,rot,blau !print *,brett call rotbewegtfelder(brett,zug8,rot,blau,rotfelder) call blaubewegtfelder(brett,zug8,rot,blau,blaufelder) !print *,rotfelder,blaufelder !print *,'rs ',rotstrategie select case (rotstrategie) case (1) bewert = 0 case (2) bewert = 2*rotfelder-blaufelder case (3) bewert = rotfelder-2*blaufelder case (4) if (zugnr < 21) then bewert = 2*rotfelder-blaufelder else bewert = rotfelder-2*blaufelder endif case (5) if (zugnr < 21) then bewert = rotfelder-2*blaufelder else bewert = 2*rotfelder-blaufelder endif !case (6) ! bewert = 3*rotfelder-blaufelder end select bewert = bewert + 20 if (blaufelder == 0) then bewert = 1000 endif end ! *********** ! ! *********** subroutine Minimax_Decision(brett,zug8,rot,blau,zug,zugnr,spieler) implicit none integer feld(352,2) integer brett(80),brett2(80),zug8(8),zug(2),zug2(2) integer value,spieler integer maxValue,minValue integer azzuege,dran,zugnr integer i,j,rot,blau,rotneu,gedrueckt,erg ! common /tic/ zugnr maxValue = -9999 !minValue = 9999 !CROSS = -1 azzuege = 0 !print *,'Min Dec vor Zug ermitteln' ! (1) Zuege ermitteln do i = 1,8 !print *,'i ',i rotneu = rot+zug8(i) if ((brett(rotneu) == 1).and.(rotneu.ne.blau)) then do j = 12,69 !print *,'j ',j gedrueckt = j if ((brett(gedrueckt) == 1).and.(rotneu.ne.gedrueckt).and.(blau.ne.gedrueckt)) then ! zug zulaessig !print *,azzuege,rotneu,gedrueckt azzuege = azzuege + 1 feld(azzuege,1) = rotneu feld(azzuege,2) = gedrueckt !brett(gedrueckt) = 0 !call bewertestellung(brett,zug8,rotstrategie,zugnr,rotneu,blau,bewert) !feld(azzuege,3) = bewert ! mache Zug rueckgaengig !brett(gedrueckt) = 1 endif end do endif end do !print *,'nach Zug ermitteln' do i = 1,azzuege do j = 1,80 brett2(j) = brett(j) end do rotneu = feld(i,1) brett2(feld(i,2)) = 0 !dran = CROSS dran = 2 zugnr = zugnr + 1 !print *,rotneu,feld(i,2) call Minimax_Value(brett2,zug8,zugnr,rotneu,blau,1,dran,value) if (value > maxValue) then !if (value < minValue) then maxValue = value !minValue = value ! bestMove = feld(i) zug(1) = feld(i,1) zug(2) = feld(i,2) endif brett2(feld(i,2)) = 0 zugnr = zugnr -1 end do !return bestMove end ! *********** ! ! *********** recursive subroutine Minimax_Value(brett,zug8,zugnr,rot,blau,h,spieler,erg) implicit none integer feld(352,2) integer brett(80),brett2(80),zug8(8),zug(2)!,zug2(2) integer legalMoves,value integer maxValue,minValue integer azzuege,erg,ergbbb,ergbbb2,zugnr,spieler,h integer i,j,dran,rot,blau,rotneu,blauneu,gedrueckt integer rotstrategie,suchtieferot,bewert,rotfelder,blaufelder common /isola4/ rotstrategie common /isola5/ suchtieferot !common /isola6/ zugnr maxValue = -9999 minValue = 9999 !CIRCLE = 1 !CROSS = -1 !print *,'vor bewert' !print *,rotstrategie,rot,blau !print *,h if (spieler == 1) then call rotbewegtfelder(brett,zug8,rot,blau,rotfelder) if (rotfelder == 0) then erg = -1000 return endif else call blaubewegtfelder(brett,zug8,rot,blau,blaufelder) if (blaufelder == 0) then erg = 1000 return endif endif !call bewertestellung(brett,zug8,rotstrategie,zugnr,rot,blau,bewert) !print *,'nach bewert' if ((h == suchtieferot)) then call bewertestellung(brett,zug8,rotstrategie,zugnr,rot,blau,bewert) erg = bewert return endif ! (1) Zuege ermitteln azzuege = 0 if (spieler == 1) then do i = 1,8 !print *,'i ',i rotneu = rot+zug8(i) if ((brett(rotneu) == 1).and.(rotneu.ne.blau)) then do j = 12,69 !print *,'j ',j gedrueckt = j if ((brett(gedrueckt) == 1).and.(rotneu.ne.gedrueckt).and.(blau.ne.gedrueckt)) then ! zug zulaessig azzuege = azzuege + 1 feld(azzuege,1) = rotneu feld(azzuege,2) = gedrueckt ! brett(gedrueckt) = 0 !call bewertestellung(brett,zug8,rotstrategie,zugnr,rotneu,blau,bewert) !feld(azzuege,3) = bewert ! mache Zug rueckgaengig !brett(gedrueckt) = 1 endif end do endif end do else do i = 1,8 !print *,'i ',i blauneu = blau+zug8(i) if ((brett(blauneu) == 1).and.(blauneu.ne.rot)) then do j = 12,69 !print *,'j ',j gedrueckt = j if ((brett(gedrueckt) == 1).and.(blauneu.ne.gedrueckt).and.(rot.ne.gedrueckt)) then ! zug zulaessig azzuege = azzuege + 1 feld(azzuege,1) = blauneu feld(azzuege,2) = gedrueckt !brett(gedrueckt) = 0 !call bewertestellung(brett,zug8,rotstrategie,zugnr,rot,blauneu,bewert) !feld(azzuege,3) = bewert ! mache Zug rueckgaengig !brett(gedrueckt) = 1 endif end do endif end do endif !print *,'Zuege ermittelt' if (spieler == 1) then !if (spieler == 2) then do i = 1,azzuege do j = 1,80 brett2(j) = brett(j) end do rotneu = feld(i,1) brett2(feld(i,2)) = 0 zugnr = zugnr + 1 dran = 2 !call Minimax_Value(brett2,h+1,dran,value) !print *,rot,blauneu call Minimax_Value(brett2,zug8,zugnr,rotneu,blau,h+1,dran,value) if (value > maxValue) then maxValue = value !zug(1) = zug2(1) !zug(2) = zug2(2) endif brett2(feld(i,2)) = 0 zugnr = zugnr - 1 end do erg = maxValue else do i = 1,azzuege do j = 1,80 brett2(j) = brett(j) end do blauneu = feld(i,1) brett2(feld(i,2)) = 0 zugnr = zugnr + 1 dran = 1 ! call Minimax_Value(brett2,h+1,dran,value) !print *,rotneu,blau call Minimax_Value(brett2,zug8,zugnr,rot,blauneu,h+1,dran,value) if (value < minValue) then minValue = value !zug(1) = zug2(1) !zug(2) = zug2(2) endif brett2(feld(i,2)) = 0 zugnr = zugnr - 1 end do erg = minValue endif end \sourceoff \showoff


   Profil
Delastelle
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 17.11.2006
Mitteilungen: 2250
  Beitrag No.101, vom Themenstarter, eingetragen 2023-02-17

Ich habe jetzt einen 3.Matheplanet-Artikel zu Isola geschrieben. Darin geht es um Alpha-Beta-Suche und Isola. ( https://www.matheplanet.de/matheplanet/nuke/html/article.php?sid=1979&mode=&order=0 ) Aber es bleibt noch einiges zu tun: - die Bewertung einer Stellung auf dem Brett kann noch verbessert werden - die Alpha-Beta-Suche kann wohl noch beschleunigt werden - auch können Fehler im Fortran Programm nicht völlig ausgeschlossen werden - es ist mein 1.Versuch zu Alpha-Beta-Suche Immerhin spielt das Programm mit Suchtiefe 5 besser als mit Suchtiefe 3.


   Profil
Delastelle hat die Antworten auf ihre/seine Frage gesehen.
Seite 3Gehe zur Seite: 1 | 2 | 3  

Wechsel in ein anderes Forum:
 Suchen    
 
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2023 by Matroids Matheplanet
This web site was originally made with PHP-Nuke, a former web portal system written in PHP that seems no longer to be maintained nor supported. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen.
Lesen Sie die Nutzungsbedingungen, die Distanzierung, die Datenschutzerklärung und das Impressum.
[Seitenanfang]