and here is the latest "unstable" version of the script : import std/[streams, os, osproc, strutils, strformat] import owlkettle viewable App: buffer: TextBuffer monospace: bool = false cursorVisible: bool = true editable: bool = true acceptsTab: bool = true indent: int = 0 sensitive: bool = true sizeRequest: tuple[x, y: int] = (-1, -1) tooltip: string = "" var MS = 1 # sleep [#] MilliSeconds var DP = 18 # eval DePth var TFecho = true #var TFecho = false when compileOption("threads"): var thread: Thread[AppState] proc chgBuffer(app: AppState, s: string) = var abt = "" var s2 = "" if TFecho: echo s try: abt = app.buffer.text except Exception as e: var error = getCurrentException() echo "*** ERROR ABT 1" try: s2 = abt & s & "\n" app.buffer.text = s2 #app.buffer.text = s & "\n" #app.buffer.text = app.buffer.text & s & "\n" except Exception as e: var error = getCurrentException() echo "*** ERROR ABT 2" sleep(500) try: app.redrawFromThread() except Exception as e: var error = getCurrentException() echo "*** ERROR ABT 3" sleep(500) #discard proc threadProc(app: AppState) {.thread.} = #let process = startProcess( "./examples/widgets/", args = [], options = { poInteractive, poUsePath } ) let process = startProcess( "./examples/widgets/Clubfoot_1.0.8e3b4da_compiled_HP", args = [], options = { poInteractive, poUsePath } ) #let process = startProcess( "./examples/widgets/amoeba_v3.4_compiled_fast", args = [], options = { poInteractive, poUsePath } ) #let process = startProcess( "./examples/widgets/camel_v1.2.0-PR90-compiled_HP", args = [], options = { poInteractive, poUsePath } ) # ??? let (fromP, toP) = ( process.outputStream , process.inputStream ) var s = "" var TF = false proc mySleep() = sleep(MS) #discard toP.write("uci\n") # returns "uciok" toP.flush s = fromP.readLine # should return "uciok" mySleep() chgBuffer(app,s) TF = true while TF: s = fromP.readLine if not isNil(s) and len(s.strip()) > 0: mySleep() else: echo "*** CONTINUE A" continue chgBuffer(app, "-=> " & s) if s == "uciok": toP.write("ucinewgame\n") # returns nothing toP.flush mySleep() chgBuffer(app,"<=- ucinewgame") toP.write("isready\n") # returns "readyok" toP.flush mySleep() chgBuffer(app,"<=- isready") s = fromP.readLine if not isNil(s) and len(s.strip()) > 0: mySleep() else: echo "*** CONTINUE B" continue # should be "readyok" chgBuffer(app,"-=> " & s) toP.write("position fen 3B4/1r2p3/r2p1p2/bkp1P1p1/1p1P1PPp/p1P1K2P/PPB5/8 w - - 1 1\n") # returns nothing toP.flush mySleep() chgBuffer(app,"<=- position fen 3B4/1r2p3/r2p1p2/bkp1P1p1/1p1P1PPp/p1P1K2P/PPB5/8 w - - 1 1") toP.write("isready\n") # returns "readyok" toP.flush mySleep() chgBuffer(app,"<=- isready") s = fromP.readLine if not isNil(s) and len(s.strip()) > 0: mySleep() else: echo "*** CONTINUE C" continue # should be "readyok" chgBuffer(app,"-=> " & s) # returns a lot of info lines, ending with "bestmove [...]" toP.write(&"go depth {DP}\n") # NOTE: using fmt"..." does NOT work here !? : use the '&' syntax.. toP.flush mySleep() chgBuffer(app, fmt"<=- go depth {DP}") elif s == "readyok": try: chgBuffer(app,"<=- readyok") except Exception as e: echo "FAILED READYOK ***********************" elif s.startsWith("bestmove"): TF = false # this will be the last echoed line # this example script ends here, # but we could input other UCI commands now (keeping TF true) #sleep(1000) toP.write("quit\n") toP.flush mySleep() echo "<=- quit" discard process.waitForExit process.close echo "MSG : process closed" method view(app: AppState): Widget = result = gui: Window: title = "*** TEST ***" defaultSize = (1100, 600) HeaderBar {.addTitlebar.}: Button {.addLeft.}: style = [ButtonFlat] text = "GO" proc clicked() = when compileOption("threads"): createThread(thread, threadProc, app) ScrolledWindow: TextView: margin = 12 buffer = app.buffer monospace = app.monospace cursorVisible = app.cursorVisible editable = app.editable acceptsTab = app.acceptsTab indent = app.indent sensitive = app.sensitive tooltip = app.tooltip sizeRequest = app.sizeRequest proc changed() = discard #when compileOption("threads") and (defined(gcOrc) or defined(gcArc)): #when compileOption("threads") and defined(mmArc): when compileOption("threads"): let buffer = newTextBuffer() buffer.text = "first text line\n" brew(gui(App(buffer = buffer))) else: #quit "Compile with --threads:on and --gc:orc to enable threads" # ORG quit "Compile with --threads:on and --mm:arc to enable threads" Run
which, can output something like this (when all goes well) .. it takes about 1 minute before "bestmove" comes (and i then quit the script by Ctrl-C) : ~/Compiled/owlkettle-main-v2.2.0$ ./examples/widgets/uci_v3 -=> uciok -=> id author Richard Delorme -=> option name Ponder type check default false -=> option name Hash type spin default 64 min 1 max 1048576 -=> option name Clear Hash type button -=> option name Threads type spin default 1 min 1 max 256 -=> option name MultiPV type spin default 1 min 1 max 256 -=> option name UCI_AnalyseMode type check default false -=> option name Affinity type string default 0:0 -=> uciok <=- ucinewgame <=- isready -=> readyok <=- position fen 3B4/1r2p3/r2p1p2/bkp1P1p1/1p1P1PPp/p1P1K2P/PPB5/8 w - - 1 1 <=- isready -=> readyok <=- go depth 18 -=> info depth 1 seldepth 20 score cp -434 time 7 nodes 13226 nps 1762926 pv c2d3 c5c4 -=> info depth 2 seldepth 21 score cp -257 time 13 nodes 21768 nps 1569385 pv c3c4 b5c4 c2d3 c4d5 -=> info depth 3 seldepth 5 score cp -257 time 14 nodes 22187 nps 1561420 pv c3c4 b5c4 c2d3 c4d5 d3a6 -=> info depth 4 seldepth 7 score cp -257 time 14 nodes 22386 nps 1556204 pv c3c4 b5c4 c2d3 c4d5 d3a6 c5d4 e3d3 -=> info depth 5 seldepth 17 score cp -236 time 15 nodes 24011 nps 1561599 pv c3c4 b5c4 c2d3 c4d5 d3a6 b7d7 d8a5 -=> info depth 6 seldepth 21 score cp -330 time 27 nodes 45847 nps 1683515 pv c3c4 b5c4 c2d3 c4d5 d3e4 d5e6 e4b7 c5d4 e3d4 f6e5 f4e5 -=> info depth 7 seldepth 16 score cp -329 time 32 nodes 54813 nps 1681669 pv c3c4 b5c4 c2d3 c4d5 d3e4 d5e6 e4b7 a3b2 b7c8 e6d5 c8b7 d5e6 -=> info depth 8 seldepth 21 score cp -409 time 138 nodes 266182 nps 1919154 pv c3c4 b5c4 c2d3 c4d5 d3e4 d5e6 e4b7 a3b2 b7c8 e6d5 c8b7 a6c6 b7c6 d5c6 -=> info depth 9 seldepth 25 score cp -415 time 200 nodes 384037 nps 1916277 pv c3c4 b5c4 c2d3 c4d5 d3e4 d5e6 e4b7 a3b2 b7a6 g5f4 e3f4 f6e5 d4e5 b2b1Q -=> info depth 10 seldepth 25 score cp -403 time 347 nodes 633637 nps 1821606 pv c3c4 b5c4 c2d3 c4d5 e5f6 a5d8 d3a6 b7b8 b2a3 c5d4 e3d3 e7f6 a6c4 d5c5 -=> info depth 11 seldepth 22 score cp -409 time 530 nodes 972651 nps 1832222 pv c3c4 b5c4 c2d3 c4d5 e5f6 g5f4 e3f3 e7f6 d3a6 b7a7 d8f6 a7a6 b2a3 a5b6 -=> info depth 12 seldepth 24 score cp -414 time 646 nodes 1200283 nps 1855648 pv c3c4 b5c4 c2d3 c4d5 e5f6 g5f4 e3f3 e7f6 d3a6 b7a7 d8f6 a7a6 b2a3 a5b6 a3b4 -=> info depth 13 seldepth 31 score cp -422 time 1234 nodes 2380377 nps 1928188 hashfull 354 pv c3c4 b5c4 c2d3 c4d5 d3a6 b7a7 e5f6 a3b2 a6d3 g5f4 e3f2 e7f6 d8f6 c5c4 d3f5 a5b6 f2f3 b6d4 f5e4 d5c5 f6h4 d6d5 -=> info depth 14 seldepth 26 score cp -427 time 1633 nodes 3141554 nps 1922969 hashfull 454 pv c3c4 b5c4 c2d3 c4d5 d3a6 b7a7 e5f6 a3b2 a6d3 g5f4 e3f2 e7f6 d8f6 c5c4 d3f5 a5b6 f2f3 -=> info depth 15 seldepth 40 score cp -429 time 2148 nodes 4144414 nps 1928994 hashfull 565 pv c3c4 b5c4 c2d3 c4d5 d3a6 b7a7 e5f6 a3b2 a6d3 g5f4 e3f2 e7f6 d8f6 c5c4 d3f5 a5b6 f2f3 b6d4 f5e4 d5c5 f6h4 a7a2 f3f4 -=> info depth 16 seldepth 29 score cp -434 time 2924 nodes 5557593 nps 1900090 hashfull 703 pv c3c4 b5c4 c2d3 c4d5 d3a6 b7a7 e5f6 a3b2 a6d3 g5f4 e3f2 e7f6 d8f6 c5c4 d3f5 a5b6 f2f3 b6d4 -=> info depth 17 seldepth 30 score cp -441 time 4760 nodes 8692636 nps 1825900 hashfull 891 pv c3c4 b5c4 c2d3 c4d5 e5f6 g5f4 e3f3 e7f6 d3a6 b7a7 d8f6 a7a6 b2b3 c5d4 f3f4 a6c6 f6h4 c6c2 g4g5 c2a2 g5g6 -=> info depth 18 seldepth 29 score cp -451 time 8345 nodes 15057773 nps 1804390 hashfull 981 pv c3c4 b5c4 c2d3 c4d5 d3a6 b7a7 e5f6 e7f6 d8f6 a7a6 b2a3 c5d4 f6d4 g5f4 e3d3 b4a3 d4f6 a6c6 g4g5 d5e6 d3e4 c6c4 e4d3 c4c6 d3e4 -=> bestmove c3c4 <=- quit MSG : process closed ^CTraceback (most recent call last) /home/roelof/Compiled/owlkettle-main-v2.2.0/examples/widgets/uci_v3.nim(239) uci_v3 /home/roelof/Compiled/owlkettle-main-v2.2.0/owlkettle.nim(160) brew /home/roelof/Compiled/owlkettle-main-v2.2.0/owlkettle/mainloop.nim(97) runMainloop SIGINT: Interrupted by Ctrl-C. Run however, it can end like this : [...] -=> info depth 9 seldepth 25 nodes 453775 time 4624 nps 98134 score cp -554 pv c3c4 b5c4 c2d3 c4d5 d3e4 d5e6 e4b7 a3b2 b7c8 e6f7 e5e6 f7e8 c8a6 b2b1q d8a5 b1a2 -=> info depth 9 seldepth 25 nodes 558907 time 5704 nps 97985 currmovenumber 5 currmove e5f6 -=> info depth 9 seldepth 27 nodes 645276 time 6704 nps 96252 currmovenumber 5 currmove e5f6 -=> info depth 9 seldepth 27 nodes 746912 time 7705 nps 96938 currmovenumber 23 currmove e3f3 -=> info depth 10 seldepth 27 nodes 844811 time 8706 nps 97037 currmovenumber 1 currmove c3c4 -=> info depth 10 seldepth 27 nodes 939526 time 9706 nps 96798 currmovenumber 1 currmove c3c4 -=> info depth 10 seldepth 27 nodes 1029896 time 10707 nps 96189 currmovenumber 1 currmove c3c4 -=> info depth 10 seldepth 27 nodes 1108090 time 11616 nps 95393 score cp -578 pv c3c4 b5c4 c2d3 c4d5 d3a6 b7a7 d8a5 a3b2 a6d3 c5d4 e3f3 a7a5 d3e4 d5c5 -=> info depth 10 seldepth 27 nodes 1202469 time 12708 nps 94622 currmovenumber 3 currmove c2d3 -=> info depth 10 seldepth 27 nodes 1289222 time 13709 nps 94042 currmovenumber 5 currmove e5f6 -=> info depth 10 seldepth 27 nodes 1372099 time 14710 nps 93276 currmovenumber 5 currmove e5f6 -=> info depth 10 seldepth 27 nodes 1458539 time 15710 nps 92841 currmovenumber 6 currmove f4g5 -=> info depth 10 seldepth 27 nodes 1546697 time 16711 nps 92555 currmovenumber 11 currmove c2g6 -=> info depth 10 seldepth 27 nodes 1639341 time 17712 nps 92555 currmovenumber 17 currmove c2d1 ** Gtk:ERROR:../../../gtk/gtktextview.c:4744:gtk_text_view_validate_onscreen: assertion failed: (priv->onscreen_validated) Bail out! Gtk:ERROR:../../../gtk/gtktextview.c:4744:gtk_text_view_validate_onscreen: assertion failed: (priv->onscreen_validated) SIGABRT: Abnormal termination. Aborted (core dumped) Run