For tests (analysis) and fun I wrote this (is under construction!) for the asmFishW-engines:
Code: Select all
;Helles asmFishW-Player, 7.Oct.2019
;For asmFishW!
;PB 5.70 LTS (x64)
;UNICODE!
;UNDER CONSTRUCTION!
;No move-check!!!
;No table-bases
;No ponderhit
;No ...
;German
;Download asmFishW-Engines:
;https://github.com/lantonov/asmFish/tree/master/WindowsOS_binaries
;https://github.com/lantonov/asmFish/blob/executables/Windows/Windows_OldBinaries.7z
;Unicode einschalten für ältere PB-Versionen!
;Unicode-Schachfiguren:
;Weisser König = 9812
;Weisse Dame = 9813
;Weisser Turm = 9814
;Weisser Läufer = 9815
;Weisser Springer = 9816
;Weisser Bauer = 9817
;Schwarzer König = 9818
;Schwarze Dame = 9819
;Schwarzer Turm = 9820
;Schwarzer Läufer = 9821
;Schwarzer Springer = 9822
;Schwarzer Bauer = 9823
;Engines that use aspiration of the search window in the root, instead of setting it to {-INF, INF} can have fail highs (beta cutoffs) or fail lows in the root.
;The returned score is then a lower bound or a upper bound, respectively. This is what the UCI keywords indicate. How the GUI displays it, is the choice of the GUI designer.
;Most logical solution would be to write a + or - with the score, e.g. 1.25+ indicating a score of at least 1.25 (i.e. a lower bound).
;UCI-Kommandos:
;erst setoptions!
;- "setoption name threads value 8" praktisch 8 logische Cores nutzen
;- "setoption name hash value 2048" Hash 2 GB
;- "position startpos moves a2a4 b7b5" starte Berechnung nach den angegebenen Zügen
;- "go depth 25" starte Programm und rechne bis einschl. Tiefe 25
;- "go movetime 10000" starte Programm und rechne 10s lang
;"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" ;Grundstellung
;option name Hash type spin Default 16 min 1 max 65536
;option name LargePages type check Default false
;option name Threads type spin Default 1 min 1 max 256
;option name NodeAffinity type string Default all
;option name Priority type combo Default none var none var normal var low var idle
;option name TTFile type string Default <empty>
;option name TTSave type button
;option name TTLoad type button
;option name Clear Hash type button
;option name Ponder type check Default false
;option name UCI_Chess960 type check Default false
;option name MultiPV type spin Default 1 min 1 max 224
;option name Contempt type spin Default 0 min -100 max 100
;option name MoveOverhead type spin Default 30 min 0 max 5000
;option name MinThinkTime type spin Default 20 min 0 max 5000
;option name SlowMover type spin Default 89 min 10 max 1000
;option name SyzygyProbeDepth type spin Default 1 min 1 max 100
;option name SyzygyProbeLimit type spin Default 6 min 0 max 6
;option name Syzygy50MoveRule type check Default true
;option name SyzygyPath type string Default <empty>
;uciok
;info string hash set To 2048 MB no large pages
;info string node 0 has threads 0 1 2 3 4 5 6 7
;Original Structure Options
;byte[rdx+Options.displayInfoMove], -1 ;hier wohl uninteressant
;dword[rdx+Options.contempt], 0
;dword[rdx+Options.threads], 1
;dword[rdx+Options.hash], 16
;byte[rdx+Options.ponder], 0
;dword[rdx+Options.multiPV], 1
;dword[rdx+Options.moveOverhead], 30
;dword[rdx+Options.minThinkTime], 20
;dword[rdx+Options.slowMover], 89
;byte[rdx+Options.chess960], 0
;dword[rdx+Options.syzygyProbeDepth], 1
;byte[rdx+Options.syzygy50MoveRule], -1
;dword[rdx+Options.syzygyProbeLimit], 6
;byte[rdx+Options.largePages], 0
;Gadgets: 0-63 : Brett
; 64-79 : Brett-Beschriftung:
; 80-81 : Hinweis-Finger
; 82 : Button-Gadget Brett drehen $21c5
; 83 : Button-Gadget Zug zurück $21e6
; 84 : Button-Gadget Zug vor $21e8
; 85 : Button-Gadget zurück zur Startstellung
; 86 : Button-Gadget vor zur Endstellung
; 87 : Button-Gadget Stellung ändern/anpassen
; 90 : TextGadget EngineName$
; 91 : TextGadget CPUName$
; 92 : TextGadget CPU-Threads$
; 93 : TextGadget Hash-Größe$
; 94-95 : TextGadget Teststellung$ (falls gewählt)
; 100-101: TextGadget Aktuelle_Suchtiefe$
; 102-103: TextGadget Aktueller_Zug$
; 104-105: TextGadget Aktuelle_ Zug-Nr.$
; 106-107: TextGadget Hauptvariante$
; 108-109: TextGadget Bewertung$
; 110-111: TextGadget Tiefe$
; 112-113: TextGadget Zeit$
; 114-115: TextGadget Knoten$
; 116-117: TextGadget Knoten_Sek$
; 118-119: TextGadget Hashfull$
; 120-121: TextGadget TB_Hits$
; 122 : EditorGadget das rechte Hauptfenster
Declare Test2Stellung()
Declare Brettmal(Width.i, Height.i, StartPosX.i, StartPosY.i)
Declare Brettmal_Leer(Width.i, Height.i, StartPosX.i, StartPosY.i)
Declare FENString(AdrStellung)
Declare Zug()
Declare FEN2Stellung()
Declare wc(hWnd.i, uMsg.i, wParam.i, lParam.i)
Declare Umwandlung()
Declare Finger()
Declare Restoring() ;z.B. Rochade-Recht bei Zug vor/zurück
Declare.s DeziPoint(In$)
Global ORand.i = 40 ;Brett-Position oben
Pixel0.f = 30.0
Pixel1.f = 9.0
Pixel2.f = 24.0
Pixel3.f = 20.0
Pixel4.f = 48.0 ;Figur für Stellungseingabe
Global Font0.i
Global Font4.i
Global GrossRochS.i = 1 ;Rochade-Recht, erstmal auf vorhanden setzen
Global KleinRochS.i = 1
Global GrossRochW.i = 1
Global KleinRochW.i = 1
Global Schlag_Bauer.i
Global ZugNr.i = 1
Global UFig.b ;Bauern-Umwandlung
Dran.i = 0 ;1=DIESER PC fängt an, macht ersten Zug
Threads.i
BackColor.l = $99FFFF
Global PID.l
Global Cores.l = 1 ;ist Bit-Muster!
AnzCore.l
Global CMN_Max.i ;currmovenumber
Port$ = "COM10"
Global EngineName$
Global Farbe_am_Zug$ = " w" ;oder " b"
Global Rochade$ = " KQkq"
Global EnPassant$ = " -"
Global Schlag_Bauer$ = " 0"
Global ZugNr$ = " 1"
Global FEN$ = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" ;Grundstellung
Global Zug$ ;bestmove
Global FigArtOri.i = ?Figuren ;Festwert
Global FigArt.i = FigArtOri ;zeigt auf jeweilige Figur
Global BlackWhite.i = 0 ;0=Weiss, 12=Schwarz
Global Weiss_unten.i = 1
Global Finger80.i
Global Finger81.i
Global FEN_Strings.i
Global FEN_Strings_Pointer.i = 0
Global FEN_Strings_Pointer_Max.i
hWnd = OpenWindow(0, 0, 100, 1000, 750, "Helles asmFishW-Player", #PB_Window_MinimizeGadget);, #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget); | #PB_Window_SizeGadget)
If hWnd
SetWindowColor(0, BackColor) ;dann auch Background für TextGadgets
StickyWindow(0, 1)
FontHigh0 = Int(Pixel0 / (GetDeviceCaps_(GetDC_(hWnd), #LOGPIXELSY) / 96.0)) ;Font anpassen Figuren auf Brett
;LoadFont(0, "Arial Unicode MS", FontHigh0)
;LoadFont(0, "Arial Unicode MS Bold", FontHigh0) ;Geschmacks-Sache
LoadFont(0, "Lucida Sans Unicode Standard", FontHigh0) ;Geschmacks-Sache
Font0 = FontID(0)
FontHigh1 = Int(Pixel1 / (GetDeviceCaps_(GetDC_(hWnd), #LOGPIXELSY) / 96.0))
LoadFont(1, "Trebuchet MS Fett", FontHigh1)
Font1 = FontID(1)
FontHigh2 = Int(Pixel2 / (GetDeviceCaps_(GetDC_(hWnd), #LOGPIXELSY) / 96.0))
LoadFont(2, "Trebuchet MS Fett", FontHigh2)
Font2 = FontID(2)
FontHigh3 = Int(Pixel3 / (GetDeviceCaps_(GetDC_(hWnd), #LOGPIXELSY) / 96.0))
LoadFont(3, "Trebuchet MS Fett", FontHigh3)
Font3 = FontID(3)
FontHigh4 = Int(Pixel4 / (GetDeviceCaps_(GetDC_(hWnd), #LOGPIXELSY) / 96.0)) ;Figur für Stellungseingabe
LoadFont(4, "Lucida Sans Unicode Standard", FontHigh4) ;Geschmacks-Sache
Font4 = FontID(4)
;----------------------------------------------
CPUName.i = AllocateMemory(48) ;48 Characters
;Lese CPU-String
!MOV r9,[v_CPUName]
!XOR r8,r8
!@@:
!MOV eax,80000002h
!ADD eax,r8d
!CPUID
!MOV [r9],eax
!MOV [r9+4],ebx
!MOV [r9+8],ecx
!MOV [r9+12],edx
!INC r8
!CMP r8,3
!JE @f
!ADD r9,16
!JMP @b
!@@:
;----------------------------------------------
TextGadget(1, 20, 20, 150, 15, "System-Infos:")
;CPU ------------------------------------------
CPUName$ = PeekS(CPUName, 48, #PB_Ascii) ;wird nochmal verwendet
TextGadget(2, 20, 40, 325, 15, "CPU: " + CPUName$)
j = 1
hThread = GetCurrentThread_()
OldThreadAffinityMask = SetThreadAffinityMask_(hThread, j)
While SetThreadAffinityMask_(hThread, j)
!INC [v_AnzCore]
!MOV eax,1
!CPUID
!SHR ebx,24 ;Initial APIC ID. Bit24: 0=phys., 1=log.Core. Bit 25-31: "Basic"-Core
!AND ebx,0FFh
!TEST ebx,1
!JNZ @f
CoreSequence$ + "P"
P_Cores + 1 ;für kein HT/SMT
Cores | j
!JMP NextCore
!@@:
CoreSequence$ + "L"
HTAV + 1
!NextCore:
j << 1
Wend
SetThreadAffinityMask_(hThread, OldThreadAffinityMask) ;Restore
;Debug Bin(Cores)
If HTAV
HTAV$ = "Ja"
Else
HTAV$ = "Nein"
EndIf
TextGadget(3, 20, 55, 325, 15, "Verfügbare Anzahl CPU-Threads: " + Str(AnzCore))
TextGadget(4, 20, 70, 325, 15, "HT/SMT: " + HTAV$)
TextGadget(5, 20, 85, 325, 15, "Core-Sequenz (0-" + Str(AnzCore - 1) + "): " + CoreSequence$)
;RAM für Hash ---------------------------------
Memory.MEMORYSTATUSEX
Memory\dwLength = SizeOf(MEMORYSTATUSEX)
GlobalMemoryStatusEx_(@Memory)
FreeMemory = Memory\ullAvailPhys / 1024 / 1024 ;so in MB
TextGadget(6, 20, 100, 325, 15, "Freier Arbeitsspeicher: " + Str(FreeMemory) + " MB")
TextGadget(7, 20, 130, 100, 15, "SETTINGS:")
TextGadget(8, 20, 150, 100, 15, "Engine: " + UCI_Prog$)
For i = 1 To 8
SetGadgetColor(i, #PB_Gadget_BackColor, BackColor)
Next
;erstmal Test, ob Fish.ini existiert
If ReadFile(0, GetCurrentDirectory() + "Fish.ini", #PB_Ascii)
UCI_Prog_All$ = ReadString(0, #PB_Ascii) ;kompletter Programm-Pfad
UCI_Prog$ = GetFilePart(UCI_Prog_All$, #PB_FileSystem_NoExtension)
CloseFile(0)
EndIf
OptionGadget(9, 20, 165, 425, 15, "Letztgewählte Engine verwenden: " + UCI_Prog$)
OptionGadget(10, 20, 180, 300, 15, "Andere Engine wählen")
If UCI_Prog$ <> ""
SetGadgetState(9, 1)
Else
SetGadgetText(9, "Letztgewählte Engine verwenden: Keine ausgewählt")
DisableGadget(9, 1)
SetGadgetState(10, 1)
EndIf
TextGadget(11, 20, 200, 175, 15, "Hashgröße setzen (MB):")
SetGadgetColor(11, #PB_Gadget_BackColor, BackColor)
HashMemMax = 1 ;Startwert in MB
HashMemWert = 0
FreeMemory - 1024 ;1GB Reserve lassen
While HashMemMax < FreeMemory
HashMemWert + 1
HashMemMax << 1
Wend
HashMem = HashMemMax >> 1
SpinGadget (12, 180, 198, 75, 20, 0, HashMemWert - 1, #PB_Spin_ReadOnly)
SetGadgetState (12, HashMem)
SetGadgetText(12, Str(HashMem))
CheckBoxGadget(13, 20, 220, 180, 15, "Large Pages anfordern")
TextGadget(14, 20, 240, 150, 15, "Festlegung Threads:")
SetGadgetColor(14, #PB_Gadget_BackColor, BackColor)
OptionGadget(15, 20, 255, 125, 15, "1 Thread")
OptionGadget(16, 20, 270, 125, 15, "Kein HT/SMT")
OptionGadget(17, 20, 285, 125, 15, "Alle Threads")
SetGadgetState(17, 1)
TextGadget(18, 20, 305, 150, 15, "Startposition:")
SetGadgetColor(18, #PB_Gadget_BackColor, BackColor)
OptionGadget(19, 20, 320, 200, 15, "Grundstellung")
OptionGadget(20, 20, 335, 200, 15, "Teststellung laden (EPD)")
OptionGadget(21, 20, 350, 200, 15, "Stellungseingabe")
OptionGadget(22, 20, 365, 200, 15, "Stellung aus Zwischenablage")
SetGadgetState(19, 1)
;----------------------------------------------
ButtonGadget(23, 25, 400, 150, 30, "L o s g e h t s !")
For i = 1 To 23
SetGadgetFont(i, Font1)
Next
;----------------------------------------------
FEN_Strings = AllocateMemory(128 * 1000) ;für 1000 Stellungen, jeweils 128 Bytes; sollte reichen. Muss für Stellungseingabe schon vorhanden sein, deshalb hier vorn
HashMemAkt = HashMemOld
Repeat
HashMemAkt = GetGadgetState(12)
If HashMemAkt <> HashMemOld
HashMemOld = HashMemAkt
HashMem = (1 << HashMemAkt)
SetGadgetText(12, Str(HashMem))
EndIf
If GetGadgetState(10) And HaveEngine = 0 ;Engine auswählen
DisableGadget(23, 1)
HaveEngine = 1
TextGadget(24, 450, 20, 540, 15, "Engine auswählen:", #PB_Text_Center)
SetGadgetFont(24, Font1)
ExplorerTreeGadget(25, 450, 40, 540, 650, GetCurrentDirectory() + "*.EXE", #PB_Explorer_NoDriveRequester)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
If GetGadgetState(9) And HaveEngine
HaveEngine = 0
DisableGadget(23, 0)
SetGadgetText(9, "Letztgewählte Engine verwenden: " + UCI_Prog$)
DisableGadget(9, 0)
SetGadgetState(9, 1)
Break
EndIf
Until EventType() = #PB_EventType_LeftDoubleClick And GetGadgetState(25) = #PB_Explorer_File
If HaveEngine
HaveEngine = 0
DisableGadget(23, 0)
UCI_Prog_All$ = GetGadgetText(25) ;kompletter Programm-Pfad
UCI_Prog$ = GetFilePart(UCI_Prog_All$, #PB_FileSystem_NoExtension)
EndIf
FreeGadget(24) : FreeGadget(25)
SetGadgetText(9, "Letztgewählte Engine verwenden: " + UCI_Prog$)
DisableGadget(9, 0)
SetGadgetState(9, 1)
EndIf
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
If EventGadget() = 23 And Not IsGadget(25)
If GetGadgetState(13) = #PB_Checkbox_Checked ;Large Pages
LargePages = 1
ElseIf GetGadgetState(13) = #PB_Checkbox_Unchecked ;hier mal so
LargePages = 0
EndIf
If GetGadgetState(15) ;nur 1 Thread
Threads = 1
P_Cores = 0
ElseIf GetGadgetState(16) ;kein HT/SMT
Threads = P_Cores
ElseIf GetGadgetState(17) ;alle Threads
Threads = P_Cores + HTAV
P_Cores = 0
EndIf
If GetGadgetState(19)
Grundstellung = 1
ElseIf GetGadgetState(20)
Teststellung = 1
ElseIf GetGadgetState(21)
Stellungseingabe = 1
ElseIf GetGadgetState(22) ;Stellung aus Zwischenablage
Zwischenablage = 1
EndIf
Break
EndIf
ForEver
For i = 1 To 23
FreeGadget(i)
Next
CreateFile(0, GetCurrentDirectory() + "Fish.ini", #PB_Ascii)
WriteStringN(0, UCI_Prog_All$, #PB_Ascii)
CloseFile(0)
If Teststellung
;EPD-Datei laden --------------------------------------
TextGadget(1, 20, 25, 340, 15, "Teststellung wählen:", #PB_Text_Center)
SetGadgetColor(1, #PB_Gadget_BackColor, BackColor)
SetGadgetFont(1, Font1)
FileExt$ = "*.EPD"
ExplorerTreeGadget(2, 10, 50, 450, 440, GetCurrentDirectory() + "Tests\" + FileExt$, #PB_Explorer_NoDriveRequester)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until EventType() = #PB_EventType_LeftDoubleClick And GetGadgetState(2) = #PB_Explorer_File
EPD$ = GetGadgetText(2) ;Programm-Pfad
;Debug EPD$
FreeGadget(1) : FreeGadget(2)
ReadFile(0, EPD$, #PB_Ascii)
E$= ReadString(0, #PB_Ascii, Lof(0))
CloseFile(0)
;Debug E$
Quot = FindString(E$, Chr(34))
If Quot ;erstmal das erste " entfernen und alles danach
F$ = Mid(E$, 1, Len(E$) - (Len(E$) - Quot + 1))
EndIf
;Debug F$
AM = FindString(F$, " am ")
If AM
F$ = Mid(F$, 1, Len(F$) - (Len(F$) - AM + 1))
EndIf
;Debug F$
BM = FindString(F$, " bm ") ;best move
If BM
F$ = Mid(F$, 1, Len(F$) - (Len(F$) - BM + 1))
EndIf
;Debug F$
FS$ = RTrim(FS$)
If FindString(F$, " 0 1") ;oder anders...
FEN$ = F$
Else
FEN$ = F$ + " 0 1"
EndIf
;Debug FEN$
EndIf ;Teststellung
;------------------------------------------------
If Stellungseingabe
Brettmal_Leer(40, 40, 20, ORand) ;leeres Brett
Figur = PeekW(?Figuren) ;wB als Anfang
TextGadget(200, 400, 200, 70, 70, Chr(Figur), #PB_Text_Center)
SetGadgetFont(200, Font4)
ButtonGadget(201, 425, 700, 150, 30, "L o s g e h t s !")
CheckBoxGadget(202, 20, 400, 200, 15, "Weiss kleine Rochade")
CheckBoxGadget(203, 20, 420, 200, 15, "Weiss große Rochade")
CheckBoxGadget(204, 20, 440, 200, 15, "Schwarz kleine Rochade")
CheckBoxGadget(205, 20, 460, 200, 15, "Schwarz kleine Rochade")
OptionGadget(206, 20, 480, 200, 15, "Weiß am Zug")
OptionGadget(207, 20, 500, 200, 15, "Schwarz am Zug")
SetGadgetState(206, 1)
For i = 201 To 207
If IsGadget(i)
SetGadgetFont(i, Font1)
EndIf
Next
SetWindowCallback(@wc())
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
If EventGadget() = 201
Break
EndIf
ForEver
SetWindowCallback(0)
Rochade$ = " " ;" KQkq"
If GetGadgetState(202) = #PB_Checkbox_Checked
Rochade$ + "K"
EndIf
If GetGadgetState(203) = #PB_Checkbox_Checked
Rochade$ + "Q"
EndIf
If GetGadgetState(204) = #PB_Checkbox_Checked
Rochade$ + "k"
EndIf
If GetGadgetState(205) = #PB_Checkbox_Checked
Rochade$ + "q"
EndIf
If Rochade$ = " "
Rochade$ = " -"
EndIf
If GetGadgetState(206)
Farbe_am_Zug$ = " w"
Else
Farbe_am_Zug$ = " b"
EndIf
FEN_Strings_Pointer = -128
FENString(?StellungEingabe) ;FEN_Strings_Pointer wird dort also wieder 0
For i = 200 To 207
FreeGadget(i)
Next
EndIf ;Stellungseingabe
;------------------------------------------------
If Zwischenablage
E$ = GetClipboardText()
;Debug E$
F$ = E$
Quot = FindString(E$, Chr(34))
If Quot ;erstmal das erste " entfernen und alles danach
F$ = Mid(E$, 1, Len(E$) - (Len(E$) - Quot + 1))
EndIf
;Debug F$
AM = FindString(F$, " am ") ;avoid move
If AM
F$ = Mid(F$, 1, Len(F$) - (Len(F$) - AM + 1))
EndIf
;Debug F$
BM = FindString(F$, " bm ") ;best move
If BM
F$ = Mid(F$, 1, Len(F$) - (Len(F$) - BM + 1))
EndIf
;Debug F$
FEN$ = RTrim(F$)
; If FindString(F$, " 0 1") ;oder anders...
;FEN$ = F$
; Else
; FEN$ = F$ + " 0 1"
; EndIf
Debug FEN$
Leer = FindString(FEN$, " ") ;Leerzeichen zwischen Stellung und Farbe am Zug
Debug Leer
Farbe_am_Zug$ = Mid(FEN$, Leer, 2) ;wird hier evtl. nicht benötigt
Debug Farbe_am_Zug$
Leer + 2 ;Rochade
LeerRA = FindString(FEN$, " ", Leer)
Debug LeerRA
;Leer+2
LeerRE = FindString(FEN$, " ", LeerRA+2)
Debug LeerRE
Rochade$ = Mid(FEN$, Leer, LeerRE-LeerRA)
Debug Rochade$
If FindString(Rochade$, "K", Leer + 1)
KleinRochW = 1
Rochade$ + "K"
Else
KleinRochW = 0
EndIf
If FindString(Rochade$, "Q", Leer + 1)
GrossRochW = 1
Rochade$ + "Q"
Else
GrossRochW = 0
EndIf
If FindString(Rochade$, "k", Leer + 1)
KleinRochS = 1
Rochade$ + "k"
Else
KleinRochS = 0
EndIf
If FindString(Rochade$, "q", Leer + 1)
GrossRochS = 1
Rochade$ + "q"
Else
GrossRochS = 0
EndIf
EndIf ;Zwischenablage
;------------------------------------------------
;Test2Stellung()
;-----------------------------------------
;Debug FEN$
;==================================================================
Chessprog = RunProgram(UCI_Prog_All$, "", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide | #PB_Program_Write | #PB_Program_Ascii)
If ProgramRunning(Chessprog)
PID = ProgramID(Chessprog) ;für Core-Zuordnung
;Gadgets definieren und ggf.setzen
TextGadget(80, 340, 330, 35, 35, Chr($261C), #PB_Text_Center) ;weisser Hinweis-Finger, wenn Weiß am Zug
SetGadgetColor(80, #PB_Gadget_BackColor, BackColor)
TextGadget(81, 340, 45, 35, 35, Chr($20), #PB_Text_Center) ;schwarzer Hinweis-Finger $261A, wenn Schwarz am Zug
SetGadgetColor(81, #PB_Gadget_BackColor, BackColor)
ButtonGadget(82, 105, 5, 30, 30, Chr($21d5), #PB_Text_Center) ;Brett drehen
ButtonGadget(83, 135, 5, 30, 30, Chr($21e6), #PB_Text_Center) ;Zug zurück
ButtonGadget(84, 165, 5, 30, 30, Chr($21e8), #PB_Text_Center) ;Zug vor
ButtonGadget(85, 195, 5, 30, 30, Chr($21da), #PB_Text_Center) ;zurück zur Startstellung
ButtonGadget(86, 225, 5, 30, 30, Chr($21db), #PB_Text_Center) ;vor zur Endstellung
ButtonGadget(87, 20, 5, 30, 30, Chr($21c6), #PB_Text_Center | #PB_Button_Toggle) ;Stellung ändern/anpassen
For i = 80 To 87
SetGadgetFont(i, Font3)
Next
If Teststellung Or Stellungseingabe Or Zwischenablage ;bei Teststellungen wird FEN$ selbst erzeugt
FEN2Stellung()
; Else
; FENString(?Stellung)
EndIf
;Debug FEN$
Brettmal(40, 40, 20, ORand) ;hier Grundstellung, sonst auch ...
;Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
;FEN_Strings = AllocateMemory(128 * 1000) ;für 1000 Stellungen, jeweils 128 Bytes; sollte reichen
PokeS(FEN_Strings, FEN$, -1, #PB_Ascii) ;Ausgangsstellung an Adresse 0
;grundlegende Angaben
WriteProgramStringN(Chessprog, "uci", #PB_Ascii)
WriteProgramStringN(Chessprog, "setoption name threads value " + Str(Threads), #PB_Ascii)
WriteProgramStringN(Chessprog, "setoption name hash value " + Str(HashMem), #PB_Ascii)
If LargePages
WriteProgramStringN(Chessprog, "setoption name largepages value true", #PB_Ascii)
EndIf
;WriteProgramStringN(Chessprog, "setoption name ucinewgame", #PB_Ascii)
;WriteProgramStringN(Chessprog, "setoption name clear hash", #PB_Ascii) ;nur mal Test
While AvailableProgramOutput(Chessprog) = 0
EngineName$ = ReadProgramString(Chessprog, #PB_Ascii) ;ist der Engine-Name
Break
Wend
;Debug EngineName$
;diese Tests erst hier, da die Datei ja umbenannt sein kann
IsFish = FindString(EngineName$, "asmFish", 1, #PB_String_NoCase) ;nicht "asmFishW" wegen älterer Versionen
If IsFish = 0
MessageRequester("Abbruch!", "Dies ist keine Windows-asmFish-Version!", #PB_MessageRequester_Error)
End
EndIf
IsPOPCNT = FindString(EngineName$, "popcnt", 10, #PB_String_NoCase)
If IsPOPCNT
!mov eax,1
!cpuid
!test ecx,800000h ;Bit23=POPCNT
!jnz ISPOPCNT ;na ja...
MessageRequester("Abbruch!", "Diese CPU kann kein popcnt!" + #LF$ + "base nehmen!", #PB_MessageRequester_Error)
End
EndIf
!ISPOPCNT:
IsBMI = FindString(EngineName$, "bmi", 10, #PB_String_NoCase) ;bmi2
If IsBMI
!xor eax,eax
!cpuid
!cmp eax,7 ;max. ID
!jb NOBMI
!mov eax,7
!xor ecx,ecx
!cpuid
!test ebx,8 ;Bit3=BMI(1) wird auch genutzt
!jz NOBMI
!test ebx,100h ;Bit8=BMI2
!jnz ISBMI ;na ja...
!NOBMI:
MessageRequester("Abbruch!", "Diese CPU kann kein bmi!" + #LF$ + "popcnt oder base nehmen!", #PB_MessageRequester_Error)
End
EndIf
!ISBMI:
TextGadget(90, 10, ORand + 350, 350, 15, "Engine: " + EngineName$)
TextGadget(91, 10, ORand + 365, 350, 15, "CPU: " + PeekS(CPUName, 48, #PB_Ascii))
TextGadget(92, 10, ORand + 380, 350, 15, "CPU-Threads: " + Str(Threads))
TextGadget(93, 10, ORand + 395, 350, 15, "") ;Platzhalter für Hash-Größe
For i = 90 To 93
SetGadgetColor(i, #PB_Gadget_BackColor, BackColor)
SetGadgetFont(i, Font1)
Next
;nur für geladene Teststellung
If Teststellung
TextGadget(94, 10, ORand + 410, 980, 15, "Teststellung: " + EPD$)
SetGadgetFont(94, Font1)
SetGadgetColor(94, #PB_Gadget_BackColor, BackColor)
TextGadget(95, 10, ORand + 425, 980, 15, E$)
SetGadgetFont(95, Font1)
SetGadgetColor(95, #PB_Gadget_BackColor, BackColor)
EndIf
TextGadget(100, 10, ORand + 500, 120, 15, "Aktuelle Suchtiefe:")
TextGadget(101, 140, ORand + 500, 60, 15, Akt_Tiefe$)
TextGadget(102, 10, ORand + 515, 120, 15, "Aktueller Zug:")
TextGadget(103, 140, ORand + 514, 60, 15, Curr_Move$)
TextGadget(104, 10, ORand + 530, 120, 15, "Aktuelle Zug-Nr.:")
TextGadget(105, 140, ORand + 530, 60, 15, Curr_Move_Nr$)
TextGadget(106, 250, ORand + 580, 100, 15, "Hauptvariante:")
EditorGadget(107, 250, ORand + 600, 740, 100, #PB_Editor_ReadOnly | #PB_Editor_WordWrap) ;100 für 5 Zeilen
TextGadget(108, 10, ORand + 600, 100, 15, "Bewertung cp:")
TextGadget(109, 120, ORand + 600, 120, 15, Score$)
TextGadget(110, 10, ORand + 615, 100, 15, "Tiefe:")
TextGadget(111, 120, ORand + 615, 120, 15, Tiefe$)
TextGadget(112, 10, ORand + 630, 100, 15, "Zeit ms:")
TextGadget(113, 120, ORand + 630, 120, 15, Zeit$)
TextGadget(114, 10, ORand + 645, 100, 15, "Knoten:")
TextGadget(115, 120, ORand + 645, 120, 15, Knoten$)
TextGadget(116, 10, ORand + 660, 100, 15, "Knoten/s:")
TextGadget(117, 120, ORand + 660, 120, 15, Knoten_Sek$)
Hashfull$ = "0" ;Optik
TextGadget(118, 10, ORand + 675, 100, 15, "Hash voll " + Chr(8240) + ":") ;Chr(8240)=Promille
TextGadget(119, 120, ORand + 675, 120, 15, Hashfull$)
TB_Hits$ = "0" ;Optik
TextGadget(120, 10, ORand + 690, 100, 15, "TB-Treffer:")
TextGadget(121, 120, ORand + 690, 120, 15, TB_Hits$)
For i = 100 To 121
SetGadgetFont(i, Font1)
Next
For i = 100 To 120 Step 2
SetGadgetColor(i, #PB_Gadget_BackColor, BackColor)
Next
EditorGadget(122, 380, 10, 610, 360) ;das rechte Hauptfenster
Delay(10)
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, PID)
;Debug "FEN$: " + FEN$
;If IsCPUSet = 0
;Debug Bin(Cores)
If P_Cores
Delay(10) ;10
SetProcessAffinityMask_(hProcess, Cores)
EndIf
;IsCPUSet = 1
;CloseHandle_(hProcess)
;EndIf
;--------------------------------------------------------------------------------------------------
;Test Analyse von Grundstellung an, mit Zug-Ausführung
Repeat
WriteProgramStringN(Chessprog, "position fen " + FEN$, #PB_Ascii)
;WriteProgramStringN(Chessprog, "position startpos moves a2b3 ", #PB_Ascii) ;Test
WriteProgramStringN(Chessprog, "go infinite", #PB_Ascii)
;Debug "------------------------------------"
;==============================================================================
;Ausgabe-Werte für Hash und Tiefe 1 auslesen und anzeigen. Tiefe 1 um sicher zu sein, das gerechnet wird wegen setzen der CPU-Core-Affinity
;wenn Tiefe1=0, dann wurde Fish Matt gesetzt!
Repeat
If AvailableProgramOutput(Chessprog)
Ausgabe$ = ReadProgramString(Chessprog, #PB_Ascii)
;Debug Ausgabe$
HashWert = FindString(Ausgabe$, "hash set to ", 13, #PB_String_NoCase)
If HashWert
SetGadgetText(93, "Hash-Größe: " + Mid(Ausgabe$, HashWert + 12))
EndIf
Tiefe1 = FindString(Ausgabe$, "info depth", 1, #PB_String_NoCase) ;hier nur für Tiefe 1 "info depth" ist Zeichen dafür, das Berechnung läuft
If Tiefe1
Akt_Tiefe$ = Mid(Ausgabe$, 12, 3) ;muss "1" sein, trotzdem auslesen
Akt_Tiefe$ = RTrim(Akt_Tiefe$, "s") ;"s" von seldepth bei Suchtiefe < 10 oder score!
;Debug Akt_Tiefe$
;Debug "???????????????????"
SetGadgetText(101, Akt_Tiefe$)
If FindString(Ausgabe$, "se", 13) ;seldepth
AddGadgetItem(122, Zeile, Ausgabe$)
Zeile + 1
SetActiveGadget(122)
EndIf
Break
EndIf
EndIf
ForEver
;==============================================================================
;==============================================================================
;Ausgabe-Werte ab Tiefe 2
Repeat
If AvailableProgramOutput(Chessprog)
Ausgabe$ = ReadProgramString(Chessprog, #PB_Ascii)
;Debug Ausgabe$
If IsCPUSet = 0
If P_Cores
Delay(10) ;10
SetProcessAffinityMask_(hProcess, Cores)
EndIf
IsCPUSet = 1
CloseHandle_(hProcess)
EndIf
;evtl.Test auf "info" oder "info depth" oder " depth"
P_Ausgabe = 12 ;Pointer in Ausgabe$, 12=Stelle nach "info depth "
If FindString(Ausgabe$, "rmove ", 14, #PB_String_NoCase) ;"rmove" von "currmove ", oder kürzer
Akt_Tiefe$ = Mid(Ausgabe$, P_Ausgabe, 3) ;aktuelle Suchtiefe
Akt_Tiefe$ = RTrim(Akt_Tiefe$, "c") ;"c" von currmove bei Suchtiefe < 10
Akt_Tiefe$ = Trim(Akt_Tiefe$)
SetGadgetText(101, Akt_Tiefe$)
Curr_Move$ = Trim(Mid(Ausgabe$, P_Ausgabe + 12, 5)) ;war (P_Ausgabe + 11, 6) geändert wegen Tiefe >=100 5 für ep???? 6
SetGadgetText(103, Curr_Move$)
P_CMN = FindString(Ausgabe$, "er ", 14, #PB_String_NoCase) ;currmovenumber
If P_CMN
Curr_Move_Nr$ = Mid(Ausgabe$, P_CMN + 3, 3) ;Länge=3 geht hier wohl ohne weitere Maßnahmen
CMN = Val(Curr_Move_Nr$)
If CMN > CMN_Max
CMN_Max = CMN
EndIf
SetGadgetText(105, Curr_Move_Nr$ + "/" + Str(CMN_Max))
EndIf
Else
Tiefe$ = Mid(Ausgabe$, P_Ausgabe, 3)
Tiefe$ = RTrim(Tiefe$, "s") ;"s" von seldepth bei Suchtiefe < 10. Ist hier nicht die aktuelle Tiefe sondern Tiefe der Haupvariante
Tiefe$ = Trim(Tiefe$)
SetGadgetText(101, Tiefe$) ;Optik
SetGadgetText(103, "")
SetGadgetText(105, "")
P_Ausgabe + 6
ST = FindString(Ausgabe$, "pth ", P_Ausgabe, #PB_String_NoCase) ;"pth " von "seldepth ", oder kürzer
If ST
Sel_Tiefe$ = Mid(Ausgabe$, ST + 4, 3)
Sel_Tiefe$ = RTrim(Sel_Tiefe$, "m") ;"m" von multipv bei Suchtiefe < 10
Sel_Tiefe$ = Trim(Sel_Tiefe$)
EndIf
SetGadgetText(111, Tiefe$ + "/" + Sel_Tiefe$)
P_Ausgabe = ST + 6
T = FindString(Ausgabe$, "time ", P_Ausgabe, #PB_String_NoCase)
If T
TT = FindString(Ausgabe$, " ", T + 6) ;T+6=erstes Leerzeichen nach Ziffer, z.B. "time 5 "
Zeit$ = Mid(Ausgabe$, T + 5, TT - T - 5);5=Länge von "time "; erste Ziffer nach "time "
Zeit$ = Trim(Zeit$) ;erstmal drinlassen
Zeit$ = DeziPoint(Zeit$)
SetGadgetText(113, Zeit$)
P_Ausgabe = T + 6
EndIf
NPS = FindString(Ausgabe$, "nps ", P_Ausgabe, #PB_String_NoCase)
If NPS
TT = FindString(Ausgabe$, " ", NPS + 5) ;NPS+5=erstes Leerzeichen nach Ziffer, z.B. "nps 5 "
Knoten_Sek$ = Mid(Ausgabe$, NPS + 4, TT - NPS - 4) ;4=Länge von "nps "; erste Ziffer nach "nps "
Knoten_Sek$ = Trim(Knoten_Sek$) ;erstmal drinlassen
Knoten_Sek$ = DeziPoint(Knoten_Sek$)
SetGadgetText(117, Knoten_Sek$)
P_Ausgabe = NPS + 5
EndIf
Score = FindString(Ausgabe$, "cp ", P_Ausgabe + 6, #PB_String_NoCase) ;+6 von Länge "score "; cp=centipawn
If Score
TT = FindString(Ausgabe$, " ", Score + 4) ;CP+4=erstes Leerzeichen nach Ziffer, z.B. "cp 5 "
Score$ = Mid(Ausgabe$, Score + 3, TT - Score - 3) ;3=Länge von "cp "; erste Ziffer nach "cp "
Score$ = Trim(Score$) ;erstmal drinlassen
P_Ausgabe = Score + 4
Bound = FindString(Ausgabe$, " upp", P_Ausgabe, #PB_String_NoCase)
If Bound
Score$ + " upperbound"
P_Ausgabe = Bound + 11
EndIf
Bound = FindString(Ausgabe$, " low", P_Ausgabe, #PB_String_NoCase)
If Bound
Score$ + " lowerbound"
P_Ausgabe = Bound + 11
EndIf
SetGadgetText(109, Score$)
EndIf
Score = FindString(Ausgabe$, " ma", P_Ausgabe + 6, #PB_String_NoCase) ;+6 von Länge "score "; ma=mate
If Score
TT = FindString(Ausgabe$, " ", Score + 6) ;Score+6=erstes Leerzeichen nach Ziffer, z.B. "mate 5 "
Score$ = Mid(Ausgabe$, Score + 5, TT - Score - 5) ;5=Länge von "mate "; erste Ziffer nach "mate "
Score$ = Trim(Score$) ;erstmal drinlassen
SetGadgetText(109, "Matt in " + Score$)
P_Ausgabe = Score + 6
EndIf
Knoten = FindString(Ausgabe$, " nod", P_Ausgabe, #PB_String_NoCase) ;nod=nodes
If Knoten
TT = FindString(Ausgabe$, " ", Knoten + 7) ;Knoten+7=erstes Leerzeichen nach Ziffer, z.B. "nodes 5 "
Knoten$ = Mid(Ausgabe$, Knoten + 6, TT - Knoten - 6) ;6=Länge von "nodes "; erste Ziffer nach "nodes "
Knoten$ = Trim(Knoten$) ;erstmal drinlassen
Knoten$ = DeziPoint(Knoten$)
SetGadgetText(115, Knoten$)
P_Ausgabe = Knoten + 7
EndIf
Hashfull = FindString(Ausgabe$, "ll", 13, #PB_String_NoCase) ;"ll" von hashfull 13?
If Hashfull
Hashfull$ = Trim(Mid(Ausgabe$, Hashfull + 3, 3))
Hashfull$ = RTrim(Hashfull$, "t") ;"t" von tbhits bei hashfull < 10
SetGadgetText(119, Hashfull$)
EndIf
TBH = FindString(Ausgabe$, " tbh", P_Ausgabe, #PB_String_NoCase)
If TBH
TT = FindString(Ausgabe$, " ", TBH + 8) ;TBH+8=erstes Leerzeichen nach Ziffer, z.B. "tbhits 0 "
TB_Hits$ = Mid(Ausgabe$, TBH + 7, TT - TBH - 7) ;7=Länge von "tbhits "; erste Ziffer nach "tbhits "
TB_Hits$ = Trim(TB_Hits$) ;erstmal drinlassen
SetGadgetText(121, TB_Hits$)
P_Ausgabe = TBH + 8
EndIf
PV = FindString(Ausgabe$, " pv", 13, #PB_String_NoCase) ;Leerzeichen wegen "multipv"! pv=principal variation = Hauptvariante
If PV
PV$ = Trim(Mid(Ausgabe$, PV + 3))
SetGadgetText(107, PV$) ;ist EditorGadget
EndIf
If FindString(Ausgabe$, "se", 13, #PB_String_NoCase) ;seldepth
AddGadgetItem(122, Zeile, Ausgabe$)
Zeile + 1
SetActiveGadget(122)
; Debug Ausgabe$
EndIf
; If FindString(Ausgabe$, "best") ;bestmove, könnte hier für Matt genutzt werden!
; Break
; EndIf
EndIf ;FindString(Ausgabe$, "rmove ", 14)
EndIf ;AvailableProgramOutput(Chessprog)
;==============================================================================
;Maus-Abfrage und evtl. Programm-Ende
Event = WindowEvent();WaitWindowEvent(250)
If #PB_Event_Gadget
Select EventGadget()
Case 82 ;Brett drehen
Weiss_unten ! 1
Brettmal(40, 40, 20, ORand)
Finger()
Case 83 ;Zug zurück
If FEN_Strings_Pointer > 0
WriteProgramStringN(Chessprog, "stop", #PB_Ascii)
FEN_Strings_Pointer - 128
FEN$ = PeekS(FEN_Strings + FEN_Strings_Pointer, -1, #PB_Ascii)
WriteProgramStringN(Chessprog, "position fen " + FEN$, #PB_Ascii)
WriteProgramStringN(Chessprog, "go infinite", #PB_Ascii)
Restoring() ;z.B. Rochade-Recht bei Zug vor/zurück aktualisieren
Debug FEN$
FEN2Stellung()
Brettmal(40, 40, 20, ORand)
Finger()
EndIf
Case 84 ;Zug vor
If FEN_Strings_Pointer < FEN_Strings_Pointer_Max
WriteProgramStringN(Chessprog, "stop", #PB_Ascii)
FEN_Strings_Pointer + 128
FEN$ = PeekS(FEN_Strings + FEN_Strings_Pointer, -1, #PB_Ascii)
WriteProgramStringN(Chessprog, "position fen " + FEN$, #PB_Ascii)
WriteProgramStringN(Chessprog, "go infinite", #PB_Ascii)
Restoring() ;z.B. Rochade-Recht bei Zug vor/zurück aktualisieren
Debug FEN$
FEN2Stellung()
Brettmal(40, 40, 20, ORand)
Finger()
EndIf
Case 85 ;zurück zur Startstellung
WriteProgramStringN(Chessprog, "stop", #PB_Ascii)
;FEN_Strings_Pointer + 128
FEN$ = PeekS(FEN_Strings, -1, #PB_Ascii)
WriteProgramStringN(Chessprog, "position fen " + FEN$, #PB_Ascii)
WriteProgramStringN(Chessprog, "go infinite", #PB_Ascii)
Restoring() ;z.B. Rochade-Recht bei Zug vor/zurück aktualisieren
Debug FEN$
FEN2Stellung()
Brettmal(40, 40, 20, ORand)
Finger()
Case 86 ;vor zur Endstellung
WriteProgramStringN(Chessprog, "stop", #PB_Ascii)
;FEN_Strings_Pointer + 128
FEN$ = PeekS(FEN_Strings + FEN_Strings_Pointer_Max, -1, #PB_Ascii)
WriteProgramStringN(Chessprog, "position fen " + FEN$, #PB_Ascii)
WriteProgramStringN(Chessprog, "go infinite", #PB_Ascii)
Restoring() ;z.B. Rochade-Recht bei Zug vor/zurück aktualisieren
Debug FEN$
FEN2Stellung()
Brettmal(40, 40, 20, ORand)
Finger()
Case 87 ;Stellung ändern/anpassen
For i = 90 To 93
HideGadget(i, 1)
Next
If Teststellung
HideGadget(94, 1)
HideGadget(95, 1)
EndIf
HideGadget(122, 1) ;das rechte Hauptfenster verstecken
WriteProgramStringN(Chessprog, "stop", #PB_Ascii)
For i = 0 To 63
PokeB(?StellungEingabe + i, PeekB(?Stellung + i))
Next
Figur = PeekW(?Figuren) ;wB als Anfang
TextGadget(200, 400, 200, 70, 70, Chr(Figur), #PB_Text_Center)
SetGadgetFont(200, Font4)
CheckBoxGadget(202, 20, 400, 200, 15, "Weiss kleine Rochade")
CheckBoxGadget(203, 20, 420, 200, 15, "Weiss große Rochade")
CheckBoxGadget(204, 20, 440, 200, 15, "Schwarz kleine Rochade")
CheckBoxGadget(205, 20, 460, 200, 15, "Schwarz kleine Rochade")
OptionGadget(206, 20, 480, 200, 15, "Weiß am Zug")
OptionGadget(207, 20, 500, 200, 15, "Schwarz am Zug")
SetGadgetState(206, 1)
For i = 202 To 207
SetGadgetFont(i, Font1)
Next
SetWindowCallback(@wc()) ;aktivieren
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
If EventGadget() = 87
Break
EndIf
ForEver
SetWindowCallback(0) ;deaktivieren
For i = 0 To 63
PokeB(?Stellung + i, PeekB(?StellungEingabe + i)) ;umkopieren
Next
;Rochade$ = " " ;" KQkq"
;If GetGadgetState(102) = #PB_Checkbox_Checked
; Rochade$ + "K"
;EndIf
;If GetGadgetState(103) = #PB_Checkbox_Checked
; Rochade$ + "Q"
;EndIf
;If GetGadgetState(104) = #PB_Checkbox_Checked
; Rochade$ + "k"
;EndIf
;If GetGadgetState(105) = #PB_Checkbox_Checked
; Rochade$ + "q"
;EndIf
;If Rochade$ = " "
; Rochade$ = " -"
;EndIf
If GetGadgetState(206)
Farbe_am_Zug$ = " w"
Else
Farbe_am_Zug$ = " b"
EndIf
Finger()
FENString(?StellungEingabe)
WriteProgramStringN(Chessprog, "position fen " + FEN$, #PB_Ascii)
WriteProgramStringN(Chessprog, "go infinite", #PB_Ascii)
For i = 200 To 207
If IsGadget(i)
FreeGadget(i)
EndIf
Next
For i = 90 To 93
HideGadget(i, 0)
Next
If Teststellung
HideGadget(94, 0)
HideGadget(95, 0)
EndIf
HideGadget(122, 0) ;das rechte Hauptfenster wieder anzeigen
EndSelect
EndIf ;#PB_Event_Gadget
If Event = #PB_Event_LeftClick
MX = WindowMouseX(0)
MY = WindowMouseY(0)
If Weiss_unten = 0
MX = 360 - MX
MY = 400 - MY
EndIf
If MX >= 20 And MX <= 340
MX - 20
MX / 40
Maus_Linie = MX + 97 ;97="a"
If MY >= ORand And MY <= ORand + 320
MY - ORand
MY / 40
Maus_Reihe = 56 - MY ;56="8"
Pos = MX + (MY * 8) ;ist die Textgadget-Nr. und Zeiger in Stellung
;Debug "Pos " + Str(Pos)
;Debug "Figur " + Hex(PeekB(?Stellung+Pos))
If Maus_AFeld$ = ""
If GetGadgetText(Pos) <> Chr($20) ;Leerfeld kann nicht Ausgangs-Feld sein
If (PeekB(?Stellung + Pos) < $62 And Farbe_am_Zug$ = " w") Or (PeekB(?Stellung + Pos) > $61 And Farbe_am_Zug$ = " b") ;angefasste Figur muss von Farbe_am_Zug sein $62=b=schw.Bishop
Maus_AFeld$ = Chr(Maus_Linie) + Chr(Maus_Reihe)
;Debug Maus_AFeld$
Feld_Color = GetGadgetColor(Pos, #PB_Gadget_BackColor) ;"alte" Feldfarbe sichern für rückgängig
SetGadgetColor(Pos, #PB_Gadget_BackColor, $FF00F0)
EndIf
EndIf
Else
;If (PeekB(?Stellung + Pos) < $62 And Farbe_am_Zug$ = " w")
Maus_ZFeld$ = Chr(Maus_Linie) + Chr(Maus_Reihe)
;Debug Maus_ZFeld$
;Debug Pos
If Maus_ZFeld$ <> Maus_AFeld$ ;so kann angefangener Zug ungültig gemacht werden
Zug$ = Maus_AFeld$ + Maus_ZFeld$
Break ;Zug wird ausgeführt
Else
Maus_AFeld$ = "" ;wieder frei für nächsten Zug
SetGadgetColor(Pos, #PB_Gadget_BackColor, Feld_Color) ;"Versehen" wieder ausbügeln
EndIf
;EndIf
EndIf
EndIf
EndIf
ElseIf Event = #PB_Event_CloseWindow
KillProgram(Chessprog) ;muss vor Close!
CloseProgram(Chessprog)
End
EndIf ;#PB_Event_LeftClick
;==============================================================================
Delay(1)
ForEver ;Ausgabe-Werte ab Tiefe 2
;Debug Zug$
Zug()
Maus_AFeld$ = "" ;frei für nächste Zug
FENString(?Stellung)
;Debug FEN$
WriteProgramStringN(Chessprog, "stop", #PB_Ascii)
ForEver ;Zug wird oben an Programm übergeben
EndIf ;ProgramRunning(Chessprog)
EndIf ;hWnd
End
;==================================================================================================
Procedure FEN2Stellung() ;FEN in Stellung, es interessieren nur die 64 Felder!
j = 1
For i = 0 To 63
Feld = Asc(Mid(FEN$, j, 1))
Select Feld
Case 47 ;"/" wegen Korrektur und Default
i - 1 ;Korrektur
Case 49 To 56 ;1-8
For k = 1 To Feld - 48
PokeB(?Stellung + i, 32)
i + 1
Next
i - 1 ;Korrektur
Default
PokeB(?Stellung + i, Feld)
EndSelect
j + 1
Next
Farbe_am_Zug$ = Mid(FEN$, j, 2) ;hier mal drangehängt
Finger()
EndProcedure
Procedure Test2Stellung() ;wenn beide nicht dann automatisch Grundstellung
If FEN;PNG
ElseIf EPD
EndIf
EndProcedure
Procedure Zug() ;für Weiß und Schwarz
;Ausgangsfeld
LinieA$=Mid(Zug$, 1, 1)
ReiheA$=Mid(Zug$, 2, 1)
AFeld = Asc(LinieA$)+Asc(ReiheA$) + 8*(56-Asc(ReiheA$)) - (97+Asc(ReiheA$)) ;56=Asc("8"), 97=asc("a")
;Zielfeld
LinieZ$=Mid(Zug$, 3, 1)
ReiheZ$=Mid(Zug$, 4, 1)
ZFeld = Asc(LinieZ$)+Asc(ReiheZ$) + 8*(56-Asc(ReiheZ$)) - (97+Asc(ReiheZ$))
Inhalt_AFeld = PeekB(?Stellung + AFeld)
Inhalt_ZFeld = PeekB(?Stellung + ZFeld) ;auch für z.B.ep
If Inhalt_ZFeld > $20 Or Inhalt_AFeld = $50 Or Inhalt_AFeld = $70 ;irgendeine Figur geschlagen oder weisser oder schwarzer Bauer gezogen
Schlag_Bauer$ = " 0"
Schlag_Bauer = 0
Else
Schlag_Bauer + 1
Schlag_Bauer$ = " " + Str(Schlag_Bauer)
;Debug Schlag_Bauer$
EndIf
PokeB(?Stellung + ZFeld, PeekB(?Stellung + AFeld))
PokeB(?Stellung + AFeld, $20)
;---------------- Bauern-Umwandlung -----------
If Inhalt_AFeld = $50 And ZFeld < 8 ;Umwandlung weisser Bauer
PokeB(?Stellung + ZFeld, $3f) ;3f=? optischer Spaß mit Fragezeichen
Brettmal(40, 40, 20, ORand)
Umwandlung() ;liefert UFig
PokeB(?Stellung + ZFeld, UFig - $20) ;weil UFig in Kleinbuchstabe!
Zug$ + Chr(UFig)
EndIf
If Inhalt_AFeld = $70 And ZFeld > 55 ;Umwandlung schwarzer Bauer
PokeB(?Stellung + ZFeld, $3f) ;3f=? optischer Spaß mit Fragezeichen
Brettmal(40, 40, 20, ORand)
Umwandlung() ;liefert UFig
PokeB(?Stellung + ZFeld, UFig)
Zug$ + Chr(UFig)
EndIf
;---------------- EnPassant, der gegnerische Bauer muss weg!
If PeekB(?Stellung + ZFeld) = $50 ;=P=weisser Bauer hat gezogen
If LinieZ$ <> LinieA$ ;war also ein Schlagzug
If Inhalt_ZFeld = $20 ;wenn Leerfeld, dann schwarzen Bauer weg
PokeB(?Stellung + ZFeld + 8, $20)
Schlag_Bauer$ = " 0"
Schlag_Bauer = 0
EndIf
EndIf
EndIf
If PeekB(?Stellung + ZFeld) = $70 ;=p=schwarzer Bauer hat gezogen
If LinieZ$ <> LinieA$ ;war also ein Schlagzug
If Inhalt_ZFeld = $20 ;wenn Leerfeld, dann weissen Bauer weg
PokeB(?Stellung + ZFeld - 8, $20)
Schlag_Bauer$ = " 0"
Schlag_Bauer = 0
EndIf
EndIf
EndIf
;---------------- Rochaden --------------------
If GrossRochS And (AFeld = 0 Or AFeld = 4) ;A8 oder E8
Rochade$ = RemoveString(Rochade$, "q", #PB_String_CaseSensitive, 2, 1)
GrossRochS = 0 ;Rochade-Recht verloren
If Len(Rochade$) = 1
Rochade$ = " -"
EndIf
If Zug$ = "e8c8" ;war sogar Rochade, den Turm-Zug bei Rochade ausführen
PokeB(?Stellung, $20)
PokeB(?Stellung + 3, $72)
EndIf
EndIf
If KleinRochS And (AFeld = 7 Or AFeld = 4) ;H8 oder E8
Rochade$ = RemoveString(Rochade$, "k", #PB_String_CaseSensitive, 2, 1)
KleinRochS = 0 ;Rochade-Recht verloren
If Len(Rochade$) = 1
Rochade$ = " -"
EndIf
If Zug$ = "e8g8" ;war sogar Rochade, den Turm-Zug bei Rochade ausführen
PokeB(?Stellung + 7, $20)
PokeB(?Stellung + 5, $72)
EndIf
EndIf
If GrossRochW And (AFeld = 56 Or AFeld = 60) ;A1 oder E1
Rochade$ = RemoveString(Rochade$, "Q", #PB_String_CaseSensitive, 2, 1)
GrossRochW = 0 ;Rochade-Recht verloren
If Len(Rochade$) = 1
Rochade$ = " -"
EndIf
If Zug$ = "e1c1" ;war sogar Rochade, den Turm-Zug bei Rochade ausführen
PokeB(?Stellung + 56, $20)
PokeB(?Stellung + 59, $52)
EndIf
EndIf
If KleinRochW And (AFeld = 63 Or AFeld = 60) ;H1 oder E1
Rochade$ = RemoveString(Rochade$, "K", #PB_String_CaseSensitive, 2, 1)
KleinRochW = 0 ;Rochade-Recht verloren
If Len(Rochade$) = 1
Rochade$ = " -"
EndIf
If Zug$ = "e1g1" ;war sogar Rochade, den Turm-Zug bei Rochade ausführen
PokeB(?Stellung + 63, $20)
PokeB(?Stellung + 61, $52)
EndIf
EndIf
;----------------------------------------------
;---------------- EnPassant ------------------- es wird nur das Zielfeld angegeben, auch wenn kein gegnerischer Bauer in der Nähe ist
If (AFeld - ZFeld = 16) And (PeekB(?Stellung + ZFeld) = $50) ;=P=weisser Bauer, ZFeld auf Bauer testen, AFeld schon leer!
EP$ = Mid(Zug$, 4, 1) ;Ziel-Reihe
EP = Val(EP$) - 1
EnPassant$ = " " + Mid(Zug$, 3, 1) + Str(EP)
ElseIf (ZFeld - AFeld = 16) And (PeekB(?Stellung + ZFeld) = $70) ;=p=schwarzer Bauer
EP$ = Mid(Zug$, 4, 1) ;Ziel-Reihe
EP = Val(EP$) + 1
EnPassant$ = " " + Mid(Zug$, 3, 1) + Str(EP)
Else
EnPassant$ = " -"
EndIf
;----------------------------------------------
If Farbe_am_Zug$ = " w"
Farbe_am_Zug$ = " b" ;nicht s!!!
Else
Farbe_am_Zug$ = " w"
ZugNr + 1
ZugNr$ = " " + Str(ZugNr)
EndIf
Finger()
CMN_Max = 0 ;currmovenumber
Brettmal(40, 40, 20, ORand)
EndProcedure
Procedure FENString(AdrStellung) ;wird an Programm gesendet
;zuerst Stellung
Leer = 0
FEN$ = ""
For i = 0 To 63 ;64 Felder, 0=A8, 63=H1
F = PeekB(AdrStellung + i)
If F > $20 ;Figur
If Leer
FEN$ + Chr($30 + Leer)
Leer = 0
EndIf
FEN$ + Chr(F)
Else
Leer + 1
EndIf
If i > 0 And ((i + 1) % 8 = 0) ;nächste Reihe
If Leer
FEN$ + Chr($30 + Leer)
EndIf
If i < 56
FEN$ + "/"
EndIf
Leer = 0
EndIf
Next
;dann Farbe am Zug
FEN$ + Farbe_am_Zug$
;dann Rochade-Möglichkeiten usw.
FEN$ + Rochade$
FEN$ + EnPassant$
FEN$ + Schlag_Bauer$
FEN$ + ZugNr$
Debug FEN$
FEN_Strings_Pointer + 128
FEN_Strings_Pointer_Max = FEN_Strings_Pointer
Debug FEN_Strings
Debug FEN_Strings_Pointer
PokeS(FEN_Strings + FEN_Strings_Pointer, FEN$, -1, #PB_Ascii)
Debug PeekS(FEN_Strings + FEN_Strings_Pointer, -1, #PB_Ascii)
EndProcedure
Procedure Brettmal(Width, Height, StartPosX, StartPosY)
PosX = StartPosX
PosY = StartPosY
Feldfarbe = $ffffff ;Weiss
Restore Stellung
Restore Figuren
For i = 0 To 63 ;64 Felder
Feld = PeekB(?Stellung + i) & $FF
Select Feld
Case $70 ;p=schwarzer Bauer
Figur = PeekW(?Figuren + 12)
Case $6e ;n=schwarzer Springer
Figur = PeekW(?Figuren + 14)
Case $62 ;b=schwarzer Läufer
Figur = PeekW(?Figuren + 16)
Case $72 ;r=schwarzer Turm
Figur = PeekW(?Figuren + 18)
Case $71 ;q=schwarze Dame
Figur = PeekW(?Figuren + 20)
Case $6b ;k=schwarzer König
Figur = PeekW(?Figuren + 22)
Case $50 ;P=weisser Bauer
Figur = PeekW(?Figuren)
Case $4e ;N=weisser Springer
Figur = PeekW(?Figuren + 2)
Case $42 ;B=weisser Läufer
Figur = PeekW(?Figuren + 4)
Case $52 ;R=weisser Turm
Figur = PeekW(?Figuren + 6)
Case $51 ;Q=weisse Dame
Figur = PeekW(?Figuren + 8)
Case $4b ;K=weisser König
Figur = PeekW(?Figuren + 10)
Case $3f ;optischer Spaß mit Fragezeichen bei Bauern-Umwandlung
Figur = $3f
Default
Figur = $20 ;Leerfeld
EndSelect
If i > 0 And (i % 8 = 0)
PosX = StartPosX
PosY + Height
Feldfarbe ! ($ffffff - $cc99) ;Wechsel Weiss <-> Grün
EndIf
If Weiss_unten
TextGadget(i, PosX, PosY, Width, Height, Chr(Figur), #PB_Text_Center)
Else
TextGadget(i, 40 * 8 - PosX, 40 * 9 - PosY, Width, Height, Chr(Figur), #PB_Text_Center)
EndIf
SetGadgetColor(i, #PB_Gadget_BackColor, Feldfarbe) ;muss vor Font!!!
SetGadgetFont(i, Font0)
PosX + Width
Feldfarbe ! ($ffffff - $cc99) ;Wechsel Weiss <-> Grün
Next
;Brettbeschriftung
j = 0
For i = 1 To 8
If Weiss_unten
TextGadget(63 + i, 5, ORand + 295 - j, 12, 16, Str(i)) ;1-8
SetGadgetFont(63 + i, Font1)
TextGadget(71 + i, 35 + j, ORAnd + 320, 14, 16, Chr(64 + i)) ;A-H
SetGadgetFont(71 + i, Font1)
Else
TextGadget(72 - i, 5, ORand + 295 - j, 12, 16, Str(9 - i)) ;8-1
SetGadgetFont(72 - i, Font1)
TextGadget(80 - i, 35 + j, ORAnd + 320, 14, 16, Chr(73 - i)) ;H-A
SetGadgetFont(80 - i, Font1)
EndIf
j + 40
Next
; ;"Icons"
; TextGadget(80, 20, 10, 25, 25, Chr($2713), #PB_Text_Center) ;
; SetGadgetFont(80, Font2)
; SetGadgetColor(80, #PB_Gadget_BackColor, $ff00)
EndProcedure
Procedure Brettmal_Leer(Width, Height, StartPosX, StartPosY)
PosX = StartPosX
PosY = StartPosY
Feldfarbe = $ffffff ;Weiss
Restore Figuren
For i = 0 To 63 ;64 Felder
Figur = $20 ;Leerfeld
If i > 0 And (i % 8 = 0)
PosX = StartPosX
PosY + Height
Feldfarbe ! ($ffffff - $cc99) ;Wechsel Weiss <-> Grün
EndIf
TextGadget(i, PosX, PosY, Width, Height, Chr(Figur), #PB_Text_Center)
SetGadgetColor(i, #PB_Gadget_BackColor, Feldfarbe) ;muss vor Font!!!
SetGadgetFont(i, Font0)
PosX + Width
Feldfarbe ! ($ffffff - $cc99) ;Wechsel Weiss <-> Grün
Next
;Brettbeschriftung
j = 0
For i = 1 To 8
TextGadget(63 + i, 5, ORand + 295 - j, 12, 16, Str(i)) ;1-8
SetGadgetFont(63 + i, Font1)
TextGadget(71 + i, 35 + j, ORAnd + 320, 14, 16, Chr(i + 64)) ;A-H
SetGadgetFont(71 + i, Font1)
j + 40
Next
; ;"Icons"
; TextGadget(80, 20, 10, 25, 25, Chr($2713), #PB_Text_Center) ;
; SetGadgetFont(80, Font2)
; SetGadgetColor(80, #PB_Gadget_BackColor, $ff00)
EndProcedure