Type object pattern #555 (#848)

* typeobject pattern

* fixing errors

* fix error cellpool

* Update README.md

* Update README.md
This commit is contained in:
AnaghaSasikumar
2019-07-25 00:38:30 +05:30
committed by Ilkka Seppälä
parent fedc2d9e47
commit 0c6237c225
13 changed files with 877 additions and 0 deletions

View File

@ -0,0 +1,85 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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 java.io.FileNotFoundException;
import java.io.IOException;
import org.json.simple.parser.ParseException;
/**<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>
*/
public class App {
/**
* Program entry point.
* @param args command line args
*/
public static void main(String[] args) throws FileNotFoundException, IOException, ParseException {
int givenTime = 50; //50ms
int toWin = 500; //points
int pointsWon = 0;
int numOfRows = 3;
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
int round = 0;
while (pointsWon < toWin && end - start < givenTime) {
round++;
CellPool pool = new CellPool(numOfRows * numOfRows + 5);
CandyGame cg = new CandyGame(numOfRows, pool);
if (round > 1) {
System.out.println("Refreshing..");
} else {
System.out.println("Starting game..");
}
cg.printGameStatus();
end = System.currentTimeMillis();
cg.round((int)(end - start), givenTime);
pointsWon += cg.totalPoints;
end = System.currentTimeMillis();
}
System.out.println("Game Over");
if (pointsWon >= toWin) {
System.out.println(pointsWon);
System.out.println("You win!!");
} else {
System.out.println(pointsWon);
System.out.println("Sorry, you lose!");
}
}
}

View File

@ -0,0 +1,60 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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;
/**
* The Candy class has a field type, which represents the 'type' of candy. The objects
* are created by parsing the candy.json file.
*/
public class Candy {
enum Type { crushableCandy, rewardFruit };
String name;
Candy parent;
String parentName;
private int points;
private 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;
}
int getPoints() {
return this.points;
}
void setPoints(int a) {
this.points = a;
}
Type getType() {
return this.type;
}
}

View File

@ -0,0 +1,171 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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 java.util.ArrayList;
import com.iluwatar.typeobject.Candy.Type;
/**
* 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.
*/
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 (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
this.cells[i][j] = this.pool.getNewCell();
this.cells[i][j].xIndex = j;
this.cells[i][j].yIndex = i;
}
}
}
static String numOfSpaces(int num) {
String result = "";
for (int i = 0; i < num; i++) {
result += " ";
}
return result;
}
void printGameStatus() {
System.out.println("");
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells.length; j++) {
String candyName = cells[i][j].candy.name;
if (candyName.length() < 20) {
int totalSpaces = 20 - candyName.length();
System.out.print(numOfSpaces(totalSpaces / 2) + cells[i][j].candy.name
+ numOfSpaces(totalSpaces - totalSpaces / 2) + "|");
} else {
System.out.print(candyName + "|");
}
}
System.out.println("");
}
System.out.println("");
}
ArrayList<Cell> adjacentCells(int yIndex, int xIndex) {
ArrayList<Cell> adjacent = new ArrayList<Cell>();
if (yIndex == 0) {
adjacent.add(this.cells[1][xIndex]);
}
if (xIndex == 0) {
adjacent.add(this.cells[yIndex][1]);
}
if (yIndex == cells.length - 1) {
adjacent.add(this.cells[cells.length - 2][xIndex]);
}
if (xIndex == cells.length - 1) {
adjacent.add(this.cells[yIndex][cells.length - 2]);
}
if (yIndex > 0 && yIndex < cells.length - 1) {
adjacent.add(this.cells[yIndex - 1][xIndex]);
adjacent.add(this.cells[yIndex + 1][xIndex]);
}
if (xIndex > 0 && xIndex < cells.length - 1) {
adjacent.add(this.cells[yIndex][xIndex - 1]);
adjacent.add(this.cells[yIndex][xIndex + 1]);
}
return adjacent;
}
boolean continueRound() {
for (int i = 0; i < this.cells.length; i++) {
if (this.cells[cells.length - 1][i].candy.getType().equals(Type.rewardFruit)) {
return true;
}
}
for (int i = 0; i < this.cells.length; i++) {
for (int j = 0; j < this.cells.length; j++) {
if (!this.cells[i][j].candy.getType().equals(Type.rewardFruit)) {
ArrayList<Cell> adj = adjacentCells(i,j);
for (int a = 0; a < adj.size(); a++) {
if (this.cells[i][j].candy.name.equals(adj.get(a).candy.name)) {
return true;
}
}
}
}
}
return false;
}
void handleChange(int points) {
System.out.println("+" + points + " points!");
this.totalPoints += points;
printGameStatus();
}
void round(int timeSoFar, int totalTime) {
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
while (end - start + timeSoFar < totalTime && continueRound()) {
for (int i = 0; i < this.cells.length; i++) {
int points = 0;
int j = this.cells.length - 1;
while (this.cells[j][i].candy.getType().equals(Type.rewardFruit)) {
points = this.cells[j][i].candy.getPoints();
this.cells[j][i].crush(pool, this.cells);
handleChange(points);
}
}
for (int i = 0; i < this.cells.length; i++) {
int j = cells.length - 1;
int 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 (int i = 0; i < this.cells.length; i++) {
int j = 0;
int points = 0;
while (j < cells.length - 1) {
points = this.cells[i][j].interact(this.cells[i][j + 1], this.pool, this.cells);
if (points != 0) {
handleChange(points);
} else {
j = j + 1;
}
}
}
end = System.currentTimeMillis();
}
}
}

