//Compilazione Visual Studio: cl /EHsc /DUNICODE cuichess.cpp /*#ifndef UNICODE #define UNICODE #endif #ifndef _UNICODE #define _UNICODE #endif */ #include #include #include #include #include #include #include #include #include //This is a header file taken from cplusplus.com //http://www.cplusplus.com/articles/Eyhv0pDG/ //concol.h #ifndef _INC_EKU_IO_CONCOL #define _INC_EKU_IO_CONCOL #pragma warning(disable : 4996) #pragma comment(lib,"Shlwapi.lib") #pragma comment (lib, "Wininet.lib") #pragma comment (lib, "User32.lib") void PrintAPILastError(const char* msg) { if (msg) fprintf(stderr, "%s", msg); DWORD dwLastError = GetLastError(); LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle(TEXT("wininet.dll")),//NULL dwLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL); if (lpMsgBuf) { MessageBoxW(NULL, (LPCTSTR)lpMsgBuf, L"Error", MB_OK | MB_ICONERROR); LocalFree(lpMsgBuf); } if (dwLastError == ERROR_INTERNET_EXTENDED_ERROR) { DWORD dwIntError, dwLength = 0; TCHAR* szBuffer = NULL; InternetGetLastResponseInfo(&dwIntError, NULL, &dwLength); if (dwLength) { if (!(szBuffer = (TCHAR*)LocalAlloc(LPTR, dwLength))) { fprintf(stderr, "Unable to allocate memory to display Internet error code. Error code: %d\n", GetLastError()); return; } if (!InternetGetLastResponseInfo(&dwIntError, (LPTSTR)szBuffer, &dwLength)) { fprintf(stderr, "Unable to get Intrnet error. Error code: %d\n", GetLastError()); return; } MessageBox(NULL, szBuffer, L"Error", MB_OK | MB_ICONERROR); LocalFree(szBuffer); } } } bool MoveWin(int x, int y) { HWND hWnd = GetConsoleWindow() ; RECT rc; GetClientRect(hWnd,&rc); return MoveWindow(hWnd, x,y,rc.right-rc.left,rc.bottom-rc.top,true); } void pos2Coo(char coo[3],int pos) { int p = pos + 1; int q = p / 8; int r = p % 8; coo[0] = char(int('A') + (r - 1)); itoa(8-q,(coo+1),10); coo[2] = 0; } int split(char newString[100][100], char* str1, char delim) { int i, j, ctr; j = 0; ctr = 0; for (i = 0; i <= int(strlen(str1)); i++) { // if space or NULL found, assign NULL into newString[ctr] if (str1[i] == delim || str1[i] == '\0') { newString[ctr][j] = '\0'; ctr++; //for next word j = 0; //for next word, init index to 0 } else { newString[ctr][j] = str1[i]; j++; } } return ctr; } std::string parseNextMove(char* str) { char str1[100] = { 0 }; char newString[50][100] = { 0 }; char nv[50][100] = { 0 }; int i, k, k1; char delim = ','; char move[100]; int r = 0; #define FMT0 "%*1c%[^}][^\n]s" #define FMT1 "%*[^{]" FMT0 if (str[0] == '{') r = sscanf(str, FMT0, str1); else r = sscanf(str, FMT1, str1); #undef FMT1 #undef FMT0 k = split(newString, str1, delim); if (k < 2) return std::string(); int ok = 0; for (i = 0; i < k; i++) { k1 = split(nv, newString[i], ':'); if ((2 == k1) && strcmp(nv[0], "\"status\"") == 0) { if (stricmp(nv[1], "\"ok\"") == 0) { ok = 1; continue; } else { ok = 0; } } if ((2 == k1) && ok && stricmp(nv[0], "\"move\"") == 0) { sscanf(nv[1], "%*[\"]%[^\"][^\n]", move); } } if (1 == ok) { std::string strMove(move); return strMove; } else return ""; } //L"www.chessdb.cn" //L"/cdb.php?action=querybest&board=rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1&json=1" char* InetRequest(const wchar_t* URLsrv, const wchar_t* GETRequest) { HINTERNET hSession = InternetOpenW( L"Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (!hSession) { PrintAPILastError("InternetOpen()"); } ///cdb.php?action=querybest&board=rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR%20w%20KQkq%20-%200%201 HINTERNET hConnect = 0; hConnect = InternetConnectW( hSession, URLsrv, INTERNET_DEFAULT_HTTPS_PORT, // THIS L"", L"", INTERNET_SERVICE_HTTP, 0, 0); if (NULL == hConnect) { PrintAPILastError("InternetConnect()"); } HINTERNET hHttpFile = HttpOpenRequestW( hConnect, L"GET", GETRequest, NULL, NULL, NULL, INTERNET_FLAG_SECURE, // THIS 0); if (!hHttpFile) { PrintAPILastError("HttpOpenRequest()"); } //while (!HttpSendRequest(hHttpFile, NULL, 0, 0, 0)) { if (!HttpSendRequest(hHttpFile, NULL, 0, 0, 0)) { //printf("HttpSendRequest error : (%lu)\n"); PrintAPILastError("HttpSendRequest()"); /* InternetErrorDlg( GetDesktopWindow(), hHttpFile, ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);*/ } DWORD dwFileSize; dwFileSize = BUFSIZ; char* buffer = 0; buffer = new char[dwFileSize + 1]; while (true) { DWORD dwBytesRead; BOOL bRead; bRead = InternetReadFile( hHttpFile, buffer, dwFileSize + 1, &dwBytesRead); if (dwBytesRead == 0) break; if (!bRead) { PrintAPILastError("InternetReadFile error()"); } else { buffer[dwBytesRead] = 0; } } InternetCloseHandle(hHttpFile); InternetCloseHandle(hConnect); InternetCloseHandle(hSession); return buffer; } namespace eku { #ifndef CONCOL #define CONCOL enum concol { black = 0, dark_blue = 1, dark_green = 2, dark_aqua, dark_cyan = 3, dark_red = 4, dark_purple = 5, dark_pink = 5, dark_magenta = 5, dark_yellow = 6, dark_white = 7, gray = 8, blue = 9, green = 10, aqua = 11, cyan = 11, red = 12, purple = 13, pink = 13, magenta = 13, yellow = 14, white = 15 }; #endif //CONCOL HANDLE std_con_out; //Standard Output Handle bool colorprotect = false; //If colorprotect is true, background and text colors will never be the same concol textcol, backcol, deftextcol, defbackcol; inline void update_colors() { CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(std_con_out, &csbi); textcol = concol(csbi.wAttributes & 15); backcol = concol((csbi.wAttributes & 0xf0) >> 4); } inline void setConsoleWinPos(int left,int top) { } inline void setcolor(concol textcolor, concol backcolor) { if (colorprotect && textcolor == backcolor)return; textcol = textcolor; backcol = backcolor; unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol; SetConsoleTextAttribute(std_con_out, wAttributes); } inline void settextcolor(concol textcolor) { if (colorprotect && textcolor == backcol)return; textcol = textcolor; unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol; SetConsoleTextAttribute(std_con_out, wAttributes); } inline void setbackcolor(concol backcolor) { if (colorprotect && textcol == backcolor)return; backcol = backcolor; unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol; SetConsoleTextAttribute(std_con_out, wAttributes); } inline void concolinit() { std_con_out = GetStdHandle(STD_OUTPUT_HANDLE); update_colors(); deftextcol = textcol; defbackcol = backcol; } template inline std::basic_ostream& operator<<(std::basic_ostream& os, concol col) { os.flush(); settextcolor(col); return os; } template inline std::basic_istream& operator>>(std::basic_istream& is, concol col) { std::basic_ostream* p = is.tie(); if (p != NULL)p->flush(); settextcolor(col); return is; } } //end of namespace eku #endif //_INC_EKU_IO_CONCOL void setFont(int FontSize, const wchar_t* wfontName) { CONSOLE_FONT_INFOEX info = { 0 }; info.cbSize = sizeof(info); info.dwFontSize.X = FontSize; // leave X as zero info.dwFontSize.Y = FontSize; info.FontWeight = FW_NORMAL; wcscpy(info.FaceName, wfontName); SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), 0, &info); } void restoreFont(CONSOLE_FONT_INFOEX info) { SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), 0, &info); } using namespace std; using namespace eku; eku::concol bkgWColor = eku::blue, bkgKColor = eku::dark_blue, txtColor = eku::black, currCellColor = eku::white, selCellColor = eku::green; wchar_t* wFontName = (wchar_t*)L"DejaVu Sans Mono"; int fontSize = 72; CONSOLE_FONT_INFOEX ConsoleFontInfo; char _ProgName[MAX_PATH] = { 0 }; int board[8][8]; int gamer = 0; char blacks[16][3] = { 0 }; char whites[16][3] = { 0 }; #define br1 0 #define bn1 1 #define bb1 2 #define bq 3 #define bk 4 #define bb2 5 #define bn2 6 #define br2 7 #define bp1 8 #define bp2 9 #define bp3 10 #define bp4 11 #define bp5 12 #define bp6 13 #define bp7 14 #define bp8 15 #define wr1 0 #define wn1 1 #define wb1 2 #define wq 3 #define wk 4 #define wb2 5 #define wn2 6 #define wr2 7 #define wp1 8 #define wp2 9 #define wp3 10 #define wp4 11 #define wp5 12 #define wp6 13 #define wp7 14 #define wp8 15 void init() { strcpy(blacks[br1], "A8");//r=pos strcpy(blacks[bn1], "B8");//n=pos strcpy(blacks[bb1], "C8");//... strcpy(blacks[bq], "D8"); strcpy(blacks[bk], "E8"); strcpy(blacks[bb2], "F8"); strcpy(blacks[bn2], "G8"); strcpy(blacks[br2], "H8"); strcpy(blacks[bp1], "A7"); strcpy(blacks[bp2], "B7"); strcpy(blacks[bp3], "C7"); strcpy(blacks[bp4], "D7"); strcpy(blacks[bp5], "E7"); strcpy(blacks[bp6], "F7"); strcpy(blacks[bp7], "G7"); strcpy(blacks[bp8], "H7"); strcpy(whites[wr1], "A1"); strcpy(whites[wn1], "B1"); strcpy(whites[wb1], "C1"); strcpy(whites[wq], "D1"); strcpy(whites[wk], "E1"); strcpy(whites[wb2], "F1"); strcpy(whites[wn2], "G1"); strcpy(whites[wr2], "H1"); strcpy(whites[wp1], "A2"); strcpy(whites[wp2], "B2"); strcpy(whites[wp3], "C2"); strcpy(whites[wp4], "D2"); strcpy(whites[wp5], "E2"); strcpy(whites[wp6], "F2"); strcpy(whites[wp7], "G2"); strcpy(whites[wp8], "H2"); } void toUp(char* arr) { for (char* c = arr; *c = toupper(*c); ++c); } void splitMove(char sFrom[3], char sTo[3], const char* resp) { //char sFrom[3],sTo[3]; if (resp && strlen(resp) == 4) { strncpy(sFrom, resp, 2); sFrom[2] = 0; strncpy(sTo, resp + 2, 2); sTo[2] = 0; } return; } int getItem(char* coo) { for (int i = 0; i < 16; i++) { if ((blacks[i][0] == coo[0]) && (blacks[i][1] == coo[1])) return i; } for (int i = 0; i < 16; i++) { if ((whites[i][0] == coo[0]) && (whites[i][1] == coo[1])) return 20 + i; //Se il pezzo e' bianco aggiungo 20 all'indice per semplificare } return -1; } char mapPiece(int i) { switch (i) { case 0: case 7: return 'r'; case 1: case 6: return 'n'; case 2: case 5: return 'b'; case 3: return 'q'; case 4: return 'k'; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: return 'p'; } switch (i) { case 20: case 27: return 'R'; case 21: case 26: return 'N'; case 22: case 25: return 'B'; case 23: return 'Q'; case 24: return 'K'; case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: return 'P'; } return 0; } int getPiece(int i) { switch (i) { case 0: case 7: return 0x265C;//r case 1: case 6: return 0x265E;//n case 2: case 5: return 0x265D;//b case 3: return 0x265B;//q case 4: return 0x265A;//k case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: return 0x265F;//p } switch (i) { case 20: case 27: return 0x2656;//R case 21: case 26: return 0x2658;//N case 22: case 25: return 0x2657;//B case 23: return 0x2655;//Q case 24: return 0x2654;//K case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: return 0x2659;//P } return -1; } int iCurr = 48; int iSelFrom = -1; int iSelTo = -1; void drawPiece(int index, int pos, eku::concol b) { eku::setbackcolor(b); eku::settextcolor(txtColor); if (pos == iCurr) eku::setbackcolor(currCellColor); if (pos == iSelFrom) eku::setbackcolor(selCellColor); int p = getPiece(index); if (p >= 0) wprintf(L"%c", p); } eku::concol getBkgCell(int i, int j) { eku::concol c; if ((i + j) % 2 == 0) c = bkgKColor; else c = bkgWColor; return c; } void drawCell(int index, eku::concol b) { if (index == iCurr) eku::setbackcolor(currCellColor); else eku::setbackcolor(b); if (index == iSelFrom) eku::setbackcolor(selCellColor); wprintf(L" "); } void drawGame() { char coo[3]; int index=0; eku::concol b; //system("cls"); //Draw coo wprintf(L" "); for (int i = 0; i < 8; i++) { eku::setbackcolor(eku::black); eku::settextcolor(eku::white); wprintf(L"%c", 'a' + i); } wprintf(L"\n"); for (int i = 7; i > -1; i--) { eku::setbackcolor(eku::black); eku::settextcolor(eku::white); wprintf(L"%d", i + 1); for (int j = 0; j < 8; j++) { coo[0] = 'A' + j; coo[1] = '0' + i + 1; coo[2] = '\0'; index = getItem(coo); b = getBkgCell(i, j); if (index >= 0) { drawPiece(index, (7 - i) * 8 + j, b); } else { drawCell((7 - i) * 8 + j, b); } } //Draw Coo eku::setbackcolor(eku::black); eku::settextcolor(eku::white); wprintf(L"%d\n", i + 1); } wprintf(L" "); for (int i = 0; i < 8; i++) { eku::setbackcolor(eku::black); eku::settextcolor(eku::white); wprintf(L"%c", 'a' + i); } } void showCursor(int visible) { HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO info; GetConsoleCursorInfo(consoleHandle, &info); info.bVisible = visible; SetConsoleCursorInfo(consoleHandle, &info); } void drawBoard() { int N = 8; int i, j; eku::concol c; for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { if (i % 2 == 0) if (j % 2 == 0) c = bkgWColor; else c = bkgKColor; else if (j % 2 == 0) c = bkgKColor; else c = bkgWColor; eku::setbackcolor(c); wprintf(L" "); } wprintf(L"\n"); } } #include string BuildFEN() { std::stringstream ss; int kb = 0; char coo[3]; int index; for (int i = 7; i > -1; i--) { for (int j = 0; j < 8; j++) { coo[0] = 'A' + j; coo[1] = '0' + i + 1; coo[2] = '\0'; index = getItem(coo); //b = getBkgCell(i, j); if (index >= 0) { if (kb > 0) { ss << kb; kb = 0; } ss << mapPiece(index); } else { kb++; } } if (kb > 0) { ss << kb; kb = 0; } if (i > 0) ss << "/"; } ss << " " << (gamer == 0 ? 'w' : 'b'); ss << " KQkq - 0 1"; ss << "&json=1"; return ss.str(); } void FENSave(const char* fileName) { FILE* fp = NULL; fp = fopen(fileName, "w"); if (!fp) return; fprintf(fp, "https://www.chessdb.cn/cdb.php?action=querybest&board="); fprintf(fp, "%s", BuildFEN().c_str()); fclose(fp); } TCHAR* getProgName() { TCHAR* out; //GetModuleFileNameA(GetModuleHandle(NULL), szPath, MAX_PATH); TCHAR buffer[MAX_PATH] = { 0 }; DWORD bufSize = sizeof(buffer) / sizeof(*buffer); // Get the fully-qualified path of the executable if (GetModuleFileName(NULL, buffer, bufSize) == bufSize) { // the buffer is too small, handle the error somehow } // now buffer = "c:\whatever\yourexecutable.exe" // Go to the beginning of the file name out = PathFindFileName(buffer); // now out = "yourexecutable.exe" // Set the dot before the extension to 0 (terminate the string there) *(PathFindExtension(out)) = 0; return out; } char* FromWide(char* out,wchar_t* wide) { size_t len = WideCharToMultiByte(CP_UTF8, 0, wide, -1, NULL, 0, NULL, NULL); if (len == 0) return NULL; if (out) WideCharToMultiByte(CP_UTF8, 0, wide, -1, out, len, NULL, NULL); return out; } void help() { stringstream ss; ss << "Chess program in shell CUI for Windows\n\t(By Fischetti P.)\n\n? Suggeest move\nh this help\nR Redraw\n\n" << "USAGE:" << _ProgName << " -fFontName[" << wFontName << "] -zFontSize[72]\n" << " -wc(white cell color) -kc(black cell color) -tc(piece color) -sc(curr cell color) " << "\n black = 0,\n\ dark_blue = 1,\n\ dark_green = 2,\n\ dark_aqua, dark_cyan = 3,\n\ dark_red = 4,\n\ dark_purple = 5, dark_pink = 5, dark_magenta = 5,\n\ dark_yellow = 6,\n\ dark_white = 7,\n\ gray = 8,\n\ blue = 9,\n\ green = 10,\n\ aqua = 11, cyan = 11,\n\ red = 12,\n\ purple = 13, pink = 13, magenta = 13,\n\ yellow = 14,\n\ white = 15\n"; //"chess progroam in shell GUI for Windows\n/? Suggeest move\nhH this help\n r R Redraw" MessageBoxA(NULL, ss.str().c_str(), _ProgName, MB_OK | MB_ICONINFORMATION); } void redrawGame() { settextcolor(deftextcol); setbackcolor(defbackcol); system("cls"); drawGame(); } void doArrowKeys(char input) { switch (input) { case 72: {//up if (iCurr - 8 >= 0) { iCurr -= 8; redrawGame(); } } break; case 75: {//left if (iCurr > 0) { iCurr--; redrawGame(); } } break; case 77: {//right if (iCurr < 63) { iCurr++; redrawGame(); } } break; case 80: {//down if ((iCurr + 8) < 64) { iCurr += 8; redrawGame(); } } break; } } void quitPrg() { //FENSave("fen.txt"); restoreFont(ConsoleFontInfo); settextcolor(deftextcol); setbackcolor(defbackcol); showCursor(1); system("pause"); showCursor(1); exit(0); } int IsTurn(int indexPiece, int gamer) { if (indexPiece < 20 && gamer == 1) { OutputDebugString(L"OKB"); return 1; } if (indexPiece >= 20 && gamer == 0) { OutputDebugString(L"OKW"); return 1; } OutputDebugString(L"N"); return 0; } void move(char* sFrom, char* sTo) { toUp(sFrom); toUp(sTo); int k = getItem(sFrom); if (k >= 20) { whites[k - 20][0] = sTo[0]; whites[k - 20][1] = sTo[1]; } else { blacks[k][0] = sTo[0]; blacks[k][1] = sTo[1]; } gamer = !gamer; redrawGame(); } void doKeys(char input) { switch (input) { case 13: {//return if(iSelFrom ==-1){ char coo[3] = { 0 }; pos2Coo(coo, iCurr); int index = -1; if((index = getItem(coo))!=-1){ if (IsTurn(index, gamer)) { iSelFrom = iCurr; redrawGame();/* char *sFrom = &coo[0]; char *sTo = &coo[1]; move(sFrom, sTo);*/ } } } else { char coo[3] = { 0 }; pos2Coo(coo, iCurr); int index = -1; if ((index = getItem(coo)) == -1) { //if(IsTurn(index, gamer)){ char cooFrom[3] = { 0 }; pos2Coo(cooFrom, iSelFrom); iSelTo = iCurr; //redrawGame(); char* sFrom = cooFrom; char* sTo = coo; iSelFrom = iSelTo = -1; move(sFrom, sTo); //} } } } break; case 63://? http req move { std::string req = "/cdb.php?action=querybest&board=" + BuildFEN(); std::wstring wstr = std::wstring(req.begin(), req.end()); const wchar_t* GETRequest = wstr.c_str(); char* pBuff = InetRequest(L"www.chessdb.cn", GETRequest); //const char* resp = strResp.c_str(); if (pBuff && strlen(pBuff) > 0) { std::string strResp = parseNextMove(pBuff);//"{\"status\":\"ok\",\"move\":\"c2c3\"}"); if (strResp.length() == 0) MessageBoxA(NULL, pBuff, "Error", MB_OK | MB_ICONERROR); else { const char* pResp = strResp.c_str(); if (MessageBoxA(NULL, pResp, "Move?", MB_OKCANCEL | MB_ICONINFORMATION) == IDOK) { char sFrom[3] = { 0 }, sTo[3] = { 0 }; splitMove(sFrom, sTo, pResp); move(sFrom, sTo); } } free(pBuff); pBuff = 0; } //L"/cdb.php?action=querybest&board=rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1&json=1"); } break; case 82://R case 114://r redrawGame(); break; case 85://S case 115://s FENSave("fen.txt"); break; case 72: case 104: help(); break; case 27://ESC //default: quitPrg(); break; } } void handler_quit(int signal) { quitPrg(); exit(0); } int main(int argc, char* argv[]) { signal(SIGINT, handler_quit); signal(SIGABRT, handler_quit); TCHAR *prgName = getProgName(); FromWide(_ProgName, prgName); //_ProgName = argv[0]; for (int i = 1; i < argc; i++) { if (('-' == argv[i][0]) || ('/' == argv[i][0])) { char cp; cp = argv[i][1]; switch (cp) { case 'w': case 'W': bkgWColor = (eku::concol)atoi(&argv[i][2]); break; case 'k': case 'K': bkgKColor = (eku::concol)atoi(&argv[i][2]); break; case 't': case 'T': txtColor = (eku::concol)atoi(&argv[i][2]); break; case 's': case 'S': currCellColor = (eku::concol)atoi(&argv[i][2]); break; case 'f': case 'F': { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, &argv[i][2], -1, wFontName, MAX_PATH); } break; case 'z': case 'Z': { fontSize = atoi(&argv[i][2]); } break; case '?': case 'h': {help(); return 1; } default: {help(); return -1; } } } else { help(); return -1; } } system("cls"); showCursor(0); _setmode(_fileno(stdout), _O_U16TEXT); //SetConsoleMaxSize(); MoveWin(0,0); ConsoleFontInfo.cbSize = sizeof(ConsoleFontInfo); if (!GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), 0, &ConsoleFontInfo)) { PrintAPILastError("GetCurrentConsoleFontEx"); return -1; } setFont(fontSize, wFontName); concolinit(); wchar_t wBuff[MAX_PATH]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, "CUI CHESS", -1, wBuff, MAX_PATH); SetConsoleTitleW(wBuff); settextcolor(red); init(); drawGame(); int IsArrowKey = 0; char input; while (true) { showCursor(0); input = getch(); if (0 == input || -32 == input) { IsArrowKey = 1; continue; } else { if (1 == IsArrowKey) doArrowKeys(input); else doKeys(input); IsArrowKey = 0; } } quitPrg(); return 0; }