mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 12:58:37 +00:00
docs: update type object
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* <p>Type object pattern is the pattern we use when the OOP concept of creating a base class and
|
||||
* inheriting from it just doesn't work for the case in hand. This happens when we either don't know
|
||||
* what types we will need upfront, or want to be able to modify or add new types conveniently w/o
|
||||
* recompiling repeatedly. The pattern provides a solution by allowing flexible creation of required
|
||||
* objects by creating one class, which has a field which represents the 'type' of the object.</p>
|
||||
* <p>In this example, we have a mini candy-crush game in action. There are many different candies
|
||||
* in the game, which may change over time, as we may want to upgrade the game. To make the object
|
||||
* creation convenient, we have a class {@link Candy} which has a field name, parent, points and
|
||||
* Type. We have a json file {@link candy} which contains the details about the candies, and this is
|
||||
* parsed to get all the different candies in {@link JsonParser}. The {@link Cell} class is what the
|
||||
* game matrix is made of, which has the candies that are to be crushed, and contains information on
|
||||
* how crushing can be done, how the matrix is to be reconfigured and how points are to be gained.
|
||||
* The {@link CellPool} class is a pool which reuses the candy cells that have been crushed instead
|
||||
* of making new ones repeatedly. The {@link CandyGame} class has the rules for the continuation of
|
||||
* the game and the {@link App} class has the game itself.</p>
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class App {
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
var givenTime = 50; //50ms
|
||||
var toWin = 500; //points
|
||||
var pointsWon = 0;
|
||||
var numOfRows = 3;
|
||||
var start = System.currentTimeMillis();
|
||||
var end = System.currentTimeMillis();
|
||||
var round = 0;
|
||||
while (pointsWon < toWin && end - start < givenTime) {
|
||||
round++;
|
||||
var pool = new CellPool(numOfRows * numOfRows + 5);
|
||||
var cg = new CandyGame(numOfRows, pool);
|
||||
if (round > 1) {
|
||||
LOGGER.info("Refreshing..");
|
||||
} else {
|
||||
LOGGER.info("Starting game..");
|
||||
}
|
||||
cg.printGameStatus();
|
||||
end = System.currentTimeMillis();
|
||||
cg.round((int) (end - start), givenTime);
|
||||
pointsWon += cg.totalPoints;
|
||||
end = System.currentTimeMillis();
|
||||
}
|
||||
LOGGER.info("Game Over");
|
||||
if (pointsWon >= toWin) {
|
||||
LOGGER.info("" + pointsWon);
|
||||
LOGGER.info("You win!!");
|
||||
} else {
|
||||
LOGGER.info("" + pointsWon);
|
||||
LOGGER.info("Sorry, you lose!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* The Candy class has a field type, which represents the 'type' of candy. The objects are created
|
||||
* by parsing the candy.json file.
|
||||
*/
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
public class Candy {
|
||||
|
||||
enum Type {
|
||||
CRUSHABLE_CANDY,
|
||||
REWARD_FRUIT
|
||||
}
|
||||
|
||||
String name;
|
||||
Candy parent;
|
||||
String parentName;
|
||||
|
||||
@Setter
|
||||
private int points;
|
||||
private final Type type;
|
||||
|
||||
Candy(String name, String parentName, Type type, int points) {
|
||||
this.name = name;
|
||||
this.parent = null;
|
||||
this.type = type;
|
||||
this.points = points;
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import com.iluwatar.typeobject.Candy.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* The CandyGame class contains the rules for the continuation of the game and has the game matrix
|
||||
* (field 'cells') and totalPoints gained during the game.
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@SuppressWarnings("java:S3776") //"Cognitive Complexity of methods should not be too high"
|
||||
public class CandyGame {
|
||||
|
||||
Cell[][] cells;
|
||||
CellPool pool;
|
||||
int totalPoints;
|
||||
|
||||
CandyGame(int num, CellPool pool) {
|
||||
this.cells = new Cell[num][num];
|
||||
this.pool = pool;
|
||||
this.totalPoints = 0;
|
||||
for (var i = 0; i < num; i++) {
|
||||
for (var j = 0; j < num; j++) {
|
||||
this.cells[i][j] = this.pool.getNewCell();
|
||||
this.cells[i][j].positionX = j;
|
||||
this.cells[i][j].positionY = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String numOfSpaces(int num) {
|
||||
return " ".repeat(Math.max(0, num));
|
||||
}
|
||||
|
||||
void printGameStatus() {
|
||||
LOGGER.info("");
|
||||
for (Cell[] cell : cells) {
|
||||
for (var j = 0; j < cells.length; j++) {
|
||||
var candyName = cell[j].candy.name;
|
||||
if (candyName.length() < 20) {
|
||||
var totalSpaces = 20 - candyName.length();
|
||||
LOGGER.info(numOfSpaces(totalSpaces / 2) + cell[j].candy.name
|
||||
+ numOfSpaces(totalSpaces - totalSpaces / 2) + "|");
|
||||
} else {
|
||||
LOGGER.info(candyName + "|");
|
||||
}
|
||||
}
|
||||
LOGGER.info("");
|
||||
}
|
||||
LOGGER.info("");
|
||||
}
|
||||
|
||||
List<Cell> adjacentCells(int y, int x) {
|
||||
var adjacent = new ArrayList<Cell>();
|
||||
if (y == 0) {
|
||||
adjacent.add(this.cells[1][x]);
|
||||
}
|
||||
if (x == 0) {
|
||||
adjacent.add(this.cells[y][1]);
|
||||
}
|
||||
if (y == cells.length - 1) {
|
||||
adjacent.add(this.cells[cells.length - 2][x]);
|
||||
}
|
||||
if (x == cells.length - 1) {
|
||||
adjacent.add(this.cells[y][cells.length - 2]);
|
||||
}
|
||||
if (y > 0 && y < cells.length - 1) {
|
||||
adjacent.add(this.cells[y - 1][x]);
|
||||
adjacent.add(this.cells[y + 1][x]);
|
||||
}
|
||||
if (x > 0 && x < cells.length - 1) {
|
||||
adjacent.add(this.cells[y][x - 1]);
|
||||
adjacent.add(this.cells[y][x + 1]);
|
||||
}
|
||||
return adjacent;
|
||||
}
|
||||
|
||||
boolean continueRound() {
|
||||
for (var i = 0; i < this.cells.length; i++) {
|
||||
if (this.cells[cells.length - 1][i].candy.getType().equals(Type.REWARD_FRUIT)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < this.cells.length; i++) {
|
||||
for (var j = 0; j < this.cells.length; j++) {
|
||||
if (!this.cells[i][j].candy.getType().equals(Type.REWARD_FRUIT)) {
|
||||
var adj = adjacentCells(i, j);
|
||||
for (Cell cell : adj) {
|
||||
if (this.cells[i][j].candy.name.equals(cell.candy.name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handleChange(int points) {
|
||||
LOGGER.info("+" + points + " points!");
|
||||
this.totalPoints += points;
|
||||
printGameStatus();
|
||||
}
|
||||
|
||||
void round(int timeSoFar, int totalTime) {
|
||||
var start = System.currentTimeMillis();
|
||||
var end = System.currentTimeMillis();
|
||||
while (end - start + timeSoFar < totalTime && continueRound()) {
|
||||
for (var i = 0; i < this.cells.length; i++) {
|
||||
var points = 0;
|
||||
var j = this.cells.length - 1;
|
||||
while (this.cells[j][i].candy.getType().equals(Type.REWARD_FRUIT)) {
|
||||
points = this.cells[j][i].candy.getPoints();
|
||||
this.cells[j][i].crush(pool, this.cells);
|
||||
handleChange(points);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < this.cells.length; i++) {
|
||||
var j = cells.length - 1;
|
||||
var points = 0;
|
||||
while (j > 0) {
|
||||
points = this.cells[j][i].interact(this.cells[j - 1][i], this.pool, this.cells);
|
||||
if (points != 0) {
|
||||
handleChange(points);
|
||||
} else {
|
||||
j = j - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Cell[] cell : this.cells) {
|
||||
var j = 0;
|
||||
var points = 0;
|
||||
while (j < cells.length - 1) {
|
||||
points = cell[j].interact(cell[j + 1], this.pool, this.cells);
|
||||
if (points != 0) {
|
||||
handleChange(points);
|
||||
} else {
|
||||
j = j + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
end = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import com.iluwatar.typeobject.Candy.Type;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* The Cell object is what the game matrix is made of and contains the candy which is to be crushed
|
||||
* or collected as reward.
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Cell {
|
||||
Candy candy;
|
||||
int positionX;
|
||||
int positionY;
|
||||
|
||||
void crush(CellPool pool, Cell[][] cellMatrix) {
|
||||
//take out from this position and put back in pool
|
||||
pool.addNewCell(this);
|
||||
this.fillThisSpace(pool, cellMatrix);
|
||||
}
|
||||
|
||||
void fillThisSpace(CellPool pool, Cell[][] cellMatrix) {
|
||||
for (var y = this.positionY; y > 0; y--) {
|
||||
cellMatrix[y][this.positionX] = cellMatrix[y - 1][this.positionX];
|
||||
cellMatrix[y][this.positionX].positionY = y;
|
||||
}
|
||||
var newC = pool.getNewCell();
|
||||
cellMatrix[0][this.positionX] = newC;
|
||||
cellMatrix[0][this.positionX].positionX = this.positionX;
|
||||
cellMatrix[0][this.positionX].positionY = 0;
|
||||
}
|
||||
|
||||
void handleCrush(Cell c, CellPool pool, Cell[][] cellMatrix) {
|
||||
if (this.positionY >= c.positionY) {
|
||||
this.crush(pool, cellMatrix);
|
||||
c.crush(pool, cellMatrix);
|
||||
} else {
|
||||
c.crush(pool, cellMatrix);
|
||||
this.crush(pool, cellMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
int interact(Cell c, CellPool pool, Cell[][] cellMatrix) {
|
||||
if (this.candy.getType().equals(Type.REWARD_FRUIT) || c.candy.getType()
|
||||
.equals(Type.REWARD_FRUIT)) {
|
||||
return 0;
|
||||
} else {
|
||||
if (this.candy.name.equals(c.candy.name)) {
|
||||
var pointsWon = this.candy.getPoints() + c.candy.getPoints();
|
||||
handleCrush(c, pool, cellMatrix);
|
||||
return pointsWon;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.iluwatar.typeobject.Candy.Type;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* The CellPool class allows the reuse of crushed cells instead of creation of new cells each time.
|
||||
* The reused cell is given a new candy to hold using the randomCode field which holds all the
|
||||
* candies available.
|
||||
*/
|
||||
@Slf4j
|
||||
public class CellPool {
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
public static final String FRUIT = "fruit";
|
||||
public static final String CANDY = "candy";
|
||||
List<Cell> pool;
|
||||
int pointer;
|
||||
Candy[] randomCode;
|
||||
|
||||
CellPool(int num) {
|
||||
this.pool = new ArrayList<>(num);
|
||||
try {
|
||||
this.randomCode = assignRandomCandytypes();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error occurred: ", e);
|
||||
//manually initialising this.randomCode
|
||||
this.randomCode = new Candy[5];
|
||||
randomCode[0] = new Candy("cherry", FRUIT, Type.REWARD_FRUIT, 20);
|
||||
randomCode[1] = new Candy("mango", FRUIT, Type.REWARD_FRUIT, 20);
|
||||
randomCode[2] = new Candy("purple popsicle", CANDY, Type.CRUSHABLE_CANDY, 10);
|
||||
randomCode[3] = new Candy("green jellybean", CANDY, Type.CRUSHABLE_CANDY, 10);
|
||||
randomCode[4] = new Candy("orange gum", CANDY, Type.CRUSHABLE_CANDY, 10);
|
||||
}
|
||||
for (int i = 0; i < num; i++) {
|
||||
var c = new Cell();
|
||||
c.candy = randomCode[RANDOM.nextInt(randomCode.length)];
|
||||
this.pool.add(c);
|
||||
}
|
||||
this.pointer = num - 1;
|
||||
}
|
||||
|
||||
Cell getNewCell() {
|
||||
var newCell = this.pool.remove(pointer);
|
||||
pointer--;
|
||||
return newCell;
|
||||
}
|
||||
|
||||
void addNewCell(Cell c) {
|
||||
c.candy = randomCode[RANDOM.nextInt(randomCode.length)]; //changing candytype to new
|
||||
this.pool.add(c);
|
||||
pointer++;
|
||||
}
|
||||
|
||||
Candy[] assignRandomCandytypes() throws JsonParseException {
|
||||
var jp = new JsonParser();
|
||||
jp.parse();
|
||||
var randomCode = new Candy[jp.candies.size() - 2]; //exclude generic types 'fruit' and 'candy'
|
||||
var i = 0;
|
||||
for (var e = jp.candies.keys(); e.hasMoreElements(); ) {
|
||||
var s = e.nextElement();
|
||||
if (!s.equals(FRUIT) && !s.equals(CANDY)) {
|
||||
//not generic
|
||||
randomCode[i] = jp.candies.get(s);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return randomCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.iluwatar.typeobject.Candy.Type;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* The JsonParser class helps parse the json file candy.json to get all the different candies.
|
||||
*/
|
||||
|
||||
public class JsonParser {
|
||||
Hashtable<String, Candy> candies;
|
||||
|
||||
JsonParser() {
|
||||
this.candies = new Hashtable<>();
|
||||
}
|
||||
|
||||
void parse() throws JsonParseException {
|
||||
var is = this.getClass().getClassLoader().getResourceAsStream("candy.json");
|
||||
var reader = new InputStreamReader(is);
|
||||
var json = (JsonObject) com.google.gson.JsonParser.parseReader(reader);
|
||||
var array = (JsonArray) json.get("candies");
|
||||
for (var item : array) {
|
||||
var candy = (JsonObject) item;
|
||||
var name = candy.get("name").getAsString();
|
||||
var parentName = candy.get("parent").getAsString();
|
||||
var t = candy.get("type").getAsString();
|
||||
var type = Type.CRUSHABLE_CANDY;
|
||||
if (t.equals("rewardFruit")) {
|
||||
type = Type.REWARD_FRUIT;
|
||||
}
|
||||
var points = candy.get("points").getAsInt();
|
||||
var c = new Candy(name, parentName, type, points);
|
||||
this.candies.put(name, c);
|
||||
}
|
||||
setParentAndPoints();
|
||||
}
|
||||
|
||||
void setParentAndPoints() {
|
||||
for (var e = this.candies.keys(); e.hasMoreElements(); ) {
|
||||
var c = this.candies.get(e.nextElement());
|
||||
if (c.parentName == null) {
|
||||
c.parent = null;
|
||||
} else {
|
||||
c.parent = this.candies.get(c.parentName);
|
||||
}
|
||||
if (c.getPoints() == 0 && c.parent != null) {
|
||||
c.setPoints(c.parent.getPoints());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{"candies" : [
|
||||
{
|
||||
"name" : "fruit",
|
||||
"parent" : "null",
|
||||
"type" : "rewardFruit",
|
||||
"points" : 20
|
||||
},
|
||||
{
|
||||
"name" : "candy",
|
||||
"parent" : "null",
|
||||
"type" : "crushableCandy",
|
||||
"points" : 10
|
||||
},
|
||||
{
|
||||
"name" : "cherry",
|
||||
"parent" : "fruit",
|
||||
"type" : "rewardFruit",
|
||||
"points" : 0
|
||||
},
|
||||
{
|
||||
"name" : "mango",
|
||||
"parent" : "fruit",
|
||||
"type" : "rewardFruit",
|
||||
"points" : 0
|
||||
},
|
||||
{
|
||||
"name" : "purple popsicle",
|
||||
"parent" : "candy",
|
||||
"type" : "crushableCandy",
|
||||
"points" : 0
|
||||
},
|
||||
{
|
||||
"name" : "green jellybean",
|
||||
"parent" : "candy",
|
||||
"type" : "crushableCandy",
|
||||
"points" : 0
|
||||
},
|
||||
{
|
||||
"name" : "orange gum",
|
||||
"parent" : "candy",
|
||||
"type" : "crushableCandy",
|
||||
"points" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.iluwatar.typeobject.Candy.Type;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* The CandyGameTest class tests the methods in the {@link CandyGame} class.
|
||||
*/
|
||||
|
||||
class CandyGameTest {
|
||||
|
||||
@Test
|
||||
void adjacentCellsTest() {
|
||||
var cg = new CandyGame(3, new CellPool(9));
|
||||
var arr1 = cg.adjacentCells(0, 0);
|
||||
var arr2 = cg.adjacentCells(1, 2);
|
||||
var arr3 = cg.adjacentCells(1, 1);
|
||||
assertTrue(arr1.size() == 2 && arr2.size() == 3 && arr3.size() == 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void continueRoundTest() {
|
||||
var matrix = new Cell[2][2];
|
||||
var c1 = new Candy("green jelly", "jelly", Type.CRUSHABLE_CANDY, 5);
|
||||
var c2 = new Candy("purple jelly", "jelly", Type.CRUSHABLE_CANDY, 5);
|
||||
var c3 = new Candy("green apple", "apple", Type.REWARD_FRUIT, 10);
|
||||
matrix[0][0] = new Cell(c1, 0, 0);
|
||||
matrix[0][1] = new Cell(c2, 1, 0);
|
||||
matrix[1][0] = new Cell(c3, 0, 1);
|
||||
matrix[1][1] = new Cell(c2, 1, 1);
|
||||
var p = new CellPool(4);
|
||||
var cg = new CandyGame(2, p);
|
||||
cg.cells = matrix;
|
||||
var fruitInLastRow = cg.continueRound();
|
||||
matrix[1][0].crush(p, matrix);
|
||||
matrix[0][0] = new Cell(c3, 0, 0);
|
||||
var matchingCandy = cg.continueRound();
|
||||
matrix[0][1].crush(p, matrix);
|
||||
matrix[0][1] = new Cell(c3, 1, 0);
|
||||
var noneLeft = cg.continueRound();
|
||||
assertTrue(fruitInLastRow && matchingCandy && !noneLeft);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* The CellPoolTest class tests the methods in the {@link CellPool} class.
|
||||
*/
|
||||
|
||||
class CellPoolTest {
|
||||
|
||||
@Test
|
||||
void assignRandomCandyTypesTest() {
|
||||
var cp = new CellPool(10);
|
||||
var ht = new Hashtable<String, Boolean>();
|
||||
var parentTypes = 0;
|
||||
for (var i = 0; i < cp.randomCode.length; i++) {
|
||||
ht.putIfAbsent(cp.randomCode[i].name, true);
|
||||
if (cp.randomCode[i].name.equals("fruit") || cp.randomCode[i].name.equals("candy")) {
|
||||
parentTypes++;
|
||||
}
|
||||
}
|
||||
assertTrue(ht.size() == 5 && parentTypes == 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.iluwatar.typeobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.iluwatar.typeobject.Candy.Type;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* The CellTest class tests the methods in the {@link Cell} class.
|
||||
*/
|
||||
class CellTest {
|
||||
|
||||
@Test
|
||||
void interactTest() {
|
||||
var c1 = new Candy("green jelly", "jelly", Type.CRUSHABLE_CANDY, 5);
|
||||
var c2 = new Candy("green apple", "apple", Type.REWARD_FRUIT, 10);
|
||||
var matrix = new Cell[4][4];
|
||||
matrix[0][0] = new Cell(c1, 0, 0);
|
||||
matrix[0][1] = new Cell(c1, 1, 0);
|
||||
matrix[0][2] = new Cell(c2, 2, 0);
|
||||
matrix[0][3] = new Cell(c1, 3, 0);
|
||||
var cp = new CellPool(5);
|
||||
var points1 = matrix[0][0].interact(matrix[0][1], cp, matrix);
|
||||
var points2 = matrix[0][2].interact(matrix[0][3], cp, matrix);
|
||||
assertTrue(points1 > 0 && points2 == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void crushTest() {
|
||||
var c1 = new Candy("green jelly", "jelly", Type.CRUSHABLE_CANDY, 5);
|
||||
var c2 = new Candy("purple candy", "candy", Type.CRUSHABLE_CANDY, 5);
|
||||
var matrix = new Cell[4][4];
|
||||
matrix[0][0] = new Cell(c1, 0, 0);
|
||||
matrix[1][0] = new Cell(c2, 0, 1);
|
||||
matrix[1][0].crush(new CellPool(5), matrix);
|
||||
assertEquals("green jelly", matrix[1][0].candy.name);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user