#include "library.h" struct actor { string name; double x, y, speed; int colour, text_place; string victory_phrase; bool reached_target, can_still_win; }; void set(actor & a, string n, double ix, double iy, double spd, int col, string vp, int tp) { a.name = n; a.x = ix; a.y = iy; a.speed = spd; a.colour = col; a.victory_phrase = vp; a.text_place = tp; a.reached_target = false; a.can_still_win = true; } void print(actor a) { cout << a.name << " at " << a.x << ", " << a.y << ", speed " << a.speed << "\n"; } bool close(double a, double b) { return fabs(a-b) < 0.1; } bool close(actor a, actor b) { return close(a.x, b.x) && close(a.y, b.y); } double direction_from_a_to_b(actor a, actor b) { return atan2(b.x-a.x, a.y-b.y); } void display_victory_phrase_for(actor a) { if (a.text_place==1) write_string(a.victory_phrase, direction::north_east); else if (a.text_place==2) write_string(a.victory_phrase, direction::south_east); else write_string(a.victory_phrase); } void show_start_position(actor a) { set_pen_color(a.colour); move_to(a.x, a.y); write_string(a.name); } void move_towards(actor & mover, actor target, double dt) { // the mover runs straight to the target: // work out the direction he runs double ang = direction_from_a_to_b(mover, target); // work out how far he runs in 0.1 seconds double dist = mover.speed * dt; // work out where he will be 0.1 seconds later double mover_new_x = mover.x + dist * sin(ang); double mover_new_y = mover.y - dist * cos(ang); // draw a line showing these few inches of progress set_pen_color(mover.colour); move_to(mover.x, mover.y); draw_to(mover_new_x, mover_new_y); mover.x = mover_new_x; mover.y = mover_new_y; // has he reached the target yet? if (close(mover, target)) { if (mover.can_still_win) display_victory_phrase_for(mover); mover.reached_target = true; } } void main() { double field_w=500, field_h=400, edge=100; actor tree, bull, boy, dinosaur; set(tree, "tree", 400, 400, 0, color::brown, "", 1); set(bull, "bull", 500, 150, 3, color::red, "Boy Eaten!", 1); set(dinosaur, "dinosaur", 150, 150, 3, color::purple, "Graaaaah!", 2); set(boy, "boy", 100, 500, 2, color::blue, "Boy Safe", 1); double bull_spd=3, delta_t=0.003; double total_time = 0.0; make_window(field_w+2*edge, field_h+2*edge); set_pen_color(color::green); fill_rectangle(edge, edge, field_w, field_h); set_pen_color(color::brown); set_pen_width(10); draw_point(tree.x, tree.y); set_pen_width(2); show_start_position(boy); show_start_position(bull); show_start_position(dinosaur); while (true) { move_towards(dinosaur, bull, delta_t); if (dinosaur.reached_target) { bull.can_still_win = false; bull.speed = 0; } move_towards(boy, tree, delta_t); if (boy.reached_target) bull.can_still_win = false; move_towards(bull, boy, delta_t); if (bull.reached_target) { boy.can_still_win = false; boy.speed = 0; } } cout << "Finished\n"; }