Crossfire Server, Branch 1.12  R12190
square_spiral.c
Go to the documentation of this file.
00001 /*
00002  * static char *rcsid_map_c =
00003  *   "$Id: square_spiral.c 11578 2009-02-23 22:02:27Z lalo $";
00004  */
00005 
00006 /*
00007     CrossFire, A Multiplayer game for X-windows
00008 
00009     Copyright (C) 2001 Mark Wedel & Crossfire Development Team
00010     Copyright (C) 1992 Frank Tore Johansen
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025 
00026     The authors can be reached via e-mail at crossfire-devel@real-time.com
00027 */
00028 
00036 /* peterm@langmuir.eecs.berkeley.edu:  this function generates a random
00037 snake-type layout.
00038 */
00039 
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <global.h>
00043 #include <time.h>
00044 
00045 #include <maze_gen.h>
00046 #include <room_gen.h>
00047 #include <random_map.h>
00048 #include <sproto.h>
00049 #include <rproto.h>
00050 
00051 char **map_gen_onion(int xsize, int ysize, int option, int layers);
00052 
00053 /* These are some helper functions which help with
00054    manipulating a centered onion and turning it into
00055    a square spiral */
00056 
00068 void find_top_left_corner(char **maze, int *cx, int *cy) {
00069     (*cy)--;
00070     /* find the top wall. */
00071     while (maze[*cx][*cy] == 0)
00072         (*cy)--;
00073     /* proceed right until a corner is detected */
00074     while (maze[*cx][*cy+1] == 0)
00075         (*cx)++;
00076 
00077     /* cx and cy should now be the top-right corner of the onion layer */
00078 }
00079 
00090 char **make_square_spiral_layout(int xsize, int ysize) {
00091     int i, j;
00092     int cx, cy;
00093     int tx, ty;
00094 
00095     /* generate and allocate a doorless, centered onion */
00096     char **maze = map_gen_onion(xsize, ysize, OPT_CENTERED|OPT_NO_DOORS, 0);
00097 
00098     /* find the layout center.  */
00099     cx = 0;
00100     cy = 0;
00101     for (i = 0; i < xsize; i++)
00102         for (j = 0; j < ysize; j++) {
00103             if (maze[i][j] == 'C') {
00104                 cx = i;
00105                 cy = j;
00106             }
00107         }
00108     tx = cx;
00109     ty = cy;
00110     while (1) {
00111         find_top_left_corner(maze, &tx, &ty);
00112 
00113         if (ty < 2 || tx < 2 || tx > xsize-2 || ty > ysize-2)
00114             break;
00115         make_wall(maze, tx, ty-1, 1);  /* make a vertical wall with a door */
00116 
00117         maze[tx][ty-1] = '#'; /* convert the door that make_wall puts here to a wall */
00118         maze[tx-1][ty] = 'D';/* make a doorway out of this layer */
00119 
00120         /* walk left until we find the top-left corner */
00121         while ((tx > 2) && maze[tx-1][ty])
00122             tx--;
00123 
00124         make_wall(maze, tx-1, ty, 0);     /* make a horizontal wall with a door */
00125 
00126         /* walk down until we find the bottom-left corner */
00127         while (((ty+1) < ysize) && maze[tx][ty+1])
00128             ty++;
00129 
00130         make_wall(maze, tx, ty+1, 1);    /* make a vertical wall with a door */
00131 
00132         /* walk rightuntil we find the bottom-right corner */
00133         while (((tx+1) < xsize) && maze[tx+1][ty])
00134             tx++;
00135 
00136         make_wall(maze, tx+1, ty, 0);   /* make a horizontal wall with a door */
00137         tx++;  /* set up for next layer. */
00138     }
00139 
00140     /* place the exits.  */
00141     if (RANDOM()%2) {
00142         maze[cx][cy] = '>';
00143         maze[xsize-2][1] = '<';
00144     } else {
00145         maze[cx][cy] = '<';
00146         maze[xsize-2][1] = '>';
00147     }
00148 
00149     return maze;
00150 }