|
Autor |
Wer gewinnt beim Spiel Isola |
|
NoraB
Aktiv  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  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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | Beitrag No.82, vom Themenstarter, eingetragen 2023-01-03
|
@gonz:
Ist Dein Program auf Basis von Alpha-Beta mit Suchbaumtechniken?
|
Profil
|
gonz
Senior  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  Dabei seit: 15.10.2014 Mitteilungen: 2716
 | 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  Dabei seit: 15.10.2014 Mitteilungen: 2716
 | 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  Dabei seit: 15.10.2014 Mitteilungen: 2716
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  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  Dabei seit: 24.10.2018 Mitteilungen: 4415
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 24.10.2018 Mitteilungen: 4415
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 24.10.2018 Mitteilungen: 4415
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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  Dabei seit: 17.11.2006 Mitteilungen: 2254
 | 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 3 | Gehe zur Seite: 1 | 2 | 3 |
|
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]
|