Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: Okay Here Goes...World and Map Generation.

  1. #1
    Junior Member
    Join Date
    Oct 2011
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Okay Here Goes...World and Map Generation. ##Mods: Is this in the right place?##

    If you haven't read my introduction post, please do: http://www.javaprogrammingforums.com...017-hello.html

    tl;dr version: I'm a fairly new-ish hobbiest java programmer teaching himself how to code, please don't hold "bad" coding practices against me, I did the best I knew how with what the google had to offer. =) This is my first *true post* on the forums. Thanks!

    I know there must be an easier way to do this, though I can't follow along with the examples I see on /the/ Google, so I attempted to write my own, and I have something now that works, albeit very shaky.

    So here it is. I'm trying to write the World and Map generator for a game. There is as of yet no real game, and just an Island Generator, and its shaky at best. It likes to randomly go out of bounds.

    My code consists of 6 classes in top down order:

    Mapper.java <-Main class for the generator.
    package com.kfgeeks.java.Mapper;
    import java.util.*;
     
     
    public class Mapper {
    	static Scanner ReadUserInput = new Scanner(System.in);
     
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		//I know...Looks stupid, but we're gonna make sure java works first  =P
    		//(Besides....Saying "Hello" is always more interesting than "Initializing Java..." Right?)
    		System.out.println("Hello Java!");
    		for (int i=0; i<10; i++){
    			System.out.println(i);
    			}
    		MapBuilder.run(40, 160);
     
    		}
    	}


    MapBuilder.java <-This class is responsible for managing all of the other builders, and telling them when to run. So far only Island Builder is Implemented, and assembling the map based on their output.
    package com.kfgeeks.java.Mapper;
     
    public class MapBuilder {
     
    	public static void run(int x, int y){
    		Map worldMap = new Map();
    		worldMap = buildMap(x, y);
    		worldMap = IslandBuilder.run(worldMap);
    		printMap(worldMap);
    	}
     
    	private static Map buildMap(int x, int y) {
    		Map worldMap = new Map();
    		worldMap.setHeight(x);
    		worldMap.setWidth(y);
    		worldMap.mapCells = new Cell[worldMap.getHeight()][];
    		for (int i = 0; i < worldMap.mapCells.length; i++) {
    			worldMap.mapCells[i] = new Cell[worldMap.getWidth()];
    			for (int j = 0; j < worldMap.mapCells[i].length; j++) {
    				worldMap.mapCells[i][j] = new Cell();
    				worldMap.mapCells[i][j].setTerrain(0);
    			}
    		}
    		return worldMap;
    	}
     
     
     
     
     
    	// Just a clever little Print function();
    	@SuppressWarnings("unused")
    	private void print(String s) {
    		System.out.println(s);
    	}
     
    	private static void printMap(Map passWorld_Map) {
    		Map worldMap = passWorld_Map;
    		for (int i = 0; i < worldMap.mapCells.length; i++) {
    			for (int j = 0; j < worldMap.mapCells[i].length; j++) {
    				System.out.print(worldMap.mapCells[i][j].getTerrain_Char());
    			}
    			System.out.print("\n");
    		}
    	}
    }

    IslandBuilder.java <-This class is responsible for building, as the name implies, the individual Islands on the map.

    package com.kfgeeks.java.Mapper;
     
    import java.util.Random;
     
    public class IslandBuilder {
     
    	public static Map run(Map passWorld_Map){
    		Map World_Map = passWorld_Map;
    		buildIslands(World_Map);
    		populateShores(World_Map);
    		return World_Map;
    	}
    private static Map buildIslands(Map passWorld_Map){
     
    		Map worldMap = passWorld_Map;
    		Island newIsland = new Island();
    		Random generator = new Random();
    		int numOfIslands = 0;
     
    		while (numOfIslands < 20){
     
    			newIsland.setMaxHeight(24);
    			newIsland.setMinHeight(5);
    			newIsland.setMaxWidth(24);
    			newIsland.setMinWidth(5);
     
    			newIsland.setHeight(generator.nextInt(newIsland.getMax_height() - newIsland.getMin_height()) + newIsland.getMin_height());
    			newIsland.setWidth(generator.nextInt(newIsland.getMax_width() - newIsland.getMin_width()) + newIsland.getMin_width());
     
    			System.out.print(newIsland.getHeight() + " -- ");
    			System.out.print(newIsland.getWidth() + "\n");
     
    			newIsland.islandCells = new Cell[newIsland.getHeight()][];
     
    				for (int i = 0; i < newIsland.islandCells.length; i++){
    				newIsland.islandCells[i]=new Cell[generator.nextInt(newIsland.getMax_width())];
    				for (int j = 0; j < newIsland.islandCells[i].length; j++){
    						newIsland.islandCells[i][j] = new Cell();
    						newIsland.islandCells[i][j].setTerrain(3);
    				}
    			}
     
    			int startCell_X = generator.nextInt(worldMap.getHeight());
    			int startCell_Y = generator.nextInt(worldMap.getWidth());
     
    			if ((startCell_X + newIsland.getHeight() < worldMap.getHeight() -1 ) && (startCell_Y + newIsland.getWidth() < worldMap.getWidth()-1)){
    				for (int i = 0; i < newIsland.islandCells.length; i++){
    					for (int j = 0; j < newIsland.islandCells[i].length; j++){
    						worldMap.mapCells[startCell_X + i ][startCell_Y + j].setTerrain(newIsland.islandCells[i][j].getTerrain());
    					}
    				}
    			}	
    			else{
    				continue;
    			}
    		numOfIslands++;
    		}
    		return worldMap;
     
    	}
     
     
     
    	private static Map populateShores(Map passWorld_Map) {
     
    		Map WorldMap = passWorld_Map;
     
    		for (int i = 1; i < WorldMap.mapCells.length - 1; i++) {
    			for (int j = 1; j < WorldMap.mapCells[i].length -1; j++) {
    				if (WorldMap.mapCells[i][j].getTerrain() == 3){
    					//check surrounding cells for water
    					for (int ii = i - 1; ii <= i + 1; ii++){
    						for (int jj = j -1; jj <= j + 1; jj++){
    							if ((ii == i)&&(jj == j)){
    								continue;
    							}
    							else if (WorldMap.mapCells[ii][jj].getTerrain() == 0){
    								WorldMap.mapCells[i][j].setTerrain(1);
    							}
    						}
    					}
    				}
    			}
    		}
    		return WorldMap;	
    	}
    }

    Map.java <-This class describes what a Map is. Maps can be of any integral width & height and are composed of individual Cells, which are stored in a two dimensional array.

    package com.kfgeeks.java.Mapper;
    public class Map {
     
    	private int size = 0;
    	private int height = 0;
    	private int width = 0;
     
    	Cell[][] mapCells;
     
    	public void setHeight(int x){
    		height = x;	
    	}
    	public void setWidth(int x){
    		width = x;
    	}
     
    	public int getWidth(){
    		return width;
    	}
    	public int getHeight(){
    		return height;
    	}
     
    			/*This Comment Intentionally Left Blank*/					
    }
    		/*Just trying to tidy up the close Braces*/
     
    	/*You know...Make it look all Pretty*/
     
    /*Before you get to........*/
    /************The Very End!*/

    Cell.java <-This class describes an individual Cell. Cells can be one of several terrain types and have several properties including passable, swimmable, buildable, value etc. The only implemented terrain types currently are Shore, Ocean, and Grassland.

    package com.kfgeeks.java.Mapper;
     
    public class Cell {
    	/***********************************************************************************************************/
     
    	private boolean passable = false;
    	private boolean shipPass = false;
    	private boolean buildible = false;
    	private boolean visited = false;
    	private int terrain_type;
    	private String Terrain_Name;
    	private char  terrainChar;
    	private float cellWeight=0;
    	private String[] aTerrain_Name = {"Ocean", "Shore", "River", "Grassland", "Forest","Mineable Stone","Non-Mineable Stone"};
    	private char[] aTerrain_Char= {'~','!','r','"','f','S','s'};
    	private boolean[] aPassable = {false,true,false,true,true,false,false};
    	private boolean[] aShip_Pass ={true,false,false,false,false,false,false};
    	private boolean[] aBuildable={false, false, false, true, true, false, false};
     
    	/********************Getters and Setters**********************************************/
    	public float getCell_weight() {
    		return cellWeight;
    	}
    	public int getTerrain(){
    		return terrain_type;
    	}
    	public char getTerrain_Char() {
    		return terrainChar;
    	}
    		public String getTerrain_Name() {
    			return Terrain_Name;
    		}
    	public boolean isBuildible() {
    		return buildible;
    	}
    	public boolean isPassable() {
    		return passable;
    	}
     
    	public boolean isShip_pass() {
    		return shipPass;
    	}
    	public boolean isVisited() {
    		return visited;
    	}
    	public void setBuildible(boolean buildible) {
    		this.buildible = buildible;
    	}
     
     
    	public void setCell_weight(float cell_weight) {
    		this.cellWeight = cell_weight;
    	}
     
    	public void setPassable(boolean passable) {
    		this.passable = passable;
    	}
    	public void setShip_pass(boolean ship_pass) {
    		this.shipPass = ship_pass;
    	}
    		/**Should be a number between 0 and 6
    		 * @0 = Ocean = '~'
    		 * @1 = Shore = '$'
    		 * @2 = River = '='
    		 * @3 = Grassland = '`'
    		 * @4 = Forest = '*'
    		 * @5 = Minable stone = '%'
    		 * @6 = Non-Minable stone = '^'
    		 */
     
    	public void setTerrain(int x){
    		    terrain_type = x;
    			setTerrain_Name(aTerrain_Name[terrain_type]);
    			setTerrain_Char(aTerrain_Char[terrain_type]);
    			setPassable(aPassable[terrain_type]);
    			setShip_pass(aShip_Pass[terrain_type]);
    			setBuildible(aBuildable[terrain_type]);
    	}
    	public void setTerrain_Char(char terrain_Char) {
    		terrainChar = terrain_Char;
    	}
    	public void setTerrain_Name(String terrain_Name) {
    		Terrain_Name = terrain_Name;
    	}
     
     
    	public void setVisited(boolean visited) {
    		this.visited = visited;
    	}
    }


    Island.java <-This Class describes an Island. Islands are randomly sized at creation, and are surrounded by shoreline.

    package com.kfgeeks.java.Mapper;
     
     
     
    public class Island {
     
    	private int islandHeight = 0;
    	private int islandWidth = 0;
    	private int maxWidth = 0;
    	private int maxHeight = 0;
    	private int minHeight = 0;
    	private int minWidth = 0;
     
    	Cell[][] islandCells;
     
     
    	public int getHeight(){
    		return islandHeight;
    	}
     
    	public int getWidth(){
    		return islandWidth;
    	}
     
    	public void setHeight(int x){
    		islandHeight = x;
    	}
     
    	public void setWidth(int x){
    		islandWidth = x;
    	}
    	public void setMaxWidth(int x){
    		maxWidth = x;
    	}
    	public void setMaxHeight(int x){
    		maxHeight = x;
    	}
    	public int getMax_height(){
    		return maxWidth;
    	}
    	public int getMax_width(){
    		return maxHeight;
    	}
     
    	public void setMinWidth(int x){
    		minWidth = x;
    	}
    	public void setMinHeight(int x){
    		minHeight = x;
    	}
    	public int getMin_height(){
    		return minWidth;
    	}
    	public int getMin_width(){
    		return minHeight;
    	}
     
    }

    A zipped file of my source will be included with this post, as well as the eclipse project data.


    My question here is this, is there an easier/"better" way to code this that will make it a) more stable and b)more predictable, although still essentially random?

    I've learned a lot to get as far as I have, however I still don't know enough to go further much further along these lines, so I would greatly appreciate somebody being able to take a quick peek at my code and see if it can be fixed or if it should just be scratched all together.

    Mapper.rar

    Thank you in advance.

    Rooster
    Last edited by rooster5105; October 29th, 2011 at 08:44 PM. Reason: Added first paragraph, and link to intro post. Edit 2: Added Code Samples inline.


  2. #2
    Senile Half-Wit Freaky Chris's Avatar
    Join Date
    Mar 2009
    Posts
    834
    My Mood
    Cynical
    Thanks
    7
    Thanked 105 Times in 90 Posts

    Default Re: Okay Here Goes...World and Map Generation.

    Hi rooster5105. Welcome to Java Programming Forums

    A very common and simple algotihm for generating, random but can also be controlled to an extent 3D terrain, obviously it is easily adaptable to 2D also is called the Diamond-Square Algorithm. It's uses a mid-point technique to slowely make smaller and smaller alterations to a terrain, which can be modelling initially to give the algorithm guidance as to what you want, or completely left to its own devices.

    Regards,
    Chris

    I hope this can help you with terrain generation!

Similar Threads

  1. Is AgileUnit the next test generation?
    By ricardo7307 in forum Member Introductions
    Replies: 0
    Last Post: May 16th, 2011, 02:33 PM
  2. Hello world!
    By SamirGunic in forum Member Introductions
    Replies: 1
    Last Post: April 14th, 2011, 06:57 AM
  3. Hello World!
    By Rudde in forum Member Introductions
    Replies: 0
    Last Post: February 19th, 2011, 03:29 AM
  4. Problem in generation of custom classes at web service client
    By vinod.pandey in forum Member Introductions
    Replies: 0
    Last Post: January 10th, 2011, 07:12 AM
  5. hello world
    By WiFiLeech in forum Member Introductions
    Replies: 2
    Last Post: August 31st, 2010, 07:33 AM