Mercurial > hg > early-roguelike
diff urogue/maze.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 31 Jan 2017 19:56:04 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/maze.c Tue Jan 31 19:56:04 2017 -0500 @@ -0,0 +1,333 @@ +/* + maze.c - functions for dealing with armor + + UltraRogue: The Ultimate Adventure in the Dungeons of Doom + Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong + All rights reserved. + + Based on "Advanced Rogue" + Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka + All rights reserved. + + See the file LICENSE.TXT for full copyright and licensing information. +*/ + +#include <stdlib.h> +#include "rogue.h" + +static char *frontier; +static char *bits; +static int urlines; +static int urcols; + +/* + domaze() + Draw the maze on this level. +*/ + +void +do_maze(void) +{ + int i, least; + struct room *rp; + struct linked_list *item; + struct object *obj; + struct thing *mp; + int treas; + coord tp; + + for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) + { + rp->r_nexits = 0; /* no exits */ + rp->r_flags = ISGONE; /* kill all rooms */ + rp->r_fires = 0; /* no fires */ + } + + rp = &rooms[0]; /* point to only room */ + rp->r_flags = ISDARK; /* mazes always dark */ + rp->r_pos.x = 0; /* room fills whole screen */ + rp->r_pos.y = 1; + rp->r_max.x = COLS - 1; + rp->r_max.y = LINES - 3; + draw_maze(); /* put maze into window */ + + /* add some gold to make it worth looking for */ + + item = spec_item(GOLD, 0, 0, 0); + obj = OBJPTR(item); + obj->o_count *= (rnd(10) + 5); /* add in one large hunk */ + + do + { + rnd_pos(rp, &tp); + } + while( mvwinch(stdscr, tp.y, tp.x) != FLOOR); + + obj->o_pos = tp; + add_obj(item, tp.y, tp.x); + + /* add in some food to make sure he has enough */ + + item = spec_item(FOOD, 0, 0, 0); + obj = OBJPTR(item); + + do + { + rnd_pos(rp, &tp); + } + while( mvwinch(stdscr, tp.y, tp.x) != FLOOR); + + obj->o_pos = tp; + add_obj(item, tp.y, tp.x); + + if (rnd(100) < 5) /* 5% for treasure maze level */ + { + treas = TRUE; + least = 20; + debug("Treasure maze."); + } + else /* normal maze level */ + { + least = 1; + treas = FALSE; + } + + for (i = 0; i < level + least; i++) + { + if (!treas && rnd(100) < 50) /* put in some little buggers */ + continue; + + /* Put the monster in */ + + item = new_item(sizeof *mp); + + mp = THINGPTR(item); + + do + { + rnd_pos(rp, &tp); + } + while(mvwinch(stdscr, tp.y, tp.x) != FLOOR); + + new_monster(item, randmonster(NOWANDER, NOGRAB), &tp, NOMAXSTATS); + + /* See if we want to give it a treasure to carry around. */ + + if (rnd(100) < monsters[mp->t_index].m_carry) + attach(mp->t_pack, new_thing()); + + /* If it carries gold, give it some */ + + if (on(*mp, CARRYGOLD)) + { + item = spec_item(GOLD, 0, 0, 0); + obj = OBJPTR(item); + obj->o_count = GOLDCALC + GOLDCALC + GOLDCALC; + obj->o_pos = mp->t_pos; + attach(mp->t_pack, item); + } + + } +} + +/* + draw_maze() + Generate and draw the maze on the screen +*/ + +void +draw_maze(void) +{ + int i, j, more; + char *ptr; + + urlines = (LINES - 3) / 2; + urcols = (COLS - 1) / 2; + + bits = ur_alloc((unsigned int) ((LINES - 3) * (COLS - 1))); + frontier = ur_alloc((unsigned int) (urlines * urcols)); + ptr = frontier; + + while (ptr < (frontier + (urlines * urcols))) + *ptr++ = TRUE; + + for (i = 0; i < LINES - 3; i++) + { + for (j = 0; j < COLS - 1; j++) + { + if (i % 2 == 1 && j % 2 == 1) + *moffset(i, j) = FALSE; /* floor */ + else + *moffset(i, j) = TRUE; /* wall */ + } + } + + for (i = 0; i < urlines; i++) + { + for (j = 0; j < urcols; j++) + { + do + more = findcells(i, j); + while (more != 0); + } + } + + crankout(); + ur_free(frontier); + ur_free(bits); +} + +/* + moffset() + Calculate memory address for bits +*/ + +char * +moffset(int y, int x) +{ + return (bits + (y * (COLS - 1)) + x); +} + +/* + foffset() + Calculate memory address for frontier +*/ + +char * +foffset(int y, int x) +{ + return (frontier + (y * urcols) + x); +} + +/* + findcells() + Figure out cells to open up +*/ + +int +findcells(int y, int x) +{ + int rtpos, i; + + struct + { + int num_pos; /* number of frontier cells next to you */ + + struct + { + int y_pos; + int x_pos; + } conn[4]; /* the y,x position of above cell */ + } mborder; + + *foffset(y, x) = FALSE; + mborder.num_pos = 0; + + if (y < urlines - 1) { /* look below */ + if (*foffset(y + 1, x)) + { + mborder.conn[mborder.num_pos].y_pos = y + 1; + mborder.conn[mborder.num_pos].x_pos = x; + mborder.num_pos += 1; + } + } + + if (y > 0) /* look above */ + { + if (*foffset(y - 1, x)) + { + mborder.conn[mborder.num_pos].y_pos = y - 1; + mborder.conn[mborder.num_pos].x_pos = x; + mborder.num_pos += 1; + } + } + + if (x < urcols - 1) /* look right */ + { + if (*foffset(y, x + 1)) + { + mborder.conn[mborder.num_pos].y_pos = y; + mborder.conn[mborder.num_pos].x_pos = x + 1; + mborder.num_pos += 1; + } + } + + if (x > 0) /* look left */ + { + if (*foffset(y, x - 1)) + { + mborder.conn[mborder.num_pos].y_pos = y; + mborder.conn[mborder.num_pos].x_pos = x - 1; + mborder.num_pos += 1; + } + } + + if (mborder.num_pos == 0)/* no neighbors available */ + return(0); + else + { + i = rnd(mborder.num_pos); + rtpos = mborder.num_pos - 1; + rmwall(mborder.conn[i].y_pos, mborder.conn[i].x_pos, y, x); + return(rtpos); + } +} + +/* + rmwall() + Removes appropriate walls from the maze +*/ + +void +rmwall(int newy, int newx, int oldy, int oldx) +{ + int xdif, ydif; + + xdif = newx - oldx; + ydif = newy - oldy; + + *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE; + + findcells(newy, newx); +} + + +/* + crankout() + Does actual drawing of maze to window +*/ + +void +crankout(void) +{ + int x, y; + + for (y = 0; y < LINES - 3; y++) + { + move(y + 1, 0); + + for (x = 0; x < COLS - 1; x++) + { + if (*moffset(y, x)) /* here is a wall */ + { + if (y == 0 || y == LINES - 4) /* top or bottom line */ + addch('-'); + else if (x == 0 || x == COLS - 2) /* left | right side */ + addch('|'); + else if (y % 2 == 0 && x % 2 == 0) + { + if (*moffset(y, x - 1) || *moffset(y, x + 1)) + addch('-'); + else + addch('|'); + } + else if (y % 2 == 0) + addch('-'); + else + addch('|'); + } + else + addch(FLOOR); + } + } +}