Skip to content

Instantly share code, notes, and snippets.

@petersvp
Created October 23, 2023 04:22
Show Gist options
  • Save petersvp/91dedaf9438087ddf2c7bf75e4f704aa to your computer and use it in GitHub Desktop.
Save petersvp/91dedaf9438087ddf2c7bf75e4f704aa to your computer and use it in GitHub Desktop.
C++ bot that plays Verbal Memory in HumanBenchmark
#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