Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Parameterübergabe an externe .exe Datei
Gehe zu Seite Zurück  1, 2, 3, 4  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
ALWIM



Anmeldungsdatum: 08.08.2006
Beiträge: 1037
Wohnort: Niederbayern

BeitragVerfasst am: 09.11.2013, 03:13    Titel: Antworten mit Zitat

grindstone hat Folgendes geschrieben:
Entschuldigung, das hätte ich dazuschreiben sollen: Der angegebene Code ist kein funktionierender Ersatz für die Original-Function, sondern nur ein "quick and dirty" zusammengestellter Notbehelf, um die Startmeldung der Engine auslesen zu können. Im Augenblick ist z.B. jeder zurückgegebene String 10000 Zeichen lang. Sieh es dir am besten selbst an. Füge dazu die Zeilen
Code:
Dim As String g
Do
   WriteEngineInfo("uci")
   Sleep 1000
   g = ReadEngineInfo()
   Print Left(g,InStr(g,Chr(0))-1);
   Sleep
Loop
am Anfang der "gui.bas" zwischen "Using fb" und "ScreenRes 640,480,32" ein. Dann setze die Bildpuffergröße deines DOS-Fensters auf 250 Zeilen und kompiliere und starte die "gui.bas" als Konsolenprogramm.

Und dann mach dir in aller Ruhe Gedanken darüber, wie man diesen Datenwust bändigen kann. zwinkern

Die ursprüngliche "ReadEngineInfo()" gibt -soweit ich das beurteilen kann- immer nur die 5 Zeichen zurück, die auf das Wort "bestmove " folgen - oder eben ein "err". Wenn du eine vollständige normgerechte Kommunikation möchtest, mußt du also noch etwas Arbeit in die Neuprogrammierung der Funktion investieren. Das überlasse ich dir, da du dich mit dem uci - Protokoll wesentlich besser auskennen dürftest als ich (Schließlich wußte ich vor einer Woche nicht einmal, daß es sowas überhaupt gibt).

Gruß
grindstone

Bei mir funktioniert es irgendwie nicht! Ich sehe nichts?
Kenne mich mit dem UCI-Protokoll auch nicht besser aus. Ich wusste, dass es so ein UCI-Protokoll gibt! Aber mehr nicht!

Vielleicht bringe ich es hin? Aber so wie es momentan aussieht eher nicht.

Edit: Jetzt sehe ich die Startmeldung auch!

Gruß
ALWIM
_________________
SHELL SHUTDOWN -s -t 05
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 09.11.2013, 11:25    Titel: Antworten mit Zitat

So, ich glaube, jetzt hab ich's. Daumen rauf!

Unser russischer Kollege hat eine...nun ja...sagen wir mal...etwas eigenwillige Logik. mit dem Kopf durch die Mauer wollen

Ich habe aus der einen Function zwei gemacht. Die eine habe ich "GetEngineResponse" genannt, sie gibt alle Meldungen der Engine ungefiltert zurück. Hat die Engine nichts mitzuteilen, wird ein Leerstring zurückgegeben.

Die neue "ReadEngineInfo" bearbeitet die Meldungen der "GetEngineResponse" für die "gui.bas", so daß dort nichts geändert werden braucht. Mit den auskommentierten "Print"-Befehlen (ich hab sie mal dringelassen) kannst du bei Bedarf die Ausgaben der Engine aufzeichen, wenn du in der "gui.bas" eine entsprechende Datei öffnest.
Code:
Function ReadEngineInfo() As String
   Dim As String g, sRet
   
   Do   
      g = GetEngineResponse() 'request a message from the engine
      'Print #1,g
      If Len(g) Then 'the engine has sent a message
         If InStrRev(g,"bestmove") Then 'the engine has finished the calculating for this move
            sRet = Mid(g,InStrRev(g,"bestmove") + 9,5) 'isolate the data of the move
            'Print #1, ""
            'Print #1, "***RETURN ";sret;"***"
            'Print #1,""
            Return sRet 'send the move to the gui
         EndIf
      Else
         Return "err" 'in the case of any other message, send "err" to the gui
      EndIf
   Loop 'wait for any message from the engine (infinite loop)
End Function

Function GetEngineResponse() As String
   Dim As Integer iTotalBytesAvail, iNumberOfBytesWritten, iBytesToReturn
   Dim As String sBuf = ""
   
   Const As Integer MaxBytesToReturn = 4096 'maximum number of bytes to be returned at one call
      
   PeekNamedPipe(hReadPipe,NULL,NULL,NULL,@iTotalBytesAvail,NULL) 'find out if there's any data in the pipe
   
   If iTotalBytesAvail Then 'the pipe is not empty
      If iTotalBytesAvail < MaxBytesToReturn Then
         iBytesToReturn = iTotalBytesAvail 'set all available bytes to be read
      Else
         iBytesToReturn = MaxBytesToReturn 'set the first 4096 bytes to be read
      EndIf
      sBuf = String(iBytesToReturn,Chr(0)) 'set the length of the return string to the necessary value
      ReadFile(hReadPipe,StrPtr(sBuf),iBytesToReturn,@iNumberOfBytesWritten,NULL) 'read the specified amount of bytes from the pipe
   EndIf
   
   Return sBuf
