]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - robots/auto.c
1 /* $NetBSD: auto.c,v 1.6 2004/01/27 20:30:30 jsm 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;
46 * ELSE move away from the closest robot;
51 * IF scrapheap is adjacenHEN
52 * move behind the scrapheap
54 * move away from the closest robot
57 * take the move that takes you away from the
58 * robots and closest to the heap
64 #define ABS(a) (((a)>0)?(a):-(a))
65 #define MIN(a,b) (((a)>(b))?(b):(a))
66 #define MAX(a,b) (((a)<(b))?(b):(a))
70 static int distance(int, int, int, int);
73 static const char *find_moves(void);
74 static COORD
*closest_robot(int *);
75 static COORD
*closest_heap(int *);
76 static char move_towards(int, int);
77 static char move_away(COORD
*);
78 static char move_between(COORD
*, COORD
*);
79 static int between(COORD
*, COORD
*);
82 * return "move" number distance of the two coordinates
85 distance(x1
, y1
, x2
, y2
)
88 return MAX(ABS(ABS(x1
) - ABS(x2
)), ABS(ABS(y1
) - ABS(y2
)));
92 * Return x coordinate moves
115 * Return y coordinate moves
138 * Find possible moves
147 static const char moves
[] = ".hjklyubn";
148 static char ans
[sizeof moves
];
151 for(m
= moves
; *m
; m
++) {
152 test
.x
= My_pos
.x
+ xinc(*m
);
153 test
.y
= My_pos
.y
+ yinc(*m
);
154 move(test
.y
, test
.x
);
155 switch(winch(stdscr
)) {
158 for(x
= test
.x
- 1; x
<= test
.x
+ 1; x
++) {
159 for(y
= test
.y
- 1; y
<= test
.y
+ 1; y
++) {
161 if(winch(stdscr
) == ROBOT
)
177 * return the robot closest to us
178 * and put in dist its distance
184 COORD
*rob
, *end
, *minrob
= NULL
;
188 end
= &Robots
[MAXROBOTS
];
189 for (rob
= Robots
; rob
< end
; rob
++) {
190 tdist
= distance(My_pos
.x
, My_pos
.y
, rob
->x
, rob
->y
);
191 if (tdist
< mindist
) {
198 } /* end closest_robot */
201 * return the heap closest to us
202 * and put in dist its distance
208 COORD
*hp
, *end
, *minhp
= NULL
;
212 end
= &Scrap
[MAXROBOTS
];
213 for (hp
= Scrap
; hp
< end
; hp
++) {
214 if (hp
->x
== 0 && hp
->y
== 0)
216 tdist
= distance(My_pos
.x
, My_pos
.y
, hp
->x
, hp
->y
);
217 if (tdist
< mindist
) {
224 } /* end closest_heap */
227 * move as close to the given direction as possible
233 char ok_moves
[10], best_move
;
235 int move_judge
, cur_judge
, mvx
, mvy
;
237 (void)strcpy(ok_moves
, find_moves());
238 best_move
= ok_moves
[0];
239 if (best_move
!= 't') {
240 mvx
= xinc(best_move
);
241 mvy
= yinc(best_move
);
242 move_judge
= ABS(mvx
- dx
) + ABS(mvy
- dy
);
243 for (ptr
= &ok_moves
[1]; *ptr
!= '\0'; ptr
++) {
246 cur_judge
= ABS(mvx
- dx
) + ABS(mvy
- dy
);
247 if (cur_judge
< move_judge
) {
248 move_judge
= cur_judge
;
254 } /* end move_towards */
257 * move away form the robot given
265 dx
= sign(My_pos
.x
- rob
->x
);
266 dy
= sign(My_pos
.y
- rob
->y
);
267 return move_towards(dx
, dy
);
268 } /* end move_away */
272 * move the closest heap between us and the closest robot
275 move_between(rob
, hp
)
282 /* equation of the line between us and the closest robot */
283 if (My_pos
.x
== rob
->x
) {
285 * me and the robot are aligned in x
286 * change my x so I get closer to the heap
287 * and my y far from the robot
289 dx
= - sign(My_pos
.x
- hp
->x
);
290 dy
= sign(My_pos
.y
- rob
->y
);
291 CONSDEBUG(("aligned in x"));
293 else if (My_pos
.y
== rob
->y
) {
295 * me and the robot are aligned in y
296 * change my y so I get closer to the heap
297 * and my x far from the robot
299 dx
= sign(My_pos
.x
- rob
->x
);
300 dy
= -sign(My_pos
.y
- hp
->y
);
301 CONSDEBUG(("aligned in y"));
304 CONSDEBUG(("no aligned"));
305 slope
= (My_pos
.y
- rob
->y
) / (My_pos
.x
- rob
->x
);
306 cons
= slope
* rob
->y
;
307 if (ABS(My_pos
.x
- rob
->x
) > ABS(My_pos
.y
- rob
->y
)) {
309 * we are closest to the robot in x
310 * move away from the robot in x and
311 * close to the scrap in y
313 dx
= sign(My_pos
.x
- rob
->x
);
314 dy
= sign(((slope
* ((float) hp
->x
)) + cons
) -
318 dx
= sign(((slope
* ((float) hp
->x
)) + cons
) -
320 dy
= sign(My_pos
.y
- rob
->y
);
323 CONSDEBUG(("me (%d,%d) robot(%d,%d) heap(%d,%d) delta(%d,%d)",
324 My_pos
.x
, My_pos
.y
, rob
->x
, rob
->y
, hp
->x
, hp
->y
, dx
, dy
));
325 return move_towards(dx
, dy
);
326 } /* end move_between */
329 * Return true if the heap is between us and the robot
337 if (hp
->x
> rob
->x
&& My_pos
.x
< rob
->x
)
340 if (hp
->x
< rob
->x
&& My_pos
.x
> rob
->x
)
345 if (hp
->y
< rob
->y
&& My_pos
.y
> rob
->y
)
350 if (hp
->y
> rob
->y
&& My_pos
.y
< rob
->y
)
356 * find and do the best move if flag
357 * else get the first move;
363 return find_moves()[0];
367 int robot_dist
, robot_heap
, heap_dist
;
369 robot_close
= closest_robot(&robot_dist
);
373 /* no scrap heaps just run away */
374 return move_away(robot_close
);
376 heap_close
= closest_heap(&heap_dist
);
377 robot_heap
= distance(robot_close
->x
, robot_close
->y
,
378 heap_close
->x
, heap_close
->y
);
379 if (robot_heap
<= heap_dist
&& !between(robot_close
, heap_close
)) {
381 * robot is closest to us from the heap. Run away!
383 return move_away(robot_close
);
386 return move_between(robot_close
, heap_close
);