home *** CD-ROM | disk | FTP | other *** search
- /*
- ** makestreet.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__
- int makestreet(int chosencell,int streetid,int streetpoints)
- #else
- int makestreet(chosencell,streetid,streetpoints)
- int chosencell,streetid, streetpoints;
- #endif
- {
-
- int choseni, chosenj;
- int nhbrid, nextnhbrid, thirdnhbrid;
- int streetwalk, highstreetnum, lowstreetnum;
- int canstraighten;
-
- /*
- ** Check that a street isn't going in next to an unused cell; if it is,
- ** mark it dead, instead if it's live; in any case, refuse to do it.
- */
-
- for (nhbrid = 0; nhbrid < 4; nhbrid++)
- {
- if (nhbrexists(chosencell,nhbrid))
- if (statlist[nhbris(chosencell,nhbrid)].status == UNUSED)
- {
- if (statlist[chosencell].status == LIVE)
- movefromto(&live,&livect,&dead,&deadct,DEAD,chosencell);
- return(1==0);
- }
- }
-
- /*
- ** Check for and abide by straightness control
- */
-
- if ((mazestraightness > 0) && (streetpoints == -1))
- if ((RANDOM()%1000) < mazestraightness)
- {
- canstraighten = (1==0);
- for (nhbrid = 0; nhbrid < 4; nhbrid++)
- if (nhbrexists(chosencell,nhbrid))
- if (statlist[nhbris(chosencell,nhbrid)].streetdir ==
- ((nhbrid+2)%4))
- canstraighten = (1==1);
- if (!canstraighten) return(1==0);
- }
- /*
- ** Update the chosen cell in the status list
- */
- switch (statlist[chosencell].status)
- {
- case UNUSED:
- case STREET:
- fprintf(stderr,"error picking street; bad cell status %d\n",
- statlist[chosencell].status);
- freespace();
- exit(1);
- break;
-
- case LIVE:
- /* fprintf(stderr,"moving cell %d from live to street\n",chosencell); */
- movefromto(&live,&livect,&street,&streetct,STREET,chosencell);
- break;
-
- case DEAD:
- /* fprintf(stderr,"moving cell %d from dead to street\n",chosencell); */
- movefromto(&dead,&deadct,&street,&streetct,STREET,chosencell);
- break;
-
- case ISOLATED:
- /* fprintf(stderr,"moving cell %d from isolated to street\n",chosencell);*/
- movefromto(&isolated,&isolatedct,&street,&streetct,STREET,chosencell);
- break;
-
- default:
- fprintf(stderr,"unexpected chosencell status in makegates %d\n",
- statlist[chosencell].status);
- }
-
- /*
- ** Give the street the required streetid, either new or continuing an
- ** existing street.
- */
-
- statlist[chosencell].streetnum = streetid;
-
- /*
- ** Update the chosen cell on the map.
- */
-
- choseni = chosencell / (mazewidth/2);
- chosenj = chosencell % (mazewidth/2);
-
- choseni = 2 * choseni + 1;
- chosenj = 2 * chosenj + 1;
-
- cmaze[choseni - 1][chosenj] = HDOOR;
- cmaze[choseni][chosenj + 1] = VDOOR;
- cmaze[choseni + 1][chosenj] = HDOOR;
- cmaze[choseni][chosenj - 1] = VDOOR;
-
- /*
- ** Update the neighbors of the new street cell;
- */
-
- for (nhbrid = 0; nhbrid < 4; nhbrid++)
- {
- if (nhbrexists(chosencell,nhbrid))
- switch (statlist[nhbris(chosencell,nhbrid)].status)
- {
- case UNUSED:
- fprintf(stderr,
- "logic error; tried to put a street beside an unused cell\n");
- showdebugmaze();
- freespace();
- exit(1);
- break;
- case STREET:
- switch (nhbrid) /* change the door to a passage, adopt a continuing */
- { /* direction from a neighbor street */
- case 0:
- cmaze[choseni - 1][chosenj] = BLANK;
- if (statlist[nhbris(chosencell,nhbrid)].streetdir == 2)
- statlist[chosencell].streetdir = 2;
- break;
- case 1:
- cmaze[choseni][chosenj + 1] = BLANK;
- if (statlist[nhbris(chosencell,nhbrid)].streetdir == 3)
- statlist[chosencell].streetdir = 3;
- break;
- case 2:
- cmaze[choseni + 1][chosenj] = BLANK;
- if (statlist[nhbris(chosencell,nhbrid)].streetdir == 0)
- statlist[chosencell].streetdir = 0;
- break;
- case 3:
- cmaze[choseni][chosenj - 1] = BLANK;
- if (statlist[nhbris(chosencell,nhbrid)].streetdir == 1)
- statlist[chosencell].streetdir = 1;
- break;
- default:
- fprintf(stderr,"bad nhbrid in nhbr update street switch case\n");
- /* The above should be impossible; nhbrexists and nhbris already */
- /* both checked for this problem */
- showdebugmaze();
- freespace();
- exit(1);
- }
-
- if (statlist[chosencell].streetnum !=
- statlist[nhbris(chosencell,nhbrid)].streetnum)
- {
-
- /*
- ** Two different streets have met; merge their streetids and decrement the
- ** streetcount.
- */
-
- lowstreetnum =
- ( ( statlist[chosencell].streetnum >
- statlist[nhbris(chosencell,nhbrid)].streetnum )
- ? statlist[nhbris(chosencell,nhbrid)].streetnum
- : statlist[chosencell].streetnum
- );
- highstreetnum =
- ( ( statlist[chosencell].streetnum <
- statlist[nhbris(chosencell,nhbrid)].streetnum )
- ? statlist[nhbris(chosencell,nhbrid)].streetnum
- : statlist[chosencell].streetnum
- );
-
- streetwalk = street;
- while (streetwalk != NOPOINTER)
- {
- if (statlist[streetwalk].streetnum == highstreetnum)
- statlist[streetwalk].streetnum = lowstreetnum;
- streetwalk = statlist[streetwalk].next;
- }
- streetnumct--;
- }
- break;
- case DEAD: /* do nothing; that's why it's called dead */
- break;
- case LIVE:
- movefromto(&live,&livect,&dead,&deadct,DEAD,nhbris(chosencell,nhbrid));
- for (nextnhbrid = 0; nextnhbrid < 4; nextnhbrid++)
- if (nhbrexists(nhbris(chosencell,nhbrid),nextnhbrid))
- if (statlist[nhbris(nhbris(chosencell,nhbrid),nextnhbrid)].status
- == ISOLATED)
- {
- movefromto(&dead,&deadct,&live,&livect,LIVE,
- nhbris(chosencell,nhbrid));
- break;
- }
- break;
- case ISOLATED:
- movefromto(&isolated,&isolatedct,&dead,&deadct,DEAD,
- nhbris(chosencell,nhbrid));
- statlist[nhbris(chosencell,nhbrid)].status = DEAD;
- /*
- ** Only let an isolated cell become live if it is interior; stops
- ** streets from running along the city wall, creating lots of gates.
- ** Don't make it live if it is next to an unused cell, either, since
- ** it can never become a street cell.
- */
- if ( interiorcell(nhbris(chosencell,nhbrid))
- && (statlist[nhbris(nhbris(chosencell,nhbrid),0)].status != UNUSED)
- && (statlist[nhbris(nhbris(chosencell,nhbrid),1)].status != UNUSED)
- && (statlist[nhbris(nhbris(chosencell,nhbrid),2)].status != UNUSED)
- && (statlist[nhbris(nhbris(chosencell,nhbrid),3)].status != UNUSED)
- )
- for (nextnhbrid = 0; nextnhbrid < 4; nextnhbrid++)
- if (nhbrexists(nhbris(chosencell,nhbrid),nextnhbrid))
- if (statlist[nhbris(nhbris(chosencell,nhbrid),nextnhbrid)].status
- == ISOLATED)
- {
- movefromto(&dead,&deadct,&live,&livect,LIVE,
- nhbris(chosencell,nhbrid));
- break;
- }
- /*
- ** When an isolated cell stops being so, neighbors may stop being live
- ** that were depending on it for that status; we're not done!
- */
- for (nextnhbrid = 0; nextnhbrid < 4; nextnhbrid++)
- if (nhbrexists(nhbris(chosencell,nhbrid),nextnhbrid))
- if (statlist[nhbris(nhbris(chosencell,nhbrid),nextnhbrid)].status
- == LIVE)
- {
- movefromto(&live,&livect,&dead,&deadct,DEAD,
- nhbris(nhbris(chosencell,nhbrid),nextnhbrid));
- for (thirdnhbrid =0; thirdnhbrid <4; thirdnhbrid++)
- {
- if (nhbrexists(nhbris(nhbris(chosencell,
- nhbrid),
- nextnhbrid),
- thirdnhbrid))
- if (statlist[nhbris(nhbris(nhbris(chosencell,
- nhbrid),
- nextnhbrid),
- thirdnhbrid)].status
- == ISOLATED)
- {
- movefromto(&dead,&deadct,&live,&livect,LIVE,
- nhbris(nhbris(chosencell,nhbrid),nextnhbrid));
- break;
- }
- }
- }
- break;
- default:
- fprintf(stderr,"bad statlist[%d].status entry %d\n",
- nhbris(chosencell,nhbrid),
- statlist[nhbris(chosencell,nhbrid)].status);
- showdebugmaze();
- freespace();
- exit(1);
- }
- }
- if (statlist[chosencell].streetdir == -1)
- if (streetpoints != -1)
- statlist[chosencell].streetdir = streetpoints;
- else
- {
- for (nhbrid = 0; nhbrid < 4; nhbrid++)
- {
- if (nhbrexists(chosencell,nhbrid))
- if (statlist[nhbris(chosencell,nhbrid)].status == STREET)
- {
- statlist[chosencell].streetdir = ((nhbrid +2)%4);
- break;
- }
- }
- }
- /* showdebugmaze(); */
- return(1==1);
- }
-