End Function
Ich habe die Programmzeilen im Hinblick auf eine mögliche internationale Verbreitung mal auf Englisch kommentiert, ich hoffe, es ist nicht allzu holperig geworden.

EDIT: Ich habe die "ReadEngineInfo2" in"GetEngineResponse" umbenannt, das macht die Sache glaube ich verständlicher.

Viel Spaß damit.

Gruß
grindstone

Ach ja: Wenn das Programm irgendwann anfängt zu spinnen, während es gegen sich selber spielt, kannst du den Wert hinter dem "Sleep" - Befehl am Ende der "WriteEngineInfo" höher setzen.
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ALWIM



Anmeldungsdatum: 08.08.2006
Beiträge: 1037
Wohnort: Niederbayern

BeitragVerfasst am: 11.11.2013, 02:40    Titel: Antworten mit Zitat

Zitat:
Ich habe aus der einen Function zwei gemacht. Die eine habe ich "GetEngineResponse" genannt, sie gibt alle Meldungen der Engine ungefiltert zurück. Hat die Engine nichts mitzuteilen, wird ein Leerstring zurückgegeben.
Wenn ich versuche irgendwas auszulesen, kommt alles auf einmal? Den Namen der Schachengine kann ich auch nicht auslesen? Der wird bei
Code:
WRITEENGINEINFO("uci")
schachmotor = GETENGINERESPONSE()
LOCATE 15,15: PRINT schachmotor

mit angezeigt. Irgendwo in der Mitte.

Code:
WRITEENGINEINFO("id name")

zeigt was anderes an als
Code:
WRITEENGINEINFO("uci")


So ganz scheint das Ganze noch nicht zu funktionieren?
Muss ich mich selber nochmal damit beschäftigen! Hatte am Wochenende keine Zeit, da ich eine Turnierpartie im Schach spielen musste.

Gruß
ALWIM
_________________
SHELL SHUTDOWN -s -t 05
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 11.11.2013, 04:25    Titel: Antworten mit Zitat

Genau das meinte ich mit dem "Datenwust". Da mußt du die gewünschten Informationen eben aus der Antwort herausfiltern (nichts anderes macht übrigens die -alte wie neue- "ReadEngineInfo").

Bevor du noch vor Verzweiflung in die Tastatur beisst (das schmeckt nicht, ich habe es schon probiert zwinkern ), habe ich dir mal ein kleines Progrämmchen dafür geschrieben, das du bei Bedarf an deine Wünsche anpassen und/oder in dein eigenes Programm einbauen kannst:
Code:
#Include "connect_engine.bi"

Dim As String antwort, schluessel
Dim As Integer x

Declare Function filter(antwort As String, schluessel As String) As String

WriteEngineInfo("uci")
antwort = GetEngineResponse()

'komplette Antwort in Datei ausgeben (zur späteren Analyse)
Open "c:\schach.txt" For Output As #1
Print #1,antwort
Close

Print Left(antwort,InStr(antwort,Chr(13))) 'die erste Zeile der Antwort ausgeben
Print

'in der Antwort nach Schlüsselwörtern suchen, die die gewünschte Information kennzeichnen
Print filter(antwort,"id name ") 'Namen der Engine herausfiltern
Print filter(antwort,"id author ") 'Namen des Autors herausfiltern

Sleep

Function filter(antwort As String, schluessel As String) As String
   'Teilstring vom Ende des Schlüsselwortes bis zum Zeilenende herausfiltern und zurückgeben
   Dim As Integer x
   x = InStr(antwort,schluessel) + Len(schluessel)
   Return Mid(antwort, x, InStr(x,antwort,Chr(13)) - x)
End Function

Außerdem habe ich die "ReadEngineInfo" und "GetEngineResponse" noch einmal überarbeitet.
Code:
Function ReadEngineInfo() As String
   Dim As String g, sRet

   g = GetEngineResponse() 'request a message from the engine
   'Print #1,g
   If InStrRev(g,"bestmove") Then 'the engine has finished the calculating for this move
      sRet = Mid(g,InStrRev(g,"bestmove") + 9,5) 'isolate the data of the move
      'Print #1, ""
      'Print #1, "***RETURN ";sret;"***"
      'Print #1,""
      Return sRet 'send the move to the gui
   Else
      Return "err" 'in any other case send "err" to the gui
   EndIf

End Function

Function GetEngineResponse() As String
   Dim As Integer iTotalBytesAvail, iNumberOfBytesWritten, iBytesToRead
   Dim As String sRet = "", sBuf

   Const As Integer MaxBytesToRead = 4096 'maximum number of bytes to be read at one 'ReadFile'-operation

   Do
      sBuf = "" 'clear buffer
      PeekNamedPipe(hReadPipe,NULL,NULL,NULL,@iTotalBytesAvail,NULL) 'find out if there's any data in the pipe

      If iTotalBytesAvail Then 'pipe is not empty
         If iTotalBytesAvail < MaxBytesToRead Then
            iBytesToRead = iTotalBytesAvail 'set all available bytes to be read
         Else
            iBytesToRead = MaxBytesToRead 'set the first 4096 bytes to be read
         EndIf
         sBuf = String(iBytesToRead,Chr(0)) 'set the length of the buffer string to the necessary value
         ReadFile(hReadPipe,StrPtr(sBuf),iBytesToRead,@iNumberOfBytesWritten,NULL) 'read the specified amount of bytes from the pipe
         sRet += sBuf 'add the buffer to the return string
         Sleep 1
      Else 'pipe is empty
         Exit Do 'return
      EndIf
   Loop

   Return sRet
