After getting the ball-out-of-bounds logic working pretty well over the weekend I was thinking more about the opponent logic. The pattern followed by the other frog seemed to work but was too simple. I wanted something a little better.
The frog should pick a different target location based on her position relative to the ball, but there are a lot of zones to consider. Is she directly in line with the ball on the X or Y axis? Is she below the ball on the Y axis? Is she on the goal side of the ball? What should be done to get her to the next location?
When dealing with these kinds of problems I find it helpful to draw a picture. I keep a graph paper tablet around for times such as these.
![]() |
| Frog zone sketch |
function setTarget(o, b) {
var zone = 0;
if (o.position.x < (b.position.x - 90) && o.position.y < (b.position.y - 5)) {
zone = 1;
} else if (o.position.x >= (b.position.x - 90) && o.position.x <= (b.position.x + 30) && o.position.y < (b.position.y - 30)) {
zone = 2;
} else if (o.position.x > (b.position.x + 30) && o.position.y < (b.position.y - 30)) {
zone = 3;
} else if (o.position.x > (b.position.x + 30) && o.position.y <= (b.position.y) && o.position.y > (b.position.y - 30)) {
zone = 4;
} else if (o.position.x > (b.position.x + 30) && o.position.y > (b.position.y) && o.position.y < (b.position.y + 30)) {
zone = 5;
} else if (o.position.x > (b.position.x + 30) && o.position.y > (b.position.y + 30)) {
zone = 6;
} else if (o.position.x >= (b.position.x - 90) && o.position.x <= (b.position.x + 30) && o.position.y > (b.position.y + 30)) {
zone = 7;
} else if (o.position.x < (b.position.x - 90) && o.position.y > (b.position.y + 5)) {
zone = 8;
} else if (o.position.x < (b.position.x - 90) && o.position.y >= (b.position.y - 5) && o.position.y <= (b.position.y + 5)) {
zone = 9;
}
var ret = {
x: o.position.x,
y: o.position.y
};
if (zone === 1) {
ret.x = b.position.x - 180;
ret.y = b.position.y + 20;
} else if (zone === 2) {
ret.x = b.position.x - 180;
ret.y = b.position.y - 150;
} else if (zone === 3) {
ret.x = b.position.x - 180;
ret.y = b.position.y - 150;
} else if (zone === 4) {
ret.x = b.position.x + 90;
ret.y = b.position.y - 90;
} else if (zone === 5) {
ret.x = b.position.x + 90;
ret.y = b.position.y + 90;
} else if (zone === 6) {
ret.x = b.position.x - 180;
ret.y = b.position.y + 150;
} else if (zone === 7) {
ret.x = b.position.x - 180;
ret.y = b.position.y + 150;
} else if (zone === 8) {
ret.x = b.position.x - 180;
ret.y = b.position.y - 20;
} else if (zone === 9) {
ret.x = b.position.x + 90;
ret.y = b.position.y - 15;
}
return ret;
}
Making the sketch plan in advance made it much easier to code, and it worked well on the first try. It still needed some fine-tuning, but it was really close. I know I could have combined some things in the code above but I wanted to keep the logic very clear and clean so I could tune it. If necessary I can always optimize it later. I tend to favor readability over other factors.
I made another video of the frogs playing. The computer-controlled frog starts out on the right side of the ball but moves herself around to the left and starts moving toward the goal. She chases it quite well when I manage to kick it away from her.
Remember, the full source code is on GitHub if you want to try improving the logic.
And that's all I have for today. Like I said, I only work on this for a few minutes each day...and this might be the last update this week. I have something different going on for Friday's comic. But I'm getting ahead of myself. Here's today's comic:
![]() |
| Amphibian.com comic for 29 July 2015 |


No comments:
Post a Comment