PageRenderTime 52ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/mona/projects/mox/src/MoxWorldBuilder.java

#
Java | 604 lines | 527 code | 43 blank | 34 comment | 75 complexity | 74d1ba5da14328435e8c7102e701bed2 MD5 | raw file
  1. /*
  2. * Build a Game of Life mox world using given parameters.
  3. */
  4. import java.util.*;
  5. import java.awt.*;
  6. public class MoxWorldBuilder
  7. {
  8. // Usage.
  9. public static final String Usage =
  10. "Usage:\n" +
  11. " java MoxWorldBuilder\n" +
  12. " -steps <steps>\n" +
  13. " -gridSize <width> <height>\n" +
  14. " -liveCellProbability <0.0-1.0>\n" +
  15. " [-randomSeed <random number seed>]\n" +
  16. " [-minBlueCells <quantity>]\n" +
  17. " [-maxBlueCells <quantity>]\n" +
  18. " [-minGreenCells <quantity>]\n" +
  19. " [-maxGreenCells <quantity>]\n" +
  20. " [-maxBuildAttempts <quantity>]\n" +
  21. " -save <file name>\n" +
  22. " [-dashboard]";
  23. // Default random seed.
  24. public static final int DEFAULT_RANDOM_SEED = 4517;
  25. // Default maximum build attempts.
  26. public static final int DEFAULT_MAX_BUILD_ATTEMPTS = 1000;
  27. // Game of Life mox world.
  28. public GameOfLife gameOfLife;
  29. // Random numbers.
  30. Random randomizer;
  31. // Dashboard display.
  32. MoxWorldDashboard dashboard;
  33. // Constructor.
  34. public MoxWorldBuilder(int width, int height)
  35. {
  36. // Create Game of Life.
  37. gameOfLife = new GameOfLife(new Dimension(width, height));
  38. }
  39. // Build.
  40. public boolean build(int steps, float liveCellProb, int randomSeed,
  41. int minBlueCells, int maxBlueCells,
  42. int minGreenCells, int maxGreenCells,
  43. int maxBuildAttempts)
  44. {
  45. // Random numbers.
  46. randomizer = new Random(randomSeed);
  47. // Try to build world.
  48. for (int i = 0; i < maxBuildAttempts; i++)
  49. {
  50. // Initialize.
  51. init(liveCellProb);
  52. // Run steps.
  53. run(steps);
  54. // Check properties.
  55. if (check(minBlueCells, maxBlueCells, minGreenCells, maxGreenCells))
  56. {
  57. return(true);
  58. }
  59. }
  60. return(false);
  61. }
  62. // Initialize.
  63. public void init(float liveCellProb)
  64. {
  65. int x, y;
  66. int width = gameOfLife.getWidth();
  67. int height = gameOfLife.getHeight();
  68. synchronized (gameOfLife.lock)
  69. {
  70. for (x = 0; x < width; x++)
  71. {
  72. for (y = 0; y < height; y++)
  73. {
  74. if (randomizer.nextFloat() < liveCellProb)
  75. {
  76. gameOfLife.cells[x][y] = 1;
  77. }
  78. }
  79. }
  80. gameOfLife.step();
  81. gameOfLife.checkpoint();
  82. }
  83. }
  84. // Run steps.
  85. public void run(int steps)
  86. {
  87. for (int i = 0; i < steps; i++)
  88. {
  89. // Update dashboard.
  90. updateDashboard(i + 1, steps);
  91. // Step Game of Life.
  92. stepGameOfLife();
  93. }
  94. synchronized (gameOfLife.lock)
  95. {
  96. gameOfLife.checkpoint();
  97. }
  98. }
  99. // Step Game Of Life.
  100. public void stepGameOfLife()
  101. {
  102. synchronized (gameOfLife.lock)
  103. {
  104. gameOfLife.step();
  105. }
  106. }
  107. // Check.
  108. public boolean check(int minBlueCells, int maxBlueCells,
  109. int minGreenCells, int maxGreenCells)
  110. {
  111. int x, y;
  112. int width = gameOfLife.getWidth();
  113. int height = gameOfLife.getHeight();
  114. int blueCount = 0;
  115. int greenCount = 0;
  116. for (x = 0; x < width; x++)
  117. {
  118. for (y = 0; y < height; y++)
  119. {
  120. if (gameOfLife.cells[x][y] == GameOfLife.BLUE_CELL_COLOR_VALUE)
  121. {
  122. blueCount++;
  123. }
  124. if (gameOfLife.cells[x][y] == GameOfLife.GREEN_CELL_COLOR_VALUE)
  125. {
  126. greenCount++;
  127. }
  128. }
  129. }
  130. if ((blueCount >= minBlueCells) && (blueCount <= maxBlueCells) &&
  131. (greenCount >= minGreenCells) && (greenCount <= maxGreenCells))
  132. {
  133. return(true);
  134. }
  135. else
  136. {
  137. return(false);
  138. }
  139. }
  140. // Create dashboard.
  141. public void createDashboard()
  142. {
  143. if (dashboard == null)
  144. {
  145. dashboard = new MoxWorldDashboard(gameOfLife);
  146. }
  147. }
  148. // Destroy dashboard.
  149. public void destroyDashboard()
  150. {
  151. if (dashboard != null)
  152. {
  153. dashboard.reset();
  154. dashboard.setVisible(false);
  155. dashboard = null;
  156. }
  157. }
  158. // Update dashboard.
  159. // Return true if dashboard operational.
  160. public boolean updateDashboard(int step, int steps, String message)
  161. {
  162. if (dashboard != null)
  163. {
  164. dashboard.setMessage(message);
  165. dashboard.update(step, steps);
  166. if (dashboard.quit)
  167. {
  168. dashboard = null;
  169. return(false);
  170. }
  171. else
  172. {
  173. return(true);
  174. }
  175. }
  176. else
  177. {
  178. return(false);
  179. }
  180. }
  181. public boolean updateDashboard(int step, int steps)
  182. {
  183. return(updateDashboard(step, steps, ""));
  184. }
  185. public boolean updateDashboard()
  186. {
  187. if (dashboard != null)
  188. {
  189. dashboard.update();
  190. if (dashboard.quit)
  191. {
  192. dashboard = null;
  193. return(false);
  194. }
  195. else
  196. {
  197. return(true);
  198. }
  199. }
  200. else
  201. {
  202. return(false);
  203. }
  204. }
  205. // Main.
  206. public static void main(String[] args)
  207. {
  208. // Get options.
  209. int steps = -1;
  210. int width = -1;
  211. int height = -1;
  212. float liveCellProb = -1.0f;
  213. int randomSeed = DEFAULT_RANDOM_SEED;
  214. int minBlueCells = 0;
  215. int maxBlueCells = -1;
  216. int minGreenCells = 0;
  217. int maxGreenCells = -1;
  218. int maxBuildAttempts = DEFAULT_MAX_BUILD_ATTEMPTS;
  219. String savefile = null;
  220. boolean dashboard = false;
  221. for (int i = 0; i < args.length; i++)
  222. {
  223. if (args[i].equals("-steps"))
  224. {
  225. i++;
  226. if (i >= args.length)
  227. {
  228. System.err.println("Invalid steps option");
  229. System.err.println(MoxWorldBuilder.Usage);
  230. System.exit(1);
  231. }
  232. try
  233. {
  234. steps = Integer.parseInt(args[i]);
  235. }
  236. catch (NumberFormatException e) {
  237. System.err.println("Invalid steps option");
  238. System.err.println(MoxWorldBuilder.Usage);
  239. System.exit(1);
  240. }
  241. if (steps < 0)
  242. {
  243. System.err.println("Invalid steps option");
  244. System.err.println(MoxWorldBuilder.Usage);
  245. System.exit(1);
  246. }
  247. continue;
  248. }
  249. if (args[i].equals("-gridSize"))
  250. {
  251. i++;
  252. if (i >= args.length)
  253. {
  254. System.err.println("Invalid gridSize option");
  255. System.err.println(MoxWorldBuilder.Usage);
  256. System.exit(1);
  257. }
  258. try
  259. {
  260. width = Integer.parseInt(args[i]);
  261. }
  262. catch (NumberFormatException e) {
  263. System.err.println("Invalid gridSize width option");
  264. System.err.println(MoxWorldBuilder.Usage);
  265. System.exit(1);
  266. }
  267. if (width < 2)
  268. {
  269. System.err.println("Invalid gridSize width option");
  270. System.err.println(MoxWorldBuilder.Usage);
  271. System.exit(1);
  272. }
  273. i++;
  274. if (i >= args.length)
  275. {
  276. System.err.println("Invalid gridSize option");
  277. System.err.println(MoxWorldBuilder.Usage);
  278. System.exit(1);
  279. }
  280. try
  281. {
  282. height = Integer.parseInt(args[i]);
  283. }
  284. catch (NumberFormatException e) {
  285. System.err.println("Invalid gridSize height option");
  286. System.err.println(MoxWorldBuilder.Usage);
  287. System.exit(1);
  288. }
  289. if (height < 2)
  290. {
  291. System.err.println("Invalid gridSize height option");
  292. System.err.println(MoxWorldBuilder.Usage);
  293. System.exit(1);
  294. }
  295. continue;
  296. }
  297. if (args[i].equals("-liveCellProbability"))
  298. {
  299. i++;
  300. if (i >= args.length)
  301. {
  302. System.err.println("Invalid liveCellProbability option");
  303. System.err.println(MoxWorldBuilder.Usage);
  304. System.exit(1);
  305. }
  306. try
  307. {
  308. liveCellProb = Float.parseFloat(args[i]);
  309. }
  310. catch (NumberFormatException e) {
  311. System.err.println("Invalid liveCellProbability option");
  312. System.err.println(MoxWorldBuilder.Usage);
  313. System.exit(1);
  314. }
  315. if ((liveCellProb < 0.0f) || (liveCellProb > 1.0f))
  316. {
  317. System.err.println("Invalid liveCellProbability option");
  318. System.err.println(MoxWorldBuilder.Usage);
  319. System.exit(1);
  320. }
  321. continue;
  322. }
  323. if (args[i].equals("-randomSeed"))
  324. {
  325. i++;
  326. if (i >= args.length)
  327. {
  328. System.err.println("Invalid randomSeed option");
  329. System.err.println(MoxWorldBuilder.Usage);
  330. System.exit(1);
  331. }
  332. try
  333. {
  334. randomSeed = Integer.parseInt(args[i]);
  335. }
  336. catch (NumberFormatException e) {
  337. System.err.println("Invalid randomSeed option");
  338. System.err.println(MoxWorldBuilder.Usage);
  339. System.exit(1);
  340. }
  341. continue;
  342. }
  343. if (args[i].equals("-minBlueCells"))
  344. {
  345. i++;
  346. if (i >= args.length)
  347. {
  348. System.err.println("Invalid minBlueCells option");
  349. System.err.println(MoxWorldBuilder.Usage);
  350. System.exit(1);
  351. }
  352. try
  353. {
  354. minBlueCells = Integer.parseInt(args[i]);
  355. }
  356. catch (NumberFormatException e) {
  357. System.err.println("Invalid minBlueCells option");
  358. System.err.println(MoxWorldBuilder.Usage);
  359. System.exit(1);
  360. }
  361. if (minBlueCells < 0)
  362. {
  363. System.err.println("Invalid minBlueCells option");
  364. System.err.println(MoxWorldBuilder.Usage);
  365. System.exit(1);
  366. }
  367. continue;
  368. }
  369. if (args[i].equals("-maxBlueCells"))
  370. {
  371. i++;
  372. if (i >= args.length)
  373. {
  374. System.err.println("Invalid maxBlueCells option");
  375. System.err.println(MoxWorldBuilder.Usage);
  376. System.exit(1);
  377. }
  378. try
  379. {
  380. maxBlueCells = Integer.parseInt(args[i]);
  381. }
  382. catch (NumberFormatException e) {
  383. System.err.println("Invalid maxBlueCells option");
  384. System.err.println(MoxWorldBuilder.Usage);
  385. System.exit(1);
  386. }
  387. if (maxBlueCells < 0)
  388. {
  389. System.err.println("Invalid maxBlueCells option");
  390. System.err.println(MoxWorldBuilder.Usage);
  391. System.exit(1);
  392. }
  393. continue;
  394. }
  395. if (args[i].equals("-minGreenCells"))
  396. {
  397. i++;
  398. if (i >= args.length)
  399. {
  400. System.err.println("Invalid minGreenCells option");
  401. System.err.println(MoxWorldBuilder.Usage);
  402. System.exit(1);
  403. }
  404. try
  405. {
  406. minGreenCells = Integer.parseInt(args[i]);
  407. }
  408. catch (NumberFormatException e) {
  409. System.err.println("Invalid minGreenCells option");
  410. System.err.println(MoxWorldBuilder.Usage);
  411. System.exit(1);
  412. }
  413. if (minGreenCells < 0)
  414. {
  415. System.err.println("Invalid minGreenCells option");
  416. System.err.println(MoxWorldBuilder.Usage);
  417. System.exit(1);
  418. }
  419. continue;
  420. }
  421. if (args[i].equals("-maxGreenCells"))
  422. {
  423. i++;
  424. if (i >= args.length)
  425. {
  426. System.err.println("Invalid maxGreenCells option");
  427. System.err.println(MoxWorldBuilder.Usage);
  428. System.exit(1);
  429. }
  430. try
  431. {
  432. maxGreenCells = Integer.parseInt(args[i]);
  433. }
  434. catch (NumberFormatException e) {
  435. System.err.println("Invalid maxGreenCells option");
  436. System.err.println(MoxWorldBuilder.Usage);
  437. System.exit(1);
  438. }
  439. if (maxGreenCells < 0)
  440. {
  441. System.err.println("Invalid maxGreenCells option");
  442. System.err.println(MoxWorldBuilder.Usage);
  443. System.exit(1);
  444. }
  445. continue;
  446. }
  447. if (args[i].equals("-maxBuildAttempts"))
  448. {
  449. i++;
  450. if (i >= args.length)
  451. {
  452. System.err.println("Invalid maxBuildAttempts option");
  453. System.err.println(MoxWorldBuilder.Usage);
  454. System.exit(1);
  455. }
  456. try
  457. {
  458. maxBuildAttempts = Integer.parseInt(args[i]);
  459. }
  460. catch (NumberFormatException e) {
  461. System.err.println("Invalid maxBuildAttempts option");
  462. System.err.println(MoxWorldBuilder.Usage);
  463. System.exit(1);
  464. }
  465. if (maxBuildAttempts < 1)
  466. {
  467. System.err.println("Invalid maxBuildAttempts option");
  468. System.err.println(MoxWorldBuilder.Usage);
  469. System.exit(1);
  470. }
  471. continue;
  472. }
  473. if (args[i].equals("-save"))
  474. {
  475. i++;
  476. if (i >= args.length)
  477. {
  478. System.err.println("Invalid save option");
  479. System.err.println(MoxWorldBuilder.Usage);
  480. System.exit(1);
  481. }
  482. if (savefile == null)
  483. {
  484. savefile = args[i];
  485. }
  486. else
  487. {
  488. System.err.println("Duplicate save option");
  489. System.err.println(MoxWorldBuilder.Usage);
  490. System.exit(1);
  491. }
  492. continue;
  493. }
  494. if (args[i].equals("-dashboard"))
  495. {
  496. dashboard = true;
  497. continue;
  498. }
  499. System.err.println(MoxWorldBuilder.Usage);
  500. System.exit(1);
  501. }
  502. // Check options.
  503. if ((steps < 0) || (width == -1) ||
  504. (height == -1) || (liveCellProb < 0.0f) ||
  505. (savefile == null))
  506. {
  507. System.err.println(MoxWorldBuilder.Usage);
  508. System.exit(1);
  509. }
  510. if (maxBlueCells == -1)
  511. {
  512. maxBlueCells = width * height;
  513. }
  514. if (maxGreenCells == -1)
  515. {
  516. maxGreenCells = width * height;
  517. }
  518. if (minBlueCells > maxBlueCells)
  519. {
  520. System.err.println(MoxWorldBuilder.Usage);
  521. System.exit(1);
  522. }
  523. if (minGreenCells > maxGreenCells)
  524. {
  525. System.err.println(MoxWorldBuilder.Usage);
  526. System.exit(1);
  527. }
  528. if ((minBlueCells + minGreenCells) > (width * height))
  529. {
  530. System.err.println(MoxWorldBuilder.Usage);
  531. System.exit(1);
  532. }
  533. // Create.
  534. MoxWorldBuilder moxWorldBuilder = new MoxWorldBuilder(width, height);
  535. // Create dashboard?
  536. if (dashboard)
  537. {
  538. moxWorldBuilder.createDashboard();
  539. }
  540. // Build mox world.
  541. if (!moxWorldBuilder.build(steps, liveCellProb, randomSeed,
  542. minBlueCells, maxBlueCells,
  543. minGreenCells, maxGreenCells,
  544. maxBuildAttempts))
  545. {
  546. System.err.println("Cannot build mox world");
  547. System.exit(1);
  548. }
  549. // Save.
  550. try
  551. {
  552. moxWorldBuilder.gameOfLife.save(savefile);
  553. }
  554. catch (Exception e)
  555. {
  556. System.err.println("Cannot save to file " + savefile + ": " + e.getMessage());
  557. System.exit(1);
  558. }
  559. System.exit(0);
  560. }
  561. }