End Function
Die "GetEngineResponse" gibt jetzt immer die komplette Meldung der Engine zurück, und die "ReadEngineInfo" kann sich jetzt nicht mehr aufhängen, wenn die Engine nicht antwortet.

Darüberhinaus ist es nicht verwunderlich, daß du bei "uci" eine andere Rückmeldung bekommst als bei "id name", es sind ja schließlich auch zwei verschiedene Anweisungen.

Gruß
grindstone

EDIT Falls es dir weiterhilft, ich habe in er "gui.bas" zwei Fehler entdeckt:

    1. erkennt das Programm kein Remis, wenn nur noch die beiden Könige übrig sind (sie müssen dann einsam und verlassen bis in alle Ewigkeit über die Felder wandern traurig) und
    2. behält der Bauer bei der Bauernumwandlung sein Aussehen, verhält sich aber wie eine Dame (oder in was immer er sich dabei verwandelt).

_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ALWIM



Anmeldungsdatum: 08.08.2006
Beiträge: 1037
Wohnort: Niederbayern

BeitragVerfasst am: 12.11.2013, 02:42    Titel: Antworten mit Zitat

Es funktioniert zwar, aber ich frage mich nur, ob das Protokoll für UCI-Engines gedacht ist oder auch für Schach-Oberflächen? Wenn es für die Schach-GUI auch gedacht ist, müsste man doch mit "id name" den Namen der Schachengine auslesen können? Bei meinem Schachprogramm (Fritz 12) geht das nämlich auch! Da kann man sich den Namen der Schachengine und den Programmierer der jeweiligen Engine anzeigen lassen!

Bei der .bi Datei (siehe unten) ist mir aufgefallen, dass 2 Sätze die gleichen sind (CreatePipe). Wenn die Engine gegen sich selber spielt, reicht doch 1 Satz der 2 Sätze oder? Wenn es zwei unterschiedliche Engines sind müssten normalerweise die 2 Sätze unterschiedlich sein? Das ist das was mich so wundert!

Code:
If CreatePipe(@hReadChildPipe,@hWritePipe,@sa,0) = 0 Then
   MessageBox(0,"Fehler beim Erzeugen der Leitung 1","",MB_ICONERROR)
EndIf

If SetHandleInformation(hWritePipe,HANDLE_FLAG_INHERIT,0) = 0 Then
   MessageBox(0,"Îøèáêà óñòàíîâêè ïðàâà íå íàñëåäîâàíèÿ äåñêðèïòîðîâ äëÿ 1 ïàéïà","",MB_ICONERROR)
EndIf

If CreatePipe(@hReadPipe,@hWriteChildPipe,@sa,0) = 0 Then
   MessageBox(0,"Fehler beim Erzeugen der Leitung 2","",MB_ICONERROR)
EndIf

If SetHandleInformation(hReadPipe,HANDLE_FLAG_INHERIT,0) = 0 Then
   MessageBox(0,"Îøèáêà óñòàíîâêè ïðàâà íå íàñëåäîâàíèÿ äåñêðèïòîðîâ äëÿ 2 ïàéïà","",MB_ICONERROR)
EndIf


Sobald ich mal etwas mehr Zeit habe, werde ich ein wenig rumexperimentieren mit den vorhandenen Quellcodes!

Zitat:
Bevor du noch vor Verzweiflung in die Tastatur beisst (das schmeckt nicht, ich habe es schon probiert zwinkern )...

Man muss es vorher nur gut würzen, dann schmeckt es schon!!! lachen

Gruß
ALWIM
_________________
SHELL SHUTDOWN -s -t 05
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 12.11.2013, 03:59    Titel: Antworten mit Zitat

ALWIM hat Folgendes geschrieben:
ich frage mich nur, ob das Protokoll für UCI-Engines gedacht ist oder auch für Schach-Oberflächen
Das kann ich dir mangels eigener Kenntnis der Materie leider auch nicht beantworten. Die originale "connect_engine.bi" ist -in dieser Form- wohl ausschließlich zur Verbindung zwischen "gui" und "Fruit 2-3-1" gedacht. Darauf deutet auch der Sleep-Befehl am Ende von "WriteEngineInfo" hin, denn er dient -soweit ich es beurteilen kann- dazu, der GUI Zeit zur Darstellung des Zuges zu geben und gehört daher von der Logik her in die GUI und nicht in die "connect_engine". Vielleicht entspricht ja auch die Antwort der "Fruit-2-3-1" nicht dem UCI-Protokoll, denn es macht meiner Meinung nach wenig Sinn, den User mit einer derartigen Flut von Informationen zu überschütten - aber wie gesagt, ich weiß es nicht.

Klär mich mal auf: Geben andere Engines beim Befehl "uci" bzw. "id name" wirklich nur ihren Namen zurück?

[edit]
Nachdem ich mir die Mühe angetan habe, die UCI - Konventionen einmal komplett durchzulesen (meine Augen beginnen langsam eckig zu werden, ich bin müde und habe Hunger), muß ich mich korrigieren. Der "Datenwust", den die Engine zurückschickt, ist durchaus normgerecht. Es handelt sich dabei um eine komplette Auflistung aller engine-seitig möglichen Optionen, damit die GUI weiß, welche Fähigkeiten die Engine hat und welche nicht. Das zu analysieren und zu verwerten, z.B. für ein zur jeweiligen Engine passendes 'Setup'-Menü, ist Aufgabe der GUI.
"id name" als Befehl von der GUI an die Engine gibt es laut UCI - Protokoll überhaupt nicht (ich beziehe mich dabei auf die Angaben in dem von RockTheShock angegebenen Link), obwohl er offenbar funktioniert - sozusagen als Kurzform. Bei "id author" gibt es allerdings nur einen Leerstring als Antwort.
Aus deinen bisherigen Postings schließe ich, daß das UCI - Protokoll für dich genauso Neuland ist wie für mich. Also nochmal die Frage: Antworten die anderen Engines auf "uci" nur mit ihrem Namen oder kommt da auch noch ein ganzer "Rattenschwanz" dahinter? Denn laut Protokoll muß die letzte Zeile der Antwort "uciok" sein.
Und zu deiner Frage
Zitat:
ich frage mich nur, ob das Protokoll für UCI-Engines gedacht ist oder auch für Schach-Oberflächen
Das Protokoll ist für die Kommunikation zwischen UCI-Engines und Schach-Oberflächen gedacht.
[/edit]

Zitat:
...müsste man doch mit "id name" den Namen der Schachengine auslesen können?
Kann man auch. [edit] (obwohl man eigentlich nicht können dürfte, siehe oben) [/edit] Setz einfach in dem Ausleseprogramm aus meinem letzten post statt "uci" "id name" ein.
Die komplette Rückmeldung lautet dann:
    Fruit 2.3.1
    Lead Programmer: Fabien Letouzey
    Co-Programmer: Ryan Benitez
    Book Builder: Salvo Spitaleri
    Beta test team: Roger Brown
    Thorsten Czub
    Mircea Hrubaru
    Marc Lacrosse
    Omar Skulason
    Also thanks to: Joachim Rang
    Compiled by: Bryan Hofmann
Wenn du daraus den Teilstring bis zum ersten CR herausfilterst, hast du deinen Enginenamen.

Zitat:
...ist mir aufgefallen, dass 2 Sätze die gleichen sind (CreatePipe).
Das stimmt nicht, die Befehle haben unterschiedliche Parameter
    CreatePipe(@hReadChildPipe,@hWritePipe,@sa,0)
    CreatePipe(@hReadPipe,@hWriteChildPipe,@sa,0)
Das eine ist der Hin- das andere der Rückkanal. Mit "Child" ist dabei jeweils die "Fruit-2-3-1.exe" gemeint. Für zwei (verschiedene) Engines würden dann entsprechend vier Pipes benötigt.

Zitat:
Man muss es vorher nur gut würzen, dann schmeckt es schon!!!
vor lachen auf dem Boden rollen

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ALWIM



Anmeldungsdatum: 08.08.2006
Beiträge: 1037
Wohnort: Niederbayern

BeitragVerfasst am: 12.11.2013, 23:58    Titel: Antworten mit Zitat

Zitat:
Klär mich mal auf: Geben andere Engines beim Befehl "uci" bzw. "id name" wirklich nur ihren Namen zurück?

Bei Stockfish sieht man bei "id name" nur den Namen der Engine sowie die Programmierer. Bei UCI kommt dann eine Auflistung von "Option Name"!

Vermutlich ist "Option Name" eine Liste mit den verfügbaren Optionen die die Engine hat bzw. die man individuell einstellen kann! Ganz zum Schluss kommt immer das "uciok".

Wird dann schon so stimmen.

Zitat:
EDIT Falls es dir weiterhilft, ich habe in er "gui.bas" zwei Fehler entdeckt:
1. erkennt das Programm kein Remis, wenn nur noch die beiden Könige übrig sind (sie müssen dann einsam und verlassen bis in alle Ewigkeit über die Felder wandern traurig) und
2. behält der Bauer bei der Bauernumwandlung sein Aussehen, verhält sich aber wie eine Dame (oder in was immer er sich dabei verwandelt).

Das habe ich selber schon festgestellt! Eine UCI-Engine prüft nicht auf vorhandenes Material! Darum spielen die bei 2 Königen weiter! Das muss die Gui prüfen!!! Wird bzw. kann nur eine Dame sein! Offensichtlich ein Fehler der Gui! Die Schachengines funktionieren bei anderen Schachoberflächen korrekt!!!

Gruß
ALWIM
_________________
SHELL SHUTDOWN -s -t 05
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 13.11.2013, 12:21    Titel: Antworten mit Zitat

ALWIM hat Folgendes geschrieben:
Bei Stockfish sieht man bei "id name" nur den Namen der Engine sowie die Programmierer.
Das ist leider nicht ganz korrekt (ich habe das inzwischen einmal selbst nachgeprüft). Die komplette Meldung von Stockfish auf "id name" lautet:
    Stockfish 4 by Tord Romstad, Marco Costalba and Joona Kiiski
    Unknown command: id name

und -ich habe ein wenig herumprobiert- eine entsprechende Meldung kommt bei jedem unbekannten Kommando - was auch nicht normgerecht ist, denn laut UCI - Protokoll muß die Engine ein unbekanntes Kommando ignorieren.

Zitat:
Vermutlich ist "Option Name" eine Liste mit den verfügbaren Optionen die die Engine hat bzw. die man individuell einstellen kann!
Das ist richtig. Ich habe mich gestern durch die Beschreibung des UCI-Protokolls gequält, so daß ich dazu heute hemmungslos klugscheißen kann. zwinkern
Eigentlich ist die Aufschlüsselung ganz einfach. Nehmen wir mal die erste "option" - Zeile von Stockfish:
    option name Write Debug Log type check default false
Die Zeile beginnt mit "option name", darauf folgt der Name der Option (genauer gesagt der Variablen), in diesem Fall "Write Debug Log".
Danach kommt das Schlüsselwort "type", gefolgt vom Datentyp der Option, in diesem Fall "check". Optionen vom Typ "check" können einen von zwei Werten annehmen, nämlich "true" oder "false" (entspricht "boolean").
Am Schluß der Zeile wird der Defaultwert der Option angegeben, nämlich "false".
Das heißt, im Setupmenü der GUI wird diese Option mit einer Checkbox versehen (daher die Typenbezeichnung "check"), deren Häkchen standardmäßig nicht gesetzt ist ("false").
Neben "check" gibt es noch die Typen "string" (entspricht einem Textfeld bzw. einer String-Variablen), "spin" (entspricht einer Integer-Variablen), "combo" (entspricht einer Combo-box mit einer bestimmten Anzahl vordefinierter Strings) und "button" (kennzeichnet ein bloßes Kommando ohne zugeordneten Wert).
Bei allen Typen außer "button" gibt es das Schlüsselwort "default" fur den voreingestellten Wert beim Programmstart, bei "spin" zusätzlich noch die Schlüsselwörter "min" und "max" für den Mindest- und Höchstwert.
Außerdem gibt es noch das Schlüsselwort "var" für einen festen Wert.

Entsprechend wäre also z.B.
    option name Book File type string default book.bin
der Filename der Eröffnungsbibliothek und
    option name Skill Level type spin default 20 min 0 max 20
die Einstellung der Spielstärke zwischen 0 und 20 mit Voreinstellung "volles Rohr".

Ich finde die Idee einer Engine-vs.-Engine-GUI absolut faszinierend (vielleicht entsteht daraus ja irgendwann einmal ein richtiger Wettbewerb mit Weltrangliste o.ä.), aber wenn du wirklich vorhast, so etwas zu schreiben, wirst du wohl nicht umhinkommen, dich eingehend mit den Konventionen des UCI-Protokolls zu beschäftigen.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ALWIM



Anmeldungsdatum: 08.08.2006
Beiträge: 1037
Wohnort: Niederbayern

BeitragVerfasst am: 15.11.2013, 03:33    Titel: Antworten mit Zitat

Eine Sache die mir Kopfzerbrechen bereitet:

Code:
WriteEngineInfo("go depth 10")
move = ReadEngineInfo()

Damit erhalte ich ja Informationen der Schachengine!
Bloß wie unterscheide ich zwischen Engine 1 und Engine 2?
Irgendwie, lässt sich der vorhandene Quellcode nicht auf 2 verschiedene Engines anwenden? Wahrscheinlich weiß ich im Moment nicht wie man das schreiben muss, damit 2 verschiedene Engines gegeneinander spielen. Ich stehe etwas auf dem Schlauch?

Meine Idee wäre im Moment: Die andere Engine nach dem erfolgtem Zug zu laden? Die erste Engine schließen? Ich hab im Moment echt noch keine Ahnung wie ich das am besten realisiere!

Ich habe eventuell schon vor, so ein Programm zu schreiben!
Vielleicht sogar Mensch gegen Engine? Das weiß ich noch nicht.
Die Idee, die ich ursprünglich vor hatte, wird nicht so einfach zum programmieren sein, falls es überhaupt geht?

4-5 Rechner/PCs! Auf jedem der PCs läuft eine Schachpartie (Engine - Engine). Gestartet auf einem Rechner!

Gruß
ALWIM
_________________
SHELL SHUTDOWN -s -t 05
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 15.11.2013, 10:37    Titel: Antworten mit Zitat

Wie wäre es, wenn du einfach zwei Paare von hReadChildPipe- hWritePipe-Handles anlegst und somit zu jedem Programm eine eigene Pipe öffnest? Aber dazu müsstest du ja den kopierten Code verstehen, und das wäre ja Arbeit...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 15.11.2013, 13:33    Titel: Antworten mit Zitat

Langsam wird die Sache interessant. lächeln

Zunächst einige grundsätzliche Gedanken: GUIs sind wohl üblicherweise dafür gedacht (und programmiert) einen menschlichen Spieler gegen eine Schachengine spielen zu lassen. Etliche GUIs dürften auch noch einen Demo-Modus haben, bei dem die Engine qasi gegen sich selbst spielt, aber dabei dürfte es sich immer um eine Engine handeln.

Um jetzt zwei verschiedene Engines (wettkampfmäßig) gegeneinander antreten zu lassen, sind mehrere Konzepte denkbar, die jeweils ihre Vor- und Nachteile haben.

Zunächst einmal eine GUI mit zwei Engines auf einem Rechner: Hier muß die GUI neben der Kommunikation zwischen den Engines dafür sorgen, daß die Rechenleistung gerecht verteilt wird. Solange die jeweilige Engine nur rechnet, solange sie am Zug ist, ist das einfach. Mit "go movetime 10000" teilt die GUI der Engine z.B. exakt 10 Sekunden Rechenzeit zu, danach stoppt die Engine und meldet den bis dahin besten Zug zurück. Schwieriger wird es, wenn die Engines im Pondermodus laufen, also auch weiterrechnen, während sie warten und sich damit gegenseitig die CPU-Leistung streitig machen.

Dann wäre es denkbar, zwei Engines mit jeweils einer eigenen GUI auf einem Rechner laufen zu lassen. Dabei wäre dann jede GUI nur für eine Engine zuständig, und jede GUI würde statt mit dem menschlichen Gegner mit der jeweils anderen GUI kommunizieren. Dafür müsste man dann ein Interface programmieren und sich ein entsprechendes Kommunikationsprotokoll ausdenken.

Richtig interessant wird es, wenn das Ganze auf mehrere Rechner verteilt wird. Ich erspare mir jetzt mal die Aufzählung aller möglichen Konstellationen und beschränke mich auf die, die mir am sinnvollsten erscheint: Jede Engine hat einen Rechner für sich und die GUI ist auf einem dritten Rechner installiert, der dann auch die optische Darstellung übernimmt.

Zum Entwickeln ist wohl erst einmal die erste Variante am geeignetsten. Sobald die Kommunikation zwischen den einzelnen Komponenten funktioniert, kann man sie dann auslagern.

Zitat:
Bloß wie unterscheide ich zwischen Engine 1 und Engine 2?
Die GUI muß jede Engine gezielt ansprechen.

Zitat:
Irgendwie, lässt sich der vorhandene Quellcode nicht auf 2 verschiedene Engines anwenden?
Nein, man muß ihn entsprechend umprogrammieren.

Zitat:
Die andere Engine nach dem erfolgtem Zug zu laden? Die erste Engine schließen?
Möglich, aber (zu) umständlich. Man müsste ja jeder Engine vor jedem Zug erst einmal per fen-String die Stellung der Figuren mitteilen.

Zitat:
Vielleicht sogar Mensch gegen Engine?
verwundert Das ist doch die übliche Anwendung einer GUI + Engine.

Zitat:
Die Idee, die ich ursprünglich vor hatte, wird nicht so einfach zum programmieren sein, falls es überhaupt geht?
Nur nicht aufgeben! Zunächst solltest du dich ein wenig mit der WinAPI - Programmierung befassen, und das UCI - Protokoll solltest du auch einmal gründlich durcharbeiten. Mit dem kleinen Analyseprogramm aus meinem Posting vom 3.10. kannst du dir die Reaktion der Engine auf jede beliebige Anweisung in Ruhe ansehen.

Gruß
grindstone

EDIT: @ALWIM: Ich bin geneigt, Jojo recht zu geben. Das Aneignen von notwendigem Hintergrundwissen scheint nicht so wirklich dein Ding zu sein.
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 16.11.2013, 10:28    Titel: Antworten mit Zitat

@ alle, die es interessiert:

Ich habe eine "quick and dirty" - Version einer Engine vs. Engine - GUI nebst "connect_engines.bi" auf Basis der "gui.bas" bzw. "connect_engine.bi" unseres russischen Kollegen, dessen Namen ich immer noch nicht kenne, unter
http://www.freebasic-portal.de/porticula/chessguienginevsengine-1664.html und
http://www.freebasic-portal.de/porticula/connectengines-bi-1665.html auf NoPaste hochgeladen.
Sie lässt die "Fruit-2-3-1" gegen die "stockfish_4_32bit" (zu finden hier) spielen. Die Engines müssen sich im selben Vereichnis befinden wie die GUI.
Das Programm ist weder ausgereift noch bedienerfreundlich, aber im Prinzip funktioniert es.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Roland Chastain



Anmeldungsdatum: 05.12.2011
Beiträge: 192
Wohnort: Frankreich

BeitragVerfasst am: 16.11.2013, 17:07    Titel: Antworten mit Zitat

Sehr interessant !

