Last active
May 13, 2018 11:20
-
-
Save agnes1/4aeeec4aef829961457aebbfe34229c1 to your computer and use it in GitHub Desktop.
Beyond Proxima Star System Generator
This file contains hidden or 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
package com.beyondproxima; | |
import java.io.*; | |
import java.net.URL; | |
import java.nio.channels.Channels; | |
import java.nio.channels.ReadableByteChannel; | |
import java.util.zip.GZIPInputStream; | |
/** | |
* downloads all csv from http://cdn.gea.esac.esa.int/Gaia/gdr2/gaia_source/csv/ | |
* Save the index page to get all the URLs and save them to a file of one URL per line: | |
* C:\Users\ags1\Desktop\Index of _Gaia_gdr2_gaia_source_csv_.txt | |
* Created by ags1 on 4/25/2018. | |
*/ | |
public class GaiaDownloada { | |
public static void main(String[] args) throws IOException, InterruptedException { | |
boolean first = true; | |
int count = 0; | |
FileReader reader = new FileReader("C:\\Users\\ags1\\Desktop\\gaia_files.txt"); | |
String name = "C:\\temp\\v2\\gdr2_10mas.csv."; | |
FileOutputStream outputStream = new FileOutputStream(name + count); | |
try(BufferedReader br = new BufferedReader(reader)) { | |
for (String line; (line = br.readLine()) != null; ) { | |
System.out.println(count); | |
if (count++ < 0) { continue; } | |
doFile(line, first, outputStream); | |
outputStream.flush(); | |
first = false; | |
if (count % 200 == 0) { | |
outputStream.close(); | |
outputStream = new FileOutputStream(name + count); | |
first = true; | |
Thread.sleep(3000); | |
} | |
} | |
} | |
outputStream.close(); | |
} | |
private static void doFile(String url, boolean first, FileOutputStream fos3) throws IOException { | |
URL website = new URL(url); | |
ReadableByteChannel rbc = Channels.newChannel(website.openStream()); | |
FileOutputStream fos = new FileOutputStream("C:\\temp\\work.csv"); | |
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); | |
try { | |
FileInputStream fis = new FileInputStream("C:\\temp\\work.csv"); | |
GZIPInputStream gis = new GZIPInputStream(fis); | |
FileOutputStream fos2 = new FileOutputStream("C:\\temp\\work2.csv"); | |
byte[] buffer = new byte[1024]; | |
int len; | |
while((len = gis.read(buffer)) != -1){ | |
fos2.write(buffer, 0, len); | |
} | |
//close resources | |
fos2.close(); | |
gis.close(); | |
//final file will be: C:\temp\gdr2_10mas_parallax.csv | |
try(BufferedReader br = new BufferedReader(new FileReader("C:\\temp\\work2.csv"))) { | |
for(String line; (line = br.readLine()) != null; ) { | |
if (first) { | |
fos3.write(line.getBytes()); | |
fos3.write("\r\n".getBytes()); | |
first = false; | |
} else { | |
String[] cells = line.split(","); | |
String px = cells[9]; | |
Double d = px.isEmpty() || px.equals("parallax") ? 0 : Double.parseDouble(px); | |
if (d >= 10.0) { | |
fos3.write(line.getBytes()); | |
fos3.write("\r\n".getBytes()); | |
first = false; | |
} | |
} | |
} | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
This file contains hidden or 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
package com.beyondproxima; | |
import java.io.*; | |
import java.util.*; | |
/** | |
* Turns dirty gaia downloads into slim, clean data. | |
* Created by ags1 on 4/27/2018. | |
*/ | |
public class GaiaProcessa { | |
@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection"}) | |
private static final TreeMap<Integer, String> columns = new TreeMap<Integer, String>(){{ | |
put(1, "source_id"); | |
put(5, "ra"); | |
put(7, "dec"); | |
put(9, "parallax"); | |
put(10, "parallax_error"); | |
put(12, "pmra"); | |
put(14, "pmdec"); | |
put(37, "astrometric_pseudo_colour"); | |
put(47, "phot_g_mean_flux"); | |
put(50, "phot_g_mean_mag"); | |
put(52, "phot_bp_mean_flux"); | |
put(55, "phot_bp_mean_mag"); | |
put(57, "phot_rp_mean_flux"); | |
put(60, "phot_rp_mean_mag"); | |
put(61, "phot_bp_rp_excess_factor"); | |
put(63, "bp_rp"); | |
put(64, "bp_g"); | |
put(65, "g_rp"); | |
put(66, "radial_velocity"); | |
put(72, "phot_variable_flag"); | |
put(78, "teff_val"); | |
put(87, "flame_flags"); | |
put(88, "radius_val"); | |
put(91, "lum_val"); | |
}}; | |
private static final String TITLE_START = "solution_id"; | |
private static final TreeMap<Integer, Integer> magCount = new TreeMap<>(); | |
private static final TreeMap<Integer, Integer> volCount = new TreeMap<>(); | |
private static final TreeMap<Integer, TreeMap<Integer, Integer>> magCounts = new TreeMap<>(); | |
public static void main(String[] args) throws FileNotFoundException { | |
int count = 0; | |
int titleLines = 0; | |
int badLines = 0; | |
int duplicates = 0; | |
int goodLines = 0; | |
Set<String> ids = new HashSet<>(); | |
String title = null; | |
List<String> faint = new ArrayList<>(); | |
List<String> near = new ArrayList<>(); | |
String nearest = null; | |
//noinspection ConstantConditions | |
for (File file : new File("C:\\temp\\v2").listFiles()) { | |
if (file.getName().startsWith("gdr2_10mas.csv")) { | |
FileReader reader = new FileReader(file); | |
try(BufferedReader br = new BufferedReader(reader)) { | |
for (String line; (line = br.readLine()) != null; ) { | |
if (count++ % 2000 == 0) { | |
System.out.printf("titles:%s, bad:%s, dupe:%s, goood:%s\r\n", titleLines, badLines, duplicates, goodLines); | |
System.out.println(magCount); | |
System.out.println(volCount); | |
} | |
if (line.startsWith(TITLE_START)) { | |
titleLines++; | |
title = line; | |
} else { | |
String[] cells = line.replace(",,", ",-,").replace(",,", ",-,").replaceAll(",$", ",-").split(","); | |
if (cells.length != 94) { | |
badLines++; | |
} else { | |
String id = cells[1]; | |
if (ids.contains(id)) { | |
duplicates++; | |
} else { | |
goodLines++; | |
ids.add(id); | |
double ra = Double.parseDouble(cells[5]); | |
double dec = Double.parseDouble(cells[7]); | |
double parallax = Double.parseDouble(cells[9]); | |
double parallaxOverError = Double.parseDouble(cells[11]); | |
double magd = Double.parseDouble(cells[50]); | |
int mag = (int) magd; | |
if (parallaxOverError < 10) { | |
continue; | |
} | |
//galactic core: ra 250 – 300, dec -40 – 20 | |
if (magd > 18.5 && ra > 250 && ra < 300 && dec > -40 && dec < 20) { | |
continue; | |
} | |
if (magd > 18.5 && ra > 290 && ra < 320 && dec > 20 && dec < 50) { | |
continue; | |
} | |
if (magd > 18.5 && ra > 150 && ra < 275 && dec > -70 && dec < -40) { | |
continue; | |
} | |
if (magd > 18.5 && ra > 70 && ra < 80 && dec > -75 && dec < -65) { | |
continue; | |
} | |
if (magd > 18.5 && ra > 110 && ra < 130 && dec > -50 && dec < -20) { | |
continue; | |
} | |
double distance = 1000.0 / parallax; //mas | |
int distanceKey = (int) ((distance * distance * distance) / 1000.0); | |
volCount.put(distanceKey, volCount.getOrDefault(distanceKey, 0) + 1); | |
magCount.put(mag, magCount.getOrDefault(mag, 0) + 1); | |
TreeMap<Integer, Integer> mc2 = magCounts.getOrDefault(distanceKey, new TreeMap<>()); | |
mc2.put(mag, mc2.getOrDefault(mag, 0) + 1); | |
magCounts.put(distanceKey, mc2); | |
if (distance < 5 && mag < 19) { | |
nearest = line; | |
} | |
if (distance < 6 && magd < 18.5) { | |
faint.add(line); | |
} | |
if (distance < 2) { | |
near.add(line); | |
} | |
//noinspection StatementWithEmptyBody | |
if (distanceKey < 3 && magd > 19.0) { | |
//System.out.println(ra + "," + dec); | |
} | |
} | |
} | |
} | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
// System.out.printf("titles:%s, bad:%s, dupe:%s, goood:%s\r\n", titleLines, badLines, duplicates, goodLines); | |
// System.out.println(magCount); | |
// System.out.println(volCount); | |
System.out.println(title); | |
for (String s : near) { | |
//System.out.println(s); | |
} | |
for (Map.Entry<Integer, Integer> entry : volCount.entrySet()) { | |
//System.out.println(entry.getKey() + "," + entry.getValue()); | |
} | |
System.out.println(title); | |
for (String s : faint) { | |
//System.out.println(s); | |
} | |
System.out.println(); | |
//System.out.println(nearest); | |
System.out.println(); | |
for (Map.Entry<Integer, TreeMap<Integer, Integer>> e : magCounts.entrySet()) { | |
System.out.println(e.getKey() + "\t:\t" + e.getValue()); | |
} | |
} | |
} |
This file contains hidden or 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
var rndarr = [0.802, 0.296, 0.221, 0.751, 0.087, 0.112, 0.263, 0.94, 0.894, 0.035, 0.046, 0.82, 0.669, 0.083, 0.308, 0.104, | |
0.742, 0.743, 0.053, 0.754, 0.655, 0.882, 0.33, 0.34, 0.428, 0.558, 0.593, 0.885, 0.177, 0.013, 0.842, 0.857, 0.129, 0.452, | |
0.375, 0.518, 0.073, 0.774, 0.346, 0.5, 0.241, 0.264, 0.205, 0.188, 0.765, 0.62, 0.382, 0.608, 0.344, 0.457, 0.095, 0.304, | |
0.159, 0.071, 0.282, 0.439, 0.957, 0.082, 0.477, 0.366, 0.469, 0.464, 0.499, 0.66, 0.23, 0.181, 0.928, 0.599, 0.224, 0.856, | |
0.036, 0.072, 0.693, 0.687, 0.336, 0.534, 0.165, 0.594, 0.587, 0.506, 0.438, 0.621, 0.846, 0.793, 0.747, 0.528, 0.541, | |
0.029, 0.398, 0.405, 0.96, 0.163, 0.606, 0.16, 0.794, 0.085, 0.61, 0.713, 0.813, 0.442, 0.358, 0.154, 0.377, 0.19, | |
0.555, 0.977, 0.87, 0.581, 0.211, 0.748, 0.58, 0.419, 0.016, 0.887, 0.567, 0.586, 0.72, 0.734, 0.831, 0.637, 0.256, | |
0.93, 0.674, 0.782, 0.876, 0.936, 0.725, 0.144, 0.522, 0.299, 0.967, 0.235, 0.138, 0.895, 0.601, 0.704, 0.337, 0.271, | |
0.781, 0.556, 0.011, 0.639, 0.028, 0.686, 0.355, 0.671, 0.761, 0.21, 0.808, 0.183, 0.517, 0.675, 0.313, 0.872, 0.033, | |
0.829, 0.309, 0.32, 0.012, 0.272, 0.387, 0.201, 0.934, 0.376, 0.86, 0.293, 0.69, 0.454, 0.986, 0.445, 0.836, 0.331, | |
0.659, 0.545, 0.238, 0.111, 0.248, 0.059, 0.488, 0.547, 0.166, 0.367, 0.48, 0.68, 0.143, 0.043, 0.97, 0.796, 0.245, | |
0.38, 0.6, 0.456, 0.156, 0.812, 0.598, 0.137, 0.951, 0.435, 0.631, 0.684, 0.711, 0.519, 0.206, 0.44, 0.2, 0.844, 0.47, | |
0.302, 0.383, 0.803, 0.05, 0.703, 0.855, 0.15, 0.862, 0.044, 0.321, 0.175, 0.312, 0.768, 0.424, 0.791, 0.394, 0.993, | |
0.901, 0.663, 0.182, 0.712, 0.536, 0.705, 0.416, 0.25, 0.108, 0.652, 0.954, 0.55, 0.634, 0.548, 0.001, 0.694, 0.351, | |
0.298, 0.502, 0.867, 0.27, 0.959, 0.992, 0.45, 0.484, 0.658, 0.152, 0.295, 0.311, 0.981, 0.079, 0.792, 0.473, 0.963, | |
0.515, 0.242, 0.276, 0.283, 0.403, 0.155, 0.113, 0.538, 0.297, 0.868, 0.198, 0.266, 0.294, 0.699, 0.896, 0.172, 0.178, | |
0.01, 0.431, 0.863, 0.091, 0.905, 0.432, 0.489, 0.933, 0.18, 0.801, 0.642, 0.892, 0.626, 0.607, 0.269, 0.354, 0.408, | |
0.288, 0.396, 0.246, 0.67, 0.115, 0.157, 0.697, 0.929, 0.651, 0.186, 0.611, 0.668, 0.592, 0.423, 0.617, 0.582, 0.644, | |
0.088, 0.716, 0.525, 0.08, 0.253, 0.141, 0.832, 0.125, 0.465, 0.629, 0.462, 0.913, 0.486, 0.7, 0.135, 0.315, 0.939, | |
0.74, 0.654, 0.619, 0.976, 0.495, 0.54, 0.103, 0.576, 0.889, 0.664, 0.341, 0.984, 0.209, 0.005, 0.151, 0.804, 0.273, | |
0.038, 0.229, 0.73, 0.806, 0.84, 0.197, 0.491, 0.961, 0.037, 0.799, 0.231, 0.239, 0.907, 0.168, 0.119, 0.07, 0.084, | |
0.252, 0.779, 0.809, 0.769, 0.343, 0.767, 0.386, 0.526, 0.292, 0.1, 0.661, 0.927, 0.319, 0.497, 0.989, 0.568, 0.614, | |
0.249, 0.718, 0.365, 0.898, 0.335, 0.544, 0.22, 0.322, 0.943, 0.261, 0.434, 0.717, 0.622, 0.146, 0.584, 0.757, 0.006, | |
0.835, 0.348, 0.886, 0.109, 0.334, 0.828, 0.514, 0.726, 0.441, 0.926, 0.662, 0.352, 0.054, 0.26, 0.988, 0.437, 0.775, | |
0.902, 0.944, 0.908, 0.52, 0.391, 0.559, 0.624, 0.749, 0.392, 0.562, 0.647, 0.244, 0.691, 0.721, 0.306, 0.921, 0.118, | |
0.945, 0.018, 0.368, 0.616, 0.85, 0.56, 0.279, 0.328, 0.922, 0.268, 0.487, 0.542, 0.543, 0.415, 0.539, 0.285, 0.214, | |
0.116, 0.552, 0.192, 0.451, 0.733, 0.356, 0.897, 0.692, 0.741, 0.064, 0.414, 0.409, 0.975, 0.461, 0.893, 0.566, 0.196, | |
0.603, 0.421, 0.648, 0.98, 0.77, 0.493, 0.065, 0.034, 0.839, 0.243, 0.958, 0.591, 0.822, 0.689, 0.443, 0.71, 0.189, | |
0.101, 0.527, 0.496, 0.837, 0.459, 0.215, 0.074, 0.956, 0.021, 0.412, 0.278, 0.569, 0.924, 0.906, 0.76, 0.475, 0.097, | |
0.36, 0.327, 0.983, 0.078, 0.919, 0.706, 0.067, 0.649, 0.225, 0.666, 0.778, 0.236, 0.531, 0.481, 0.098, 0.969, 0.124, | |
0.99, 0.871, 0.466, 0.965, 0.173, 0.307, 0.971, 0.317, 0.564, 0.549, 0.859, 0.762, 0.099, 0.232, 0.448, 0.917, 0.347, | |
0.401, 0.262, 0.447, 0.026, 0.825, 0.142, 0.338, 0.561, 0.361, 0.164, 0.089, 0.972, 0.553, 0.738, 0.149, 0.162, 0.858, | |
0.316, 0.251, 0.942, 0.217, 0.126, 0.719, 0.89, 0.4, 0.318, 0.783, 0.014, 0.756, 0.571, 0.595, 0.003, 0.433, 0.79, 0.737, | |
0.537, 0.449, 0.753, 0.841, 0.324, 0.615, 0.583, 0.494, 0.682, 0.247, 0.17, 0.207, 0.393, 0.635, 0.476, 0.123, 0.467, | |
0.788, 0.342, 0.468, 0.735, 0.218, 0.388, 0.819, 0.962, 0.471, 0.589, 0.998, 0.732, 0.478, 0.827, 0.851, 0.357, 0.147, | |
0.363, 0.628, 0.402, 0.574, 0.219, 0.004, 0.677, 0.729, 0.557, 0.511, 0.51, 0.184, 0.404, 0.171, 0.194, 0.429, 0.623, | |
0.107, 0.653, 0.093, 0.573, 0.427, 0.35, 0.042, 0.128, 0.498, 0.59, 0.492, 0.373, 0.632, 0.277, 0.017, 0.187, 0.949, | |
0.995, 0.879, 0.131, 0.134, 0.873, 0.384, 0.81, 0.766, 0.678, 0.911, 0.002, 0.641, 0.63, 0.805, 0.938, 0.811, 0.888, | |
0.931, 0.096, 0.369, 0.577, 0.326, 0.852, 0.847, 0.508, 0.974, 0.708, 0.53, 0.49, 0.736, 0.797, 0.727, 0.329, 0.179, | |
0.349, 0.213, 0.255, 0.39, 0.966, 0.12, 0.195, 0.964, 0.854, 0.826, 0.426, 0.062, 0.92, 0.145, 0.849, 0.773, 0.482, | |
0.117, 0.203, 0.683, 0.978, 0.418, 0.13, 0.222, 0.463, 0.739, 0.226, 0.047, 0.676, 0.234, 0.24, 0.707, 0.455, 0.504, | |
0.744, 0.941, 0.695, 0.105, 0.996, 0.362, 0.955, 0.102, 0.728, 0.815, 0.575, 0.935, 0.191, 0.37, 0.585, 0.049, 0.817, | |
0.139, 0.223, 0.667, 0.968, 0.032, 0.798, 0.665, 0.777, 0.848, 0.759, 0.789, 0.374, 0.228, 0.267, 0.031, 0.444, 0.061, | |
0.529, 0.185, 0.413, 0.843, 0.643, 0.764, 0.625, 0.0, 0.932, 0.023, 0.612, 0.65, 0.153, 0.814, 0.609, 0.672, 0.516, | |
0.121, 0.41, 0.605, 0.133, 0.286, 0.332, 0.417, 0.563, 0.199, 0.106, 0.022, 0.453, 0.915, 0.891, 0.953, 0.136, 0.379, | |
0.579, 0.42, 0.158, 0.679, 0.787, 0.715, 0.723, 0.077, 0.613, 0.818, 0.399, 0.909, 0.291, 0.048, 0.918, 0.345, 0.019, | |
0.807, 0.565, 0.884, 0.546, 0.645, 0.051, 0.385, 0.638, 0.056, 0.786, 0.265, 0.3, 0.853, 0.904, 0.785, 0.698, 0.864, | |
0.696, 0.503, 0.997, 0.227, 0.513, 0.875, 0.063, 0.75, 0.485, 0.824, 0.88, 0.314, 0.588, 0.407, 0.937, 0.991, 0.946, | |
0.024, 0.979, 0.132, 0.193, 0.731, 0.212, 0.281, 0.91, 0.823, 0.772, 0.29, 0.216, 0.397, 0.535, 0.883, 0.985, 0.389, | |
0.43, 0.425, 0.554, 0.254, 0.274, 0.845, 0.025, 0.925, 0.533, 0.284, 0.532, 0.627, 0.912, 0.275, 0.57, 0.618, 0.081, | |
0.086, 0.474, 0.259, 0.31, 0.066, 0.055, 0.045, 0.28, 0.406, 0.784, 0.994, 0.46, 0.776, 0.039, 0.505, 0.763, 0.877, | |
0.903, 0.041, 0.982, 0.83, 0.878, 0.685, 0.596, 0.947, 0.092, 0.95, 0.572, 0.325, 0.258, 0.795, 0.578, 0.287, 0.008, | |
0.359, 0.821, 0.521, 0.509, 0.058, 0.167, 0.752, 0.866, 0.161, 0.114, 0.914, 0.122, 0.838, 0.524, 0.027, 0.237, 0.604, | |
0.673, 0.745, 0.771, 0.094, 0.722, 0.176, 0.11, 0.512, 0.602, 0.501, 0.323, 0.688, 0.204, 0.8, 0.09, 0.714, 0.646, | |
0.202, 0.395, 0.303, 0.999, 0.333, 0.916, 0.339, 0.746, 0.636, 0.14, 0.257, 0.364, 0.758, 0.681, 0.834, 0.378, 0.9, | |
0.148, 0.009, 0.371, 0.597, 0.507, 0.174, 0.833, 0.052, 0.523, 0.701, 0.372, 0.899, 0.923, 0.702, 0.381, 0.233, 0.816, | |
0.411, 0.06, 0.301, 0.657, 0.78, 0.015, 0.724, 0.208, 0.458, 0.656, 0.069, 0.987, 0.446, 0.551, 0.483, 0.04, 0.075, | |
0.305, 0.755, 0.422, 0.127, 0.948, 0.479, 0.952, 0.436, 0.03, 0.874, 0.472, 0.289, 0.865, 0.007, 0.861, 0.169, 0.633, | |
0.64, 0.076, 0.02, 0.068, 0.881, 0.057, 0.353, 0.869, 0.709, 0.973]; | |
var rnd0; | |
var rnd1; | |
var rnd2; | |
var lavaRatio = 0.15; | |
var cryoRatio = 10.0; | |
var innerGreenRatio = 0.71; | |
var outerGreenRatio = 2.0; | |
var spec = "O.........B......A...F..G..K.....M"; | |
var planetType = ["Empty", "Dust", "Rubble", "Rocky", "Ice", "Ice Giant", "Gas Giant"]; | |
var planetCode = ["E", "D", "A", "R", "I", "G", "H"]; | |
var planetMass = [0, 0.1, 0.1, 1, 2, 20, 250]; | |
var planetRadi = [0, 0, 0, 1, 1.12, 3.9, 10.7]; | |
var planetMoon = [0, 0, 0, 0.02, 0.02, 0.002, 0.002]; | |
var atmosphereType = ["Vacuum", "Near Vacuum", "Very Thin", "Thin", "Medium", "Thick", "Very Thick", "Dense", "H2"]; | |
var zone = ["Lava", "Hot", "Green", "Cold", "Cryo"]; | |
var createSystem = function(spectralClass, subclass, stage, seed0, seed1, seed2) { | |
rnd0 = seed0; | |
rnd1 = seed1; | |
rnd2 = seed2; | |
federationSystemKey = spectralClass + subclass + stage + "/"; | |
//print(federationSystemKey); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
var numPlanets = Math.min(r_int(16), Math.floor(rndarr[rnd2++ % 1000] * 16)); | |
var spectralClassNum = spec.length() - spec.indexOf(spectralClass); | |
mod = (subclass - 5) / 3; | |
var greenZone = Math.pow(1.4, spectralClassNum - mod) * 9; | |
orbitIncrease = 1; | |
var initialOrbit = (1 + r_int(30)) * greenZone / 20.0; | |
starSystem = [spectralClass + subclass + stage, seed0, seed1, seed2, greenZone]; | |
//print(starSystem); | |
for (i = 0; i < numPlanets; i++) { | |
r_double(); | |
r_double(); | |
PLANET = spectralClass == "M" || spectralClass == "K" | |
? r_double() < 0.6 ? 3 : r_int(planetType.length) | |
: r_int(planetType.length); | |
r_double(); | |
r_double(); | |
r_double(); | |
var ORBIT = initialOrbit; | |
initialOrbit = initialOrbit * (12 + r_int(10)) / 10 * orbitIncrease; //next planet; | |
massMod = (1.05 + rndarr[rnd2++ % 1000] - r_double()); | |
if (massMod > 1) { | |
massMod = Math.pow(massMod, 4); | |
} | |
MASS = massMod * planetMass[PLANET]; | |
if (MASS > 200 && ORBIT / greenZone < 1.4) { | |
orbitIncrease = 1.4; | |
ORBIT = ORBIT * 1.4; | |
} else if (MASS > 20 && ORBIT / greenZone < 1.4) { | |
orbitIncrease = 1.2; | |
ORBIT = ORBIT * 1.2; | |
} else { | |
orbitIncrease = 1; | |
} | |
ZONE = ORBIT < (lavaRatio * greenZone) ? "Lava" | |
: ORBIT < (innerGreenRatio * greenZone) ? "Hot" | |
: ORBIT > (cryoRatio * greenZone) ? "Cryo" | |
: ORBIT > (outerGreenRatio * greenZone) ? "Cold" | |
: "Green"; | |
while ((federationSystemKey.match(/-/g) || []).length < zone.indexOf(ZONE)) { | |
federationSystemKey = federationSystemKey + "-"; | |
} | |
federationSystemKey = federationSystemKey + planetCode[PLANET]; | |
//var planetCode = ["E", "D", "A", "R", "I", "G", "H"]; | |
radiusMod = (10 + r_double() - r_double()) / 10; | |
massRadiusMod = PLANET == 6 ? Math.pow(massMod, 0.16666667) : Math.pow(massMod, 0.33333333); | |
RADIUS = PLANET < 3 ? 0 : planetRadi[PLANET] * massRadiusMod * radiusMod; | |
DENSITY = PLANET < 3 ? 0 : MASS / Math.pow(RADIUS, 3); | |
GRAVITY = PLANET < 3 ? 0 : MASS / RADIUS / RADIUS; | |
DAY = r_bool() ? 16 + r_int(16) | |
: r_bool() ? 8 + r_int(8) | |
: 30 + r_int(2000); | |
DAY = PLANET < 3 ? 0 : ZONE == "Lava" || (spectralClass == "M" && r_double() < 0.8)? "Locked" : DAY; | |
atmosphere = atmosphereFunc(PLANET, GRAVITY, ZONE); | |
ATMOSPHERE = atmosphereType[atmosphere]; | |
KMH2O = 0; LAND = 0; | |
if (atmosphere > 1 && atmosphere < 7) { | |
KMH2O = PLANET == 3 ? r_double() * 10 : PLANET == 4 ? 50 + r_int(1000) : 0; | |
LAND = PLANET == 3 && ZONE == "Green" ? 100 / Math.max(1, KMH2O * (1 + r_double())) : 0; | |
} | |
GEOLOGICAL_STABILITY = Math.max(r_int(10), r_int(10)); | |
MAGNETIC_FIELD = Math.min(r_int(10), r_int(10)); | |
POLAR_TILT = Math.max(r_int(90), r_int(90)); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
LIFESTATS = lifeStats(atmosphere, ZONE, GRAVITY, LAND, PLANET); | |
//[HABITABILITY_IDX, INTELLIGENT, PLANT_LIFE, SEA_LIFE, LAND_LIFE, AIR_LIFE, FLAG, POPULATION, POLITICS] | |
if (LIFESTATS.length > 1) { | |
federationSystemKey = federationSystemKey + LIFESTATS[0] + LIFESTATS[7] | |
if (LIFESTATS[1]) { | |
federationSystemKey = federationSystemKey + "*"; | |
} | |
} | |
planet = [ | |
planetType[PLANET], | |
ZONE, | |
"orbit="+parseFloat(ORBIT).toPrecision(4), | |
"day="+parseInt(DAY), | |
"density="+parseFloat(DENSITY).toPrecision(3), | |
"radius="+parseFloat(RADIUS).toPrecision(3), | |
"g="+parseFloat(GRAVITY).toPrecision(3), | |
"mass="+parseFloat(MASS).toPrecision(3), | |
"kmh2o="+parseFloat(KMH2O).toPrecision(3), | |
"land="+parseFloat(LAND).toPrecision(3), | |
"atm="+ATMOSPHERE, | |
"life="+LIFESTATS | |
]; | |
//print(" " + planet); | |
moons = PLANET - 2 + r_int(3) - Math.floor(rndarr[rnd2++ % 1000] * 3); | |
if (ZONE == "Lava") moons = 0; | |
if (ZONE == "Hot") moons = moons / 2; | |
if (ZONE == "Cold") moons = moons * 2; | |
if (ZONE == "Cryo") moons = moons * 3; | |
MOONS = []; | |
moonOrbit = r_int(10) + 3; | |
for (m = 0; m < moons; m++) { | |
moonOrbit = moonOrbit * (3 + r_double() + r_double()) / 2.8; | |
moonPlanetType = ORBIT < greenZone * 2 ? 3 : 4; | |
moonMass = MASS * planetMoon[PLANET] * Math.min(rndarr[rnd2++ % 1000] + 0.001, r_double() + 0.001); | |
if (moonOrbit < 4) moonPlanetType = r_int(2) + 1; | |
//moons less dense than planets | |
moonRadius = moonPlanetType < 3 ? 0 : (10 + r_double()) / 10 * planetRadi[moonPlanetType] * Math.pow(moonMass / planetMass[moonPlanetType], 0.3333333); | |
moonDensity = moonPlanetType < 3 ? 0 : moonMass / Math.pow(moonRadius, 3); | |
moonGrav = moonPlanetType < 3 ? 0 : moonMass / moonRadius / moonRadius; | |
//moons are poor in volatiles | |
moonAtm = Math.min(atmosphereFunc(moonPlanetType, moonGrav, ZONE), r_int(5), r_int(5), r_int(5)); | |
moonKMH2O = 0; moonLAND = 0; | |
if (moonAtm > 1 && moonAtm < 7) { | |
moonKMH2O = moonPlanetType == 3 ? Math.min(r_double(), rndarr[rnd2++ % 1000]) * 1 : moonPlanetType == 4 ? 50 + r_int(1000) : 0; | |
moonLAND = moonPlanetType == 3 && ZONE == "Green" ? 100 / Math.max(1, moonKMH2O * (1 + r_double())) : 0; | |
} | |
moonLIFESTATS = lifeStats(moonAtm, ZONE, moonGrav, moonLAND, moonPlanetType); | |
if (moonLIFESTATS.length > 1) { | |
federationSystemKey = federationSystemKey + planetCode[moonPlanetType].toLowerCase() + moonLIFESTATS[0] + moonLIFESTATS[7] | |
if (moonLIFESTATS[1]) { | |
federationSystemKey = federationSystemKey + "*"; | |
} | |
} | |
moonGEOLOGICAL_STABILITY = Math.max(r_int(10), r_int(10)); | |
moonMAGNETIC_FIELD = Math.min(r_int(10), r_int(10)); | |
monPOLAR_TILT = POLAR_TILT; | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
r_double(); | |
moon = [ | |
planetType[moonPlanetType], | |
ZONE, | |
"orbit="+parseFloat(moonOrbit).toPrecision(4), | |
"day="+parseInt(moonOrbit * 24), | |
"density="+parseFloat(moonDensity).toPrecision(3), | |
"radius="+parseFloat(moonRadius).toPrecision(3), | |
"g="+parseFloat(moonGrav).toPrecision(3), | |
"mass="+parseFloat(moonMass).toPrecision(3), | |
"kmh2o="+parseFloat(moonKMH2O).toPrecision(3), | |
"land="+parseFloat(moonLAND).toPrecision(3), | |
"atm="+moonAtm, | |
"life="+moonLIFESTATS | |
]; | |
//print(" " + moon); | |
} | |
} | |
//print(federationSystemKey + Number(numPlanets) + "/" + numPlanets + "/" + numPlanets); | |
return federationSystemKey; | |
} | |
var atmosphereFunc = function(PLANET, GRAVITY, ZONE) { | |
atmosphere = PLANET > 4 ? 8 | |
: PLANET < 3 ? 0 | |
: GRAVITY < 0.4 ? 2 | |
: GRAVITY < 0.8 ? 3 | |
: GRAVITY > 2 ? 7 | |
: GRAVITY > 1.6 ? 6 | |
: GRAVITY > 1.2 ? 5 | |
: 4; | |
if (PLANET == 3 || PLANET == 4) { | |
atmosphere = atmosphere + r_int(2) - r_int(2); | |
if (ZONE == "Lava") atmosphere = atmosphere - 2; | |
if (ZONE == "Hot") atmosphere = atmosphere - 1; | |
if (ZONE == "Cold") atmosphere = atmosphere + 1; | |
if (ZONE == "Cryo") atmosphere = atmosphere + 2; | |
} | |
//sometimes atmospheres are blasted off by impacts | |
if (PLANET == 3 & r_double() < 0.5) { | |
atmosphere = r_int(atmosphere); | |
} | |
if (atmosphere < 0) atmosphere = 0; | |
if (atmosphere > 8) atmosphere = 8; | |
return atmosphere; | |
} | |
var lifeStats = function(atmosphere, ZONE, GRAVITY, LAND, PLANET) { | |
PLANT_LIFE = 0; SEA_LIFE = 0; LAND_LIFE = 0; AIR_LIFE = 0, INTELLIGENT = false; | |
HABITABILITY_IDX = "NA"; | |
if (atmosphere > 1 && atmosphere < 7 && ZONE == "Green" && (PLANET == 3 || PLANET == 4)) { | |
grav_livable = GRAVITY > 0.8 && GRAVITY < 1.1 ? 3 | |
: GRAVITY > 0.6 && GRAVITY < 1.25 ? 2 | |
: GRAVITY > 0.45 && GRAVITY < 1.4 ? 1 | |
: 0; | |
atms_livable = atmosphere == 4 ? 3 | |
: atmosphere == 3 || atmosphere == 5 ? 2 | |
: 0; | |
land_livable = LAND > 25 && LAND < 35 ? 3 | |
: LAND > 15 && LAND < 45 ? 2 | |
: LAND > 10 && LAND < 60 ? 1 | |
: 0; | |
HABITABILITY_IDX = grav_livable + atms_livable + land_livable; | |
PLANT_LIFE = r_int(7) + HABITABILITY_IDX - r_int(6); | |
SEA_LIFE = r_int(7) + HABITABILITY_IDX - r_int(6); | |
LAND_LIFE = r_int(7) + HABITABILITY_IDX - (GRAVITY > 1.7 ? 2 : GRAVITY > 1.35 ? 1 : 0) - r_int(6); | |
AIR_LIFE = r_int(4) + HABITABILITY_IDX - r_int(6) | |
- (GRAVITY > 1.7 ? 5 : GRAVITY > 1.4 ? 3 : GRAVITY > 1.1 ? 1 : 0) | |
+ (GRAVITY < 0.5 ? 3 : GRAVITY < 0.65 ? 2 : GRAVITY < 0.8 ? 1 : 0) | |
+ (atmosphere - 4); | |
INTELLIGENT = r_double() > 0.99 && r_double() > 0.99; | |
POPULATION = INTELLIGENT ? 9 : r_int(HABITABILITY_IDX + 1); | |
POLITICS = r_int(1000); | |
POLITICS2 = r_int(1000); | |
FLAG = r_double() > 0.85 ? r_bool() ? "D" : "G" : ""; | |
} | |
return HABITABILITY_IDX == "NA" ? ["NA"] : [HABITABILITY_IDX, INTELLIGENT, PLANT_LIFE, SEA_LIFE, LAND_LIFE, AIR_LIFE, FLAG, POPULATION, POLITICS, POLITICS2]; | |
} | |
var r_double = function() { | |
rnd0 += rndarr[rnd1] * 1000; | |
rnd1++; | |
if (rnd0 > 999) rnd0 = rnd0 - 1000; | |
if (rnd1 > 999) rnd1 = rnd1 - 1000; | |
return rndarr[Math.floor(rnd0)]; | |
} | |
var r_int = function(limit) { | |
rnd0 += rndarr[rnd1] * 1000; | |
rnd1++; | |
if (rnd0 > 999) rnd0 = rnd0 - 1000; | |
if (rnd1 > 999) rnd1 = rnd1 - 1000; | |
x = rndarr[Math.floor(rnd0)] + 0.0002; | |
return Math.floor(x * limit); | |
} | |
var r_bool = function() { | |
rnd0 += rndarr[rnd1] * 1000; | |
rnd1++; | |
if (rnd0 > 999) rnd0 = rnd0 - 1000; | |
if (rnd1 > 999) rnd1 = rnd1 - 1000; | |
x = rndarr[Math.floor(rnd0)]; | |
return Math.floor(x < 0.5); | |
} |
This file contains hidden or 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
package com.beyondproxima.fictional; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Random; | |
import static com.beyondproxima.fictional.PlanetGenerator.Atmosphere.thick; | |
import static com.beyondproxima.fictional.PlanetGenerator.Atmosphere.thin; | |
import static com.beyondproxima.fictional.PlanetGenerator.PlanetType.*; | |
import static com.beyondproxima.fictional.PlanetGenerator.Zone.*; | |
/** | |
* Generates: planet size, gravity, atmosphere, biome, moons | |
* Created by Agslinda on 4/15/2018. | |
*/ | |
public class PlanetGenerator { | |
private static int seed = (int) (Math.random() * 10000); | |
private static Random R = new Random(7328); | |
static { | |
System.out.println(seed); | |
//good: 7089, 134, 1015, 4608 | |
//bug: | |
} | |
public static void main(String[] args) { | |
int numMultiHabitable = 0; | |
int max = 0, total = 0; | |
for (int i = 0; i < 1000; i++) { | |
StarSystem s = generate(); | |
total += s.desirable; | |
max = Math.max(max, s.desirable); | |
if (s.habitable > 0 && s.desirable > 0) { | |
numMultiHabitable++; | |
System.out.println(seed); | |
System.out.println(s.star); | |
System.out.println(" type mass radius dens grav moon zone atmosph kmh20 land day period habIndex"); | |
for (Planet actual : s.planets) { | |
System.out.printf("%10s %7.2f %7.2f %5.2f %5.2f %5s %7s %10s %7.1f %7.1f %9.1f %9.1f %9s\n", | |
actual.type, actual.mass, actual.radius, actual.density, actual.g, actual.moons, actual.zone, actual.atmosphere, | |
actual.kmH20, actual.landPercent, actual.dayLength, actual.period, actual.habIndex); | |
synopsis(actual); | |
for (Planet moon : actual.moonList) { | |
System.out.printf("%10s %7.2f %7.2f %5.2f %5.2f %5s %7s %10s %7.1f %7.1f %9.1f %9.1f %9s\n", | |
"moon", moon.mass, moon.radius, moon.density, moon.g, "", "", moon.atmosphere, | |
moon.kmH20, moon.landPercent, moon.dayLength, moon.period, moon.habIndex); | |
synopsis(moon); | |
} | |
} | |
} | |
seed = (int) (Math.random() * 10000); | |
R = new Random(seed); | |
} | |
System.out.println(numMultiHabitable); | |
System.out.println(max); | |
System.out.println(total); | |
} | |
private static void synopsis(Planet p) { | |
if (p.lifeForms != null) { | |
System.out.printf("\t\t\tThe planet is inhabited by %s %s and %s %s.\n", | |
p.lifeForms.animalSize, p.lifeForms.highestAnimals, p.lifeForms.plantSize, p.lifeForms.highestPlants); | |
String[] warm = new String[]{"much colder than", "noticeably colder than", "slightly colder than", "as warm as", "slightly warmer than", "noticeably warmer than", "much warmer than"}; | |
int warmIdx = getInRange(p.climate.temperature - 2, warm, 1); | |
System.out.printf("\t\t\tThe planet is %s the Earth.\n", warm[warmIdx]); | |
String[] extremes = new String[]{"much more extreme than", "somewhat more extreme than", "similar to", "somewhat milder than", "much milder than"}; | |
System.out.printf("\t\t\tThe north pole is %s the Earth.\n", extremes[getInRange(p.climate.northPole - 3, extremes, 1)]); | |
System.out.printf("\t\t\tThe north temperate zone is %s the Earth.\n", extremes[getInRange(p.climate.northTemperate - 3, extremes, 1)]); | |
System.out.printf("\t\t\tThe equator is %s the Earth.\n", extremes[getInRange(p.climate.equator - 3, extremes, 1)]); | |
System.out.printf("\t\t\tThe south temperate zone is %s the Earth.\n", extremes[getInRange(p.climate.southTemperate - 3, extremes, 1)]); | |
System.out.printf("\t\t\tThe south pole is %s the Earth.\n", extremes[getInRange(p.climate.southPole - 3, extremes, 1)]); | |
System.out.printf("\t\t\tThe planet axial tilt is %s degrees.\n", p.climate.polarTilt); | |
System.out.printf("\t\t\tStorm systems on the planet are Intensity %s, versus Earth 5.\n", p.climate.storms); | |
} | |
} | |
private static int getInRange(int val, String[] arr, int div) { | |
return Math.max(Math.min(val, (arr.length - 1) / div), 0); | |
} | |
public static class StarSystem { | |
static final double lavaRatio = 0.1; | |
static final double cryoRatio = 10.0; | |
static final double innerGreenRatio = 0.71; | |
static final double outerGreenRatio = 2.0; | |
int spectralTypeNum = Math.max(R.nextInt(10), R.nextInt(10)); | |
String star = new String[]{"F5", "G2", "G7", "K0", "K2", "K5", "K8", "M0", "M5", "M9"}[spectralTypeNum]; | |
double greenZone = new double[]{500, 400, 360, 300, 220, 120, 60, 20, 11, 7}[spectralTypeNum]; | |
int survivable; | |
int habitable; | |
int desirable; | |
List<Planet> planets = new ArrayList<>(); | |
} | |
private static StarSystem generate() { | |
StarSystem s = new StarSystem(); | |
double period = s.greenZone / (R.nextInt(20) + 1 + R.nextDouble()); | |
for (int p = 0; p < R.nextInt(16); p++) { | |
Zone zone = green; | |
if (period < s.greenZone * StarSystem.lavaRatio) { | |
zone = lava; | |
} else if (period < s.greenZone * StarSystem.innerGreenRatio) { | |
zone = hot; | |
} else if (period > s.greenZone * StarSystem.cryoRatio) { | |
zone = cryo; | |
} else if (period > s.greenZone * StarSystem.outerGreenRatio) { | |
zone = Zone.ice; | |
} | |
Planet actual = new Planet(); | |
s.planets.add(actual); | |
actual.period = period; | |
//period for next planet | |
period = period * (1.3 + R.nextDouble()); | |
if (R.nextBoolean()) period = period * (1.3 + R.nextDouble()); | |
actual.zone = zone; | |
actual.type = PlanetType.values()[R.nextInt(PlanetType.values().length)]; | |
if (actual.type == dust || actual.type == rubble) { | |
continue; | |
} | |
//actual.type = PlanetType.gasGiant; | |
double mass = Math.max(0.05, 1 - R.nextDouble() + R.nextDouble()); | |
double radiusMod = (R.nextDouble() + 9.5) / 10.0; | |
doPlanet(actual, mass, radiusMod, zone, true); | |
if (actual.habIndex > 6) { | |
s.desirable++; | |
} | |
if (actual.habIndex > 3) { | |
s.habitable++; | |
} | |
if (actual.habIndex > -1) { | |
s.survivable++; | |
} | |
for (int k = 0; k < actual.moons; k++) { | |
Planet moon = new Planet(); | |
moon.period = 5 * Math.pow(1.5, k + 1 + R.nextDouble()); | |
moon.type = zone == lava || zone == hot || zone == green ? rocky : PlanetType.ice; | |
moon.zone = zone; | |
double massMod = Math.min(Math.min(R.nextDouble(), R.nextDouble()), R.nextDouble()); | |
double moonMass = actual.type == PlanetType.gasGiant | |
? actual.mass * 0.001 * massMod//assume gas giant moons are relatively smaller than rocky/ice planet moons | |
: actual.type == PlanetType.iceGiant ? actual.mass * 0.03 * massMod | |
: actual.mass * 0.16 * massMod; //Charon is 0.125 Pluto | |
double moonRadiusMod = (R.nextDouble() + 9.5) / 10.0; | |
doPlanet(moon, moonMass, moonRadiusMod, zone, false); | |
actual.moonList.add(moon); | |
if (moon.habIndex > 6) { | |
s.desirable++; | |
} | |
if (moon.habIndex > 3) { | |
s.habitable++; | |
} | |
if (moon.habIndex > -1) { | |
s.survivable++; | |
} | |
} | |
} | |
return s; | |
} | |
private static void doPlanet(Planet actual, double massIncrease, double radiusMod, Zone zone, boolean isPlanet) { | |
if (isPlanet) { | |
massIncrease = massIncrease <= 1 ? massIncrease : massIncrease * 5; | |
if (actual.type == PlanetType.iceGiant) { | |
massIncrease = (massIncrease + 3) / 4.0; | |
} | |
} | |
actual.mass = massIncrease * actual.type.mass; | |
double volume = massIncrease > 1 && actual.type == gasGiant ? (massIncrease + 1) / 2.0 : massIncrease; | |
double radiusIncrease = Math.pow(volume, 0.3333); | |
actual.radius = radiusMod * actual.type.radius * radiusIncrease; | |
actual.density = actual.mass / Math.pow(actual.radius, 3); | |
double sphere = Math.pow(actual.mass * zone.roche, 0.3333); | |
actual.moons = Math.max((int) Math.ceil(sphere) - R.nextInt(3), 0); | |
actual.g = actual.mass / Math.pow(actual.radius, 2.0); | |
actual.atmosphere = Atmosphere.get(zone, actual.type, actual.g); | |
actual.kmH20 = getWaterDepth(actual.atmosphere, actual.type, zone, actual.radius); | |
actual.landPercent = getLandPercent(actual, zone); | |
actual.dayLength = | |
R.nextDouble() < 0.1 ? actual.dayLength / 2 | |
: R.nextDouble() < 0.1 ? actual.dayLength * (R.nextInt(10) + 1) | |
: actual.dayLength; | |
actual.dayLength = isPlanet ? actual.zone == lava ? 0 : actual.dayLength : actual.period * 24; | |
actual.habIndex = setHabIndex(actual); | |
actual.lifeForms = generateLife(actual); | |
actual.climate = getClimate(actual); | |
} | |
private static int setHabIndex(Planet actual) { | |
if (actual.atmosphere == Atmosphere.vacuum || actual.atmosphere == Atmosphere.exothin | |
|| actual.atmosphere == Atmosphere.dense || actual.atmosphere == Atmosphere.giantH2 | |
|| actual.atmosphere == Atmosphere.thickH2) { | |
return -1; | |
} | |
int val = actual.zone == green ? actual.type == rocky ? 1 : actual.type == PlanetType.ice ? 0 : -1 : -1; | |
if (val > -1) { | |
if (Math.max(actual.g, 1.0) / Math.min(actual.g, 1.0) < 1.1) { | |
val++; | |
} | |
if (Math.max(actual.g, 1.0) / Math.min(actual.g, 1.0) < 1.3) { | |
val++; | |
} | |
if (Math.max(actual.g, 1.0) / Math.min(actual.g, 1.0) > 1.5) { | |
val--; | |
} | |
if (Math.max(actual.g, 1.0) / Math.min(actual.g, 1.0) > 1.6) { | |
val--; | |
} | |
if (Math.max(actual.g, 1.0) / Math.min(actual.g, 1.0) > 1.7) { | |
val--; | |
} | |
if (Math.max(actual.g, 1.0) / Math.min(actual.g, 1.0) > 1.8) { | |
val--; | |
} | |
if (Math.max(actual.g, 1.0) / Math.min(actual.g, 1.0) > 1.9) { | |
val--; | |
} | |
if (Math.max(actual.g, 1.0) / Math.min(actual.g, 1.0) > 2.0) { | |
val--; | |
} | |
if (Math.max(actual.dayLength, 24) / Math.min(actual.dayLength, 24) > 1.15) { | |
val++; | |
} | |
if (Math.max(actual.dayLength, 24) / Math.min(actual.dayLength, 24) > 1.3) { | |
val++; | |
} | |
if (actual.dayLength > 48) { | |
val--; | |
} | |
if (actual.dayLength > 96) { | |
val--; | |
} | |
if (actual.landPercent > 5) { | |
val++; | |
} | |
if (actual.landPercent < 75) { | |
val++; | |
} | |
if (actual.atmosphere == Atmosphere.terran) { | |
val += 2; | |
} | |
} | |
return val; | |
} | |
private static double getLandPercent(Planet actual, Zone zone) { | |
if (actual.type == gasGiant || actual.type == iceGiant) { | |
return 0; | |
} | |
if (actual.type == PlanetType.ice && (zone == lava || zone == hot)) { | |
return 0; | |
} | |
//methane seas: | |
if ((zone == Zone.ice || zone == cryo) && (actual.atmosphere != Atmosphere.vacuum && actual.atmosphere != Atmosphere.exothin)) { | |
return 80.0 + R.nextInt(20); | |
} | |
if (zone == Zone.ice || zone == cryo) { | |
return 100; | |
} | |
if (actual.type == rocky && zone == hot) { | |
return 100; | |
} | |
if (actual.type == rocky && zone == lava) { | |
return 40; | |
} | |
return actual.kmH20 != 0 & actual.kmH20 < 10 ? 100 / (actual.kmH20 + 1) : 0; | |
} | |
private static double getWaterDepth(Atmosphere atmosphere, PlanetType type, Zone zone, double radius) { | |
if (type == PlanetType.ice) { | |
if (zone == green) { | |
return (R.nextDouble() * 1000) + 50 * radius; | |
} else { | |
return 0; | |
} | |
} else if (type == rocky && atmosphere != Atmosphere.vacuum && atmosphere != Atmosphere.exothin && atmosphere != Atmosphere.dense) { | |
return Math.min(R.nextDouble(), R.nextDouble()) * 10; | |
} | |
return 0; | |
} | |
@SuppressWarnings("WeakerAccess") | |
public static class Planet { | |
PlanetType type; | |
double mass, radius, density, g, moons; | |
Atmosphere atmosphere; | |
ArrayList<Planet> moonList = new ArrayList<>(); | |
public double kmH20; | |
public double landPercent; | |
public double dayLength = (R.nextDouble() + 1) * 16; | |
double period; | |
Zone zone; | |
public int habIndex; | |
public LifeForms lifeForms; | |
public Climate climate; | |
} | |
enum Zone { | |
lava(0.1, 5), hot(0.5, 40), green(1.0, 300), ice(2.0, 700), cryo(4.0, 4000); | |
public final double roche; | |
public final double period; | |
Zone(double roche, double period) { | |
this.roche = roche; | |
this.period = period; | |
} | |
} | |
enum Atmosphere { | |
vacuum(0), exothin(0.3), thin(0.6), terran(0.9), thick(1.3), dense(1.8), thickH2(2.3), giantH2(5.0); | |
final double gThreshold; | |
Atmosphere(double gThreshold) { | |
this.gThreshold = gThreshold; | |
} | |
static Atmosphere get(Zone z, PlanetType p, double g) { | |
if (p == gasGiant || p == iceGiant) { | |
return giantH2; | |
} | |
int v = g > thickH2.gThreshold ? 6 | |
: g > dense.gThreshold ? 5 | |
: g > thick.gThreshold ? 4 | |
: g > terran.gThreshold ? 3 | |
: g > thin.gThreshold ? 2 | |
: g > exothin.gThreshold ? 1 | |
: 0; | |
v = R.nextInt(4) == 0 ? R.nextBoolean() ? v + 1 : v - 1 : v; | |
if (z == lava && R.nextBoolean()) { | |
v -= 1; | |
} | |
if ((z == Zone.ice || z == cryo) && R.nextBoolean()) { | |
v += 1; | |
} | |
v = v < 0 ? 0 : v > 6 ? 6 : v; | |
return values()[v]; | |
} | |
} | |
public static class Climate { | |
int polarTilt = Math.min(R.nextInt(91), R.nextInt(91)); | |
int ellipticalOrbit = Math.min(Math.min(R.nextInt(3), R.nextInt(3)), R.nextInt(3)); | |
int storms = 5; | |
int temperature = 5 - R.nextInt(2) + R.nextInt(2); | |
int northPole = 5; | |
int northTemperate = 5; | |
int equator = 5; | |
int southTemperate = 5; | |
int southPole = 5; | |
} | |
private static Climate getClimate(Planet p) { | |
if (p.zone == green && p.kmH20 > 0) { | |
Climate c = new Climate(); | |
if (p.atmosphere == thin) { | |
c.temperature--; | |
c.northPole -= 2; | |
c.southPole -= 2; | |
c.northTemperate--; | |
c.southTemperate--; | |
c.storms--; | |
} else if (p.atmosphere == thick) { | |
c.temperature++; | |
c.northPole += 2; | |
c.southPole += 2; | |
c.northTemperate++; | |
c.southTemperate++; | |
c.storms++; | |
} | |
if (p.radius < 0.8) { | |
c.northPole++; | |
c.southPole++; | |
c.northTemperate++; | |
c.southTemperate++; | |
} else if (p.radius > 1.2) { | |
c.northPole--; | |
c.southPole--; | |
c.northTemperate--; | |
c.southTemperate--; | |
} | |
if (c.polarTilt < 15) { | |
c.northPole--; | |
c.southPole--; | |
c.equator--; | |
} else if (c.polarTilt > 55) { | |
c.northPole -= 2; | |
c.southPole -= 2; | |
c.northTemperate--; | |
c.southTemperate--; | |
c.equator -= 1; | |
} else if (c.polarTilt > 33) { | |
c.northPole--; | |
c.southPole--; | |
c.equator++; | |
} | |
if (p.landPercent < 10) { | |
c.storms += 3; | |
c.northPole += 2; | |
c.southPole += 2; | |
c.northTemperate++; | |
c.southTemperate++; | |
c.equator++; | |
} else if (p.landPercent < 20) { | |
c.storms++; | |
c.northPole++; | |
c.southPole++; | |
} else if (p.landPercent > 60) { | |
c.storms -= 2; | |
c.northPole -= 2; | |
c.southPole -= 2; | |
c.northTemperate--; | |
c.southTemperate--; | |
c.equator--; | |
} else if (p.landPercent > 40) { | |
c.storms--; | |
c.northPole--; | |
c.southPole--; | |
} | |
if (c.ellipticalOrbit > 0) { | |
if (c.polarTilt < 15 || c.polarTilt > 55) { | |
c.northPole -= c.ellipticalOrbit; | |
c.southPole -= c.ellipticalOrbit; | |
c.northTemperate -= c.ellipticalOrbit; | |
c.southTemperate -= c.ellipticalOrbit; | |
c.equator -= c.ellipticalOrbit; | |
} else { | |
int flip = R.nextBoolean() ? -1 : 1; | |
c.northPole -= c.ellipticalOrbit * flip; | |
c.southPole += c.ellipticalOrbit * flip; | |
c.northTemperate -= c.ellipticalOrbit * flip; | |
c.southTemperate += c.ellipticalOrbit * flip; | |
} | |
} | |
if (p.dayLength < 20) { | |
c.northPole++; | |
c.southPole++; | |
c.northTemperate++; | |
c.southTemperate++; | |
c.equator++; | |
} else if (p.dayLength > 80) { | |
c.northPole -= 2; | |
c.southPole -= 2; | |
c.northTemperate -= 2; | |
c.southTemperate -= 2; | |
c.equator -= 2; | |
} else if (p.dayLength > 40) { | |
c.northPole--; | |
c.southPole--; | |
c.northTemperate--; | |
c.southTemperate--; | |
c.equator--; | |
} | |
return c; | |
} else { | |
return null; | |
} | |
} | |
static class LifeForms { | |
AnimalLife highestAnimals; | |
LifeSize animalSize; | |
PlantLife highestPlants; | |
LifeSize plantSize; | |
} | |
private static LifeForms generateLife(Planet p) { | |
int animTypes = AnimalLife.values().length; | |
int plntTypes = PlanetType.values().length; | |
int sizeTypes = LifeSize.values().length; | |
int maxHab = 3; | |
if (p.zone == green && p.kmH20 > 0) { | |
int kindToPlants = p.habIndex / 3; | |
int plantIdx = Math.max( | |
Math.min(R.nextInt(plntTypes - maxHab + 1 + kindToPlants), PlantLife.values().length - 1), | |
0); | |
int plantSizeBias = plantIdx / 2; | |
int plantSizeIdx = Math.max( | |
Math.min(R.nextInt(sizeTypes - (plntTypes / 2) + plantSizeBias), LifeSize.values().length - 1), | |
0); | |
int kindToAnimals = plantSizeIdx / 2; | |
int animalIdx = Math.max( | |
Math.min(R.nextInt(animTypes - (sizeTypes / 2) + 1 + kindToAnimals), AnimalLife.values().length - 1), | |
0); | |
int animalSizeIdx = Math.max( | |
Math.min(R.nextInt(sizeTypes - (animTypes / 2) + (animalIdx / 2)), LifeSize.values().length - 1), | |
0); | |
LifeForms lf = new LifeForms(); | |
lf.plantSize = LifeSize.values()[plantSizeIdx]; | |
lf.highestPlants = PlantLife.values()[plantIdx]; | |
lf.animalSize = LifeSize.values()[animalSizeIdx]; | |
lf.highestAnimals = AnimalLife.values()[animalIdx]; | |
return lf; | |
} else { | |
return null; | |
} | |
} | |
enum AnimalLife { | |
bacteria, amoeba, jellyfishAndFlatworms, wormsAndMolluscs, fishAndInsects, wormsAndMolluscs2, fishAndInsects2, amphibians, lizards, mammalsAndBirds, amphibians2, lizards2, mammalsAndBirds2 | |
} | |
enum PlantLife { | |
cyanobacteria, algae, lichen, moss, fern, flower, moss2, fern2, flower2 | |
} | |
enum LifeSize { | |
microscopic, tiny, oneCm, tenCm, thirtyCm, oneM, twoM, fiveM, tenM, twentyM, thirtyM, fiftyM, hundredM | |
} | |
enum PlanetType { | |
rocky(1, 1.0, 1.0), | |
ice(1, 0.5, 1.25), | |
iceGiant(14, 0.25, 4), | |
gasGiant(95, 0.14, 9.5), | |
dust(0.1, 1.0, 1.0), | |
rubble(0.1, 1.0, 1.0); | |
public final double mass, density, radius; | |
PlanetType(double earths, double density, double radius) { | |
this.mass = earths; | |
this.density = density; | |
this.radius = radius; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment