Making of LLemMings

Climber and functionality to helper functions

ChatGPT: New climber implementation and helpers

The LLM kept on misunderstanding how to use getPixelColor() and its siblings.
It kept passing in an array of colors. Eventually I gave in and made it
re-implement them. It was not without frustration this was done, though. It
actually ended up with me cheating with one line of code... after like
5-6 attempts.

>>> Prompt making a function
Rewrite this function so that I can pass in multiple colors in the color argument, note how 'color' is already an array.
So, valid arguments would be:
[ 0xff, 0xff, 0xff ] or [[ 0xff, 0xff, 0xff ], [0xee, 0xee, 0xee]], ...

Use getPixelColor(imageData, x, y) to get the color of the pixel in the data.

function pixelIsColor(imageData, x, y, color, debug) {
x = Math.round(x);
y = Math.round(y);

const [r, g, b, alpha] = getPixelColor(imageData, x, y);

// if(r === undefined) {
// console.warn("Should not happen:", "lemming:", debug, "len:", lemmings.length, "image:", imageData, r, g, b, alpha, "x:"+x, "y:"+y, "comparing:"+color, "_index:"+Math.floor((y * width + x) * 4));
// debug.draw();
// throw "This should not happen"
// }

return r === color[0] && g === color[1] && b === color[2];

>>> HUMAN CHEAT: Arrrgh. After 5-6 attempts, I give up. I rewrote the function myself! It kept omitting, e.g.: if(!Array.isArray(color[0])) { color = [ color ]; }

>>> Prompt regarding bounds checking:
Rewrite this whole method to make sure we do not attempt to check pixels that are out of bounds of the canvas:
Make sure to check bounds so that e.g. getPixelIndex() does not attempt to get out of bounds
pixels either.
(and then the full update() method was passed in)

>>> Prompt for the climber:
We are making a game with lemmings. A specific type of lemming is a Climber. A lemming that is a Climber
will climb up (not down) steep dirt or rock obstacles (compare their colors against the canvas data, always
use oldImgData for that -- not ctx), it will walk like any other lemming, the only difference is that it
can also ascend steeper obstacles.

When it is climbing these steep obstacles, move it upwards along Y axis, but make sure the lemming move
along the pixels it is climbing on (that is, on either side of the lemming).

If a climber is climbing, you should probably not do the heightAdjustment as that only applies if the lemming
is walking on the ground.

As a hint, since you are struggling, you want to put the functionality for this inside if(this.action === "Climber") { ... },
in the appropriate place in the update function.

To illustrate with ASCII:

S o c |

"S" is where the lemmings start walking
"-" is a platform (rock or dirt)
"|" is either rock or dirt too, but it's very steep and would stop a normal lemming from going further
"o" is a normal walking lemming
"c" is a Climber
"G" is the goal where the lemmings want to go

The Climber (c) in the above illustration would be able to reach the goal, but the normal lemming (o) would not,
it would simply walk back and forth between the steep obstacle and S.

The following functionality is declared implemented:
function isColorOneOf(needle, haystack) {
for (let i = 0; i < haystack.length; i++) {
const color = haystack[i];

if (color[0] === needle[0] &&
color[1] === needle[1] &&
color[2] === needle[2]) {
return true;

return false;

const terrainColorBytes = [
[102, 102, 102], // rock color
[150, 75, 0] // dirt color

Don't use pixelIsColor to check if pixels are climbable surfaces. Use isColorOneOf(needle, haystack) instead, where
needle is the pixel's color, and haystack is an array of several colors (e.g. the ones in terrainColorBytes).

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

... a lot more code from Lemming object ...

I only want to change the update() function in the lemming. Show me the changed update() function, the
rest of the Lemming you don't have to give me code for.

I don't want pseudo-code, I want real code. It could be that you need more context from the existing
code-base, please let me know if so.

>>> And a HUMAN CHEAT:
When clicking a button in the bar, do:
selectedLemming.action = "Climber";
selectedLemming.isSelected = false;

>>> Catch-up notes:
Backup was named: '_index - Copy (43) - new climber prompt.html'
Associated LLM context: n/a