grindstone hat Folgendes geschrieben:
[...] unseres russischen Kollegen, dessen Namen ich immer noch nicht kenne [...]


Er heißt Stanislav Budinov, alias "VANYA" (siehe hier).

"BasicCoder2" hat die Figuren gemacht (siehe hier).
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
ALWIM



Anmeldungsdatum: 08.08.2006
Beiträge: 1037
Wohnort: Niederbayern

BeitragVerfasst am: 16.11.2013, 19:20    Titel: Antworten mit Zitat

grindstone hat Folgendes geschrieben:
@ alle, die es interessiert:

Ich habe eine "quick and dirty" - Version einer Engine vs. Engine - GUI nebst "connect_engines.bi" auf Basis der "gui.bas" bzw. "connect_engine.bi" unseres russischen Kollegen, dessen Namen ich immer noch nicht kenne, unter
http://www.freebasic-portal.de/porticula/chessguienginevsengine-1664.html und
http://www.freebasic-portal.de/porticula/connectengines-bi-1665.html auf NoPaste hochgeladen.
Sie lässt die "Fruit-2-3-1" gegen die "stockfish_4_32bit" (zu finden hier) spielen. Die Engines müssen sich im selben Vereichnis befinden wie die GUI.
Das Programm ist weder ausgereift noch bedienerfreundlich, aber im Prinzip funktioniert es.

Gruß
grindstone

Im Grunde genommen, ist es so einfach! Eigentlich hätte ich selber drauf kommen können! Mir war es dann schon klar, dass ich die Funktion 2x brauche mit unterschiedlichen Namen. Wusste aber nicht, wie ich das dann in der Gui realisiere! Jetzt weiß ich es! Mal schauen was draus wird! Es ist aber immer noch ein Fehler drin! Welcher es ist, verrate ich nicht! Ihr kommt ja sowie so drauf. Vielleicht wisst ihr ihn schon? Stockfish ist eine der Top Schachmotoren die es gratis zum Download gibt!

Die besten sind:
Houdini 4, Deep Rybka 4.1, Stockfish 4, Deep Fritz 14, Deep Shredder, Deep Hiarcs

Ich werde auf jeden Fall was draus machen, nachdem ich jetzt weiß wie!
Die Frage ist nur wann? Habe im Moment wenig Zeit! Schach geht vor!
_________________
SHELL SHUTDOWN -s -t 05
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 17.11.2013, 03:35    Titel: Antworten mit Zitat

@Roland Chastain: Vielen Dank für die Information (war ja schon peinlich).

@ALWIM:
Zitat:
Im Grunde genommen, ist es so einfach!
Wenn man weiß, wie es geht, ist es immer einfach. zwinkern
Zitat:
Wusste aber nicht, wie ich das dann in der Gui realisiere!
Einfach reinschreiben.
Zitat:
Es ist aber immer noch ein Fehler drin!


Es sind noch etliche Fehler drin (ich sagte ja: "quick and dirty")

  • fehlerhafte Darstellung der Rochade
  • fehlerhaftes Timing bei größeren Rechentiefen
  • Nichterkennung von Remis
  • Nichterkennung von Zugwiederholung
  • das Schachbrett steht auf dem Kopf (mit korrekten Koordinaten 1 - 8 )
  • die Koordinaten A - H des Schachbretts sind gespiegelt
  • Die Blöcke "*** ENGINE BLACK ***" und "*** ENGINE WHITE***" müssen vertauscht werden (mein Fehler, ich nehme an, das meintest du)

Einige der Fehler (Koordinaten, vertauschte Engines) habe ich behoben und als chess_gui_engine_vs_engine_0.2 hochgeladen (gibt es eigentlich keine Möglichkeit, vorhandenen Programmcode auf NoPaste zu editieren?). Außerdem habe ich die Schriftfarbe auf schwarz geändert, was die Lesbarkeit deutlich verbessert.
Was die Koordinaten betrifft, hatte Kollege VANYA im "Data" - Block "boardLayout" die schwarzen und weißen Figuren vertauscht und anschließend das ganze Programm an diesen Fehler angepasst. Ich hoffe, jetzt ist -zumindest in dieser Beziehung- alles korrekt.
Zitat:
Schach geht vor!

Na dann: viel Spaß beim Schachern! lächeln

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 17.11.2013, 13:42    Titel: Quelltext-Versionen im NoPaste Antworten mit Zitat

Hallo!
grindstone hat Folgendes geschrieben:
gibt es eigentlich keine Möglichkeit, vorhandenen Programmcode auf NoPaste zu editieren?

Es gibt für mehrere IDEs Plugins, über die man seine NoPaste-Einträge verwalten und bearbeiten kann. Über das Web-Interface ist momentan leider keine Bearbeitung vorgesehen.

Das Konzept der Rubrik "NoPaste" beim Portal ist aber auch eher, dass man für eine neue/korrigierte Version eines Quelltexts einfach einen neuen Eintrag postet. Da sich Kommentare und Diskussionen im Forum ja auch auf einen bestimmten Entwicklungsstand des Quelltexts beziehen, wäre es ja schon sinnvoll, diesen Stand weiter aufzubewahren, damit man nachher beim Lesen weiß, worauf sich z. B. eine Problembeschreibung bezieht. Im NoPaste kann also nach Belieben neu gepostet werden.

