]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - robots/auto.c
1 /* $NetBSD: auto.c,v 1.8 2008/04/28 20:22:54 martin Exp $ */
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
36 * IF scrapheaps don't exist THEN
37 * IF not in danger THEN
38 * stay at current position
40 * move away from the closest robot
45 * IF scrapheap is adjacent THEN
46 * move behind the scrapheap
48 * take the move that takes you away from the
49 * robots and closest to the heap
55 #define ABS(a) (((a)>0)?(a):-(a))
56 #define MIN(a,b) (((a)>(b))?(b):(a))
57 #define MAX(a,b) (((a)<(b))?(b):(a))
61 static int distance(int, int, int, int);
64 static const char *find_moves(void);
65 static COORD
*closest_robot(int *);
66 static COORD
*closest_heap(int *);
67 static char move_towards(int, int);
68 static char move_away(COORD
*);
69 static char move_between(COORD
*, COORD
*);
70 static int between(COORD
*, COORD
*);
73 * return "move" number distance of the two coordinates
76 distance(x1
, y1
, x2
, y2
)
79 return MAX(ABS(ABS(x1
) - ABS(x2
)), ABS(ABS(y1
) - ABS(y2
)));
83 * Return x coordinate moves
106 * Return y coordinate moves
129 * Find possible moves
138 static const char moves
[] = ".hjklyubn";
139 static char ans
[sizeof moves
];
142 for(m
= moves
; *m
; m
++) {
143 test
.x
= My_pos
.x
+ xinc(*m
);
144 test
.y
= My_pos
.y
+ yinc(*m
);
145 move(test
.y
, test
.x
);
146 switch(winch(stdscr
)) {
149 for(x
= test
.x
- 1; x
<= test
.x
+ 1; x
++) {
150 for(y
= test
.y
- 1; y
<= test
.y
+ 1; y
++) {
152 if(winch(stdscr
) == ROBOT
)
168 * return the robot closest to us
169 * and put in dist its distance
175 COORD
*rob
, *end
, *minrob
= NULL
;
179 end
= &Robots
[MAXROBOTS
];
180 for (rob
= Robots
; rob
< end
; rob
++) {
181 tdist
= distance(My_pos
.x
, My_pos
.y
, rob
->x
, rob
->y
);
182 if (tdist
< mindist
) {
189 } /* end closest_robot */
192 * return the heap closest to us
193 * and put in dist its distance
199 COORD
*hp
, *end
, *minhp
= NULL
;
203 end
= &Scrap
[MAXROBOTS
];
204 for (hp
= Scrap
; hp
< end
; hp
++) {
205 if (hp
->x
== 0 && hp
->y
== 0)
207 tdist
= distance(My_pos
.x
, My_pos
.y
, hp
->x
, hp
->y
);
208 if (tdist
< mindist
) {
215 } /* end closest_heap */
218 * move as close to the given direction as possible
224 char ok_moves
[10], best_move
;
226 int move_judge
, cur_judge
, mvx
, mvy
;
228 (void)strcpy(ok_moves
, find_moves());
229 best_move
= ok_moves
[0];
230 if (best_move
!= 't') {
231 mvx
= xinc(best_move
);
232 mvy
= yinc(best_move
);
233 move_judge
= ABS(mvx
- dx
) + ABS(mvy
- dy
);
234 for (ptr
= &ok_moves
[1]; *ptr
!= '\0'; ptr
++) {
237 cur_judge
= ABS(mvx
- dx
) + ABS(mvy
- dy
);
238 if (cur_judge
< move_judge
) {
239 move_judge
= cur_judge
;
245 } /* end move_towards */
248 * move away form the robot given
256 dx
= sign(My_pos
.x
- rob
->x
);
257 dy
= sign(My_pos
.y
- rob
->y
);
258 return move_towards(dx
, dy
);
259 } /* end move_away */
263 * move the closest heap between us and the closest robot
266 move_between(rob
, hp
)
273 /* equation of the line between us and the closest robot */
274 if (My_pos
.x
== rob
->x
) {
276 * me and the robot are aligned in x
277 * change my x so I get closer to the heap
278 * and my y far from the robot
280 dx
= - sign(My_pos
.x
- hp
->x
);
281 dy
= sign(My_pos
.y
- rob
->y
);
282 CONSDEBUG(("aligned in x"));
284 else if (My_pos
.y
== rob
->y
) {
286 * me and the robot are aligned in y
287 * change my y so I get closer to the heap
288 * and my x far from the robot
290 dx
= sign(My_pos
.x
- rob
->x
);
291 dy
= -sign(My_pos
.y
- hp
->y
);
292 CONSDEBUG(("aligned in y"));
295 CONSDEBUG(("no aligned"));
296 slope
= (My_pos
.y
- rob
->y
) / (My_pos
.x
- rob
->x
);
297 cons
= slope
* rob
->y
;
298 if (ABS(My_pos
.x
- rob
->x
) > ABS(My_pos
.y
- rob
->y
)) {
300 * we are closest to the robot in x
301 * move away from the robot in x and
302 * close to the scrap in y
304 dx
= sign(My_pos
.x
- rob
->x
);
305 dy
= sign(((slope
* ((float) hp
->x
)) + cons
) -
309 dx
= sign(((slope
* ((float) hp
->x
)) + cons
) -
311 dy
= sign(My_pos
.y
- rob
->y
);
314 CONSDEBUG(("me (%d,%d) robot(%d,%d) heap(%d,%d) delta(%d,%d)",
315 My_pos
.x
, My_pos
.y
, rob
->x
, rob
->y
, hp
->x
, hp
->y
, dx
, dy
));
316 return move_towards(dx
, dy
);
317 } /* end move_between */
320 * Return true if the heap is between us and the robot
328 if (hp
->x
> rob
->x
&& My_pos
.x
< rob
->x
)
331 if (hp
->x
< rob
->x
&& My_pos
.x
> rob
->x
)
336 if (hp
->y
< rob
->y
&& My_pos
.y
> rob
->y
)
341 if (hp
->y
> rob
->y
&& My_pos
.y
< rob
->y
)
347 * find and do the best move if flag
348 * else get the first move;
354 return find_moves()[0];
358 int robot_dist
, robot_heap
, heap_dist
;
360 robot_close
= closest_robot(&robot_dist
);
364 /* no scrap heaps just run away */
365 return move_away(robot_close
);
367 heap_close
= closest_heap(&heap_dist
);
368 robot_heap
= distance(robot_close
->x
, robot_close
->y
,
369 heap_close
->x
, heap_close
->y
);
370 if (robot_heap
<= heap_dist
&& !between(robot_close
, heap_close
)) {
372 * robot is closest to us from the heap. Run away!
374 return move_away(robot_close
);
377 return move_between(robot_close
, heap_close
);