View File

@ -0,0 +1,90 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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;
/**
* The Cell object is what the game matrix is made of and contains the candy which is
* to be crushed or collected as reward.
*/
public class Cell {
Candy candy;
int xIndex;
int yIndex;
Cell(Candy candy, int xIndex, int yIndex) {
this.candy = candy;
this.xIndex = xIndex;
this.yIndex = yIndex;
}
Cell() {
this.candy = null;
this.xIndex = 0;
this.yIndex = 0;
}
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 (int y = this.yIndex; y > 0; y--) {
cellMatrix[y][this.xIndex] = cellMatrix[y - 1][this.xIndex];
cellMatrix[y][this.xIndex].yIndex = y;
}
Cell newC = pool.getNewCell();
cellMatrix[0][this.xIndex] = newC;
cellMatrix[0][this.xIndex].xIndex = this.xIndex;
cellMatrix[0][this.xIndex].yIndex = 0;
}
void handleCrush(Cell c, CellPool pool, Cell[][] cellMatrix) {
if (this.yIndex >= c.yIndex) {
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.rewardFruit) || c.candy.getType().equals(Type.rewardFruit)) {
return 0;
} else {
if (this.candy.name.equals(c.candy.name)) {
int pointsWon = this.candy.getPoints() + c.candy.getPoints();
handleCrush(c,pool,cellMatrix);
return pointsWon;
} else {
return 0;
}
}
}
}

View File

@ -0,0 +1,96 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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 java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Random;
import org.json.simple.parser.ParseException;
import com.iluwatar.typeobject.Candy.Type;
/**
* 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.
*/
public class CellPool {
ArrayList<Cell> pool;
int pointer;
Candy[] randomCode;
CellPool(int num) {
this.pool = new ArrayList<Cell>(num);
try {
this.randomCode = assignRandomCandytypes();
} catch (Exception e) {
e.printStackTrace();
//manually initialising this.randomCode
this.randomCode = new Candy[5];
randomCode[0] = new Candy("cherry", "fruit", Type.rewardFruit, 20);
randomCode[1] = new Candy("mango", "fruit", Type.rewardFruit, 20);
randomCode[2] = new Candy("purple popsicle", "candy", Type.crushableCandy, 10);
randomCode[3] = new Candy("green jellybean", "candy", Type.crushableCandy, 10);
randomCode[4] = new Candy("orange gum", "candy", Type.crushableCandy, 10);
}
for (int i = 0; i < num; i++) {
Cell c = new Cell();
Random rand = new Random();
c.candy = randomCode[rand.nextInt(randomCode.length)];
this.pool.add(c);
}
this.pointer = num - 1;
}
Cell getNewCell() {
Cell newCell = this.pool.remove(pointer);
pointer--;
return newCell;
}
void addNewCell(Cell c) {
Random rand = new Random();
c.candy = randomCode[rand.nextInt(randomCode.length)]; //changing candytype to new
this.pool.add(c);
pointer++;
}
Candy[] assignRandomCandytypes() throws FileNotFoundException, IOException, ParseException {
JsonParser jp = new JsonParser();
jp.parse();
Candy[] randomCode = new Candy[jp.candies.size() - 2]; //exclude generic types 'fruit' and 'candy'
int i = 0;
for (Enumeration<String> e = jp.candies.keys(); e.hasMoreElements();) {
String s = e.nextElement();
if (!s.equals("fruit") && !s.equals("candy")) {
//not generic
randomCode[i] = jp.candies.get(s);
i++;
}
}
return randomCode;
}
}

