home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
gamearca
/
pc_xbd.arj
/
FIELD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-28
|
15KB
|
631 lines
/*********************************************/
/* you just keep on pushing my luck over the */
/* BOULDER DASH */
/* */
/* Jeroen Houttuin, ETH Zurich, 1990 */
/* */
/* */
/* PC-VGA version from : */
/* */
/* Herve SOULARD, Paris, 1990 */
/* */
/*********************************************/
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/timeb.h>
#include "xbd.h"
void blink(i, j)
int i, j;
{
field[i][j].changed = TRUE;
}
void move_cell(i, j, ii, jj)
int i, j, ii, jj;
{
field[ii][jj] = field[i][j];
field[ii][jj].speed = 1;
field[ii][jj].changed = TRUE;
field[ii][jj].dir = ((ii - i) == 1) ? S : ((i - ii) == 1) ?
N : ((jj - j) == 1) ? E : W;
set_cell(i, j, SPACE);
}
void explode(a, b, stage)
int a, b, stage;
{
if (field[a][b].content != STEEL) {
set_cell(a, b, EXPLOSION);
field[a][b].stage = stage;/* dirty fix, not what stage was meant for */
}
}
Bool move_nucbal(i, j, t)
int i, j, t;
{
ii = (!t) ? (i + y - 1) % y : i;
if (!t)
jj = j;
else
switch (field[i][j].dir) {
case E:
jj = (t == 1) ? (j + x - 1) % x : (j + 1) % x;
break;
case W:
default:
jj = (t == 2) ? (j + x - 1) % x : (j + 1) % x;
break;
}
switch (field[ii][jj].content) {
case SPACE:
move_cell(i, j, ii, jj);
return (TRUE);
case NUCBAL:
explode(i, j, DIAEXPLO);
explode(ii, jj, DIAEXPLO);
return (TRUE);
default:
if (field[i][j].dir == N)
field[i][j].dir = E;
else
field[i][j].dir = ((field[i][j].dir + 2) % 4);
return (FALSE);
}
}
Bool move_monster(content, direction)
char content, direction;
{
switch (direction) {
case N:
ii = (i + y - 1) % y;
jj = j;
break;
case E:
jj = (j + 1) % x;
ii = i;
break;
case S:
ii = (i + 1) % y;
jj = j;
break;
default:
jj = (j + x - 1) % x;
ii = i;
break; /* default must be SOMEthing, West */
}
switch (field[ii][jj].content) {
case SPACE:
if (!field[ii][jj].changed) {
move_cell(i, j, ii, jj);
field[ii][jj].dir = direction;
return (TRUE);
}
else
return (FALSE);
break;
case BOULDER:
case DIAMOND:
if ((direction == N) && (field[ii][jj].speed != 0))
if (content == RMONSTER) {
explode(i, j, DIAEXPLO);
return (TRUE);
}
else
if (content == LMONSTER) {
explode(i, j, SPACEEXPLO);
return (TRUE);
}
else
return (FALSE);
else
return (FALSE);
break;
default:
return (FALSE);
break;
}
return (FALSE);
}
Bool search_destroy(content)
char content;
{
ii = (i + y - 1) % y;
jj = (j + x - 1) % x;
if (field[i][jj].content == PLAYER || field[i][jj].content == BLOB) {
set_cell(i, j, SPACE);
if (field[i][jj].content == PLAYER) {
lives--;
scoreobs = TRUE;
}
if (content == RMONSTER)
explode(i, jj, DIAEXPLO);
else
explode(i, jj, SPACEEXPLO);
return (TRUE);
}
else
if (field[ii][j].content == PLAYER || field[ii][j].content == BLOB) {
set_cell(i, j, SPACE);
if (field[ii][j].content == PLAYER) {
lives--;
scoreobs = TRUE;
}
if (content == RMONSTER)
explode(ii, j, DIAEXPLO);
else
explode(ii, j, SPACEEXPLO);
return (TRUE);
}
else {
ii = (i + 1) % y;
jj = (j + 1) % x;
if (field[i][jj].content == PLAYER || field[i][jj].content == BLOB) {
set_cell(i, j, SPACE);
if (field[i][jj].content == PLAYER) {
lives--;
scoreobs = TRUE;
}
if (content == RMONSTER)
explode(i, jj, DIAEXPLO);
else
explode(i, jj, SPACEEXPLO);
return (TRUE);
}
else
if (field[ii][j].content == PLAYER || field[ii][j].content == BLOB) {
set_cell(i, j, SPACE);
if (field[ii][j].content == PLAYER) {
lives--;
scoreobs = TRUE;
}
if (content == RMONSTER)
explode(ii, j, DIAEXPLO);
else
explode(ii, j, SPACEEXPLO);
return (TRUE);
}
else
return (FALSE);
}
}
void propagate(i, j, dias)
int i, j;
Bool dias;
{
int t, it, jt;
if (dias)
set_cell(i, j, DIAMOND);
else {
field[i][j].checked = PROPAGATED;
field[i][j].caught = TRUE;
}
for (t = 0; (t < 4); ++t) {
it = (t == 1) ? (i + y - 1) % y : (t == 3) ? (i + 1) % y : i;
jt = (t == 2) ? (j + x - 1) % x : (t == 0) ? (j + 1) % x : j;
switch (field[it][jt].content) {
case BLOB:
if (field[it][jt].checked != PROPAGATED)
propagate(it, jt, dias);
break;
case SPACE:
case GRASS:
if (!(rand() % (blobbreak + 1))) {
set_cell(it, jt, BLOB);
field[it][jt].checked = PROPAGATED;
field[it][jt].caught = TRUE;
}
break;
default:
break;
}
}
}
Bool caught(i, j)
int i, j;
{
Bool Free;
int t, it, jt;
field[i][j].checked = 1;
Free = FALSE;
for (t = 0; ((t < 4) && !Free); ++t) {
it = (t == 1) ? (i + y - 1) % y : (t == 3) ? (i + 1) % y : i;
jt = (t == 2) ? (j + x - 1) % x : (t == 0) ? (j + 1) % x : j;
switch (field[it][jt].content) {
case SPACE:
case GRASS:
case RMONSTER:
case LMONSTER:
case EATER:
Free = TRUE;
break;
case BLOB:
Free = (Free || ((field[it][jt].checked == 1) ?
!field[i][j].caught : !caught(it, jt)));
break;
default:
break;
}
}
field[i][j].caught != Free;
return (!Free);
}
void diaboulderproc(i, j)
int i, j;
{
if (field[i][j].content == DIAMOND)
blink(i, j);
ii = (ii + 1) % y;
field[i][j].dir = NODIR;
switch (field[ii][j].content) {
case SPACE: /* directly underneath */
move_cell(i, j, ii, j);
field[ii][j].speed = 1;
break;
case PLAYER:
if (field[i][j].speed) {
set_cell(i, j, SPACE);
explode(ii, j, SPACEEXPLO);
lives--;
scoreobs = TRUE;
}
break;
case LMONSTER:
case EATER:
if (field[i][j].speed) {
set_cell(i, j, SPACE);
explode(ii, j, SPACEEXPLO);
}
break;
case RMONSTER:
if (field[i][j].speed) {
set_cell(i, j, SPACE);
explode(ii, j, DIAEXPLO);
}
break;
case TINKLE:
if (field[i][j].speed) {
tinkact = TRUE;
field[ii][j].stage = field[i][j].content;
field[ii][j].speed = 1;
set_cell(i, j, SPACE);
break;
}
break;
case WALL:
case BOULDER:
case DIAMOND:
case EXPLOSION:
jj = (j + 1) % x;
if (field[i][jj].content == SPACE && field[ii][jj].content == SPACE) {
move_cell(i, j, i, jj);
field[i][jj].speed = 0;
}
else {
jj = (j - 1) % x;
if (field[i][jj].content == SPACE && field[ii][jj].content == SPACE) {
move_cell(i, j, i, jj);
field[i][jj].speed = 0;
}
else
field[i][j].speed = 0;
}
break;
default:
field[i][j].speed = 0;
break;
}
}
void calculate_field()
{
players = 0;
/* Iterate through each horizontal line */
if (!curtime)
curorder = KILL;
for (i = y - 1; i >= 0; --i) {
for (j = 0; j < x; ++j) {
if (!(field[i][j].changed)) {
ii = i;
jj = j;
switch (field[i][j].content) {
case PLAYER:
players++;
switch (curorder) {
case STAND:
break;
case UP:
ii = (i + y - 1) % y;
break;
case DOWN:
ii = (i + 1) % y;
break;
case LEFT:
jj = (j + x - 1) % x;
break;
case RIGHT:
jj = (j + 1) % x;
break;
}
if (!(curorder == STAND) && !(field[i][j].changed)) {
if (curorder == KILL) {
set_cell(i, j, EXPLOSION);
lives--;
scoreobs = TRUE;
break;
}
switch (field[ii][jj].content) {
case SPACE:
case GRASS:
case DIAMOND:
if (field[ii][jj].content == DIAMOND) {
if (curorder == UP && field[ii][jj].speed)
break;
score += diapoints;
if (diareq)
diareq--;
scoreobs = TRUE;
}
if (steal)
set_cell(ii, jj, SPACE);
else
move_cell(i, j, ii, jj);
break;
case BOULDER:
jjj = (2 * jj - j + x) % x;
if (field[i][jjj].content == SPACE &&
((rand() % 2) == 0) &&
!(field[ii][jj].dir == E)) {
move_cell(i, jj, i, jjj);
field[i][jjj].speed = 0;
if (!steal) {
move_cell(i, j, i, jj);
}
}
break;
case EXIT:
if (diareq < 1) {
if (!steal)
move_cell(i, j, ii, jj);
else
set_cell(ii, jj, SPACE);
if (!levincreased) {
levelnum++;
lives++;
levincreased = TRUE;
for (jj = curtime / 10; jj > 0; --jj) {
score += 10;
draw_score();
}
}
gamestop = TRUE;
stoplevel = TRUE;
}
break;
}
}
blink(i, j);
break;
case DIAMOND:
case BOULDER:
diaboulderproc(i, j);
break;
case EATER:
if (!field[i][j].speed) {
for (jjj = 0; ((!field[i][j].changed) && (jjj < 4)); ++jjj) {
ii = (jjj == 2) ? (i + 1) % y : (jjj == 0) ? (i + y - 1) % y : i;
jj = (jjj == 1) ? (j + 1) % x : (jjj == 3) ? (j + x - 1) % x : j;
switch (field[ii][jj].content) {
case PLAYER:
lives--;
scoreobs = TRUE;
case DIAMOND:
if (field[ii][jj].speed && (ii == i - 1) && (jj == j))
break;
case BLOB:
case LMONSTER:
case RMONSTER:
case NUCBAL:
move_cell(i, j, ii, jj);
break;
default:
break;
}
}
}
else {
jjj = field[i][j].dir;
ii = (jjj == 2) ? (i + 1) % y : (jjj == 0) ? (i + y - 1) % y : i;
jj = (jjj == 1) ? (j + 1) % x : (jjj == 3) ? (j + x - 1) % x : j;
switch (field[ii][jj].content) {
case LMONSTER:
case BLOB:
case SPACE:
case GRASS:
case DIAMOND:
case RMONSTER:
case PLAYER:
case NUCBAL:
if (field[ii][jj].content == PLAYER) {
lives--;
scoreobs = TRUE;
}
move_cell(i, j, ii, jj);
break;
case BOULDER:
jjj = (2 * jj - j + x) % x;
if (field[i][jjj].content == SPACE &&
((rand() % 2) == 0) &&
!(field[ii][jj].dir == E)) {
move_cell(i, jj, i, jjj);
move_cell(i, j, i, jj);
}
else
field[i][j].speed = 0;
break;
default:
field[i][j].speed = 0;
break;
}
}
blink(i, j);
break;
case RMONSTER:
blink(i, j);
if (search_destroy(RMONSTER))
break;
jjj = 3;
while (jjj >= 0 && !move_monster(RMONSTER, (field[i][j].dir + jjj + 2) % 4))
jjj--;
break;
case LMONSTER:
blink(i, j);
if (search_destroy(LMONSTER))
break;
jjj = 0;
while (jjj <= 4 && !move_monster(LMONSTER, (field[i][j].dir + jjj + 3) % 4))
jjj++;
break;
case EXPLOSION:
jjj = field[i][j].stage;
if (!(jjj % 5)) {
jjj++; /* use jjj for setting new stage */
ii = (i + 1) % y;
jj = (j + 1) % x;
explode(i, j, jjj);
explode(i, jj, jjj);
explode(ii, j, jjj);
explode(ii, jj, jjj);
ii = (i + y - 1) % y;
explode(ii, j, jjj);
explode(ii, jj, jjj);
jj = (j + x - 1) % x;
explode(ii, jj, jjj);
explode(i, jj, jjj);
ii = (i + 1) % y;
explode(ii, jj, jjj);
}
else {
if (jjj % 10 < 3)
field[i][j].stage++;
else
if (jjj > DIAEXPLO) {
set_cell(i, j, DIAMOND);
}
else
if (jjj > BOULDEXPLO) {
set_cell(i, j, BOULDER);
}
else
if (jjj > SPACEEXPLO) {
set_cell(i, j, SPACE);
}
else
field[i][j].stage++;
}
break;
case EXIT:
blink(i, j);
break;
case BLOB:
blobcells++;
if (blobcollapse)
set_cell(i, j, BOULDER);
else {
if (blobcells > critical)
blobcollapse = TRUE;
else {
if (!field[i][j].checked) {
if (caught(i, j))
propagate(i, j, DIAMOND);
else
propagate(i, j, FALSE);
}
field[i][j].checked = FALSE;
field[i][j].caught = TRUE;
}
}
blink(i, j);
break;
case NUCBAL:
for (jjj = 0; ((jjj < 3) && !move_nucbal(i, j, jjj)); ++jjj);
blink(i, j);
break;
case MAGICWALL:
jj = (j + x - 1) % x;
if (field[i][jj].content == SPACE)
set_cell(i, jj, MAGICWALL);
jj = (j + 1) % x;
if (field[i][jj].content == SPACE)
set_cell(i, jj, MAGICWALL);
break;
case TINKLE:
if (tinkact) {
blink(i, j);
if (tinkdur > 0) {
switch (field[i][j].stage) {
case BOULDER:
{
field[i][j].content = DIAMOND;
diaboulderproc(i, j);
break;
}
case DIAMOND:
{
field[i][j].content = BOULDER;
diaboulderproc(i, j);
break;
}
default:
break;
}
}
}
set_cell(i, j, TINKLE); /* reset to empty tinkle wall */
break;
default:
break;
}
}
}
}
curorder = STAND; /* reset orders */
blobcells = 0;
pgc = (pgc == pgc1) ? ((rand() % 22) == 0) ? pgc2 : pgc1 : pgc1;
dgc = (dgc == dgc1) ? dgc2 : dgc1;
lgc = (lgc == lgc1) ? lgc2 : lgc1;
rgc = (rgc == rgc1) ? rgc2 : rgc1;
egc = (egc == egc1) ? egc2 : egc1;
Bgc = (Bgc == Bgc1) ? Bgc2 : Bgc1;
if (tinkact)
tgc = (tgc == tgc1) ? tgc2 : tgc1;
if (!diareq) {
Egc = (Egc == Egc1) ? Egc2 : Egc1;
if (diareq == 0) {
diapoints = extradiapoints;
scoreobs = TRUE;
}
}
}