Skip to content

Instantly share code, notes, and snippets.

@noih
Last active October 13, 2022 18:11
Show Gist options
  • Save noih/e07ff80fbd6d20d1dfba0c1920911f14 to your computer and use it in GitHub Desktop.
Save noih/e07ff80fbd6d20d1dfba0c1920911f14 to your computer and use it in GitHub Desktop.
global Percent = 85 ; hp %
global BeltIndex = 1 ; belt index, 1 ~ 5
global UseDelay = 80 ; use belt again delay
; ==========================================
global KeysThreshold = 9
global MaxRound = 15
global SuccessThreshold = 3
#SingleInstance, Force
#NoEnv
#MaxHotkeysPerInterval 99000000
#HotkeyInterval 99000000
#KeyHistory 0
ListLines Off
Process, Priority, , H
SetBatchLines, -1
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
SetWinDelay, -1
SetControlDelay, -1
SendMode Input
^r::Reload
Delete::ExitApp
!p::
try {
OutputDebug, % "start"
base := GetRelativeCenterBottom({ x: 40, y: 596 })
count := 0
Loop {
if (GetKeyState("Alt", "P")) {
Send, {Alt Up}
}
if (IsGameClosed()) {
; OutputDebug, % "closed"
continue
}
colors := GetColors(base.x, base.y - 85, base.y) ; 596 - 511 = 85
p := Segment(colors)
OutputDebug, % "p: " . p * 100 . ", count: " . count
if (Floor(p * 100) <= Percent) {
count := count + 1
if (count >= SuccessThreshold) {
UseBelt(BeltIndex)
count := 0
Sleep, % UseDelay
}
} else {
count := 0
}
}
} catch e {
; MsgBox, % e
}
return
UseBelt(index) {
if (RegExMatch(index, "^[1-5]$")) {
Send, {%index% Down}
Sleep, 80
Send, {%index% Up}
}
}
Segment(colors) {
labels := Kmeans(colors)
keys := GetKeys(colors)
d1 := Distance(labels[1].key, keys[1])
d2 := Distance(labels[1].key, keys[2])
if (d1 < d2) {
p := Calc(labels[1].colors.Length(), labels[2].colors.Length())
} else {
p := Calc(labels[2].colors.Length(), labels[1].colors.Length())
}
if (p = "") {
return 1
}
return p
}
Hex2Rgb(v) {
n := InStr(v, "0x") ? v : (InStr(v, "#") ? "0x" SubStr(v, 2) : "0x" v)
return [(n / 65536) & 255, (n / 256) & 255, n & 255]
}
GetColors(x, startY, endY) {
colors := []
y := startY
While (y <= endY) {
PixelGetColor, c, %x%, %y%
colors.Push(Hex2Rgb(c))
y := y + 1
}
return colors
}
Calc(t, b) {
if (t != "" AND b != "") {
return b / (t + b)
}
return ""
}
Kmeans(data) {
round := 1
labels := {}
reRandom := False
Loop {
if (round = 1 OR reRandom) {
reRandom := FALSE
keys := GetKeys(data)
if (keys.Length() < 2) {
break
}
} else {
keys[1] := GetMean(labels[1].colors)
keys[2] := GetMean(labels[2].colors)
}
d := Distance(keys[1], keys[2])
if (d <= KeysThreshold) {
reRandom := TRUE
round := round + 1
continue
}
labels := GetLabels(data, keys)
if (labels[1].colors.Length() = 0 OR labels[2].colors.Length() = 0) {
reRandom := TRUE
}
round := round + 1
} Until (round > MaxRound)
return labels
}
Distance(a, b) {
return Abs(a[1] - b[1]) + Abs(a[2] - b[2]) + Abs(a[3] - b[3])
}
GetKeys(data) {
half := data.Length() / 2
keys := []
r := 0
g := 0
b := 0
Loop, % half {
r := r + data[A_Index][1]
g := g + data[A_Index][2]
b := b + data[A_Index][3]
}
keys.Push([r / half, g / half, b / half])
r := 0
g := 0
b := 0
Loop, % half {
r := r + data[data.MaxIndex() - A_Index][1]
g := g + data[data.MaxIndex() - A_Index][2]
b := b + data[data.MaxIndex() - A_Index][3]
}
keys.Push([r / half, g / half, b / half])
return keys
}
GetLabels(data, keys) {
labels := [{ key: keys[1], colors: [] }, { key: keys[2], colors: [] }]
for k, v in data {
d1 := Distance(v, labels[1].key)
d2 := Distance(v, labels[2].key)
if (d1 < d2) {
labels[1].colors.Push(v)
} else {
labels[2].colors.Push(v)
}
}
return labels
}
GetMean(data) {
r := 0
g := 0
b := 0
for k, v in data {
r := r + v[1]
g := g + v[2]
b := b + v[3]
}
return [r / data.Length(), g / data.Length(), b / data.Length()]
}
IsGameClosed() {
p := GetRelativeCenterBottom({ x: 352, y: 552 })
PixelGetColor, color, p.x, p.y
return color != 0x000000
}
GetRelativeCenterBottom(position, width = 800, height = 600) {
return { x: Floor((A_ScreenWidth / 2) - (width / 2) + position.x), y: A_ScreenHeight - height + position.y }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment