Created
October 17, 2015 07:58
-
-
Save sampersand/34bb3009264f6c495506 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Random; | |
public class FireSim { | |
public static final int EMPTY = 0; | |
public static final int BURNING_STATE_1 = 1; | |
public static final int BURNING_STATE_2 = 2; | |
public static final int TREE = 3; | |
public static final int SAPLING = 4; | |
public static final int LIGHTNING = 5; | |
public static final int INFLAMMABLE = 6; // small large | |
public static final int SMOKE_STATE_1 = 7; | |
public static final int SMOKE_STATE_2 = 8; | |
public static final int FIREFIGHTER = 9; | |
public static final int HOUSE = 11; | |
public static final String[] typeChars = {" ", "🔥", "💥", "🌲", "🌱", "⚡️","🌳","💭","💭","🚒","🚒","🏡"}; | |
public static Random RAND = new Random(); | |
private int[][] earth; | |
private double entropyFire; | |
private double entropyGrow; | |
private double entropyLightning; | |
private double entropyWither = 0.2D; | |
private double entropyInflammable = 0.0001D; | |
private double windDir; | |
private double windStr; | |
private int saplingTreeReqToGrow = 1; | |
private int treeReqToNotWither = 2; | |
private int convFromRoman(String inp){ | |
char[] numerals = {'I','V','X','L','C','D','M'}; | |
int[] decivals = {1,5,10,50,100,500,1000}; | |
int ret = 0; | |
return ret; | |
} | |
public static void main(String[] args) { | |
// System.out.println(convFromRoman("MCMXLIII")); | |
// Y | X | FIRE| GROW| LIGHT| WIND DIR | WIND STR | |
// FireSim earth = new FireSim(30, 58, 0.75D,0.02D,0.0002D); | |
// FireSim earth = new FireSim(30, 117, 0.25, 0.02D, 0.002D, Math.PI/4*0, 0.4); | |
FireSim earth = new FireSim(30, 115, 0.75D,0.02D,0.0002D); //neither wins | |
earth.seed(); | |
earth.dispEarth(); | |
while(earth.update(100)) | |
earth.dispEarth(); | |
earth.dispEarth(); | |
} | |
public FireSim() { | |
this(10); | |
} | |
public FireSim(int xy) { | |
this(xy, xy); | |
} | |
public FireSim(int x, int y) { | |
this(x, y, 0.2D); | |
} | |
public FireSim(int x, int y, double burnprob) { | |
this(x, y, burnprob, 0); | |
} | |
public FireSim(int x, int y, double burnprob, double growprob) { | |
this(x, y, burnprob, growprob, 0); | |
} | |
public FireSim(int x, int y, double burnprob, double growprob, double lightprob) { | |
this(x, y, burnprob, growprob, lightprob, 0); | |
} | |
public FireSim(int x, int y, double burnprob, double growprob, double lightprob, double winddir) { | |
this(x, y, burnprob, growprob, lightprob, lightprob, 0); | |
} | |
public FireSim(int xL, int yL, double burnprob, double growprob, double lightprob, double winddir, double windpow) { | |
earth = new int[xL + 2][yL + 2]; | |
for(int x = 1; x < earth.length -1; x++) { | |
for(int y = 1; y < earth[0].length -1; y++) { | |
earth[x][y] = TREE; | |
} | |
} | |
entropyFire = burnprob; | |
entropyGrow = growprob; | |
entropyLightning = lightprob; | |
windDir = winddir; | |
windStr = windpow; | |
} | |
public void setMisc(double probwither, int mintreecount, double probinflam){ | |
entropyWither = probwither; | |
entropyInflammable = probinflam; | |
saplingTreeReqToGrow = mintreecount; | |
} | |
public void seed() { | |
for(int x = 0; x < FireSim.RAND.nextInt(4) + 1; x++) | |
earth[FireSim.RAND.nextInt(earth.length - 1) + 1] | |
[FireSim.RAND.nextInt(earth[0].length - 1) + 1] = LIGHTNING; // FIREFIGHTER; | |
} | |
public boolean update() { | |
return update(200); | |
} | |
public boolean update(int delay) { | |
try { | |
Thread.sleep(delay); | |
} catch(InterruptedException ex) { | |
Thread.currentThread().interrupt(); | |
} | |
int[][] ret = new int[earth.length][earth[0].length]; | |
for(int x = 1; x < earth.length -1; x++) { | |
for(int y = 1; y < earth[0].length -1; y++) { | |
ret[x][y] = earth[x][y]; | |
} | |
} | |
ret = applySpread(ret); | |
boolean same = true; | |
for(int x = 1; x < earth.length -1; x++) { | |
for(int y = 1; y < earth[0].length -1; y++) { | |
same = earth[x][y] == ret[x][y]; | |
if(!same) | |
break; | |
} | |
} | |
if(same) { | |
earth = ret; | |
for(int[] x : earth) | |
for(int y : x) | |
if(y != EMPTY && y != INFLAMMABLE) | |
return true; | |
return false; | |
} | |
earth = ret; | |
return true; | |
} | |
public void dispEarth() { | |
final String ANSI_CLS = "\u001b[2J"; | |
final String ANSI_HOME = "\u001b[H"; | |
System.out.print(ANSI_CLS + ANSI_HOME); | |
System.out.flush(); | |
for(int x = 1; x < earth[0].length; x++) System.out.print("-"); | |
System.out.println(); | |
for(int x = 1; x < earth.length - 1; x++) { | |
for(int y = 1; y < earth[0].length - 1; y++) { | |
System.out.print(typeChars[reduce(earth[x][y])]); | |
} | |
System.out.println(); | |
} | |
for(int x = 1; x < earth[0].length; x++) System.out.print("-"); | |
System.out.println(); | |
} | |
private int reduce(int pos){ | |
return pos >= typeChars.length ? typeChars.length-1 : pos; | |
} | |
private int updatePatch(int[][] dirs) { | |
int site = dirs[1][1]; | |
int[] count = new int[typeChars.length]; | |
for(int[] row : dirs) for (int pos : row) | |
count[reduce(pos)]++; | |
count[reduce(site)]-=1; //the for loop counts the center one, which is not desired. | |
switch(site){ | |
case EMPTY: | |
if(FireSim.RAND.nextDouble() <= entropyGrow && count[TREE] >= saplingTreeReqToGrow) | |
if(FireSim.RAND.nextDouble() <= entropyInflammable) | |
return INFLAMMABLE; | |
else | |
return SAPLING; | |
return EMPTY; | |
case SMOKE_STATE_2: | |
return SMOKE_STATE_1; | |
case SMOKE_STATE_1: | |
return EMPTY; | |
case LIGHTNING: | |
return BURNING_STATE_2; | |
case BURNING_STATE_2: | |
return BURNING_STATE_1; | |
case BURNING_STATE_1: | |
// if(count[FIREFIGHTER] == 1 && count[BURNING_STATE_1]+count[BURNING_STATE_2]<=2) | |
// return FIREFIGHTER; | |
return SMOKE_STATE_2; | |
case FIREFIGHTER: | |
if(count[BURNING_STATE_1]+count[BURNING_STATE_2] > 5) | |
return EMPTY; | |
if(count[FIREFIGHTER] > 1) | |
return EMPTY; | |
return FIREFIGHTER; | |
case INFLAMMABLE: | |
return FireSim.RAND.nextDouble() <= entropyFire * entropyLightning ? LIGHTNING : INFLAMMABLE; | |
case SAPLING: | |
if(FireSim.RAND.nextDouble() <= entropyGrow) | |
return TREE; | |
if(count[TREE] < treeReqToNotWither) | |
return FireSim.RAND.nextDouble() <= entropyWither ? EMPTY : SAPLING; | |
return SAPLING; | |
case HOUSE: | |
case TREE: | |
if (count[TREE] < treeReqToNotWither) //withering | |
if (FireSim.RAND.nextDouble() <= entropyWither) | |
return EMPTY; | |
if (FireSim.RAND.nextDouble() <= entropyFire * entropyLightning) | |
return LIGHTNING; | |
//burning | |
double burnChance = 0D; | |
for(int x = 0; x < dirs[0].length; x++) //2 is dirs row | |
for(int y = 0; y < dirs.length; y++) //2 is dirs hight | |
if(dirs[x][y] == BURNING_STATE_1 || dirs[x][y] == BURNING_STATE_2){ | |
burnChance +=.2D; | |
//lazy | |
// double ang = Math.PI/4; | |
// if(x == 0) ang *= 3 - y; | |
// if(x == 1) ang *= y == 0 ? 4 : 0; | |
// if(x == 2) ang *= 5 + y; | |
// System.out.print( | |
// Math.abs(Math.sin((windDir-ang)/2))+ | |
// "|"+ ang/Math.PI+ | |
// "|"+ windDir/Math.PI+ | |
// "|"+x+"|"+y+"|"+dirs[x][y]+"|"); | |
// for(int[] X : dirs) for(int Y : X) System.out.print(Y+","); | |
// System.out.println(); | |
// burnChance += windStr | |
// burnChance += windStr * Math.abs(Math.sin((windDir-ang)/2)); | |
// burnChance += windStr * (Math.cos(windDir) - Math.cos(ang) + | |
// Math.sin(windDir) - Math.sin(ang)); | |
} | |
if(FireSim.RAND.nextDouble() > 1 - Math.abs(burnChance) * entropyFire) | |
return BURNING_STATE_2; | |
else | |
return site; | |
default: | |
return EMPTY; | |
} | |
} | |
private int[][] applySpread(int[][] pearth) { | |
for(int x = 1; x < pearth.length - 1; x++) | |
for(int y = 1; y < pearth[0].length - 1; y++) | |
// pearth[x][y] = updatePatchOld(earth[x][y], earth[x][y + 1], earth[x][y - 1], | |
// earth[x + 1][y], earth[x - 1][y]); | |
pearth[x][y] = updatePatch(new int[][]{ | |
{earth[x-1][y+1], earth[x][y+1], earth[x+1][y+1]}, | |
{earth[x-1][y] , earth[x][y] , earth[x+1][y]}, | |
{earth[x-1][y-1], earth[x][y-1], earth[x+1][y-1]}}); | |
return pearth; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment