Advertisement
Guest User

Viciu

a guest
Jun 8th, 2014
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.86 KB | None | 0 0
  1. import java.awt.Color;
  2. import java.awt.Graphics2D;
  3. import java.awt.image.BufferedImage;
  4. import java.io.File;
  5. import java.io.FileNotFoundException;
  6. import java.io.IOException;
  7. import java.util.ArrayList;
  8. import java.util.HashMap;
  9. import java.util.Random;
  10.  
  11. import javax.imageio.IIOException;
  12. import javax.imageio.stream.FileImageOutputStream;
  13.  
  14. /**
  15.  * @author Viciu
  16.  *
  17.  */
  18. public class Forest
  19. {
  20.     public static void main(String... strings) throws IIOException, FileNotFoundException, IOException
  21.     {
  22.         int N = 40;
  23.         String output_file = "image.gif";
  24.         int delayMiliseconds = 40;
  25.         int totalMonths = 3600;
  26.         Forest forest = new Forest(N);
  27.         FileImageOutputStream output = new FileImageOutputStream(new File(output_file));
  28.         GifSequenceWriter giffer = new GifSequenceWriter(output, BufferedImage.TYPE_INT_ARGB, delayMiliseconds, false);
  29.         System.out.println("Month\tBears\tjacks\ttrees\tlumber\tmaws");
  30.        
  31.         for (int i = 0; i < totalMonths && forest.trees.size() > 0; i++)
  32.         {
  33.             forest.monthPassed();
  34.             forest.readLastLog();
  35.             giffer.writeToSequence(forest.getImage(5));
  36.         }
  37.         giffer.close();
  38.         output.close();
  39.     }
  40.  
  41.     public Forest(int N)
  42.     {
  43.         init_forest(N);
  44.     }
  45.  
  46.     private static double INITIAL_TREE_RATIO = 0.5;
  47.     private static double INITIAL_BEAR_RATIO = 0.02;
  48.     private static double INITIAL_LUMBERJACK_RATIO = 0.1;
  49.     private static double TREE_SPAWN_RATIO = 0.1;
  50.     private static double ELDER_TREE_SPAWN_RATIO = 0.2;
  51.     private static double SAPLING_MATURITY = 12;
  52.     private static double TREE_MATURITY = 120;
  53.     private static int LUMBERJACK_RANGE = 3;
  54.     private static int BEAR_RANGE = 5;
  55.  
  56.     private HashMap<XY, Tree> trees = new HashMap<XY, Tree>();
  57.     private HashMap<XY, Lumberjack> lumberjacks = new HashMap<XY, Lumberjack>();
  58.     private HashMap<XY, Bear> bears = new HashMap<XY, Bear>();
  59.  
  60.     private int month;
  61.     private int lumber;
  62.     private int maws;
  63.     private int N;
  64.  
  65.     private ArrayList<Integer> logTrees = new ArrayList<Integer>();
  66.     private ArrayList<Integer> logBears = new ArrayList<Integer>();
  67.     private ArrayList<Integer> logLumberjacks = new ArrayList<Integer>();
  68.     private ArrayList<Integer> logLumber = new ArrayList<Integer>();
  69.     private ArrayList<Integer> logMaws = new ArrayList<Integer>();
  70.  
  71.     public void init_forest(int N)
  72.     {
  73.         this.N = N;
  74.         int totalArea = N * N;
  75.         month = 0;
  76.         maws = 0;
  77.         lumber = 0;
  78.         for (int i = 0; i < totalArea * INITIAL_LUMBERJACK_RATIO; i++)
  79.             newLumberjack(lumberjacks);
  80.         for (int i = 0; i < totalArea * INITIAL_TREE_RATIO; i++)
  81.             newTree();
  82.         for (int i = 0; i < totalArea * INITIAL_BEAR_RATIO; i++)
  83.             newBear();
  84.         logState();
  85.     }
  86.  
  87.     public void monthPassed()
  88.     {
  89.         ArrayList<Tree> newTrees = new ArrayList<Tree>();
  90.         for (Tree tree : trees.values())
  91.         {
  92.             // trees age
  93.             tree.age();
  94.             // trees procreate
  95.             ArrayList<XY> neighbors = tree.position.neighbors(N);
  96.             neighbors.removeAll(trees.keySet());
  97.             if (neighbors.size() > 0)
  98.             {
  99.                 XY pos = neighbors.get(rng.nextInt(neighbors.size()));
  100.                 switch (tree.stage)
  101.                 {
  102.                     case TREE:
  103.                         if (rng.nextDouble() < TREE_SPAWN_RATIO)
  104.                             newTrees.add(new Tree(pos, Tree.Stage.SAPLING));
  105.                     case ELDER_TREE:
  106.                         if (rng.nextDouble() < ELDER_TREE_SPAWN_RATIO)
  107.                             newTrees.add(new Tree(pos, Tree.Stage.SAPLING));
  108.                     default:
  109.                         break;
  110.                 }
  111.             }
  112.         }
  113.         for (Tree tree : newTrees)
  114.             trees.put(tree.position, tree);
  115.         HashMap<XY, Lumberjack> newLumberjacks = new HashMap<XY, Lumberjack>();
  116.         for (Lumberjack lumberjack : lumberjacks.values())
  117.         {
  118.             XY position = null;
  119.             // lumberjacks wander
  120.             for (int i = 0; i < LUMBERJACK_RANGE; i++)
  121.             {
  122.                 ArrayList<XY> neighbors = lumberjack.position.neighbors(N);
  123.                 neighbors.removeAll(lumberjacks.keySet());
  124.                 position = lumberjack.wander(rng, neighbors);
  125.                 if (bears.containsKey(position))
  126.                 {
  127.                     maws++;
  128.                     position = null;
  129.                     break;
  130.                 }
  131.                 // cuts trees
  132.                 if (trees.containsKey(position))
  133.                 {
  134.                     if (trees.get(position).stage == Tree.Stage.TREE)
  135.                     {
  136.                         lumber++;
  137.                         trees.remove(position);
  138.                     }
  139.                     else if (trees.get(position).stage == Tree.Stage.TREE)
  140.                     {
  141.                         lumber += 2;
  142.                         trees.remove(position);
  143.                     }
  144.                 }
  145.             }
  146.             if (position != null)
  147.                 newLumberjacks.put(position, lumberjack);
  148.         }
  149.         lumberjacks = newLumberjacks;
  150.         if(lumberjacks.size()<1)
  151.             newLumberjack(lumberjacks);
  152.  
  153.         HashMap<XY, Bear> newBears = new HashMap<XY, Bear>();
  154.         for (Bear bear : bears.values())
  155.         {
  156.             XY pos = null;
  157.             // bear wanders
  158.             for (int i = 0; i < BEAR_RANGE; i++)
  159.             {
  160.                 pos = bear.wander(rng, bear.position.neighbors(N));
  161.                 // maws lumberjack
  162.                 if (lumberjacks.containsKey(pos))
  163.                 {
  164.                     maws++;
  165.                     lumberjacks.remove(pos);
  166.                     if (lumberjacks.size() < 1)
  167.                         newLumberjack(lumberjacks);
  168.                     break;
  169.                 }
  170.             }
  171.             if (pos != null)
  172.                 newBears.put(pos, bear);
  173.         }
  174.         bears = newBears;
  175.  
  176.         if (month % 12 == 0)
  177.         {
  178.             if (lumber < lumberjacks.size())
  179.             {// fire somebody
  180.                 if (lumberjacks.size() > 1)
  181.                 {
  182.                     int index = rng.nextInt(lumberjacks.size());
  183.                     for (XY pos : lumberjacks.keySet())
  184.                     {
  185.                         if (index == 0)
  186.                         {
  187.                             lumberjacks.remove(pos);
  188.                             break;
  189.                         }
  190.                         index--;
  191.                     }
  192.                 }
  193.             } else
  194.             {// hire more lumberjacks
  195.                 for (int i = 0; i < lumber / 10; i++)
  196.                     newLumberjack(lumberjacks);
  197.             }
  198.             lumber = 0;
  199.             if (maws > 0)
  200.             {// kill bear
  201.                 if (bears.size() > 0)
  202.                 {
  203.                     int index = rng.nextInt(bears.size());
  204.                     for (XY pos : bears.keySet())
  205.                     {
  206.                         if (index == 0)
  207.                         {
  208.                             bears.remove(pos);
  209.                             break;
  210.                         }
  211.                         index--;
  212.                     }
  213.                 }
  214.             } else
  215.             {// bears procreate
  216.                 newBear();
  217.             }
  218.             maws = 0;
  219.         }
  220.         month++;
  221. //      logState();
  222.     }
  223.  
  224.     public void readLastLog()
  225.     {
  226.         System.out.println(month + "\t" + bears.size() + "\t" + lumberjacks.size() + "\t" + trees.size() + "\t" + lumber + "\t" + maws + "\t");
  227.     }
  228.  
  229.     public BufferedImage getImage(int unitSize)
  230.     {
  231.         BufferedImage image = new BufferedImage(N*unitSize, N*unitSize, BufferedImage.TYPE_INT_ARGB);
  232.         Graphics2D g2 = image.createGraphics();
  233.         for(int x=0;x<N;x++)
  234.             for(int y=0;y<N;y++)
  235.             {
  236.                 XY pos = new XY(x,y);
  237.                 int argb=0;
  238.                 if(trees.containsKey(pos))
  239.                     argb|=0xff<<8;
  240.                 if(lumberjacks.containsKey(pos))
  241.                     argb|=0xff;
  242.                 if(bears.containsKey(pos))
  243.                     argb|=0xff<<16;
  244.                 g2.setColor(new Color(argb));
  245.                 g2.drawRect(x*unitSize, y*unitSize, unitSize, unitSize);
  246.                 g2.fillRect(x*unitSize, y*unitSize, unitSize, unitSize);
  247.             }
  248.         return image;
  249.     }
  250.  
  251.     private void logState()
  252.     {
  253.         logBears.add(bears.size());
  254.         logTrees.add(trees.size());
  255.         logLumberjacks.add(lumberjacks.size());
  256.         logLumber.add(lumber);
  257.         logMaws.add(maws);
  258.     }
  259.  
  260.     private void newLumberjack(HashMap<XY,Lumberjack> lumberjacks)
  261.     {
  262.         XY pos;
  263.         do
  264.         {
  265.             pos = new XY(rng, N);
  266.         } while (lumberjacks.containsKey(pos));
  267.         lumberjacks.put(pos, new Lumberjack(pos));
  268.     }
  269.  
  270.     private void newBear()
  271.     {
  272.         XY pos;
  273.         do
  274.         {
  275.             pos = new XY(rng, N);
  276.         } while (bears.containsKey(pos));
  277.         bears.put(pos, new Bear(pos));
  278.     }
  279.  
  280.     private void newTree()
  281.     {
  282.         XY pos;
  283.         do
  284.         {
  285.             pos = new XY(rng, N);
  286.         } while (trees.containsKey(pos));
  287.         trees.put(pos, new Tree(pos));
  288.     }
  289.  
  290.     private Random rng = new Random();
  291.  
  292.     // @Override
  293.     // public String toString()
  294.     // {
  295.     // StringBuilder sb = new StringBuilder();
  296.     // for(int[] line:forest)
  297.     // {
  298.     // sb.append(Arrays.toString(line));
  299.     // sb.append("\n");
  300.     // }
  301.     // return sb.toString();
  302.     // }
  303.  
  304.     public static class XY
  305.     {
  306.         public final int x;
  307.         public final int y;
  308.  
  309.         public XY(Random rng, int N)
  310.         {
  311.             this.x = rng.nextInt(N);
  312.             this.y = rng.nextInt(N);
  313.         }
  314.  
  315.         public XY(int x, int y)
  316.         {
  317.             this.x = x;
  318.             this.y = y;
  319.         }
  320.  
  321.         @Override
  322.         public boolean equals(Object obj)
  323.         {
  324.             if (this == obj)
  325.                 return true;
  326.             if (obj instanceof XY)
  327.             {
  328.                 XY other = (XY) obj;
  329.                 return this.x == other.x && this.y == other.y;
  330.             }
  331.             return false;
  332.         }
  333.  
  334.         @Override
  335.         public int hashCode()
  336.         {
  337.             return this.x * 31 + this.y;
  338.         }
  339.  
  340.         @Override
  341.         public String toString()
  342.         {
  343.             return "(" + x + "," + y + ")";
  344.         }
  345.  
  346.         ArrayList<XY> neighbors(int N)
  347.         {
  348.             ArrayList<XY> neighbors = new ArrayList<XY>();
  349.             if (x > 0 && y > 0)
  350.                 neighbors.add(new XY(x - 1, y - 1));
  351.             if (x > 0)
  352.                 neighbors.add(new XY(x - 1, y));
  353.             if (x > 0 && y + 1 < N)
  354.                 neighbors.add(new XY(x - 1, y + 1));
  355.             if (y > 0)
  356.                 neighbors.add(new XY(x, y - 1));
  357.             if (y + 1 < N)
  358.                 neighbors.add(new XY(x, y + 1));
  359.             if (x + 1 < N && y > 0)
  360.                 neighbors.add(new XY(x + 1, y - 1));
  361.             if (x + 1 < N)
  362.                 neighbors.add(new XY(x + 1, y));
  363.             if (x + 1 < N && y + 1 < N)
  364.                 neighbors.add(new XY(x + 1, y + 1));
  365.             return neighbors;
  366.         }
  367.     }
  368.  
  369.     static class Tree
  370.     {
  371.         enum Stage
  372.         {
  373.             SAPLING, TREE, ELDER_TREE
  374.         }
  375.  
  376.         Tree(XY pos)
  377.         {
  378.             position = pos;
  379.             stage = Stage.TREE;
  380.         }
  381.  
  382.         Tree(XY pos, Stage stage)
  383.         {
  384.             position = pos;
  385.             this.stage = stage;
  386.         }
  387.  
  388.         void age()
  389.         {
  390.             age++;
  391.             switch (stage)
  392.             {
  393.                 case SAPLING:
  394.                     if (age >= SAPLING_MATURITY)
  395.                     {
  396.                         age = 0;
  397.                         stage = Stage.TREE;
  398.                     }
  399.                     break;
  400.                 case TREE:
  401.                     if (age >= TREE_MATURITY)
  402.                     {
  403.                         age = 0;
  404.                         stage = Stage.ELDER_TREE;
  405.                     }
  406.                 default:
  407.                     break;
  408.             }
  409.         }
  410.  
  411.         // age in months since changing stage
  412.         int age;
  413.         Stage stage;
  414.         XY position;
  415.     }
  416.  
  417.     static class Lumberjack
  418.     {
  419.         Lumberjack(XY pos)
  420.         {
  421.             position = pos;
  422.         }
  423.  
  424.         XY wander(Random rng, ArrayList<XY> neighbors)
  425.         {
  426.             if(neighbors.size()>0)
  427.                 position = neighbors.get(rng.nextInt(neighbors.size()));
  428.             return position;
  429.         }
  430.  
  431.         XY position;
  432.     }
  433.  
  434.     static class Bear
  435.     {
  436.         Bear(XY pos)
  437.         {
  438.             position = pos;
  439.         }
  440.  
  441.         XY wander(Random rng, ArrayList<XY> neighbors)
  442.         {
  443.             position = neighbors.get(rng.nextInt(neighbors.size()));
  444.             return position;
  445.         }
  446.  
  447.         XY position;
  448.     }
  449. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement