sclass G22ColorWalker > G22Walker { // the ideal image it is looking for (set/get) int[] rememberedImage; // size visionW*visionH void move(IRGBImage image) { stuck = false; guessWork = 0; // How far can I move until I hit the image's borders Rect movement1 = rectFromPoints(visionW/2, visionH/2, image.getWidth()-(visionW+1)/2, (visionH+1)/2); // How far can I walk in one frame Rect movement2 = rectAroundPt(position, range*2+1); Rect movement = intersectRects(movement1, movement2); if (empty(movement)) ret with set stuck; printVars(+movement, +movement1, +movement2); if (rememberedImage == null) ret with rememberImage(image); Rect r = window_uncropped(); new MultiBest bestPositions; int mx1 = movement.x1(), mx2 = movement.x2(); int my1 = movement.y1(), my2 = movement.y2(); for (int y = my1; y < my2; y++) for (int x = mx1; x < mx2; x++) { var newPos = pt(x, y); bestPositions.put(newPos, scorePosition(newPos, image)); } var best = bestPositions!; guessWork = l(best); position = random(best); // It's actually a question how often we grab a fresh image. // For now, every time. rememberImage(image); } // only works when we already have a rememberedImage double scorePosition(Pt pos, IBWImage image) { int vx = pos.x-visionW, vy = pos.y-visionH, i = 0; int diff = 0; for y to visionH: for x to visionW: diff += colorDiff(rememberedImage[i++], image.getIntPixel(vx+x, vy+y)); ret -diff; } void rememberImage(IRGBImage image) { if (rememberedImage == null) rememberedImage = new int[visionW*visionH]; int vx = visionX1(), vy = visionY1(), i = 0; for y to visionH: for x to visionW: rememberedImage[i++] = image.getIntPixel(vx+x, vy+y); } }