View File

@ -0,0 +1,87 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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 java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import com.iluwatar.typeobject.Candy.Type;
/**
* 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<String, Candy>();
}
void parse() throws FileNotFoundException, IOException, ParseException {
JSONParser parser = new JSONParser();
JSONObject jo = (JSONObject) parser.parse(new FileReader(new File("").getAbsolutePath()
+ "\\src\\main\\java\\com\\iluwatar\\typeobject\\candy.json"));
JSONArray a = (JSONArray) jo.get("candies");
for (Object o : a) {
JSONObject candy = (JSONObject) o;
String name = (String) candy.get("name");
String parentName = (String) candy.get("parent");
String t = (String) candy.get("type");
Type type = null;
if (t.equals("rewardFruit")) {
type = Type.rewardFruit;
} else {
type = Type.crushableCandy;
}
int points = Integer.parseInt((String) candy.get("points"));
Candy c = new Candy(name, parentName, type, points);
this.candies.put(name, c);
}
setParentAndPoints();
}
void setParentAndPoints() {
for (Enumeration<String> e = this.candies.keys(); e.hasMoreElements();) {
Candy 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());
}
}
}
}

View File

@ -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"
}
]
}

View File

@ -0,0 +1,69 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.*;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import com.iluwatar.typeobject.Candy.Type;
/**
* The CandyGameTest class tests the methods in the {@link CandyGame} class.
*/
class CandyGameTest {
@Test
void adjacentCellsTest() {
CandyGame cg = new CandyGame(3,new CellPool(9));
ArrayList<Cell> arr1 = cg.adjacentCells(0, 0);
ArrayList<Cell> arr2 = cg.adjacentCells(1, 2);
ArrayList<Cell> arr3 = cg.adjacentCells(1, 1);
assertTrue(arr1.size() == 2 && arr2.size() == 3 && arr3.size() == 4);
}
@Test
void continueRoundTest() {
Cell[][] matrix = new Cell[2][2];
Candy c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5);
Candy c2 = new Candy("purple jelly", "jelly", Type.crushableCandy, 5);
Candy c3 = new Candy("green apple", "apple", Type.rewardFruit, 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);
CellPool p = new CellPool(4);
CandyGame cg = new CandyGame(2,p);
cg.cells = matrix;
boolean fruitInLastRow = cg.continueRound();
matrix[1][0].crush(p, matrix);
matrix[0][0] = new Cell(c3,0,0);
boolean matchingCandy = cg.continueRound();
matrix[0][1].crush(p,matrix);
matrix[0][1] = new Cell(c3,1,0);
boolean noneLeft = cg.continueRound();
assertTrue(fruitInLastRow && matchingCandy && !noneLeft);
}
}

View File

@ -0,0 +1,52 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.*;
import org.junit.jupiter.api.Test;
import java.util.Hashtable;
/**
* The CellPoolTest class tests the methods in the {@link CellPool} class.
*/
class CellPoolTest {
@Test
void assignRandomCandyTypesTest() {
CellPool cp = new CellPool(10);
Hashtable<String, Boolean> ht = new Hashtable<String, Boolean>();
int parentTypes = 0;
for (int i = 0; i < cp.randomCode.length; i++) {
if (ht.get(cp.randomCode[i].name) == null) {
ht.put(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);
}
}

View File

@ -0,0 +1,61 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.*;
import org.junit.jupiter.api.Test;
import com.iluwatar.typeobject.Candy.Type;
/**
* The CellTest class tests the methods in the {@link Cell} class.
*/
class CellTest {
@Test
void interactTest() {
Candy c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5);
Candy c2 = new Candy("green apple", "apple", Type.rewardFruit, 10);
Cell[][] 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);
CellPool cp = new CellPool(5);
int points1 = matrix[0][0].interact(matrix[0][1], cp, matrix);
int points2 = matrix[0][2].interact(matrix[0][3], cp, matrix);
assertTrue(points1 > 0 && points2 == 0);
}
@Test
void crushTest() {
Candy c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5);
Candy c2 = new Candy("purple candy", "candy", Type.crushableCandy, 5);
Cell[][] 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);
assertTrue(matrix[1][0].candy.name.equals("green jelly"));
}
}