search.h
Code: Select all
#pragma once
#include<atomic>
static std::atomic_bool stop=false;
namespace Search
{
int Alphabeta()
{
int r = 10;
int Rounds = 0;
while ((++Rounds<20)&&!stop)
{
int sum = 0;
for (size_t i = 0; i < 100000000; i++)
{
sum += i;
}
sync_cout << sum<< sync_endl;
}
sync_cout << "Stopping" << sync_endl;
return r;
}
}
Code: Select all
#pragma once
#include<iostream>
#include<string>
#include <sstream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<Windows.h>
enum SyncCout { IO_LOCK, IO_UNLOCK };
//taken from StockFish
std::ostream& operator<<(std::ostream& os, SyncCout sc) {
static std::mutex m;
if (sc == IO_LOCK) m.lock();
if (sc == IO_UNLOCK) m.unlock();
return os;
}
#define sync_cout std::cout << IO_LOCK
#define sync_endl std::endl << IO_UNLOCK
#include"search.h"
class Thread
{
public:
Thread()
{
sync_cout << "@Consturcting" << sync_endl;
nativeThread = std::thread(&Thread::MainLoop, this);
hConIn = GetStdHandle(STD_INPUT_HANDLE);
ir.EventType = KEY_EVENT;
ir.Event.KeyEvent.bKeyDown = TRUE;
ir.Event.KeyEvent.dwControlKeyState = 0;
ir.Event.KeyEvent.uChar.UnicodeChar = VK_RETURN;
ir.Event.KeyEvent.wRepeatCount = 1;
ir.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
ir.Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
}
void MainLoop()
{
while (!exit)
{
while (pause)
{
sync_cout << "@Sleeping" << sync_endl;
std::unique_lock<std::mutex> lk(mutex);
cv.wait(lk);
lk.unlock();
}
std::string token, cmd;
while (!pause && !exit && std::getline(std::cin, cmd))
{
sync_cout << "@Working" << sync_endl;
std::istringstream is(cmd);
is >> std::skipws >> token;
if (token == "stop")
{
stop = true;
PauseThread();
}
else if (token == "isready") std::cout << "readyok" << std::endl;
else if (token == "") PauseThread();
}
}
}
void PauseThread()
{
//pause
std::lock_guard<std::mutex> lk(mutex);
pause = true;
}
void ResumeThread()
{
std::lock_guard<std::mutex> lk(mutex);
pause = false;
cv.notify_one();
}
void SignalSearchEnd()
{
DWORD dwTmp = 0;
WriteConsoleInput(hConIn, &ir, 1, &dwTmp);
FlushConsoleInputBuffer(hConIn);//check if not needed ?
}
~Thread()
{
sync_cout << "@destructing" << sync_endl;
mutex.lock();
pause = false;
exit = true;
cv.notify_one();
mutex.unlock();
nativeThread.join();
}
private:
HANDLE hConIn;
INPUT_RECORD ir;
std::thread nativeThread;
std::mutex mutex;
std::condition_variable cv;
bool pause = true, exit = false;
};
namespace UCI
{
void Loop()
{
Thread th;
std::string token, cmd;
while (std::getline(std::cin, cmd))
{
std::cout << "Loop : ";
std::istringstream is(cmd);
is >> std::skipws >> token;
if (token == "go")
{
std::cout << "go start" << std::endl;
stop = false;
th.ResumeThread();
Search::Alphabeta();
th.SignalSearchEnd();
std::cout << "go end" << std::endl;
}
else if (token == "isready") std::cout << "readyok" << std::endl;
else if (token == "quiet")
{
std::cout << "quieting" << std::endl;
break;
}
}
}
}
Code: Select all
#include"UCI.h"
int main()
{
UCI::Loop();
}
The only solution I found so far is writing to the stdin directly but it's so ugly and completely unportable , is there a better way and if not what are the equivalent option for Linux and other popular os' ?
*Ps, I know this is more suited to SO but I think I may get more answers here if someone tried the same thing before
