Hello Community

I'm currently trying my skill at javascripting for the first time in coding a Civilization Revolution clone. Perhaps not the easiest choice of task, I know. I've only gotten started and I'm already running into problems with the map generation. Thus, I would much appreciate your knowledgeable advice.

Below is the code I came up with. The problem that keeps occurring when running the code is this: Sometimes, the map generation will just stop short. (Infrequently, the map will generate completely.) As you will see upon inspecting my code, I'm using a div (with id = 'map') for displaying the map, appending other divs (with className = 'col') to it to make the map's columns and appending these with yet more divs (with className = 'tile') to make the actual tiles of the map.

When tweaking the code I found I could increase the chance of the map generating completely by decreasing the number of rows (stored in variable 'Rows'). In fact, it seems that once the first column has generated with all its tiles, so will the rest of the columns and the map will generate fully. That is to say: The abortion of the map generation only seems to occur whenever there's something wrong with the FIRST column.

I'm relying on a randomised variable (called 't') for the allocation of different terrains to the tiles. Perhaps that's what causes the bug?

Again: I would much appreciate your help in this matter. As of now, the map generation isn't all that fancy. I would really love to improve on it to come up with some nifty maps once this bug is squashed.

Here's my code:

<!doctype html>

<html>

<head>

<title>
A Map in Javascript
</title>

<style>

#map {
width: 2560px; // 80 tiles * 32px
height: 1440px; // 45 tiles * 32px
}

.col {
float: left;
width: 32px;
}

.tile {
width: 32px;
height: 32px;
}

</style>

<script>
// Draw Map
// ********

function drawMap () {
for (var x = 0; x < Cols; x++) {

// Create New Column-Div
// *********************
var newCol = document.createElement('div');
newCol.className = 'col';
document.getElementById('map').appendChild(newCol);

for (var y = 0; y < Rows; y++) {

// Create New Tile-Div
// *******************
var newTile = document.createElement('div');
newTile.className = 'tile';
document.getElementsByClassName('col')[x].appendChild(newTile);

if (map[x][y].terrain == "deep sea") newTile.style.background = "navy";
if (map[x][y].terrain == "shallow sea") newTile.style.background = "aqua";
if (map[x][y].terrain == "plain") newTile.style.background = "lawngreen";
if (map[x][y].terrain == "grassland") newTile.style.background = "limegreen";
if (map[x][y].terrain == "forest") newTile.style.background = "darkgreen";
if (map[x][y].terrain == "hill") newTile.style.background = "saddlebrown";
if (map[x][y].terrain == "mountain") newTile.style.background = "dimgrey";
if (map[x][y].terrain == "desert") newTile.style.background = "khaki";
if (map[x][y].terrain == "ice") newTile.style.background = "white";
}
}
}

// Tile-Constructor
// ****************

function tile (x, y, terrain) {
this.x = x;
this.y = y;
this.terrain = terrain;
}

// CheckAdjacentTilesForLand
// *************************

function checkAdjacentTilesForLand (x, y) {
if (map[x-1][y-1].terrain !== "sea") return true;
if (map[x] [y-1].terrain !== "sea") return true;
if (map[x+1][y-1].terrain !== "sea") return true;
if (map[x-1][y] .terrain !== "sea") return true;
if (map[x+1][y] .terrain !== "sea") return true;
if (map[x-1][y+1].terrain !== "sea") return true;
if (map[x] [y+1].terrain !== "sea") return true;
if (map[x+1][y+1].terrain !== "sea") return true;
return false;
}

// Set Map Dimensions
// ******************
var Cols = 80; // Set map width
var Rows = 45; // Set map height

// Set Partioning of Terrains
// **************************
var Sea = 40; // Set % of sea-tiles
var Plains = 10; // Set % of plain-tiles
var Grasslands = 10; // Set % of grassland-tiles
var Forests = 15; // Set % of forest-tiles
var Hills = 10; // Set % of hill-tiles
var Mountains = 10; // Set % of mountain-tiles
var Deserts = 5; // Set % of desert-tiles

if (Sea + Plains + Grasslands + Forests + Hills + Mountains + Deserts < 100) alert ('Too few!');
if (Sea + Plains + Grasslands + Forests + Hills + Mountains + Deserts > 100) alert ('Too much!');

// Initialize Map
// **************
var map = new Array (Cols);

for (var x = 0; x < Cols; x++) {

map[x] = new Array (Rows);

for (var y = 0; y < Rows; y++) {

// Set Terrain
// ***********
var t = Math.floor(Math.random()*100)+1;
var terrain;
if (t < Sea) terrain = "sea";
else if (t < Sea + Plains) terrain = "plain";
else if (t < Sea + Plains + Grasslands) terrain = "grassland";
else if (t < Sea + Plains + Grasslands + Forests) terrain = "forest";
else if (t < Sea + Plains + Grasslands + Forests + Hills) terrain = "hill";
else if (t < Sea + Plains + Grasslands + Forests + Hills + Mountains) terrain = "mountain";
else if (t < Sea + Plains + Grasslands + Forests + Hills + Mountains + Deserts) terrain = "desert";

// Add Ice-Caps
// ************
if (y == 0 || y == Rows-1) terrain = "ice";

// Shallow or Deep Sea
// *******************
if (terrain == "sea") {
if (checkAdjacentTilesForLand (x, y)) terrain = "shallow sea";
if (!checkAdjacentTilesForLand (x, y)) terrain = "deep sea";
}

// Create New Tile
// ***************
map[x][y] = new tile (x, y, terrain);
}
}
</script>

</head>

<body onload="drawMap()">

<div id="map"></div>

</body>

</html>