Use these Images to create an Auto hotkey script t...
Created on: August 26, 2025
Answered using GPT-5 Thinking by Chat01
Created on: August 26, 2025
Answered using GPT-5 Thinking by Chat01
pythonos.listdir('/mnt/data') ['image.png']
pythonfrom PIL import Image, ImageStat, ImageFilter, ImageOps, ImageEnhance, ImageColor, ImageChops, ImageDraw, ImageFont, Image img = Image.open('/mnt/data/image.png') img.size (82, 85)
pythonimg = img.convert('RGB') # Get most common colors from collections import Counter pixels = list(img.getdata()) cnt = Counter(pixels) cnt.most_common(10)[:10]
pythonfrom PIL import ImageFile, Image ImageFile.LOAD_TRUNCATED_IMAGES = True img = Image.open('/mnt/data/image.png') img = img.convert('RGB') img.size (67, 52)
pythonfrom collections import Counter cnt = Counter(list(img.getdata())) cnt.most_common(10) [((92, 255, 101), 372), ((42, 64, 86), 201), ((42, 63, 86), 181), ((91, 255, 100), 115), ((91, 255, 101), 82), ((42, 63, 85), 74), ((55, 70, 92), 37), ((41, 63, 86), 29), ((41, 63, 85), 25), ((76, 255, 85), 23)]
Here’s a ready-to-run AutoHotkey v1 script that finds the bright green “bill” sitting on the dark/black square (using color search, not image search) and clicks it three times.
It searches for a bright green pixel, confirms there’s dark/black square color nearby, then clicks. I pre-tuned the colors from your images (bill ≈ 0x5BFF64
, square ≈ 0x2A3F56
). You can adjust the tolerances if needed.
ahk; =============================== ; Find the bill on the black square (AHK v1) ; Hotkey: Ctrl+Alt+B to run ; Esc to exit ; =============================== #SingleInstance force SetBatchLines, -1 SendMode, Input CoordMode, Pixel, Screen CoordMode, Mouse, Screen SetMouseDelay, -1 ; ---- Colors (from your images) ---- billGreen := 0x5BFF64 ; bright green bill (RGB) squareDark := 0x2A3F56 ; dark/black square (RGB) ; ---- Tolerances (increase if your colors vary more) ---- billVar := 80 ; 0–255, color variation allowed for the bill darkVar := 60 ; 0–255, variation for the dark square ; ---- Search area (full screen) ---- x1 := 0, y1 := 0, x2 := A_ScreenWidth-1, y2 := A_ScreenHeight-1 ^!b:: if (FindBillOnDarkSquare(x1, y1, x2, y2, billGreen, billVar, squareDark, darkVar, outX, outY)) { ; Click the bill three times Click, %outX%, %outY%, Left, 3 SoundBeep, 1000, 100 } else { MsgBox, 48, Not found, Couldn't find the bill on a black square. } return Esc::ExitApp ; ---------- Functions ---------- FindBillOnDarkSquare(x1, y1, x2, y2, billColor, billVar, darkColor, darkVar, ByRef outX, ByRef outY) { startX := x1, startY := y1 ; Try multiple passes in case there are multiple green pixels Loop, 100 { PixelSearch, gx, gy, startX, startY, x2, y2, %billColor%, %billVar%, Fast RGB if ErrorLevel return false ; Look for the dark/black square color near this green hit to confirm it's the “bill on square” nx1 := Max(x1, gx - 70), ny1 := Max(y1, gy - 70) nx2 := Min(x2, gx + 70), ny2 := Min(y2, gy + 70) PixelSearch, bx, by, nx1, ny1, nx2, ny2, %darkColor%, %darkVar%, Fast RGB if (!ErrorLevel) { outX := gx, outY := gy return true } ; Continue searching after the last hit startX := gx + 5, startY := gy if (startX >= x2) { startX := x1 startY := gy + 5 } if (startY >= y2) break } return false } Max(a,b) { return a>b ? a : b } Min(a,b) { return a<b ? a : b }
FindBill.ahk
.billGreen
and squareDark
(keep the RGB
option in PixelSearch
).billVar
/darkVar
(e.g., 90–120).x1,y1,x2,y2
to that rectangle.This sticks strictly to color searching (no image templates) and clicks the bill three times once it’s verified to be on the black square.
It doesnt work, fix it
Got it—here’s a more robust AHK v1 version that doesn’t rely on a single color code.
It scans the screen for green-dominant pixels, then verifies that a ring around that spot is dark (the black square), and finally clicks the center of the green patch three times.
ahk; =============================== ; Find & click the green bill on a black square (AHK v1) ; Hotkey: Ctrl+Alt+B ; Esc quits ; =============================== #SingleInstance force SetBatchLines, -1 SendMode, Input CoordMode, Pixel, Screen CoordMode, Mouse, Screen SetMouseDelay, -1 ; ---- Tunables ---- scanStep := 6 ; bigger = faster, smaller = more precise greenMin := 150 ; minimum G channel (0-255) for a pixel to count as "green" greenGap := 45 ; G must exceed both R and B by at least this much ringRadius := 18 ; how far from candidate pixel to check for dark background darkAvgMax := 360 ; R+G+B must be <= this to count as dark (≈ avg 120) needDarkHits := 8 ; how many ring samples must be dark to "confirm" the square centroidBox := 40 ; half-size of the box used to refine the click point ^!b:: if (FindBill(outX, outY)) { Click, %outX%, %outY%, 3 SoundBeep, 900, 120 } else { MsgBox, 48, Not found, Couldn't find the green bill on a black square. } return Esc::ExitApp ; ---------- Main search ---------- FindBill(ByRef cx, ByRef cy) { global scanStep, ringRadius, darkAvgMax, needDarkHits, centroidBox, greenMin, greenGap x2 := A_ScreenWidth - 1 y2 := A_ScreenHeight - 1 ; coarse scan for green-dominant pixels y := 0 while (y <= y2) { x := 0 while (x <= x2) { PixelGetColor, c, x, y, RGB Alt if (IsGreenRGB(c, greenMin, greenGap)) { ; confirm there is a dark/black ring around (i.e., we're on the square) if (CountDarkAround(x, y, ringRadius, darkAvgMax) >= needDarkHits) { ; refine to the center of the green blob if (GreenCentroid(x, y, centroidBox, cx, cy)) return true cx := x, cy := y return true } } x += scanStep } y += scanStep } return false } ; ---------- Helpers ---------- IsGreenRGB(c, gMin, gap) { r := (c >> 16) & 0xFF g := (c >> 8) & 0xFF b := c & 0xFF ; strong green with a clear advantage over R/B return (g >= gMin) && (g - r >= gap) && (g - b >= gap) } IsDarkRGB(c, sumMax) { r := (c >> 16) & 0xFF g := (c >> 8) & 0xFF b := c & 0xFF return (r + g + b) <= sumMax } CountDarkAround(x, y, r, sumMax) { ; sample 16 points around a ring count := 0 Loop, 16 { ang := (A_Index - 1) * (6.28318530718 / 16) ; 2*pi/16 sx := Round(x + r * Cos(ang)) sy := Round(y + r * Sin(ang)) PixelGetColor, cc, sx, sy, RGB Alt if (IsDarkRGB(cc, sumMax)) count++ } return count } GreenCentroid(cx, cy, halfBox, ByRef ox, ByRef oy) { global greenMin, greenGap x1 := Max(0, cx - halfBox), y1 := Max(0, cy - halfBox) x2 := Min(A_ScreenWidth-1, cx + halfBox) y2 := Min(A_ScreenHeight-1, cy + halfBox) sumx := 0, sumy := 0, n := 0 y := y1 while (y <= y2) { x := x1 while (x <= x2) { PixelGetColor, cc, x, y, RGB Alt if (IsGreenRGB(cc, greenMin, greenGap)) { sumx += x, sumy += y, n++ } x += 1 } y += 1 } if (n > 0) { ox := Round(sumx / n), oy := Round(sumy / n) return true } return false } Max(a,b) { return a>b ? a : b } Min(a,b) { return a<b ? a : b }
greenMin := 135
and/or greenGap := 35
.darkAvgMax
(e.g. 330
). If it’s lighter, raise it (e.g. 390
).