151 lines
4.2 KiB
C
151 lines
4.2 KiB
C
/*
|
|
* static char *rcsid_map_c =
|
|
* "$Id: square_spiral.c 11578 2009-02-23 22:02:27Z lalo $";
|
|
*/
|
|
|
|
/*
|
|
CrossFire, A Multiplayer game for X-windows
|
|
|
|
Copyright (C) 2001 Mark Wedel & Crossfire Development Team
|
|
Copyright (C) 1992 Frank Tore Johansen
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
The authors can be reached via e-mail at crossfire-devel@real-time.com
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* Square-spiral layout generator.
|
|
* @todo
|
|
* what does that look like? :)
|
|
*/
|
|
|
|
/* peterm@langmuir.eecs.berkeley.edu: this function generates a random
|
|
snake-type layout.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <global.h>
|
|
#include <time.h>
|
|
|
|
#include <maze_gen.h>
|
|
#include <room_gen.h>
|
|
#include <random_map.h>
|
|
#include <sproto.h>
|
|
#include <rproto.h>
|
|
|
|
char **map_gen_onion(int xsize, int ysize, int option, int layers);
|
|
|
|
/* These are some helper functions which help with
|
|
manipulating a centered onion and turning it into
|
|
a square spiral */
|
|
|
|
/**
|
|
* This starts from within a centered onion layer (or between two layers),
|
|
* and looks up until it finds a wall, and then looks right until it
|
|
* finds a vertical wall, i.e., the corner. It sets cx and cy to that.
|
|
* it also starts from cx and cy.
|
|
* @param maze
|
|
* where to look.
|
|
* @param cx
|
|
* @param cy
|
|
* where to start from, and detected corner.
|
|
*/
|
|
void find_top_left_corner(char **maze, int *cx, int *cy) {
|
|
(*cy)--;
|
|
/* find the top wall. */
|
|
while (maze[*cx][*cy] == 0)
|
|
(*cy)--;
|
|
/* proceed right until a corner is detected */
|
|
while (maze[*cx][*cy+1] == 0)
|
|
(*cx)++;
|
|
|
|
/* cx and cy should now be the top-right corner of the onion layer */
|
|
}
|
|
|
|
/**
|
|
* Generates a square-spiral layout.
|
|
* @param xsize
|
|
* @param ysize
|
|
* size of the layout.
|
|
* @return
|
|
* generated layout.
|
|
* @todo
|
|
* use function in another file for character searching.
|
|
*/
|
|
char **make_square_spiral_layout(int xsize, int ysize) {
|
|
int i, j;
|
|
int cx, cy;
|
|
int tx, ty;
|
|
|
|
/* generate and allocate a doorless, centered onion */
|
|
char **maze = map_gen_onion(xsize, ysize, OPT_CENTERED|OPT_NO_DOORS, 0);
|
|
|
|
/* find the layout center. */
|
|
cx = 0;
|
|
cy = 0;
|
|
for (i = 0; i < xsize; i++)
|
|
for (j = 0; j < ysize; j++) {
|
|
if (maze[i][j] == 'C') {
|
|
cx = i;
|
|
cy = j;
|
|
}
|
|
}
|
|
tx = cx;
|
|
ty = cy;
|
|
while (1) {
|
|
find_top_left_corner(maze, &tx, &ty);
|
|
|
|
if (ty < 2 || tx < 2 || tx > xsize-2 || ty > ysize-2)
|
|
break;
|
|
make_wall(maze, tx, ty-1, 1); /* make a vertical wall with a door */
|
|
|
|
maze[tx][ty-1] = '#'; /* convert the door that make_wall puts here to a wall */
|
|
maze[tx-1][ty] = 'D';/* make a doorway out of this layer */
|
|
|
|
/* walk left until we find the top-left corner */
|
|
while ((tx > 2) && maze[tx-1][ty])
|
|
tx--;
|
|
|
|
make_wall(maze, tx-1, ty, 0); /* make a horizontal wall with a door */
|
|
|
|
/* walk down until we find the bottom-left corner */
|
|
while (((ty+1) < ysize) && maze[tx][ty+1])
|
|
ty++;
|
|
|
|
make_wall(maze, tx, ty+1, 1); /* make a vertical wall with a door */
|
|
|
|
/* walk rightuntil we find the bottom-right corner */
|
|
while (((tx+1) < xsize) && maze[tx+1][ty])
|
|
tx++;
|
|
|
|
make_wall(maze, tx+1, ty, 0); /* make a horizontal wall with a door */
|
|
tx++; /* set up for next layer. */
|
|
}
|
|
|
|
/* place the exits. */
|
|
if (RANDOM()%2) {
|
|
maze[cx][cy] = '>';
|
|
maze[xsize-2][1] = '<';
|
|
} else {
|
|
maze[cx][cy] = '<';
|
|
maze[xsize-2][1] = '>';
|
|
}
|
|
|
|
return maze;
|
|
}
|