/*
** makeunused.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 makeunused()
#else
int makeunused()
#endif
{

  int totalcells;
  int chosencell;
  int tries;
  int i;
  int mazei, mazej;
/*
** Pepper unused cells around the city interior; keep them apart for
** algorithmic robustness and connectivity reasons.
*/

#if PROGRESS
  fprintf(stderr,"Unused ");
#endif

  totalcells = ((mazeheight-1)/2 * (mazewidth-1)/2);

  for (i = 0; i < mazeunused; i++)
  {

/*  fprintf(stderr,"Unused %d\n",i); */

/*
** Set up to prevent infinite loop from unforseen geometry problems.
*/

   tries = 0;

/*
** Keep looking until a candidate cell is found for this ith unused cell.
*/
    do
    {
      /* not perfectly fair, but good enough for moderate sized mazes. */

      chosencell = RANDOM()%totalcells;

/*    fprintf(stderr,"  chosencell %d\n",chosencell); */

      tries++;

/*
** Some C compilers couldn't cope with the big ugly while condition that used
** to be here, so it has become an internal routine called here.  Thanks to
** dwade@jarthur.Claremont.edu and rmk@rmkhome.uucp (Rick Kelly) for reporting
** the problem.
*/

    } while ((tries <= MAXTRIES) && wimpy_cc(chosencell));

    if (tries <= MAXTRIES)
    {
      movefromto(&isolated,&isolatedct,&unused,&unusedct,UNUSED,chosencell);
      mazei = (chosencell/((mazewidth-1)/2));
      mazej = (chosencell%((mazewidth-1)/2));
      mazei = (2*mazei) + 1;
      mazej = (2*mazej) + 1;
      cmaze[mazei][mazej] = WALL;
/*
** Tried moving neighbors of unused cells to the DEAD list here; big mistake;
** ended up with isolated dead cells; let the later routines do it.
*/
    }
  }
  return;
}

/*
** Several compilers across the net died trying to digest what is now the
** contents of this routine as a single statement.  Sigh.
*/

#ifdef __STDC__
int wimpy_cc(int chosencell)
#else
int wimpy_cc(chosencell)
  int chosencell;
#endif

{

/*

To avoid locking in an isolated room, check all 49 cells centered on
this cell, the hard way: no loop, no direct index to the cells. Goal
is to be able to run a street on all four sides of the 3x3 cell array
centered at this cell. 

First verify cell and immediate neighbors two out all have all their
neighbors; if not, we're too close to a border. 

  if (interiorcell(chosencell) != (1==1)) return((1==1));

  if (interiorcell(nhbris(chosencell,0)) != (1==1)) return((1==1));

  if (interiorcell(nhbris(nhbris(chosencell,0),0)) != (1==1)) return((1==1));

  if (interiorcell(nhbris(chosencell,1)) != (1==1)) return((1==1));

  if (interiorcell(nhbris(nhbris(chosencell,1),1)) != (1==1)) return((1==1));

  if (interiorcell(nhbris(chosencell,2)) != (1==1)) return((1==1));

  if (interiorcell(nhbris(nhbris(chosencell,2),2)) != (1==1)) return((1==1));

  if (interiorcell(nhbris(chosencell,3)) != (1==1)) return((1==1));

  if (interiorcell(nhbris(nhbris(chosencell,3),3)) != (1==1)) return((1==1));

/*
** Now check all 49 cells for ISOLATED status -- yeech!
**
** Check the chosen cell.
*/

  if (statlist[chosencell].status != ISOLATED)  return((1==1));
/*
** Check to the north/up.
*/

  if (statlist[nhbris(chosencell,0)].status != ISOLATED) return((1==1));

  if (statlist[nhbris(nhbris(chosencell,0),0)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,0),0),1)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,0),0),3)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,0),0),3),3)].status
      != ISOLATED)
     return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,0),0),0)].status != ISOLATED)
     return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,0),0),0),1)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,0),0),0),1),1)
              ].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,0),0),0),3)].status
      != ISOLATED)
   	 return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,0),0),0),3),3)
              ].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,0),0),
               0),3),3),3)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(chosencell,0),3)].status != ISOLATED)
    return((1==1));

/*
** Check to the east/right.
*/

  if (statlist[nhbris(chosencell,1)].status != ISOLATED) return((1==1));

  if (statlist[nhbris(nhbris(chosencell,1),0)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(chosencell,1),1)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,1),1),2)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,1),1),0)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,1),1),0),0)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,1),1),1)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,1),1),1),2)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,1),1),1),2),2)
              ].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,1),1),1),0)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,1),1),1),0),0)
              ].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,1),1),
                      1),0),0),0)].status != ISOLATED)
    return((1==1));

/*
** check to the south/down
*/

  if (statlist[nhbris(chosencell,2)].status != ISOLATED) return((1==1));

  if (statlist[nhbris(nhbris(chosencell,2),1)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(chosencell,2),2)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,2),2),3)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,2),2),1)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,2),2),1),1)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,2),2),2)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,2),2),2),3)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,2),2),2),3),3)
              ].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,2),2),2),1)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,2),2),2),1),1)
              ].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,2),2),
               2),1),1),1)].status != ISOLATED)
    return((1==1));

/*
** check to the west/left
*/

  if (statlist[nhbris(chosencell,3)].status != ISOLATED) return((1==1));

  if (statlist[nhbris(nhbris(chosencell,3),2)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(chosencell,3),3)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,3),3),0)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,3),3),2)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,3),3),2),2)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(chosencell,3),3),3)].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,3),3),3),0)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,3),3),3),0),0)
              ].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(chosencell,3),3),3),2)].status
      != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,3),3),3),2),2)
              ].status != ISOLATED)
    return((1==1));

  if (statlist[nhbris(nhbris(nhbris(nhbris(nhbris(nhbris(chosencell,3),3),
               3),2),2),2)].status != ISOLATED)
    return((1==1));

/*
** Found no unisolated cell!  Celebrate the good news.
*/
    return((1==0));

}
