]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - robots/auto.c
1 /* $NetBSD: auto.c,v 1.7 2004/08/27 09:06:25 christos 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.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
43 * IF scrapheaps don't exist THEN
44 * IF not in danger THEN
45 * stay at current position
47 * move away from the closest robot
52 * IF scrapheap is adjacent THEN
53 * move behind the scrapheap
55 * take the move that takes you away from the
56 * robots and closest to the heap
62 #define ABS(a) (((a)>0)?(a):-(a))
63 #define MIN(a,b) (((a)>(b))?(b):(a))
64 #define MAX(a,b) (((a)<(b))?(b):(a))
68 static int distance(int, int, int, int);
71 static const char *find_moves(void);
72 static COORD
*closest_robot(int *);
73 static COORD
*closest_heap(int *);
74 static char move_towards(int, int);
75 static char move_away(COORD
*);
76 static char move_between(COORD
*, COORD
*);
77 static int between(COORD
*, COORD
*);
80 * return "move" number distance of the two coordinates
83 distance(x1
, y1
, x2
, y2
)
86 return MAX(ABS(ABS(x1
) - ABS(x2
)), ABS(ABS(y1
) - ABS(y2
)));
90 * Return x coordinate moves
113 * Return y coordinate moves
136 * Find possible moves
145 static const char moves
[] = ".hjklyubn";
146 static char ans
[sizeof moves
];
149 for(m
= moves
; *m
; m
++) {
150 test
.x
= My_pos
.x
+ xinc(*m
);
151 test
.y
= My_pos
.y
+ yinc(*m
);
152 move(test
.y
, test
.x
);
153 switch(winch(stdscr
)) {
156 for(x
= test
.x
- 1; x
<= test
.x
+ 1; x
++) {
157 for(y
= test
.y
- 1; y
<= test
.y
+ 1; y
++) {
159 if(winch(stdscr
) == ROBOT
)
175 * return the robot closest to us
176 * and put in dist its distance
182 COORD
*rob
, *end
, *minrob
= NULL
;
186 end
= &Robots
[MAXROBOTS
];
187 for (rob
= Robots
; rob
< end
; rob
++) {
188 tdist
= distance(My_pos
.x
, My_pos
.y
, rob
->x
, rob
->y
);
189 if (tdist
< mindist
) {
196 } /* end closest_robot */
199 * return the heap closest to us
200 * and put in dist its distance
206 COORD
*hp
, *end
, *minhp
= NULL
;
210 end
= &Scrap
[MAXROBOTS
];
211 for (hp
= Scrap
; hp
< end
; hp
++) {
212 if (hp
->x
== 0 && hp
->y
== 0)
214 tdist
= distance(My_pos
.x
, My_pos
.y
, hp
->x
, hp
->y
);
215 if (tdist
< mindist
) {
222 } /* end closest_heap */
225 * move as close to the given direction as possible
231 char ok_moves
[10], best_move
;
233 int move_judge
, cur_judge
, mvx
, mvy
;
235 (void)strcpy(ok_moves
, find_moves());
236 best_move
= ok_moves
[0];
237 if (best_move
!= 't') {
238 mvx
= xinc(best_move
);
239 mvy
= yinc(best_move
);
240 move_judge
= ABS(mvx
- dx
) + ABS(mvy
- dy
);
241 for (ptr
= &ok_moves
[1]; *ptr
!= '\0'; ptr
++) {
244 cur_judge
= ABS(mvx
- dx
) + ABS(mvy
- dy
);
245 if (cur_judge
< move_judge
) {
246 move_judge
= cur_judge
;
252 } /* end move_towards */
255 * move away form the robot given
263 dx
= sign(My_pos
.x
- rob
->x
);
264 dy
= sign(My_pos
.y
- rob
->y
);
265 return move_towards(dx
, dy
);
266 } /* end move_away */
270 * move the closest heap between us and the closest robot
273 move_between(rob
, hp
)
280 /* equation of the line between us and the closest robot */
281 if (My_pos
.x
== rob
->x
) {
283 * me and the robot are aligned in x
284 * change my x so I get closer to the heap
285 * and my y far from the robot
287 dx
= - sign(My_pos
.x
- hp
->x
);
288 dy
= sign(My_pos
.y
- rob
->y
);
289 CONSDEBUG(("aligned in x"));
291 else if (My_pos
.y
== rob
->y
) {
293 * me and the robot are aligned in y
294 * change my y so I get closer to the heap
295 * and my x far from the robot
297 dx
= sign(My_pos
.x
- rob
->x
);
298 dy
= -sign(My_pos
.y
- hp
->y
);
299 CONSDEBUG(("aligned in y"));
302 CONSDEBUG(("no aligned"));
303 slope
= (My_pos
.y
- rob
->y
) / (My_pos
.x
- rob
->x
);
304 cons
= slope
* rob
->y
;
305 if (ABS(My_pos
.x
- rob
->x
) > ABS(My_pos
.y
- rob
->y
)) {
307 * we are closest to the robot in x
308 * move away from the robot in x and
309 * close to the scrap in y
311 dx
= sign(My_pos
.x
- rob
->x
);
312 dy
= sign(((slope
* ((float) hp
->x
)) + cons
) -
316 dx
= sign(((slope
* ((float) hp
->x
)) + cons
) -
318 dy
= sign(My_pos
.y
- rob
->y
);
321 CONSDEBUG(("me (%d,%d) robot(%d,%d) heap(%d,%d) delta(%d,%d)",
322 My_pos
.x
, My_pos
.y
, rob
->x
, rob
->y
, hp
->x
, hp
->y
, dx
, dy
));
323 return move_towards(dx
, dy
);
324 } /* end move_between */
327 * Return true if the heap is between us and the robot
335 if (hp
->x
> rob
->x
&& My_pos
.x
< rob
->x
)
338 if (hp
->x
< rob
->x
&& My_pos
.x
> rob
->x
)
343 if (hp
->y
< rob
->y
&& My_pos
.y
> rob
->y
)
348 if (hp
->y
> rob
->y
&& My_pos
.y
< rob
->y
)
354 * find and do the best move if flag
355 * else get the first move;
361 return find_moves()[0];
365 int robot_dist
, robot_heap
, heap_dist
;
367 robot_close
= closest_robot(&robot_dist
);
371 /* no scrap heaps just run away */
372 return move_away(robot_close
);
374 heap_close
= closest_heap(&heap_dist
);
375 robot_heap
= distance(robot_close
->x
, robot_close
->y
,
376 heap_close
->x
, heap_close
->y
);
377 if (robot_heap
<= heap_dist
&& !between(robot_close
, heap_close
)) {
379 * robot is closest to us from the heap. Run away!
381 return move_away(robot_close
);
384 return move_between(robot_close
, heap_close
);