Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.Color;
- import java.awt.Graphics2D;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Random;
- import javax.imageio.IIOException;
- import javax.imageio.stream.FileImageOutputStream;
- /**
- * @author Viciu
- *
- */
- public class Forest
- {
- public static void main(String... strings) throws IIOException, FileNotFoundException, IOException
- {
- int N = 40;
- String output_file = "image.gif";
- int delayMiliseconds = 40;
- int totalMonths = 3600;
- Forest forest = new Forest(N);
- FileImageOutputStream output = new FileImageOutputStream(new File(output_file));
- GifSequenceWriter giffer = new GifSequenceWriter(output, BufferedImage.TYPE_INT_ARGB, delayMiliseconds, false);
- System.out.println("Month\tBears\tjacks\ttrees\tlumber\tmaws");
- for (int i = 0; i < totalMonths && forest.trees.size() > 0; i++)
- {
- forest.monthPassed();
- forest.readLastLog();
- giffer.writeToSequence(forest.getImage(5));
- }
- giffer.close();
- output.close();
- }
- public Forest(int N)
- {
- init_forest(N);
- }
- private static double INITIAL_TREE_RATIO = 0.5;
- private static double INITIAL_BEAR_RATIO = 0.02;
- private static double INITIAL_LUMBERJACK_RATIO = 0.1;
- private static double TREE_SPAWN_RATIO = 0.1;
- private static double ELDER_TREE_SPAWN_RATIO = 0.2;
- private static double SAPLING_MATURITY = 12;
- private static double TREE_MATURITY = 120;
- private static int LUMBERJACK_RANGE = 3;
- private static int BEAR_RANGE = 5;
- private HashMap<XY, Tree> trees = new HashMap<XY, Tree>();
- private HashMap<XY, Lumberjack> lumberjacks = new HashMap<XY, Lumberjack>();
- private HashMap<XY, Bear> bears = new HashMap<XY, Bear>();
- private int month;
- private int lumber;
- private int maws;
- private int N;
- private ArrayList<Integer> logTrees = new ArrayList<Integer>();
- private ArrayList<Integer> logBears = new ArrayList<Integer>();
- private ArrayList<Integer> logLumberjacks = new ArrayList<Integer>();
- private ArrayList<Integer> logLumber = new ArrayList<Integer>();
- private ArrayList<Integer> logMaws = new ArrayList<Integer>();
- public void init_forest(int N)
- {
- this.N = N;
- int totalArea = N * N;
- month = 0;
- maws = 0;
- lumber = 0;
- for (int i = 0; i < totalArea * INITIAL_LUMBERJACK_RATIO; i++)
- newLumberjack(lumberjacks);
- for (int i = 0; i < totalArea * INITIAL_TREE_RATIO; i++)
- newTree();
- for (int i = 0; i < totalArea * INITIAL_BEAR_RATIO; i++)
- newBear();
- logState();
- }
- public void monthPassed()
- {
- ArrayList<Tree> newTrees = new ArrayList<Tree>();
- for (Tree tree : trees.values())
- {
- // trees age
- tree.age();
- // trees procreate
- ArrayList<XY> neighbors = tree.position.neighbors(N);
- neighbors.removeAll(trees.keySet());
- if (neighbors.size() > 0)
- {
- XY pos = neighbors.get(rng.nextInt(neighbors.size()));
- switch (tree.stage)
- {
- case TREE:
- if (rng.nextDouble() < TREE_SPAWN_RATIO)
- newTrees.add(new Tree(pos, Tree.Stage.SAPLING));
- case ELDER_TREE:
- if (rng.nextDouble() < ELDER_TREE_SPAWN_RATIO)
- newTrees.add(new Tree(pos, Tree.Stage.SAPLING));
- default:
- break;
- }
- }
- }
- for (Tree tree : newTrees)
- trees.put(tree.position, tree);
- HashMap<XY, Lumberjack> newLumberjacks = new HashMap<XY, Lumberjack>();
- for (Lumberjack lumberjack : lumberjacks.values())
- {
- XY position = null;
- // lumberjacks wander
- for (int i = 0; i < LUMBERJACK_RANGE; i++)
- {
- ArrayList<XY> neighbors = lumberjack.position.neighbors(N);
- neighbors.removeAll(lumberjacks.keySet());
- position = lumberjack.wander(rng, neighbors);
- if (bears.containsKey(position))
- {
- maws++;
- position = null;
- break;
- }
- // cuts trees
- if (trees.containsKey(position))
- {
- if (trees.get(position).stage == Tree.Stage.TREE)
- {
- lumber++;
- trees.remove(position);
- }
- else if (trees.get(position).stage == Tree.Stage.TREE)
- {
- lumber += 2;
- trees.remove(position);
- }
- }
- }
- if (position != null)
- newLumberjacks.put(position, lumberjack);
- }
- lumberjacks = newLumberjacks;
- if(lumberjacks.size()<1)
- newLumberjack(lumberjacks);
- HashMap<XY, Bear> newBears = new HashMap<XY, Bear>();
- for (Bear bear : bears.values())
- {
- XY pos = null;
- // bear wanders
- for (int i = 0; i < BEAR_RANGE; i++)
- {
- pos = bear.wander(rng, bear.position.neighbors(N));
- // maws lumberjack
- if (lumberjacks.containsKey(pos))
- {
- maws++;
- lumberjacks.remove(pos);
- if (lumberjacks.size() < 1)
- newLumberjack(lumberjacks);
- break;
- }
- }
- if (pos != null)
- newBears.put(pos, bear);
- }
- bears = newBears;
- if (month % 12 == 0)
- {
- if (lumber < lumberjacks.size())
- {// fire somebody
- if (lumberjacks.size() > 1)
- {
- int index = rng.nextInt(lumberjacks.size());
- for (XY pos : lumberjacks.keySet())
- {
- if (index == 0)
- {
- lumberjacks.remove(pos);
- break;
- }
- index--;
- }
- }
- } else
- {// hire more lumberjacks
- for (int i = 0; i < lumber / 10; i++)
- newLumberjack(lumberjacks);
- }
- lumber = 0;
- if (maws > 0)
- {// kill bear
- if (bears.size() > 0)
- {
- int index = rng.nextInt(bears.size());
- for (XY pos : bears.keySet())
- {
- if (index == 0)
- {
- bears.remove(pos);
- break;
- }
- index--;
- }
- }
- } else
- {// bears procreate
- newBear();
- }
- maws = 0;
- }
- month++;
- // logState();
- }
- public void readLastLog()
- {
- System.out.println(month + "\t" + bears.size() + "\t" + lumberjacks.size() + "\t" + trees.size() + "\t" + lumber + "\t" + maws + "\t");
- }
- public BufferedImage getImage(int unitSize)
- {
- BufferedImage image = new BufferedImage(N*unitSize, N*unitSize, BufferedImage.TYPE_INT_ARGB);
- Graphics2D g2 = image.createGraphics();
- for(int x=0;x<N;x++)
- for(int y=0;y<N;y++)
- {
- XY pos = new XY(x,y);
- int argb=0;
- if(trees.containsKey(pos))
- argb|=0xff<<8;
- if(lumberjacks.containsKey(pos))
- argb|=0xff;
- if(bears.containsKey(pos))
- argb|=0xff<<16;
- g2.setColor(new Color(argb));
- g2.drawRect(x*unitSize, y*unitSize, unitSize, unitSize);
- g2.fillRect(x*unitSize, y*unitSize, unitSize, unitSize);
- }
- return image;
- }
- private void logState()
- {
- logBears.add(bears.size());
- logTrees.add(trees.size());
- logLumberjacks.add(lumberjacks.size());
- logLumber.add(lumber);
- logMaws.add(maws);
- }
- private void newLumberjack(HashMap<XY,Lumberjack> lumberjacks)
- {
- XY pos;
- do
- {
- pos = new XY(rng, N);
- } while (lumberjacks.containsKey(pos));
- lumberjacks.put(pos, new Lumberjack(pos));
- }
- private void newBear()
- {
- XY pos;
- do
- {
- pos = new XY(rng, N);
- } while (bears.containsKey(pos));
- bears.put(pos, new Bear(pos));
- }
- private void newTree()
- {
- XY pos;
- do
- {
- pos = new XY(rng, N);
- } while (trees.containsKey(pos));
- trees.put(pos, new Tree(pos));
- }
- private Random rng = new Random();
- // @Override
- // public String toString()
- // {
- // StringBuilder sb = new StringBuilder();
- // for(int[] line:forest)
- // {
- // sb.append(Arrays.toString(line));
- // sb.append("\n");
- // }
- // return sb.toString();
- // }
- public static class XY
- {
- public final int x;
- public final int y;
- public XY(Random rng, int N)
- {
- this.x = rng.nextInt(N);
- this.y = rng.nextInt(N);
- }
- public XY(int x, int y)
- {
- this.x = x;
- this.y = y;
- }
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- return true;
- if (obj instanceof XY)
- {
- XY other = (XY) obj;
- return this.x == other.x && this.y == other.y;
- }
- return false;
- }
- @Override
- public int hashCode()
- {
- return this.x * 31 + this.y;
- }
- @Override
- public String toString()
- {
- return "(" + x + "," + y + ")";
- }
- ArrayList<XY> neighbors(int N)
- {
- ArrayList<XY> neighbors = new ArrayList<XY>();
- if (x > 0 && y > 0)
- neighbors.add(new XY(x - 1, y - 1));
- if (x > 0)
- neighbors.add(new XY(x - 1, y));
- if (x > 0 && y + 1 < N)
- neighbors.add(new XY(x - 1, y + 1));
- if (y > 0)
- neighbors.add(new XY(x, y - 1));
- if (y + 1 < N)
- neighbors.add(new XY(x, y + 1));
- if (x + 1 < N && y > 0)
- neighbors.add(new XY(x + 1, y - 1));
- if (x + 1 < N)
- neighbors.add(new XY(x + 1, y));
- if (x + 1 < N && y + 1 < N)
- neighbors.add(new XY(x + 1, y + 1));
- return neighbors;
- }
- }
- static class Tree
- {
- enum Stage
- {
- SAPLING, TREE, ELDER_TREE
- }
- Tree(XY pos)
- {
- position = pos;
- stage = Stage.TREE;
- }
- Tree(XY pos, Stage stage)
- {
- position = pos;
- this.stage = stage;
- }
- void age()
- {
- age++;
- switch (stage)
- {
- case SAPLING:
- if (age >= SAPLING_MATURITY)
- {
- age = 0;
- stage = Stage.TREE;
- }
- break;
- case TREE:
- if (age >= TREE_MATURITY)
- {
- age = 0;
- stage = Stage.ELDER_TREE;
- }
- default:
- break;
- }
- }
- // age in months since changing stage
- int age;
- Stage stage;
- XY position;
- }
- static class Lumberjack
- {
- Lumberjack(XY pos)
- {
- position = pos;
- }
- XY wander(Random rng, ArrayList<XY> neighbors)
- {
- if(neighbors.size()>0)
- position = neighbors.get(rng.nextInt(neighbors.size()));
- return position;
- }
- XY position;
- }
- static class Bear
- {
- Bear(XY pos)
- {
- position = pos;
- }
- XY wander(Random rng, ArrayList<XY> neighbors)
- {
- position = neighbors.get(rng.nextInt(neighbors.size()));
- return position;
- }
- XY position;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement