home *** CD-ROM | disk | FTP | other *** search
- /*
- ** connectst.c Copyright 1991 Kent Paul Dolan,
- ** Mountain View, CA, USA 94039-0755
- **
- ** Written to satisfy an inquiry on USENet's rec.games.programmer newsgroup.
- ** May be freely used or modified in any non-commercial work. Copyrighted
- ** only to prevent patenting by someone else.
- */
-
- #include <stdio.h>
- #include "townmaze.h"
- #include "townproto.h"
-
- #ifdef __STDC__
- void connectstreets()
- #else
- int connectstreets()
- #endif
- {
- int targetcell;
- int livewalk, i;
- int deadwalk, lastdead, j, k;
- int cheapdir;
- int nhbrid;
-
- /*
- ** Sanity check; make sure we don't go spinning off with no work possible.
- */
-
- if (streetnumct < 1)
- {
- fprintf(stderr,"No streets seeded! Oops! Logic bomb!\n");
- freespace();
- exit(1);
- }
-
- /*
- ** Three phase maneuver; phase 1, try to connect streets by using live
- ** cells to turn into street cells.
- */
-
- #if PROGRESS
- fprintf(stderr,"Streets 1 ");
- #endif
-
-
- while((streetnumct > 1) && (livect > 0))
- {
- targetcell = RANDOM()%livect;
- livewalk = live;
- for (i = 0; i < (targetcell - 1); i++)
- if (livewalk == NOPOINTER)
- {
- fprintf(stderr,"live list too short in connectstreets\n");
- showdebugmaze();
- freespace();
- exit(1);
- }
- else
- {
- livewalk = statlist[livewalk].next;
- }
- /*
- ** Since this is a live cell, it is supposed to have a street cell
- ** neighbor; find one and adopt its street number. If directions
- ** are implemented, then this has to be expanded to pick a random
- ** neighbor street fairly and adopt its number and direction.
- ** [Done in makestreet(), instead, by the "-1" direction parameter..]
- */
- for (nhbrid = 0; nhbrid < 4; nhbrid++)
- if (nhbrexists(livewalk,nhbrid))
- if (statlist[nhbris(livewalk,nhbrid)].status == STREET)
- {
- makestreet(livewalk,
- statlist[nhbris(livewalk,nhbrid)].streetnum,-1);
- break;
- }
- }
-
- /*
- ** Phase 2: try for a cheap connect by only using dead cells between streets
- ** with different streetnums; this should get some more streets connected,
- ** without turning the whole map into streets.
- */
-
- if ((streetnumct > 1) && (deadct > 0))
- {
-
- #if PROGRESS
- fprintf(stderr,"Streets 2 ");
- #endif
-
- deadwalk = dead;
- for (i = 0; i < deadct; i++)
- {
- if (deadwalk == NOPOINTER) break;
- if (streetnumct <= 1) break;
- lastdead = deadwalk;
- deadwalk = statlist[deadwalk].next;
- if (interiorcell(lastdead))
- {
- for (j = 0; j < 4; j++)
- if (nhbrexists(lastdead,j))
- for (k = 0; k < 4; k++)
- {
- if (j == k) continue;
- if (nhbrexists(lastdead,k))
- /*
- ** The reason this loop doesn't keep trying to make a street out of the
- ** chosen cell after it has done so once is that makestreet() causes
- ** all the adjacent streets to be merged and have the same street number,
- ** so that the next if always fails after the first success. It can thus
- ** safely be let run to completion.
- */
- if ( (statlist[nhbris(lastdead,j)].status == STREET)
- && (statlist[nhbris(lastdead,k)].status == STREET)
- && (statlist[nhbris(lastdead,j)].streetnum
- != statlist[nhbris(lastdead,k)].streetnum)
- )
- {
- cheapdir = ((j+2)%4);
- if (statlist[nhbris(lastdead,k)].streetdir == ((k+2)%4))
- cheapdir = ((k+2)%4);
- makestreet(lastdead,statlist[nhbris(lastdead,j)].streetnum,
- cheapdir);
- }
- }
- }
-
- }
- }
-
- /*
- ** Phase 3: when out of luck, use brute force (haven't ever seen this
- ** required, but can't prove it isn't)..
- */
-
- #if PROGRESS
- if (streetnumct > 1) fprintf(stderr,"Streets 3 ");
- #endif
-
- while((streetnumct > 1) && (deadct > 0))
- {
- targetcell = RANDOM()%deadct;
- deadwalk = dead;
- for (i = 0; i < (targetcell - 1); i++)
- if (deadwalk == NOPOINTER)
- {
- fprintf(stderr,"dead list too short in connectstreets\n");
- showdebugmaze();
- freespace();
- exit(1);
- }
- else
- {
- deadwalk = statlist[deadwalk].next;
- }
- /*
- ** Since this is a dead cell, it is necessary to check that it is an interior
- ** one. This should again be enhanced when directions are installed.
- */
- if (interiorcell(deadwalk))
- {
- for (nhbrid = 0; nhbrid < 4; nhbrid++)
- if (nhbrexists(deadwalk,nhbrid))
- if (statlist[nhbris(deadwalk,nhbrid)].status == STREET)
- {
- makestreet(deadwalk,
- statlist[nhbris(deadwalk,nhbrid)].streetnum,-1);
- break;
- }
- }
- }
-
- }
-