first try of the AI.. but it's wors they kill themselfs again

origin
stpohle 23 years ago
parent 378294b502
commit e1809dc130

@ -329,7 +329,7 @@ player_drop_bomb (int pl_nr)
for (i = 0; ((i < player->bombs_n) && (player->bombs[i].state != BS_off)); i++);
if (i < player->bombs_n) { // free bomb found
if (i < player->bombs_n && PS_IS_alife(player->state)) { // free bomb found
// get the best position for the bomb.
bomb = &player->bombs[i];

@ -1,4 +1,4 @@
/* $Id: single.c,v 1.16 2003/05/23 21:17:30 stpohle Exp $ */
/* $Id: single.c,v 1.17 2003/05/25 02:24:18 stpohle Exp $ */
/* single player */
#include "basic.h"
@ -29,8 +29,8 @@ single_game_new ()
bman.players[p].bombs_n = START_BOMBS;
bman.players[p].range = START_RANGE;
bman.players[p].speed = START_SPEED;
bman.players[p].special= SP_nothing;
bman.updatestatusbar=1;
bman.players[p].special = SP_nothing;
bman.updatestatusbar = 1;
for (i = 0; i < MAX_BOMBS; i++) {
bman.players[p].bombs[i].state = BS_off;
bman.players[p].bombs[i].ex_nr = -1;
@ -63,57 +63,223 @@ single_game_new ()
};
int
ai_checkfield (int x, int y)
{
return (bman.field[x][y].type == FT_nothing && bman.bfield[x][y] == 0);
}
/* 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 ("Check Run away (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)
{
int d;
int dir = -1;
for (d = 0; (d < 4 && dir == -1); d++)
if (ai_checkrunaway (p, range, d))
dir = d;
d_printf ("ai_runawayfrom (%d)\n", dir);
return dir;
};
/* count the points for dropping a bomb here */
int
ai_bombpoints (_point pos, int range)
{
int points = 0,
d,
r;
_point p,
m;
if (bman.field[pos.x][pos.y].type != FT_block && bman.field[pos.x][pos.y].type != FT_stone) {
for (d = 0; d < 4; d++) {
switch (d) {
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;
}
p = pos;
for (r = 0; (r < range && bman.field[p.x][p.y].type == FT_nothing); r++) {
p.x += m.x;
p.y += m.y;
}
if (bman.field[p.x][p.y].type != FT_nothing && bman.field[p.x][p.y].type != FT_block)
points++;
}
}
if (ai_runawayfrom (pos, range) == -1)
points = 0;
return points;
};
/* find the best position to go for dropping a bomb */
int
ai_findbestbombdir (_player * pl)
{
int points[5] = { 0, 0, 0, 0 };
int d,
bestd = pl->d;
_point m,
p;
for (d = 0; d < 5; d++) {
switch (d) {
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;
case (down):
m.x = 0;
m.y = 1;
break;
default:
m.x = 0;
m.y = 0;
break;
}
p.x = (pl->pos.x >> 8) + m.x;
p.y = (pl->pos.y >> 8) + m.y;
points[d] = ai_bombpoints (p, pl->range);
if (points[d] > points[bestd])
bestd = d;
}
if (points[bestd] <= points[4] && points[4] != 0)
bestd = 4;
d_printf ("ai_findbestbombdir (%d %d %d %d %d)\n", points[0], points[1], points[2], points[3],
points[4]);
return bestd;
}
/* check if is there is a bom in the near
returns the directions (bits 0(left)-3(down)) where a bomb is */
int ai_findnearbombs (_player *pl) {
returns the directions (bits 0(left)-3(down) bit4 bomb under us) where a bomb is */
int
ai_findnearbombs (_player * pl)
{
int d,
res = 0, // result if there is a bomb
done = 0,
row;
_point m[4]; // direction addition
_point dist[4][3]; // to check every direction (on three ways)
_point dist[4]; // to check every direction (on three ways)
for (d = 0; d < 4; d++)
switch (d) {
case (left):
m[d].x = -1;
m[d].y = 0;
dist[d][0].x = (pl->pos.x>>8) - 1;
dist[d][1].x = (pl->pos.x>>8) - 1;
dist[d][2].x = (pl->pos.x>>8) - 1;
dist[d][0].y = (pl->pos.y>>8) - 1;
dist[d][1].y = (pl->pos.y>>8);
dist[d][2].y = (pl->pos.y>>8) + 1;
dist[d].x = (pl->pos.x >> 8) + 1;
dist[d].y = (pl->pos.y >> 8);
break;
case (right):
m[d].x = 1;
m[d].y = 0;
dist[d][0].x = (pl->pos.x>>8) + 1;
dist[d][1].x = (pl->pos.x>>8) + 1;
dist[d][2].x = (pl->pos.x>>8) + 1;
dist[d][0].y = (pl->pos.y>>8) - 1;
dist[d][1].y = (pl->pos.y>>8);
dist[d][2].y = (pl->pos.y>>8) + 1;
dist[d].x = (pl->pos.x >> 8) - 1;
dist[d].y = (pl->pos.y >> 8);
break;
case (up):
m[d].x = 0;
m[d].y = -1;
dist[d][0].x = (pl->pos.x>>8) - 1;
dist[d][1].x = (pl->pos.x>>8);
dist[d][2].x = (pl->pos.x>>8) + 1;
dist[d][0].y = (pl->pos.y>>8) - 1;
dist[d][1].y = (pl->pos.y>>8) - 1;
dist[d][2].y = (pl->pos.y>>8) - 1;
dist[d].x = (pl->pos.x >> 8);
dist[d].y = (pl->pos.y >> 8) - 1;
break;
case (down):
m[d].x = 0;
m[d].y = 1;
dist[d][0].x = (pl->pos.x>>8) - 1;
dist[d][1].x = (pl->pos.x>>8);
dist[d][2].x = (pl->pos.x>>8) + 1;
dist[d][0].y = (pl->pos.y>>8) + 1;
dist[d][1].y = (pl->pos.y>>8) + 1;
dist[d][2].y = (pl->pos.y>>8) + 1;
dist[d].x = (pl->pos.x >> 8);
dist[d].y = (pl->pos.y >> 8) + 1;
break;
}
@ -122,41 +288,142 @@ int ai_findnearbombs (_player *pl) {
/* check every direction again */
for (d = 0; d < 4; d++)
for (row = 0; row < 3; row++)
if (dist[d][row].x >= 0 && dist[d][row].x < bman.fieldsize.x &&
dist[d][row].y >= 0 && dist[d][row].y < bman.fieldsize.y) {
if (bman.bfield[dist[d][row].x][dist[d][row].y] != 0) {
if (dist[d].x >= 0 && dist[d].x < bman.fieldsize.x &&
dist[d].y >= 0 && dist[d].y < bman.fieldsize.y) {
if (bman.bfield[dist[d].x][dist[d].y] != 0) {
res |= 1 << d; // set the bit for the direction;
dist[d][row].x = dist[d][row].y = -1; // don't check no more.
dist[d].x = dist[d].y = -1; // don't check no more.
}
if (bman.field[dist[d][row].x][dist[d][row].y].type != FT_nothing)
dist[d][row].x = dist[d][row].y = -1; // don't check no more.
if (dist[d][row].x != -1 && dist[d][row].y != -1) {
dist[d][row].x += m[d].x;
dist[d][row].y += m[d].y;
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) {
dist[d].x += m[d].x;
dist[d].y += m[d].y;
done = 0;
}
}
}
if (bman.bfield[pl->pos.x >> 8][pl->pos.y >> 8] != 0)
res |= 16; // set the 4th. bit
return res;
}
/* flee from a bomb in the near */
int
ai_fleefrombomb (_player * pl, int nearbomb)
{
int posdir[4]; // possibvle directions to run away
int d = 0,
i,
dir = -1;
_point pos;
pos.x = pl->pos.x >> 8;
pos.y = pl->pos.y >> 8;
if (nearbomb == 4)
dir = ai_runawayfrom (pos, pl->range);
if (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);
if ((pl->pos.x & 255) != 0 || (pl->pos.y & 255) != 0)
dir = pl->d;
}
return dir;
};
void
single_loop ()
{
int p;
_player *pl;
int nearbomb,
bestbombdir;
for (p = 0; p < MAX_PLAYERS; p++)
if (p != bman.p_nr && PS_IS_playing (bman.players[p].state)) {
if (p != bman.p_nr && PS_IS_alife (bman.players[p].state)) {
pl = &bman.players[p];
ai_findnearbombs (pl);
bestbombdir = ai_findbestbombdir (pl);
nearbomb = ai_findnearbombs (pl);
if (((pl->pos.x & 255) >= 64 && (pl->pos.x & 255) <= 255 && pl->d == left) ||
((pl->pos.x & 255) > 0 && (pl->pos.x & 255) <= 192 && pl->d == right) ||
((pl->pos.y & 255) >= 64 && (pl->pos.y & 255) <= 255 && pl->d == up) ||
((pl->pos.y & 255) > 0 && (pl->pos.y & 255) <= 192 && pl->d == down)) {
pl->m = 1;
}
else if (bestbombdir == 4 && nearbomb == 0) // best position is here
player_drop_bomb (p);
else if (nearbomb != 0) { // there is a bomb in the near
pl->m = 1;
pl->d = ai_fleefrombomb (pl, nearbomb);
}
else if (bestbombdir == -1) { // no good position found
pl->d = s_random (4);
pl->m = 1;
}
else { // go into this direction
pl->d = bestbombdir;
pl->m = 1;
}
player_ilness_loop (p);
move_player (p);
}
};
/* create a giving number of ai players */
void
single_create_ai (int players)
@ -177,18 +444,19 @@ single_create_ai (int players)
if (pl == NULL)
return;
}
};
void single_playergame () {
void
single_playergame ()
{
int p;
/* delete player from the game */
for (p = 0; p < MAX_PLAYERS; p++)
bman.players[p].state = 0;
single_create_ai (1);
single_create_ai (6);
single_game_new ();
gfx_game_init ();
game_loop ();

Loading…
Cancel
Save