Advertisement
Guest User

Untitled

a guest
Apr 1st, 2015
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.80 KB | None | 0 0
  1. import javalib.impworld.World;
  2. import javalib.worldimages.Posn;
  3. import javalib.worldimages.RectangleImage;
  4. import javalib.worldimages.WorldImage;
  5. import tester.*;
  6.  
  7. import java.awt.Color;
  8. import java.util.*;
  9.  
  10. //Represents a list of type T
  11. interface IList<T> extends Iterable<T >{
  12.  
  13. // Appends this list onto the given list
  14. IList<T> append(IList<T> that);
  15.  
  16. // Apply f to each element of this list
  17. <R> IList<R> map(IFunc<T, R> f);
  18.  
  19. // Remove all elements of this list that do not satisfy the pred
  20. IList<T> filter(IPred<T> pred);
  21.  
  22. // To return the result of applying the given visitor to this list
  23. <R> R accept(IListVisitor<T, R> visitor);
  24.  
  25. }
  26.  
  27. // Represents an empty list of type T
  28. class Empty<T> implements IList<T> {
  29.  
  30. /*
  31. * Fields: Methods: this.append(IList<T>) - IList<T> this.map(IFunc<T, R>) -
  32. * IList<R> this.filter(IPred<T>) - IList<T> this.accept(IListVisitor<T, R>)
  33. * IList<R> Method from fields:
  34. */
  35.  
  36. // Appends this empty list onto the given list
  37. public IList<T> append(IList<T> that) {
  38. return that;
  39. }
  40.  
  41. // Apply f to each element of this empty list
  42. public <R> IList<R> map(IFunc<T, R> f) {
  43. return new Empty<R>();
  44. }
  45.  
  46. // Remove all elements of this empty list that don't satisfy pred
  47. public IList<T> filter(IPred<T> pred) {
  48. return this;
  49. }
  50.  
  51. // To return the result of applying the given visitor to this empty list
  52. public <R> R accept(IListVisitor<T, R> visitor) {
  53. return visitor.visit(this);
  54. }
  55.  
  56. @Override
  57. public Iterator<T> iterator() {
  58. throw new RuntimeException("you can't iterate over an empty");
  59. }
  60.  
  61. }
  62.  
  63. // Represents a non-empty list of type T
  64. class Cons<T> implements IList<T> {
  65. T first;
  66. IList<T> rest;
  67.  
  68. Cons(T first, IList<T> rest) {
  69. this.first = first;
  70. this.rest = rest;
  71. }
  72.  
  73. /*
  74. * Fields: this.first - T this.rest - IList<T> Methods:
  75. * this.append(IList<T>) - IList<T> this.map(IFunc<T, R>) - IList<R>
  76. * this.filter(IPred<T>) - IList<T> this.accept(IListVisitor<T, R>) IList<R>
  77. * Method from fields: this.rest.append(IList<T>) - IList<T>
  78. * this.rest.map(IFunc<T, R>) - IList<R> this.rest.filter(IPred<T>) -
  79. * IList<T> this.rest.accept(IListVisitor<T, R>) IList<R>
  80. */
  81.  
  82. // Appends this non-empty list onto the given list
  83. public IList<T> append(IList<T> that) {
  84. return new Cons<T>(this.first, this.rest.append(that));
  85. }
  86.  
  87. // Apply f to each element of this non-empty list
  88. public <R> IList<R> map(IFunc<T, R> f) {
  89. return new Cons<R>(f.apply(this.first), this.rest.map(f));
  90. }
  91.  
  92. // Remove all elements from this non-empty list that don't satisfy the pred
  93. public IList<T> filter(IPred<T> pred) {
  94. if (pred.apply(this.first)) {
  95. return new Cons<T>(this.first, this.rest.filter(pred));
  96. } else {
  97. return this.rest.filter(pred);
  98. }
  99. }
  100.  
  101. // To return the result of applying the given visitor to this non-empty list
  102. public <R> R accept(IListVisitor<T, R> visitor) {
  103. return visitor.visit(this);
  104. }
  105.  
  106. @Override
  107. public Iterator<T> iterator() {
  108. return new IListIterator<T>(this);
  109. }
  110.  
  111. }
  112.  
  113. class IListIterator<T> implements Iterator<T> {
  114.  
  115. Cons<T> cur;
  116.  
  117.  
  118.  
  119. IListIterator(Cons<T> cur) {
  120. this.cur = cur;
  121. }
  122.  
  123. @Override
  124. public boolean hasNext() {
  125. return cur.accept(new IsEmptyVisitor<T>());
  126. }
  127.  
  128. @Override
  129. public T next() {
  130. Cons<T> prev = this.cur;
  131. if (this.hasNext()) {
  132. cur = (Cons<T>) cur.rest;
  133. }
  134. else {
  135. throw new RuntimeException("There is no next");
  136. }
  137.  
  138. return prev.first;
  139. }
  140.  
  141. }
  142.  
  143. class IsEmptyVisitor<T> implements IListVisitor<T, Boolean> {
  144.  
  145. @Override
  146. public Boolean visit(Empty<T> empty) {
  147. return true;
  148. }
  149.  
  150. @Override
  151. public Boolean visit(Cons<T> cons) {
  152. return false;
  153. }
  154.  
  155. }
  156.  
  157. // Represents a function from type T to type R
  158. interface IFunc<A, R> {
  159.  
  160. // Applies this function to the argument and returns type R
  161. R apply(A arg);
  162. }
  163.  
  164. // Represents a predicate for type T
  165. interface IPred<T> {
  166.  
  167. // Applies this predicate to the given t
  168. boolean apply(T t);
  169. }
  170.  
  171. // To implement a function over lists of T, returning value of type R
  172. interface IListVisitor<T, R> {
  173.  
  174. // To visit the given Empty<T> and return list of type R
  175. R visit(Empty<T> empty);
  176.  
  177. // To visit the given Cons<T> and return list of type R
  178. R visit(Cons<T> cons);
  179.  
  180. }
  181.  
  182. // Visits the given list, mapping the given function, returning list of type R
  183. class MapVisitor<T, R> implements IListVisitor<T, IList<R>> {
  184. IFunc<T, R> op;
  185.  
  186. MapVisitor(IFunc<T, R> op) {
  187. this.op = op;
  188. }
  189.  
  190. /*
  191. * Fields: this.op - IFunc<T, R> Methods: this.visit(Empty<T>) - IList<R>
  192. * this.visit(Cons<T>) - IList<R> Methods on fields: this.op.apply(T) - R
  193. */
  194.  
  195. // Visits the given Empty<T> and returns Empty<R>
  196. public IList<R> visit(Empty<T> empty) {
  197. return new Empty<R>();
  198. }
  199.  
  200. // Visits the given Cons<T> and applies the op to each element
  201. public IList<R> visit(Cons<T> cons) {
  202. return new Cons<R>(this.op.apply(cons.first), cons.rest.accept(this));
  203. }
  204.  
  205. }
  206.  
  207. // Visits the given list, removing all elements that do not satisfy this
  208. // visitor's pred
  209. class FilterVisitor<T> implements IListVisitor<T, IList<T>> {
  210. IPred<T> pred;
  211.  
  212. FilterVisitor(IPred<T> pred) {
  213. this.pred = pred;
  214. }
  215.  
  216. /*
  217. * Fields: this.pred - IPred<T> Methods: this.visit(Empty<T>) - IList<T>
  218. * this.visit(Cons<T>) - IList<T> Methods on fields: this.pred.apply(T) -
  219. * boolean
  220. */
  221.  
  222. // Visits the given Empty<T> and returns an Empty<T>
  223. public IList<T> visit(Empty<T> empty) {
  224. return empty;
  225. }
  226.  
  227. // Visits the given Cons<T> and removes the elements that do not satisfy the
  228. // pred
  229. public IList<T> visit(Cons<T> cons) {
  230. if (this.pred.apply(cons.first)) {
  231. return new Cons<T>(cons.first, cons.rest.accept(this));
  232. } else {
  233. return cons.rest.accept(this);
  234. }
  235. }
  236. }
  237.  
  238. class getFirstVisitor<T> implements IListVisitor<T, T> {
  239.  
  240. @Override
  241. public T visit(Empty<T> empty) {
  242. throw new RuntimeException("can't get the first of an empty list");
  243. }
  244.  
  245. @Override
  246. public T visit(Cons<T> cons) {
  247. return cons.first;
  248. }
  249.  
  250. }
  251.  
  252. // Represents a single square of the game area
  253. class Cell implements Iterable<Cell> {
  254. Cell(double height, int x, int y, Cell left, Cell top, Cell right,
  255. Cell bottom, boolean isFlooded) {
  256. this.height = height;
  257. this.x = x;
  258. this.y = y;
  259. this.left = left;
  260. this.top = top;
  261. this.right = right;
  262. this.bottom = bottom;
  263. this.isFlooded = isFlooded;
  264. }
  265.  
  266. // convenience constructor for initializing cells
  267. Cell(double height, int x, int y) {
  268. this.height = height;
  269. this.x = x;
  270. this.y = y;
  271. this.left = null;
  272. this.top = null;
  273. this.right = null;
  274. this.bottom = null;
  275. this.isFlooded = false;
  276. }
  277.  
  278. // represents absolute height of this cell, in feet
  279. double height;
  280.  
  281. // In logical coordinates, with the origin at the top-left corner of the
  282. // scren
  283. int x, y;
  284.  
  285. // the four adjacent cells to this one
  286. Cell left, top, right, bottom;
  287.  
  288. // reports whether this cell is flooded or not
  289. boolean isFlooded;
  290.  
  291. // top left corner
  292. @Override
  293. public Iterator<Cell> iterator() {
  294. return new topLeftIterator(this);
  295. }
  296.  
  297. public WorldImage draw() {
  298. int x = this.x * ForbiddenIslandWorld.SCALE_SIZE;
  299. int y = this.y * ForbiddenIslandWorld.SCALE_SIZE;
  300.  
  301. Color c;
  302.  
  303. if (this.height < 0) {
  304. c = new Color(0, 0, 255);
  305. //TODO make blue darker for sinking lands and deal with the actual water level
  306. }
  307. else {
  308. int rbVal = ((int) ((ForbiddenIslandWorld.MAX_HEIGHT - this.height) *
  309. (155 / ForbiddenIslandWorld.MAX_HEIGHT))) + 100;
  310.  
  311. c = new Color(rbVal, 255, rbVal);
  312. }
  313.  
  314. return new RectangleImage(
  315. new Posn(x + ForbiddenIslandWorld.SCALE_SIZE /2,
  316. y + ForbiddenIslandWorld.SCALE_SIZE /2),
  317. ForbiddenIslandWorld.SCALE_SIZE,
  318. ForbiddenIslandWorld.SCALE_SIZE, c);
  319. }
  320. }
  321.  
  322. class topLeftIterator implements Iterator<Cell> {
  323.  
  324. Cell cur;
  325. boolean goingRight;
  326.  
  327. topLeftIterator(Cell cur) {
  328. this.cur = cur;
  329. goingRight = true;
  330. }
  331.  
  332. @Override
  333. public boolean hasNext() {
  334. return !(cur == null);
  335. }
  336.  
  337. @Override
  338. public Cell next() {
  339. Cell prev = cur;
  340.  
  341. if (this.hasNext()) {
  342. if (goingRight) {
  343. if (cur.x == ForbiddenIslandWorld.ISLAND_SIZE
  344. && cur.y == ForbiddenIslandWorld.ISLAND_SIZE) {
  345. cur = null;
  346. } else if (cur.x == ForbiddenIslandWorld.ISLAND_SIZE) {
  347. cur = cur.bottom;
  348. goingRight = !goingRight;
  349. } else {
  350. cur = cur.right;
  351. }
  352. } else if (cur.x == 0 && cur.y == ForbiddenIslandWorld.ISLAND_SIZE) {
  353. cur = null;
  354. } else if (cur.x == 0) {
  355. cur = cur.bottom;
  356. } else {
  357. cur = cur.left;
  358. }
  359. }
  360.  
  361. return prev;
  362. }
  363. }
  364.  
  365. class OceanCell extends Cell {
  366. OceanCell(int x, int y, Cell left, Cell top, Cell right, Cell bottom) {
  367. super(-1, x, y, left, top, right, bottom, true);
  368. }
  369.  
  370. // convenience constructor for initializing
  371. OceanCell(int x, int y) {
  372. super(-1, x, y, null, null, null, null, true);
  373. }
  374. }
  375.  
  376. class ForbiddenIslandWorld extends World {
  377. // size of the island
  378. static final int ISLAND_SIZE = 48;
  379.  
  380. // max height of the island
  381. static final double MAX_HEIGHT = ForbiddenIslandWorld.ISLAND_SIZE
  382. - ForbiddenIslandWorld.ISLAND_SIZE / 4;
  383.  
  384. // how large to scale up the board
  385. static final int SCALE_SIZE = 10;
  386.  
  387. // All the cells of the game, including the ocean
  388. IList<Cell> board;
  389.  
  390. // the current height of the ocean
  391. int waterHeight;
  392.  
  393. ForbiddenIslandWorld(IList<Cell> board, int waterHeight) {
  394. this.board = board;
  395. this.waterHeight = waterHeight;
  396. }
  397.  
  398. ForbiddenIslandWorld() {
  399. this.board = this.mountainWorld();
  400. this.waterHeight = 0;
  401. }
  402.  
  403. // creates a uniform mountain world
  404. IList<Cell> mountainWorld() {
  405. ArrayList<ArrayList<Double>> sizes = new ArrayList<ArrayList<Double>>(
  406. ForbiddenIslandWorld.ISLAND_SIZE + 1);
  407.  
  408. for (int i = 0; i <= ForbiddenIslandWorld.ISLAND_SIZE; i += 1) {
  409. sizes.add(i,
  410. new ArrayList<Double>(ForbiddenIslandWorld.ISLAND_SIZE + 1));
  411.  
  412. for (int j = 0; j <= ForbiddenIslandWorld.ISLAND_SIZE; j += 1) {
  413.  
  414. if (this.manhattanDistanceToCenter(i, j) < ForbiddenIslandWorld.ISLAND_SIZE / 2) {
  415. double num = ForbiddenIslandWorld.MAX_HEIGHT
  416. - this.manhattanDistanceToCenter(i, j);
  417. sizes.get(i).add(j, num);
  418. } else {
  419. sizes.get(i).add(j, -1.0);
  420. }
  421. }
  422. }
  423. return this.generateBoardFromSizes(sizes);
  424. }
  425.  
  426. // creates a random mountain
  427. IList<Cell> randomWorld() {
  428. ArrayList<ArrayList<Double>> sizes = new ArrayList<ArrayList<Double>>(
  429. ForbiddenIslandWorld.ISLAND_SIZE + 1);
  430.  
  431. for (int i = 0; i <= ForbiddenIslandWorld.ISLAND_SIZE; i += 1) {
  432. sizes.add(i,
  433. new ArrayList<Double>(ForbiddenIslandWorld.ISLAND_SIZE + 1));
  434.  
  435. for (int j = 0; j <= ForbiddenIslandWorld.ISLAND_SIZE; j += 1) {
  436. if (this.manhattanDistanceToCenter(i, j) < ForbiddenIslandWorld.ISLAND_SIZE / 2) {
  437. double num = (Math.random() * ForbiddenIslandWorld.MAX_HEIGHT);
  438. sizes.get(i).add(j, num);
  439. } else {
  440. sizes.get(i).add(j, -1.0);
  441. }
  442. }
  443. }
  444. return this.generateBoardFromSizes(sizes);
  445. }
  446.  
  447. IList<Cell> generateBoardFromSizes(ArrayList<ArrayList<Double>> sizes) {
  448. ArrayList<ArrayList<Cell>> cells = new ArrayList<ArrayList<Cell>>(
  449. ForbiddenIslandWorld.ISLAND_SIZE + 1);
  450.  
  451. for (int i = 0; i < sizes.size(); i += 1) {
  452. cells.add(i, new ArrayList<Cell>(ForbiddenIslandWorld.ISLAND_SIZE + 1));
  453.  
  454. for (int j = 0; j < sizes.get(i).size(); j += 1) {
  455. double size = sizes.get(i).get(j);
  456. if (size < 0) {
  457. cells.get(i).add(j, new OceanCell(j, i));
  458. } else {
  459. cells.get(i).add(j, new Cell(size, j, i));
  460. }
  461. }
  462. }
  463.  
  464. this.fixConnections(cells);
  465. return this.generateIList(cells);
  466. }
  467.  
  468. //EFFECT: fixes connections between cells in the ArrayList
  469. void fixConnections(ArrayList<ArrayList<Cell>> cells) {
  470. for (int i = 0; i < cells.size(); i += 1) {
  471.  
  472. for (int j = 0; j < cells.get(i).size(); j += 1) {
  473. Cell cur = cells.get(i).get(j);
  474. if (cur.x == 0 && cur.y == 0) {
  475. cur.left = cur;
  476. cur.top = cur;
  477. cur.right = cells.get(i).get(j + 1);
  478. cur.bottom = cells.get(i + 1).get(j);
  479. } else if (cur.x == ForbiddenIslandWorld.ISLAND_SIZE
  480. && cur.y == 0) {
  481. cur.left = cells.get(i).get(j - 1);
  482. cur.top = cur;
  483. cur.right = cur;
  484. cur.bottom = cells.get(i + 1).get(j);
  485. } else if (cur.y == 0) {
  486. cur.left = cells.get(i).get(j - 1);
  487. cur.top = cur;
  488. cur.right = cells.get(i).get(j + 1);
  489. cur.bottom = cells.get(i + 1).get(j);
  490. } else if (cur.x == ForbiddenIslandWorld.ISLAND_SIZE
  491. && cur.y == ForbiddenIslandWorld.ISLAND_SIZE) {
  492. cur.left = cells.get(i).get(j - 1);
  493. cur.top = cells.get(i - 1).get(j);
  494. cur.right = cur;
  495. cur.bottom = cur;
  496. } else if (cur.x == ForbiddenIslandWorld.ISLAND_SIZE) {
  497. cur.left = cells.get(i).get(j - 1);
  498. cur.top = cells.get(i - 1).get(j);
  499. cur.right = cur;
  500. cur.bottom = cells.get(i + 1).get(j);
  501. } else if (cur.x == 0
  502. && cur.y == ForbiddenIslandWorld.ISLAND_SIZE) {
  503. cur.left = cur;
  504. cur.top = cells.get(i - 1).get(j);
  505. cur.right = cells.get(i).get(j + 1);
  506. cur.bottom = cur;
  507. } else if (cur.y == ForbiddenIslandWorld.ISLAND_SIZE) {
  508. cur.left = cells.get(i).get(j - 1);
  509. cur.top = cells.get(i - 1).get(j);
  510. cur.right = cells.get(i).get(j + 1);
  511. cur.bottom = cur;
  512. } else if (cur.x == 0) {
  513. cur.left = cur;
  514. cur.top = cells.get(i - 1).get(j);
  515. cur.right = cells.get(i).get(j + 1);
  516. cur.bottom = cells.get(i + 1).get(j);
  517. } else {
  518. cur.left = cells.get(i).get(j - 1);
  519. cur.top = cells.get(i - 1).get(j);
  520. cur.right = cells.get(i).get(j + 1);
  521. cur.bottom = cells.get(i + 1).get(j);
  522. }
  523. }
  524. }
  525. }
  526.  
  527. IList<Cell> generateIList(ArrayList<ArrayList<Cell>> cells) {
  528. IList<Cell> listOfCells = new Empty<Cell>();
  529.  
  530. for(ArrayList<Cell> a: cells) {
  531. for(Cell c: a) {
  532. listOfCells = new Cons<Cell>(c, listOfCells);
  533. }
  534. }
  535. return listOfCells;
  536. }
  537.  
  538. int manhattanDistanceToCenter(int x, int y) {
  539. int centerX = ForbiddenIslandWorld.ISLAND_SIZE / 2;
  540. int centerY = ForbiddenIslandWorld.ISLAND_SIZE / 2;
  541.  
  542. return Math.abs((centerX - Math.abs(x - centerX))
  543. + (centerY - Math.abs(y - centerY)));
  544. }
  545.  
  546. @Override
  547. public WorldImage makeImage() {
  548. int size = (ForbiddenIslandWorld.ISLAND_SIZE + 1)
  549. * ForbiddenIslandWorld.SCALE_SIZE;
  550. WorldImage bg = new RectangleImage(new Posn(size / 2, size / 2), size, size,
  551. new Color(0, 0, 0));
  552.  
  553. return this.renderScene(bg);
  554.  
  555. }
  556.  
  557. WorldImage renderScene(WorldImage bg) {
  558. Cell first = this.board.accept(new getFirstVisitor<Cell>());
  559. for(Cell c: first) {
  560. //bg = bg.overlayImages(bg, c.draw()); //TODO
  561. }
  562. return bg;
  563. }
  564. }
  565.  
  566. class ExamplesForbiddenIsland {
  567. ForbiddenIslandWorld mountainWorld = new ForbiddenIslandWorld();
  568.  
  569. /*void testBigBang(Tester t) {
  570. int size = (ForbiddenIslandWorld.ISLAND_SIZE + 1) * ForbiddenIslandWorld.SCALE_SIZE;
  571.  
  572. mountainWorld.bigBang(size, size);
  573. }*/
  574.  
  575. /*void testStuff(Tester t) {
  576. System.out.println(mountainWorld.board.accept(new getFirstVisitor<Cell>()).right.x);
  577. }*/
  578. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement