Wednesday, July 29, 2015

Making a Smarter Opponent

The frog soccer game made with Phaser is coming along nicely.

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
I sketched out the different zones the frog could be in relative to the ball and what I believed the target should be when in each of those zones. After that, it was easy to translate these behaviors into code.

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