Quote: "If you had an array 200*100 and you put a 1 in random slots that are adjacent but not diagonal you get the same effect with no bugs. But I don't think that you are considering roads. I would make the roads first, and then fill in the gaps with buildings."
I agree. I would break everything into a grid. I would start with an empty space and fill it with a generic flat/empty city variation like generic grass lawn or paved parking lot.
Then I would begin laying roads. Maybe the roads would be in square city block orientations. Or possibly randomly placed horizontal and vertical roads.
Id then have code to run through all of the squares looking for intersecting roads, changing those areas to intersection grid pieces.
I'd plot any essential buildings or parts at this point.
Then I'd begin selecting buildings or building parts, starting with the largest variety and searching for random roadside spaces for them to be plotted. Id work my way down to the smaller pieces.
There's a lot of places where randomness can be inserted.
For more sophisticated things like diagonal roads, etc. You really just need to build on a framework like this. Create all of the grid based segments for what ever you are making, in a way where they can snap together with basically any other part. Some exceptions are okay. Such as you really don't want road to cut away immediately to grass. So make a dead end roadway piece, and program the city generator to always cap the ends of roads with it. In that specific case it might be good to have several dead end variations that the generator selects for variety.