Wenn du eine neue Version von einem Quelltext erarbeitet hast, würd ich einfach einen neuen Eintrag posten (ggf. mit Versionsangabe wie z. B. 1.0.4 im Titel zur Unterscheidbarkeit) und den neuen Link hier im Forum posten (oder hinzu-editieren). lächeln

Viele Grüße!
Sebastian
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 18.11.2013, 12:37    Titel: Antworten mit Zitat

Sebastian hat Folgendes geschrieben:
...einfach einen neuen Eintrag posten ... und den neuen Link hier im Forum posten
In Ordnung, werde ich machen. Ich wollte mich nur nicht dem Vorwurf aussetzen, mit halbfertigen Programmen die Rubrik zuzumüllen.

Also hier gleich die Version 0.3 der engine_vs_engine.
Die Rochade wird jetzt korrekt dargestellt, ebenso die Bauernumwandlung, und längere Rechenzeiten sind auch kein Problem mehr. Es lässt sich jetzt wahlweise -wenn auch noch etwas unkomfortabel- die Rechentiefe oder die Rechenzeit vorgeben, und die Tätigkeit der Engines wird in einer Protokolldatei aufgezeichnet. Außerdem habe ich den ganzen Code etwas aufgeräumt und die "connect_engines" in das Programm integriert, so daß jetzt nur noch ein Programm heruntergeladen werden muß.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 21.11.2013, 11:39    Titel: Antworten mit Zitat

Hier die neueste Version der engine_vs_engine. Sie hat noch etliche Macken (z.B. keine Remis-Erkennung, und die Protokollierung ist auch nicht fehlerfrei), aber man kann schon zwei Engines endlos gegeneinander spielen lassen (mit Seitenwechsel nach jeder Partie).

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ALWIM



Anmeldungsdatum: 08.08.2006
Beiträge: 1037
Wohnort: Niederbayern

BeitragVerfasst am: 22.11.2013, 00:53    Titel: Antworten mit Zitat

@grindstone:

Noch ein kleiner Hinweis: Man kann das Programm nicht beenden, wenn es mal läuft!

Ich habe bereits das Problem gefunden:

Code:
While btn<>1
      Getmouse mx,my,,btn
      ' IF MULTIKEY(&h01) THEN END  ' Programm mit ESC-Taste beenden!
      ' IF taste = Chr(255, 107) THEN END
      SLEEP 10
   Wend


Diese eine Schleife sorgt dafür, dass man das Programm nicht beenden kann! Zur Behebung habe ich in meinem (noch unfertigen) Programm eine Abfrage mit eingebaut! Nur habe ich noch keine Lösung gefunden, um das Programm mit einem Mausklick auf das X zu beenden.

Die Figur wird jetzt umgewandelt, aber irgendwie schon bevor der Bauer zieht?

Bauer kann auf die Grundlinie ziehen, wird aber schon vorher als Dame angezeigt. Also zieht praktisch eine Dame auf die Grundlinie. Der Bauer wird vorher schon in eine Dame umgewandelt.

Für das Problem mit dem Remis habe ich bereits eine Idee!

3-fache Stellungswiederholung: Jede Schachstellung aufzeichnen und abfragen, wie oft jede Stellung schon vorhanden war! Sobald eine zum 3. Mal vorhanden war, Remis geben.

50-Züge-Regel: Variable immer eins hochzählen lassen. Sobald ein Bauer bewegt wurde oder eine Figur geschlagen wurde, die Variable sofort wieder zurücksetzen.

75-Züge-Regel genauso wie bei der 50-Züge-Regel!
5-fache-Stellungswiederholung genauso wie bei der 3-fachen-Stellungswiederholung!

Gruß
ALWIM
_________________
SHELL SHUTDOWN -s -t 05
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 22.11.2013, 01:07    Titel: Schließen-Button des Fensters über INKEY abfragen Antworten mit Zitat

ALWIM hat Folgendes geschrieben:
Nur habe ich noch keine Lösung gefunden, um das Programm mit einem Mausklick auf das X zu beenden.


Ein Klick auf das X ("Schließen-Knopf") wird als Tastenkombination an das Programm vermeldet und kann über die INKEY-Funktion erkannt werden. Siehe dazu: FreeBASIC-FAQ: Wie kann ich prüfen, ob Pfeiltasten / ESC / Enter / der Schließen-Knopf des Fensters gedrückt wurde?

In deinem Programm-Ausschnitt taucht die Variable taste auf. Hier muss natürlich sichergestellt sein, dass diese Variable vorher funktionstüchtig mit einem abgefragten Wert von INKEY belegt wird, damit das einen Sinn hat. Zudem ist die Zeile auskommentiert.

Wenn ich grindstones Code auf die Schnelle richtig überflogen habe, prüft er auf ESC-Tastendruck als Abbruchbedingung.
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite Zurück  1, 2, 3, 4  Weiter
Seite 2 von 4

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz