Övning 11 -- lösningsförslag

Sköldpaddsflock

Följande program löser uppgiften (man kan, som vanligt, lösa uppgiften på många andra, likvärdiga sätt).

import se.lth.cs.pt.graphics.*;
import se.lth.cs.pt.graphics.events.*;
import se.lth.cs.pt.turtle.visible.*;
import java.util.*;

class Stampede {

    public static void main(String[] args) {
        new Stampede().run();
    }

    void run() {
        new Game().run();
    }
}

class Game {

    private GraphicsWindow w;
    private List<Turtle> turtles = new LinkedList<Turtle>();
    private Turtle marked;
    private int speed = 4;
    private int nbrOfTurtles = 5;
    private int timeStep = 250;

    public void run() {
        setup();
        mainLoop();
    }

    private void setup() {
        w = new GraphicsWindow(500, 500);
        for (int k = 1; k <= nbrOfTurtles; k++) {
            turtles.add(new Turtle(w,
                                   w.getWidth()/2,
                                   w.getHeight()/2));
        }
        Random rng = new Random();
        for (Turtle t : turtles) {
            t.setSpeed(360);
            t.left(rng.nextInt(360));
        }
        w.checkMouse(true, false, false, false, false);
        w.checkKeys(true, false, false);
        w.timeStep(timeStep);
    }

    private void mainLoop() {
        while (true) {
            GameEvent e = w.getNextEvent();
            switch (e.getKind()) {
            case GameEvent.MOUSE_CLICKED:
                mouseClicked(e.getX(), e.getY());
                break;
            case GameEvent.KEY_PRESSED:
                keyPressed(e.getKey());
                break;
            case GameEvent.TICK:
                tick();
                break;
            }
        }
    }

    private void tick() {
        for (Turtle t : turtles) {
            t.forward(speed);
        }
    }

    private void keyPressed(char ch) {
        if (ch == 'q') {
            System.exit(0);
        }
        if (marked != null) {
            switch (ch) {
            case 'a':
                marked.left(30);
                break;
            case 'd':
                marked.right(30);
                break;
            }
        }
    }

    private void mouseClicked(double x, double y) {
        Turtle closest = null;
        double closestDist = Double.POSITIVE_INFINITY;
        for (Turtle t : turtles) {
            double dist = distance(x, y, t);
            if (dist < closestDist) {
                closestDist = dist;
                closest = t;
            }
        }
        if (closestDist < 30) {
            marked = closest;
        }
    }

    private double distance(double x, double y, Turtle t) {
        double dx = x - t.getX();
        double dy = y - t.getY();
        return Math.sqrt(dx * dx + dy * dy);
    }
}