single player ai test 2

origin
stpohle 23 years ago
parent deb2100bbc
commit 03ecc242d6

@ -1,3 +1,6 @@
- Added Sound Support (thanks to Henrik Enqvist for
the help and the sound files.)
- Added new powerups (Patty)
- Fixed make install, so the source will be able to

@ -161,6 +161,15 @@ enum _direction { // to handle directions better
down
};
enum _dirbitmask { // bit mask for the directions
DIRM_left = 1,
DIRM_right = 2,
DIRM_up = 4,
DIRM_down = 8,
DIRM_under = 16
};
struct __point {
short int x;
short int y;

@ -1,4 +1,4 @@
/* $Id: bomberclone.h,v 1.26 2003/05/26 20:25:54 stpohle Exp $ */
/* $Id: bomberclone.h,v 1.27 2003/05/28 22:31:47 stpohle Exp $ */
/* bomberclone.h */
#ifndef _BOMBERCLONE_H_
@ -235,6 +235,7 @@ extern void d_in_pl_detail (char *head);
extern void d_playerdetail (char *head);
extern void d_gamedetail (char *head);
extern void d_printf (char *fmt,...);
extern void d_bitprint (int bits, int nr);
// single.c
@ -242,6 +243,15 @@ extern void single_game_new ();
extern void single_create_ai (int players);
extern void single_loop();
extern void single_playergame ();
extern int ai_choosedir (int dir, int nearbomb, int oldpos);
extern int ai_invertdir (int dir);
extern int ai_checkpos (_player * pl, _point * pos);
extern int ai_findnearbombs (_point pos);
extern int ai_findbestbombdir (_point pos, int dir, int range);
extern int ai_bombpoints (_point pos, int range);
extern int ai_runawayfrom (_point p, int nearbomb, signed char norecursive);
extern int ai_checkfield (int x, int y);
// mapmenu.c
extern void map_random ();

@ -37,3 +37,16 @@ void d_playerdetail (char *head) {
for (i = 0; i < MAX_PLAYERS; i++)
d_printf ("%2d %16s %3d %3d %3d %3d [%s:%s]\n",i, bman.players[i].name, bman.players[i].gfx_nr, bman.players[i].state, bman.players[i].points, bman.players[i].wins, bman.players[i].net.addr.host, bman.players[i].net.addr.port);
};
void d_bitprint (int bits, int nr) {
int i;
for (i = nr-1; i >= 0; i--)
if ((bits & (1 << i)) == 0)
printf ("-");
else
printf ("X");
printf (" ");
};

@ -1,4 +1,4 @@
/* $Id: single.c,v 1.20 2003/05/26 20:25:54 stpohle Exp $ */
/* $Id: single.c,v 1.21 2003/05/28 22:31:47 stpohle Exp $ */
/* single player */
#include "basic.h"
@ -70,71 +70,96 @@ ai_checkfield (int x, int y)
}
/* check if we can run away in this direction */
int
ai_checkrunaway (_point pos, int range, int direction)
{
_point m,
p;
int ok = 0,
i;
p = pos;
switch (direction) {
case (left):
m.x = -1;
m.y = 0;
break;
case (right):
m.x = 1;
m.y = 0;
break;
case (up):
m.x = 0;
m.y = -1;
break;
default:
m.x = 0;
m.y = 1;
break;
}
for (i = 1; (ok == 0 && i < range && ai_checkfield (p.x, p.y)); i++) {
p.x += m.x;
p.y += m.y;
printf (" - ");
if (direction == left || direction == right) {
if (ai_checkfield (p.x, p.y - 1) || ai_checkfield (p.x, p.y + 1))
ok = 1;
}
else {
if (ai_checkfield (p.x + 1, p.y) || ai_checkfield (p.x - 1, p.y))
ok = 1;
}
}
if (i >= range)
ok = 1;
d_printf ("ai_runaway (pos %d,%d , direction %d) %d\n", pos.x, pos.y, direction, ok);
return ok;
};
/* give the run away direction */
int
ai_runawayfrom (_point p, int range)
ai_runawayfrom (_point p, int nearbomb, signed char norecursive)
{
int d;
int dir = -1;
for (d = 0; (d < 4 && dir == -1); d++)
if (ai_checkrunaway (p, range, d))
dir = d;
int i, done = 0, dir = 0, nbomb, tdir, _i;
_point pos[4], m[4];
return dir;
for (i = 0; i < 4; i++) {
pos[i] = p;
switch (i) {
case (left):
m[i].x = -1;
m[i].y = 0;
break;
case (right):
m[i].x = 1;
m[i].y = 0;
break;
case (up):
m[i].x = 0;
m[i].y = -1;
break;
default:
m[i].x = 0;
m[i].y = 1;
break;
}
pos[i].x += m[i].x;
pos[i].y += m[i].y;
}
/* test if we just have to move to the side */
if (!norecursive)
for (i = 0; i < 4; i++)
if (ai_findnearbombs (pos[i]) == 0)
dir |= (1 << i);
/* test the possible ways */
while (!done) {
done = 1;
for (i = 0; i < 4; i++) {
/* check if we are still in the game field */
if (pos[i].x <= 0 || pos[i].y <= 0 || pos[i].x >= bman.fieldsize.x-1 || pos[i].y >= bman.fieldsize.y-1)
pos[i].x = pos[i].y = -1;
if (pos[i].x != -1 && pos[i].y != -1) {
/* check if this place is free to go to */
if (ai_checkfield (pos[i].x, pos[i].y)) {
done = 0;
/* check the field left and right beside */
if (i == left || i == right) {
if (ai_checkfield (pos[i].x, pos[i].y - 1) || ai_checkfield (pos[i].x, pos[i].y + 1))
dir |= (1 << i);
}
else {
if (ai_checkfield (pos[i].x - 1, pos[i].y) || ai_checkfield (pos[i].x + 1, pos[i].y))
dir |= (1 << i);
}
pos[i].x += m[i].x;
pos[i].y += m[i].y;
}
}
}
}
printf ("["); d_bitprint (dir, 4);
if (norecursive == 0) {// to prevent from invinite loops
for (i = 0; i < 4; i ++)
if ((dir & (1 << i)) != 0) { // test if we can use this direction
pos[0].x = p.x + m[i].x;
pos[0].y = p.y + m[i].y;
if (ai_checkfield (pos[0].x, pos[0].y)) {
nbomb = ai_findnearbombs (pos[0]);
if (nbomb != 0) { // test if this is a useless direction
tdir = ai_runawayfrom (pos[0], nbomb, 1);
_i = ai_invertdir (i);
if (tdir == (1 << _i)) // don't use this direction
dir &= (0xFF - (1 << i)); // delete these direction
}
}
else
dir &= (0xFF - (1 << i));
}
}
d_bitprint (dir, 4); printf ("] ");
return dir;
};
@ -181,7 +206,7 @@ ai_bombpoints (_point pos, int range)
}
}
if (ai_runawayfrom (pos, range) == -1)
if ((ai_runawayfrom (p, 16, 0) == 0) || ai_findnearbombs (p) != 0)
points = 0;
return points;
@ -247,7 +272,6 @@ ai_findnearbombs (_point pos)
{
int d,
res = 0, // result if there is a bomb
done = 0;
_point m[4]; // direction addition
_point dist[4]; // to check every direction (on three ways)
@ -257,13 +281,13 @@ ai_findnearbombs (_point pos)
case (left):
m[d].x = -1;
m[d].y = 0;
dist[d].x = pos.x + 1;
dist[d].x = pos.x - 1;
dist[d].y = pos.y;
break;
case (right):
m[d].x = 1;
m[d].y = 0;
dist[d].x = pos.x - 1;
dist[d].x = pos.x + 1;
dist[d].y = pos.y;
break;
case (up):
@ -292,7 +316,7 @@ ai_findnearbombs (_point pos)
}
if (bman.field[dist[d].x][dist[d].y].type != FT_nothing)
dist[d].x = dist[d].y = -1; // don't check no more.
if (dist[d].x != -1 && dist[d].y != -1) {
else if (dist[d].x != -1 && dist[d].y != -1) {
dist[d].x += m[d].x;
dist[d].y += m[d].y;
done = 0;
@ -307,62 +331,6 @@ ai_findnearbombs (_point pos)
}
/* flee from a bomb in the near */
int
ai_fleefrombomb (_point pos, int nearbomb, int range)
{
int d = 0,
dir = -1;
if ((nearbomb & 3) != 0) { // bomb is in the same row.. try to go up down
if (s_random (2) == 0 || (nearbomb & 4) != 0)
d = 1;
if (bman.field[pos.x][pos.y + d].type == FT_nothing) {
if (d == 1)
dir = down;
else
dir = up;
}
else if (bman.field[pos.x][pos.y - d].type == FT_nothing) {
if (d == 1)
dir = up;
else
dir = down;
}
else if ((nearbomb & 1) == 0)
dir = left;
else if ((nearbomb & 2) == 0)
dir = right;
}
else if ((nearbomb & 12) != 0) { // bomb is updown from us
if (s_random (2) == 0 || (nearbomb & 1) != 0)
d = 1;
if (bman.field[pos.x + d][pos.y].type == FT_nothing) {
if (d == 1)
dir = right;
else
dir = left;
}
else if (bman.field[pos.x - d][pos.y].type == FT_nothing) {
if (d == 1)
dir = left;
else
dir = right;
}
else if ((nearbomb & 4) == 0)
dir = up;
else if ((nearbomb & 8) == 0)
dir = down;
}
if (dir == -1)
dir = s_random (4);
return dir;
};
/* check if we are still running and fill out the position
return == 0 we're still walking ... else we have reached a point */
int
@ -385,46 +353,60 @@ ai_checkpos (_player * pl, _point * pos)
};
void
single_loop ()
{
int p;
_player *pl;
_point plpos;
int nearbomb = 0,
bestbombdir = 0,
i;
for (p = 0; p < MAX_PLAYERS; p++)
if (p != bman.p_nr && PS_IS_alife (bman.players[p].state)) {
pl = &bman.players[p];
i = ai_checkpos (pl, &plpos);
/* random choose direction */
int
ai_choosedir (int dir, int nearbomb, int oldpos) {
int rdir[4];
int bdir[4];
int i, rnr, bnr;
for (rnr = bnr= i = 0; i < 4; i++) {
if ((dir & (1 << i)) != 0) {
rdir[rnr] = i;
rnr++;
}
if (((nearbomb & (DIRM_up+DIRM_down)) != 0) && ((dir & (1 << i)) != 0) && (i == left || i == right) && i != ai_invertdir (oldpos)) {
bdir[bnr] = i;
bnr++;
}
if (((nearbomb & (DIRM_left+DIRM_right)) != 0) && ((dir & (1 << i)) != 0) && (i == down || i == up) && i != ai_invertdir (oldpos)) {
bdir[bnr] = i;
bnr++;
}
}
if (rnr == 0)
return (s_random (4));
if (bnr != 0)
i = bdir[s_random (bnr)];
else
i = rdir[s_random (rnr)];
printf ("AIDir %d,%d->%d ", rnr,bnr, i);
return i;
};
d_printf ("single_loop pos:%d,%d nearbomb:%d bestbombdir:%d, checkpos: %d\n", plpos.x,
plpos.y, nearbomb, bestbombdir, i);
if (!i) {
/* we're still moving */
pl->m = 1;
}
else {
nearbomb = ai_findnearbombs (plpos);
if (nearbomb == 0) { // no bombs found
}
else {
// bombs in the near found
pl->m = 1;
pl->d = ai_fleefrombomb (plpos, nearbomb, pl->range + 1);
printf (" %d ", pl->d);
}
}
player_ilness_loop (p);
move_player (p);
}
int
ai_invertdir (int dir) {
int idir;
switch (dir) {
case (left):
idir = right; break;
case (right):
idir = left; break;
case (down):
idir = up; break;
default:
idir = down; break;
}
return idir;
};
/* create a giving number of ai players */
void
single_create_ai (int players)
@ -457,9 +439,62 @@ single_playergame ()
for (p = 0; p < MAX_PLAYERS; p++)
bman.players[p].state = 0;
single_create_ai (1);
single_create_ai (5);
single_game_new ();
gfx_game_init ();
game_loop ();
gfx_game_shutdown ();
};
void
single_loop ()
{
int p;
_player *pl;
_point plpos;
int nearbomb = 0, bestbdir,
i;
for (p = 0; p < MAX_PLAYERS; p++)
if (p != bman.p_nr && PS_IS_alife (bman.players[p].state)) {
pl = &bman.players[p];
i = ai_checkpos (pl, &plpos);
if (!i)
/* we're still moving */
pl->m = 1;
else {
nearbomb = ai_findnearbombs (plpos);
printf ("SP: %d,%d NB:", plpos.x, plpos.y); d_bitprint (nearbomb, 5);
if (nearbomb == 0) { // no bombs found
bestbdir = ai_findbestbombdir (plpos, pl->d, pl->range);
if (bestbdir >= 4)
player_drop_bomb (p);
else if (bestbdir == -1) {
pl->d = s_random (4);
pl->m = 1;
}
else {
pl->d = bestbdir;
pl->m = 1;
}
}
else {
// bombs in the near found
printf (" FB: %d,%d ", plpos.x, plpos.y);
if ((i = ai_runawayfrom (plpos, nearbomb, 0)) != 0) {
pl->d = ai_choosedir (i, nearbomb, pl->d); // we have to make a choice.. do it
pl->m = 1;
}
printf ("D:%d, M:%d, Flee", pl->d, pl->m);
d_bitprint (i, 4);
}
printf ("\n");
}
player_ilness_loop (p);
move_player (p);
}
};

Loading…
Cancel
Save