148 lines
8.5 KiB
C
148 lines
8.5 KiB
C
// modifie la position du joueur pour éviter le spawn kill et le spawn win
|
|
//implémenté par Vincent BRUNEAU ;)- (oubliez pas de me citer)
|
|
static void prevent_bad_spawn(game *g)
|
|
{
|
|
if (g->m->nb_minotaurs == g->m->nb_reachable - 4)
|
|
{
|
|
//avec autant de minotaure, cette fonction serait une perte de temps
|
|
return;
|
|
}
|
|
const int save = g->m->player; //la cellule qui contient le joueur
|
|
free_occupied_maze(g->m, save);
|
|
int neighbour = get_adj_maze(g->m, save, NORTH);
|
|
bool good_spawn = has_wall_maze(g->m, save, NORTH) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour);
|
|
neighbour = get_adj_maze(g->m, save, EAST);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, save, EAST) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
neighbour = get_adj_maze(g->m, save, SOUTH);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, save, SOUTH) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
neighbour = get_adj_maze(g->m, save, WEST);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, save, WEST) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
good_spawn = good_spawn && get_object_maze(g->m, save) != EXIT;
|
|
int fusible = g->m->hsize * g->m->vsize / 2; // on limite le nombre de tentatives
|
|
while (!good_spawn && fusible-- > 0)
|
|
{
|
|
getrandom(&g->m->player, sizeof(g->m->player), 0);
|
|
g->m->player = abs(g->m->player) % (g->m->hsize * g->m->vsize);
|
|
//le départ doit être valide
|
|
good_spawn = can_be_used(g->m, g->m->player) && !is_occupied_maze(g->m, g->m->player);
|
|
//le départ ne doit pas tuer le joueur
|
|
neighbour = get_adj_maze(g->m, g->m->player, NORTH);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, g->m->player, NORTH) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
neighbour = get_adj_maze(g->m, g->m->player, EAST);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, g->m->player, EAST) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
neighbour = get_adj_maze(g->m, g->m->player, SOUTH);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, g->m->player, SOUTH) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
neighbour = get_adj_maze(g->m, g->m->player, WEST);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, g->m->player, WEST) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
//le départ ne doit pas être la sortie
|
|
good_spawn = good_spawn && get_object_maze(g->m, g->m->player) != EXIT;
|
|
}
|
|
if (fusible <= 0)
|
|
{
|
|
for (int i = 0; i < g->m->hsize * g->m->vsize; i++)
|
|
{
|
|
good_spawn = can_be_used(g->m, i) && !is_occupied_maze(g->m, i);
|
|
neighbour = get_adj_maze(g->m, i, NORTH);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, i, NORTH) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
neighbour = get_adj_maze(g->m, i, EAST);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, i, EAST) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
neighbour = get_adj_maze(g->m, i, SOUTH);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, i, SOUTH) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
neighbour = get_adj_maze(g->m, i, WEST);
|
|
good_spawn = good_spawn && (has_wall_maze(g->m, i, WEST) || !can_be_used(g->m, neighbour) || !is_occupied_maze(g->m, neighbour));
|
|
good_spawn = good_spawn && get_object_maze(g->m, i) != EXIT;
|
|
if (good_spawn)
|
|
{
|
|
g->m->player = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!good_spawn)
|
|
{
|
|
//plutôt que de bouger le joueur, on bouge les minotaures
|
|
g->m->player = save;
|
|
make_occupied_maze(g->m, save);
|
|
neighbour = get_adj_maze(g->m, save, NORTH);
|
|
int mino = has_minotaur_maze(g->m, neighbour);
|
|
if (mino != -1 && !has_wall_maze(g->m, save, NORTH))
|
|
{
|
|
int place; //la cellule qui contient le minotaure actuel
|
|
do
|
|
{
|
|
getrandom(&place, sizeof(place), 0);
|
|
place %= g->m->hsize * g->m->vsize;
|
|
good_spawn = can_be_used(g->m, place) && !is_occupied_maze(g->m, place);
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, NORTH) != save || has_wall_maze(g->m, place, NORTH));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, EAST) != save || has_wall_maze(g->m, place, EAST));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, WEST) != save || has_wall_maze(g->m, place, WEST));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, SOUTH) != save || has_wall_maze(g->m, place, SOUTH));
|
|
} while (!good_spawn);
|
|
free_occupied_maze(g->m, g->m->minotaurs[mino]);
|
|
g->m->minotaurs[mino] = place;
|
|
make_occupied_maze(g->m, place);
|
|
}
|
|
neighbour = get_adj_maze(g->m, save, SOUTH);
|
|
mino = has_minotaur_maze(g->m, neighbour);
|
|
if (mino != -1 && !has_wall_maze(g->m, save, SOUTH))
|
|
{
|
|
int place; //la cellule qui contient le minotaure actuel
|
|
do
|
|
{
|
|
getrandom(&place, sizeof(place), 0);
|
|
place %= g->m->hsize * g->m->vsize;
|
|
good_spawn = can_be_used(g->m, place) && !is_occupied_maze(g->m, place);
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, EAST) != save || has_wall_maze(g->m, place, EAST));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, SOUTH) != save || has_wall_maze(g->m, place, SOUTH));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, WEST) != save || has_wall_maze(g->m, place, WEST));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, NORTH) != save || has_wall_maze(g->m, place, NORTH));
|
|
} while (!good_spawn);
|
|
free_occupied_maze(g->m, g->m->minotaurs[mino]);
|
|
g->m->minotaurs[mino] = place;
|
|
make_occupied_maze(g->m, place);
|
|
}
|
|
neighbour = get_adj_maze(g->m, save, EAST);
|
|
mino = has_minotaur_maze(g->m, neighbour);
|
|
if (mino != -1 && !has_wall_maze(g->m, save, EAST))
|
|
{
|
|
int place; //la cellule qui contient le minotaure actuel
|
|
do
|
|
{
|
|
getrandom(&place, sizeof(place), 0);
|
|
place %= g->m->hsize * g->m->vsize;
|
|
good_spawn = can_be_used(g->m, place) && !is_occupied_maze(g->m, place);
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, NORTH) != save || has_wall_maze(g->m, place, NORTH));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, EAST) != save || has_wall_maze(g->m, place, EAST));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, SOUTH) != save || has_wall_maze(g->m, place, SOUTH));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, WEST) != save || has_wall_maze(g->m, place, WEST));
|
|
} while (!good_spawn);
|
|
free_occupied_maze(g->m, g->m->minotaurs[mino]);
|
|
g->m->minotaurs[mino] = place;
|
|
make_occupied_maze(g->m, place);
|
|
}
|
|
neighbour = get_adj_maze(g->m, save, WEST);
|
|
mino = has_minotaur_maze(g->m, neighbour);
|
|
if (mino != -1 && !has_wall_maze(g->m, save, WEST))
|
|
{
|
|
int place; //la cellule qui contient le minotaure actuel
|
|
do
|
|
{
|
|
getrandom(&place, sizeof(place), 0);
|
|
place %= g->m->hsize * g->m->vsize;
|
|
good_spawn = can_be_used(g->m, place) && !is_occupied_maze(g->m, place);
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, NORTH) != save || has_wall_maze(g->m, place, NORTH));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, SOUTH) != save || has_wall_maze(g->m, place, SOUTH));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, WEST) != save || has_wall_maze(g->m, place, WEST));
|
|
good_spawn = good_spawn && (get_adj_maze(g->m, place, EAST) != save || has_wall_maze(g->m, place, EAST));
|
|
} while (!good_spawn);
|
|
free_occupied_maze(g->m, g->m->minotaurs[mino]);
|
|
g->m->minotaurs[mino] = place;
|
|
make_occupied_maze(g->m, place);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
make_occupied_maze(g->m, g->m->player);
|
|
}
|
|
}
|