Created
October 23, 2023 04:22
-
-
Save petersvp/91dedaf9438087ddf2c7bf75e4f704aa to your computer and use it in GitHub Desktop.
C++ bot that plays Verbal Memory in HumanBenchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <iostream> | |
#include "stdio.h" | |
#include <vector> | |
#include <set> | |
using namespace std; | |
// This is the time in ms when the program waits before taking a new screen shot | |
const int turnTime = 50; | |
/* START the program, start the game and follow the instructions in the console app: | |
1. Start the program | |
2. Open the game | |
3. Point your mouse in the middle ot the word and tap Q | |
4. Point your mouse on the SEEN button and tap S | |
5. Point your mouse on the NEW button and tap N | |
6. Enjoy. | |
To quit, tap R or press ESC | |
This bot screenshots part of the screen around the word, hashes the image to single 64-bit number | |
and keeps those in a set, taking decisions if the image is seen for the first time or not. | |
*/ | |
// Memory Hashing | |
uint64_t HashMemory(void* data, int byteSize) | |
{ | |
uint64_t hv = 0x0; // an initial value, could be anything | |
unsigned char* pd = (unsigned char*)data; | |
for (int n = 0; n < byteSize; ++n) | |
{ | |
hv << 4; | |
hv += pd[n]; | |
} | |
return hv; | |
} | |
// Screen shots part of the screen then hashes it | |
uint64_t GetScreenHash(int px, int py) | |
{ | |
HDC hScreenDC = GetDC(0); // CreateDC("DISPLAY",nullptr,nullptr,nullptr); | |
HDC hMemoryDC = CreateCompatibleDC(hScreenDC); | |
int width = 400; | |
int height = 40; | |
int x = px - width/2; | |
int y = py - height/2; | |
size_t size = width * height * 4; | |
BYTE* data = new BYTE[size]; | |
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height); | |
HBITMAP hOldBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hBitmap)); | |
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, x, y, SRCCOPY); | |
hBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hOldBitmap)); | |
BITMAPINFO bi; | |
ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER)); | |
bi.bmiHeader.biSize = sizeof(bi.bmiHeader); | |
GetDIBits(hMemoryDC, hBitmap, 0, 0, NULL, &bi, DIB_RGB_COLORS); | |
GetDIBits(hMemoryDC, hBitmap, 0, bi.bmiHeader.biHeight, data, &bi, DIB_RGB_COLORS); | |
uint64_t h = HashMemory(data, bi.bmiHeader.biSizeImage); | |
DeleteDC(hMemoryDC); | |
delete data; | |
return h; | |
} | |
void VerbalMemory() | |
{ | |
reset: | |
POINT Word, Seen, New; | |
cout << "Point your mouse to the center of the word and press [Q] to confirm\n"; | |
while (!GetAsyncKeyState('Q')) Sleep(16); | |
GetCursorPos(&Word); | |
cout << "Point your mouse to the SEEN button and press [S] to confirm\n"; | |
while (!GetAsyncKeyState('S')) Sleep(16); | |
GetCursorPos(&Seen); | |
cout << "Point your mouse to the NEW button and press [N] to confirm\n"; | |
while (!GetAsyncKeyState('N')) Sleep(16); | |
GetCursorPos(&New); | |
set<uint32_t> seen; | |
while (!GetAsyncKeyState(VK_ESCAPE)) | |
{ | |
if (GetAsyncKeyState('R')) | |
{ | |
cout << "RESET"; | |
seen.clear(); | |
goto reset; | |
} | |
auto hash = GetScreenHash(Word.x, Word.y); | |
if (seen.find(hash) == seen.end()) | |
{ | |
SetCursorPos(New.x, New.y); | |
seen.insert(hash); | |
} | |
else SetCursorPos(Seen.x, Seen.y); | |
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); | |
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); | |
Sleep(turnTime); | |
} | |
cout << "OK"; | |
} | |
int main() | |
{ | |
VerbalMemory(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment