Return random value from HashMap<Enum, Object> - java

In the class Room I need to write a method to return a random exit from HashMap exits, or return null if there are no exits in that HashMap.
I have tried using iterators and saving it the HashMap in a Set but nothing works.
public class Room
{
private String description;
private HashMap<Direction, Room> exits; // stores exits of this room.
public Set<Character> chars; // stores the characters that are in this room.
/**
* Create a room described "description". Initially, it has
* no exits. "description" is something like "a kitchen" or
* "an open court yard".
* #param description The room's description.
* Pre-condition: description is not null.
*/
public Room(String description)
{
assert description != null : "Room.Room has null description";
this.description = description;
exits = new HashMap<Direction, Room>();
chars = new HashSet<Character>();
sane();
}
/**
* Define an exit from this room.
* #param direction The direction of the exit.
* #param neighbor The room to which the exit leads.
* Pre-condition: neither direction nor neighbor are null;
* there is no room in given direction yet.
*/
public void setExit(Direction direction, Room neighbor)
{
assert direction != null : "Room.setExit gets null direction";
assert neighbor != null : "Room.setExit gets null neighbor";
assert getExit(direction) == null : "Room.setExit set for direction that has neighbor";
sane();
exits.put(direction, neighbor);
sane();
assert getExit(direction) == neighbor : "Room.setExit has wrong neighbor";
}
/**
* Return the room that is reached if we go from this room in direction
* "direction". If there is no room in that direction, return null.
* #param direction The exit's direction.
* #return The room in the given direction.
* Pre-condition: direction is not null
*/
public Room getExit(Direction direction)
{
assert direction != null : "Room.getExit has null direction";
sane();
return exits.get(direction);
}
Direction:
public enum Direction
{
NORTH("north"), WEST("west"), SOUTH("south"), EAST("east");
private String name;
/**
* Constructor with parameter.
* Pre-condition: name is not null.
*/
private Direction(String name)
{
assert name != null : "Direction.Direction has null name";
this.name = name;
assert toString().equals(name) : "Direction.Direction produces wrong toString";
}
/**
* Return the direction name.
*/
public String toString()
{
return name;
}
}
Any help will be appreciated

Try converting the map to a list something like this (inside Room class) :
public Direction getRandomExit(){
List<Direction> directions = new ArrayList<Direction>(exits.keySet());
if (directions.size()==0){
return null;
}
Random rand = new Random();
int randomIndex = rand.nextInt(directions.size());
return directions.get(randomIndex);
}

Related

Problem with BFS in graph java . It is n`t returning anything

I am making a project like google map in which I have to construct a graph in which vertices are intersections and edges are roads .
In my code I was able to add intersections and roads but I`m not able to return a path through breadth first search . And this is my code ,
public class MapGraph {
//TODO: Add your member variables here in WEEK 3
HashSet<GeographicPoint> intersections ;
HashMap<GeographicPoint,LinkedList<GeographicPoint>> roads ;
HashMap<HashMap<GeographicPoint,GeographicPoint>,ArrayList<String>> roadInfo ;
/**
* Create a new empty MapGraph
*/
public MapGraph()
{
// TODO: Implement in this constructor in WEEK 3
intersections = new HashSet<GeographicPoint>() ;
roads = new HashMap<GeographicPoint,LinkedList<GeographicPoint>>() ;
roadInfo = new HashMap<HashMap<GeographicPoint,GeographicPoint>,ArrayList<String>>() ;
}
/**
* Get the number of vertices (road intersections) in the graph
* #return The number of vertices in the graph.
*/
public int getNumVertices()
{
//TODO: Implement this method in WEEK 3
return intersections.size();
}
/**
* Return the intersections, which are the vertices in this graph.
* #return The vertices in this graph as GeographicPoints
*/
public Set<GeographicPoint> getVertices()
{
//TODO: Implement this method in WEEK 3
return intersections;
}
/**
* Get the number of road segments in the graph
* #return The number of edges in the graph.
*/
public int getNumEdges()
{
//TODO: Implement this method in WEEK 3
int num = 0 ;
for(GeographicPoint gp : roads.keySet()) {
num+=roads.get(gp).size() ;
}
return num;
}
/** Add a node corresponding to an intersection at a Geographic Point
* If the location is already in the graph or null, this method does
* not change the graph.
* #param location The location of the intersection
* #return true if a node was added, false if it was not (the node
* was already in the graph, or the parameter is null).
*/
public boolean addVertex(GeographicPoint location)
{
// TODO: Implement this method in WEEK 3
if(!intersections.contains(location) && !(location == null)) {
intersections.add(location) ;
return true ;
}
return false;
}
/**
* Adds a directed edge to the graph from pt1 to pt2.
* Precondition: Both GeographicPoints have already been added to the graph
* #param from The starting point of the edge
* #param to The ending point of the edge
* #param roadName The name of the road
* #param roadType The type of the road
* #param length The length of the road, in km
* #throws IllegalArgumentException If the points have not already been
* added as nodes to the graph, if any of the arguments is null,
* or if the length is less than 0.
*/
public void addEdge(GeographicPoint from, GeographicPoint to, String roadName,
String roadType, double length) throws IllegalArgumentException {
//TODO: Implement this method in WEEK 3
if(roads.containsKey(from)) {
roads.get(from).add(to) ;
} else {
List curr1 = new LinkedList<GeographicPoint>() ;
curr1.add(to);
roads.put(from, (LinkedList<GeographicPoint>) curr1) ;
HashMap<GeographicPoint,GeographicPoint> curr = new HashMap<GeographicPoint,GeographicPoint>() ;
curr.put(from, to) ;
List<String> info = new ArrayList<String>() ;
info.add(roadName);info.add(roadType);info.add(Double.toString(length));
roadInfo.put(curr , (ArrayList<String>) info) ;
}
}
/** Find the path from start to goal using breadth first search
*
* #param start The starting location
* #param goal The goal location
* #return The list of intersections that form the shortest (unweighted)
* path from start to goal (including both start and goal).
*/
public List<GeographicPoint> bfs(GeographicPoint start, GeographicPoint goal) {
// Dummy variable for calling the search algorithms
Consumer<GeographicPoint> temp = (x) -> {};
return bfs(start, goal, temp);
}
/** Find the path from start to goal using breadth first search
*
* #param start The starting location
* #param goal The goal location
* #param nodeSearched A hook for visualization. See assignment instructions for how to use it.
* #return The list of intersections that form the shortest (unweighted)
* path from start to goal (including both start and goal).
*
*/
private List<GeographicPoint> getNeighbors(GeographicPoint curr){
List<GeographicPoint> answer = new ArrayList<GeographicPoint> () ;
for(GeographicPoint gp : roads.keySet()) {
if(curr==gp) {
answer = roads.get(gp) ;
}
}
System.out.println(answer);
return answer ;
}
public List<GeographicPoint> bfs(GeographicPoint start,
GeographicPoint goal, Consumer<GeographicPoint> nodeSearched)
{
// TODO: Implement this method in WEEK 3
// Hook for visualization. See writeup.
//nodeSearched.accept(next.getLocation());
if (start == null || goal == null) {
System.out.println("Start or goal node is null! No path exists.");
return new LinkedList<GeographicPoint>();
}
HashSet<GeographicPoint> visited = new HashSet<GeographicPoint>();
Queue<GeographicPoint> toExplore = new LinkedList<GeographicPoint>();
HashMap<GeographicPoint, GeographicPoint> parentMap = new HashMap<GeographicPoint, GeographicPoint>();
toExplore.add(start);
boolean found = false;
while (!toExplore.isEmpty()) {
GeographicPoint curr = toExplore.remove();
if (curr == goal) {
found = true;
break;
}
List<GeographicPoint> neighbors = getNeighbors(curr);
ListIterator<GeographicPoint> it = neighbors.listIterator(neighbors.size());
while (it.hasPrevious()) {
GeographicPoint next = it.previous();
nodeSearched.accept(next);
if (!visited.contains(next)) {
visited.add(next);
parentMap.put(next, curr);
toExplore.add(next);
}
}
}
if (!found) {
System.out.println("No path exists");
return new ArrayList<GeographicPoint>();
}
// reconstruct the path
LinkedList<GeographicPoint> path = new LinkedList<GeographicPoint>();
GeographicPoint curr = goal;
while (curr != start) {
path.addFirst(curr);
curr = parentMap.get(curr);
}
path.addFirst(start);
return path;
}
strong text
This is the code with comments could anyone figure what is wrong with my implementation

Saving enum values in a hashmap in a Class

I need to extend the class Room such that a room can contain zero or many characters by adding a field and a method in Room class that adds characters to rooms created. I already created an enum class called Character as can be seen below but I don't know how to use that in my Room class to add characters to a Room object.
I already created a HashMap field for storing the characters called charactersroom. The method in my code for adding characters is called addCharacter.
Room Class
public class Room
{
private String description;
private HashMap<Direction, Room> exits; // stores exits of this room.
private HashMap<Character, Room> charactersroom;
/**
* Create a room described "description". Initially, it has
* no exits. "description" is something like "a kitchen" or
* "an open court yard".
* #param description The room's description.
* Pre-condition: description is not null.
*/
public Room(String description)
{
assert description != null : "Room.Room has null description";
this.description = description;
exits = new HashMap<Direction, Room>();
charactersroom = new HashMap<Character, Room>();
sane();
}
public void addCharacter(Character character)
{
}
/**
* Class invariant: getShortDescription() and getLongDescription() don't return null.
*/
public void sane()
{
assert getShortDescription() != null : "Room has no short description" ;
assert getLongDescription() != null : "Room has no long description" ;
}
/**
* Define an exit from this room.
* #param direction The direction of the exit.
* #param neighbor The room to which the exit leads.
* Pre-condition: neither direction nor neighbor are null;
* there is no room in given direction yet.
*/
public void setExit(Direction direction, Room neighbor)
{
assert direction != null : "Room.setExit gets null direction";
assert neighbor != null : "Room.setExit gets null neighbor";
assert getExit(direction) == null : "Room.setExit set for direction that has neighbor";
sane();
exits.put(direction, neighbor);
sane();
assert getExit(direction) == neighbor : "Room.setExit has wrong neighbor";
}
/**
* #return The short description of the room
* (the one that was defined in the constructor).
*/
public String getShortDescription()
{
return description;
}
/**
* Return a description of the room in the form:
* You are in the kitchen.
* Items: map
* Exits: north west
* #return A long description of this room
*/
public String getLongDescription()
{
return "You are " + description + ".\n" + getExitString();
}
/**
* Return a string describing the room's exits, for example
* "Exits: north west".
* #return Details of the room's exits.
*/
private String getExitString()
{
String returnString = "Exits:";
Set<Direction> keys = exits.keySet();
for(Direction exit : keys) {
returnString += " " + exit;
}
return returnString;
}
/**
* Return the room that is reached if we go from this room in direction
* "direction". If there is no room in that direction, return null.
* #param direction The exit's direction.
* #return The room in the given direction.
* Pre-condition: direction is not null
*/
public Room getExit(Direction direction)
{
assert direction != null : "Room.getExit has null direction";
sane();
return exits.get(direction);
}
}
Character enum class
public enum Character
{
LAURA("Laura",Item.SANDWICH),SALLY("Sally", Item.CRISPS),ANDY("Andy", Item.DRINK),ALEX("Alex", null);
private String charDescription;
private Item item;
private Character(String Chardescription, Item item) {
this.charDescription = charDescription;
this.item = item;
}
public String toString()
{
return charDescription+item;
}
/**
* Takes the indicated item from the character
* #return true if successful
*
*/
public boolean take(Item item)
{
if (item == this.item) {
this.item = null;
return true;
}
return false;
}
}
EDIT: This method is in my superclass Game for creating the rooms and their exits:
/**
* Create all the rooms and link their exits together.
*/
private void createRooms()
{
Room trafalgarSquare, chinatown, oxfordStreet, soho, coventGarden,
britishMuseum, stPancras, kingsCross, britishLibrary, leicesterSquare;
// create the rooms
trafalgarSquare = new Room("on Trafalgar Square");
chinatown = new Room("in Chinatown");
oxfordStreet = new Room("on Oxford Street");
soho = new Room("in Soho");
coventGarden = new Room("in Covent Garden");
britishMuseum = new Room("in the British Museum");
stPancras = new Room("in St Pancras");
kingsCross = new Room("in Kings Cross");
britishLibrary = new Room("in the British Library");
leicesterSquare = new Room("on Leicester Square");
// initialise room exits
kingsCross.setExit(Direction.WEST, stPancras);
stPancras.setExit(Direction.EAST, kingsCross);
stPancras.setExit(Direction.WEST, britishLibrary);
britishLibrary.setExit(Direction.EAST, stPancras);
britishLibrary.setExit(Direction.SOUTH, britishMuseum);
britishMuseum.setExit(Direction.NORTH, britishLibrary);
britishMuseum.setExit(Direction.WEST, oxfordStreet);
oxfordStreet.setExit(Direction.EAST, britishMuseum);
britishMuseum.setExit(Direction.SOUTH, coventGarden);
coventGarden.setExit(Direction.NORTH, britishMuseum);
oxfordStreet.setExit(Direction.SOUTH, soho);
soho.setExit(Direction.NORTH, oxfordStreet);
soho.setExit(Direction.SOUTH, chinatown);
chinatown.setExit(Direction.NORTH, soho);
chinatown.setExit(Direction.SOUTH, leicesterSquare);
leicesterSquare.setExit(Direction.NORTH, chinatown);
leicesterSquare.setExit(Direction.EAST, coventGarden);
coventGarden.setExit(Direction.WEST, leicesterSquare);
leicesterSquare.setExit(Direction.SOUTH, trafalgarSquare);
trafalgarSquare.setExit(Direction.NORTH, leicesterSquare);
currentRoom = stPancras; // start game at St Pancras
}

Java Swing: How to build Connect 4 GUI

So I'm trying to create a Connect 4 GUI program in Java using the MVC pattern, where this class is the Model:
public class ConnectFourGame {
private Board board;
private Player playerX;
private Player playerO;
private int turnCount;
private CheckWinnerAlgorithm checkWinner;
/**
* Constructs a new ConnectFourGame instance.
*/
public ConnectFourGame() {
this.board = new Board();
this.playerX = new Player('X');
this.playerO = new Player('O');
this.turnCount = 1;
this.checkWinner = new CheckWinnerAlgorithm();
}
/**
* Accesses the current game board.
* #return a Board object representing the current game board
*/
public Board getBoard() {
return this.board;
}
/**
* Accesses player X and their attributes.
* #return a PlayerX object
*/
public Player getPlayerX() {
return this.playerX;
}
/**
* Accesses player O and their attributes.
* #return a PlayerO object
*/
public Player getPlayerO() {
return this.playerO;
}
/**
* Returns the winner of the game.
* #return a CheckWinnerAlgorithm object containing the winner token
*/
public CheckWinnerAlgorithm getWinner() {
return this.checkWinner;
}
/**
* Determines whose turn it is based on the game's turn counter.
* #return the Player whose turn it currently is
*/
public Player determineTurn() {
if (this.turnCount % 2 == 0) {
return this.playerO;
}
else {
return this.playerX;
}
}
/**
* Assesses whether a player move can be made, placing a token if valid.
* #param colNum An int specifying the column chosen by the player
* #param playerToken A char representing the player's token
* #return a boolean, true if a valid move has been made and false otherwise
*/
public boolean moveIsMade(int colNum, char playerToken) {
// move cannot be made if selected column is full
if (board.getBoard()[0][colNum-1] != ' ') {
System.out.println("The selected column is full.");
return false;
}
// if column is not full, place token at bottom-most available spot
for (int row=0; row<6; row++) {
if (board.getBoard()[row][colNum-1] != ' ') {
board.getBoard()[row-1][colNum-1] = playerToken;
this.turnCount++;
return true;
}
}
// place token at bottom of empty column
board.getBoard()[5][colNum-1] = playerToken;
this.turnCount++;
return true;
}
/**
* Specifies whether the game is over.
* #return a boolean, true if the game is over and false otherwise
*/
public boolean isOver() {
if (this.checkWinner.findWinner(this.board)!=' ') {
this.resetGame();
return true;
}
return false;
}
/**
* Resets the game to a beginning state.
*/
public void resetGame() {
this.board.clearBoard();
this.checkWinner.resetWinnerToken();
this.turnCount = 1;
}
}
Now I'm trying to figure out how to start building the View class with Swing GUI elements. Below is a rough mockup of the GUI I have in mind:
The top row are JButtons which will drop a token into the corresponding column of the board when clicked. I'm thinking of using a 2D 6*7 array of JLabels to represent the board. How can I display this in the above manner?
Help would be greatly appreciated!
How can I display JLabels in the above manner (like a grid)?
You would use the GridLayout.
Your other alternative is to use a JPanel as a drawing panel, and draw the game board. By drawing the game board, you can make the pieces circles instead of squares.
How do I set up handling for all this in the Controller class?
You will have more than one controller class. In Java Swing, action listeners are the controllers in your model / view / controller pattern.
The JButtons to drop pieces will each have a separate action listener.

Easy way to add 3 different types of Objects to one ArrayList with one method?

This is a copy from an assignment I've done, so apologizes for some of the Norwegian commenting.
My question is:
I have an items ArrayList which holds Objects from the classes Item, Swords, Potions. (Potions & Swords are subclasses of Items). And I have 3 different methods to add these Objects to the ArrayList.
My question is Simple actually. Is there a (simple, I'm new and learning still) way for me to add all Items and Subclasses of Item to the ArrayList without having 3 different methods which look all alike. (addItem, addSword, addPotion), all close to the bottom of the code.
I'd want something like this ( not thought through, just wrote something)
public void addItem(String typeofItem){
item = new typeofItem;
items.add(item);
}
There is alot more to the code, but i feel like this is whats relevant.
public class Player
{
// Fields -------
private String name;
private String type;
private int health;
private ArrayList<Item> items = new ArrayList<>();
private Item item;
private Swords sword;
private Potions potion;
private Checker valid;
private int maxCarry;
private int gold;
private int currentWeight;
// ----------------
/**
* Klassens konstruktør. Players health vil alltid settes til 100.
*
* #param name Player navn
* #param type Player type
* #param goldValue Players starting gold
* #param setMaxWeight Players max carry weight
*/
public Player (String name, String type, int goldValue, int setMaxWeight) {
valid = new Checker(); // Creates a checker object to do String and integer checks
this.name = valid.checkString(name); // Setter player name, etter å ha sjekka at den ikke er tom
this.type = checkType(type); // Setter type, etter å ha processet den
health = 100; // Health skal alltid starte som 100
maxCarry = valid.checkInt(setMaxWeight); // Sets max carry weight
currentWeight = 0; // Start vekten til player
gold = valid.checkInt(goldValue); // setter goldbeholding etter å ha sjekka at den ikke er negativ
}
/**
* En metode for å selge ett Item objekt, reduserer gold og øker weight ved kjøp.
*
* #param item Item object to sell
*/
private void buyItem(Item item)
{
// Temporary values given from items methods getweight and getvalue to be used in a mutation
int tempWeight;
int tempValue;
tempWeight = item.getWeight();
tempValue = item.getValue();
// Checks if the item meets te conditions to be bought (enough gold, and can be carried)
if (checkConditions(tempValue, tempWeight)) {
// Adds the item to ArrayList if conditions met and updates gold and weight
items.add(item);
currentWeight += tempWeight;
gold -= tempValue;
}
}
/**
* Method to calculate if given value and weight is accepted to perform a purchase (total gold > 0 && total weight < maxWeight)
*
* #param value Gold value of item
* #param weight Weight of item
* #return boolean Returns true if conditions met
*/
private boolean checkConditions(int value, int weight)
{
if (!(gold >= value))
{
System.out.println("You don't have enough gold!");
return false;
} else {
if (!(weight + currentWeight <= maxCarry)){
System.out.println("You'll be too heavy carry this item!");
return false;
} else {
// All conditions met
return true;
}
}
}
/**
* Adds an item to player inventory (uses method buyItem to process the item as a purchase)
*
* #param itemName String to name item
* #param itemDesc String to describe item
* #param itemValue int to declare items value
* #param itemWeight int to declare items Weight
* #param itemAction String to give item an action
*/
public void addItem(String itemName, String itemDesc, int itemValue, int itemWeight, String itemAction)
{
// A Player generated item, which needs all parameters to specify it
item = new Item(itemName, itemDesc, itemValue, itemWeight, itemAction);
buyItem(item);
}
/**
* Randomly generates a Sword object and adds it to players inventory (uses buyItem to process)
* #see Swords#Swords
*/
public void addSword()
{
sword = new Swords();
buyItem(sword);
}
/**
* Randomly generates a Potion object and adds it to players inventory (uses buyItem to process)
* #see Potions#Potions
*/
public void addPotion()
{
potion = new Potions();
buyItem(potion);
}
You can create something called a Factory class. A factory class's responsibility is to generate instances of a type of item for you.
https://www.tutorialspoint.com/design_pattern/factory_pattern.htm
Essentially you wrap the method you talk about in a class and return a new instance of that object.
public class ItemFactory{
public static Item addItem(String typeofItem){
switch(typeofItem){
case "Sword":
return new Sword();
case "Potion":
return new Potion();
...
default:
//put any code here that is like the "else" of an if-else block
return null;
}
}
}
Then when you need to add a new item of a specific type:
buyItem(ItemFactory.addItem("Sword"));

Direction with JUnit Testing

I am trying to wrap my head around Junit testing and have read examples and what not, but still finding it difficult to understand how and what to test. Below is the Class with methods that I am creating my test cases from (as well as my test case Class).
import java.util.Iterator;
/**
* The Probability class understands the likelihood that something will happen.
* <p>
* (c) Copyright Fred George 2008. All right reserved. Adapted and used for
* educational purposes with permission from Fred George.
* </p>
*
* #author Fred George
*/
public class Probability {
/** Value of receiver. */
private final double value;
/** Cannot happen. */
private static final double IMPOSSIBLE_VALUE = 0.0;
/** Will happen. */
private static final double CERTAIN_VALUE = 1.0;
/** Instance that represents outcome that will happen. */
public static final Probability CERTAIN = new Probability(CERTAIN_VALUE);
/**
* Answer a new instance of the receiver with the specified value as the
* likelihood that it occurs.
*
* #param valueAsFraction
* value between 0.0 and 1.0
* #throws
*/
public Probability(final double valueAsFraction) {
if (valueAsFraction < IMPOSSIBLE_VALUE || valueAsFraction > CERTAIN_VALUE) {
throw new IllegalArgumentException("Specified value of "
+ valueAsFraction + " is not between 0.0 and 1.0");
}
value = valueAsFraction;
}
/**
* Answer the liklihood that the receiver will occur and the specified other
* Probability will occur.
*
* #return "and" of receiver and other Probability
* #param other
* Probability being and'ed to receiver
*/
public final Probability and(final Probability other) {
return new Probability(this.value * other.value);
}
/**
* Answer the value of the receiver as a scaled double between 0.0
* (impossible) to 1.0 (certain).
* <p>
* This method is modeled after those in Double, Integer, and the rest of
* the wrapper classes.
*
* #return value of receiver as double between 0.0 and 1.0
*/
public final double doubleValue() {
return value;
}
/**
* Answer true if the receiver has the same value as the other (assuming
* other is a Probability).
*
* #return true if receiver's value equals other's value
* #param other
* Object (assumed to be Probability) to compare
*/
public final boolean equals(final Object other) {
if (!(other instanceof Probability)) {
return false;
}
return this.value == ((Probability) other).value;
}
/**
* Answers with a hashcode for the receiver.
* #return the hash
*/
public final int hashCode() {
return (new Double(this.value)).hashCode();
}
/**
* Answer true if the combined likelihoods of the specified Collection of
* Probabilities sums to certain (100%).
*
* #return true if combined likelihoods is 100%
* #param probabilities
* Collection of likelihoods to sum
*/
public static final boolean isTotalCertain(final java.util.Collection probabilities) {
double sum = 0;
for (Iterator i = probabilities.iterator(); i.hasNext();) {
sum += ((Probability) i.next()).value;
}
return sum == CERTAIN_VALUE;
}
/**
* Answer the liklihood that the receiver will not occur.
*
* #return "not" of receiver
*/
public final Probability not() {
return new Probability(CERTAIN_VALUE - value);
}
/**
* Answer the liklihood that the receiver will occur or the specified other
* Probability will occur, or both.
*
* #return "or" of receiver and other Probability
* #param other
* Probability being or'ed to receiver
*/
public final Probability or(final Probability other) {
return this.not().and(other.not()).not(); // DeMorgan's Law
}
/** Multiplier from double to percentage. */
private static final int PERCENTAGE_MULTIPLIER = 100;
/**
* Answers a String representation of the receiver suitable for debugging.
*
* #return String representation of the receiver
*/
public final String toString() {
int percentage = (int) (value * PERCENTAGE_MULTIPLIER);
return percentage + "%";
}
}
And here is what I've attempted for some of the test cases. I haven't tried them all, but am stuck on the "equals" method.
package edu.psu.ist.probability;
import edu.psu.ist.decision.Decision;
import junit.framework.TestCase;
import junit.framework.*;
public class ProbabilityTest extends TestCase {
private Probability p1;
private Probability p2;
private Probability p3;
private Decision d1;
protected void setUp() {
p1 = new Probability(.6);
p2 = new Probability(.7);
p3 = new Probability(.6);
d1 = new Decision("No decision made");
}
public void testHashCode() {
fail("Not yet implemented");
}
public void testProbability() {
assertEquals(p1.doubleValue(), .6);
try{
p1 = p3;
//get here, bad
fail("Should raise an IllegalArgumentException");
}catch (IllegalArgumentException e){
//good!
}
}
public void testAnd() {
assertEquals((p1.and(p2)).doubleValue(), .42);
}
public void testDoubleValue() {
assertEquals(p1.doubleValue(), .6);
}
public void testEqualsObject() {
assertEquals(p1, p3);
//assertEquals(p1, p2);
assertTrue(!p1.equals(p2));
assertTrue(p1.equals(p3));
/*Probability p1 = new Probability (.7);
Probability p2 = new Probability (.6);
Decision d1 = new Decision();
boolean TRUE = p1.equals(p2);
boolean FALSE = p1.equals(d1);
try {
p1.equals(p2);
p1.equals(d1);
p1.equals(null);
} catch (NullPointerException ex){
// exception should be thrown
}
// assertEquals("Return true if theses values are the same",p1.doubleValue(), p2.doubleValue());
// assertEquals("Return false if not equal", p1.doubleValue(), d1.equals(p1.doubleValue()));
// assertNotSame("Objects are not the same", p1, d1);
*/
}
public void testIsTotalCertain() {
fail("Not yet implemented");
}
public void testNot() {
fail("Not yet implemented");
}
public void testOr() {
fail("Not yet implemented");
}
public void testToString() {
fail("Not yet implemented");
}
}
Maybe someone can shed some light that will help me understand this process more clearly.
You've chosen a somewhat hairy first step, comparing floating point numbers can be non-intuitive. You want to make sure you use the assertXXX methods with a delta:
double x = 1.3;
double y = 13.0 / 10.0;
double acceptable_difference = 0.05;
assertEquals(x,y, acceptable_difference);
That should return true as you're unlikely to make your value match.
In terms of writing your tests just think what you want to make sure of, being careful to test the boundary conditions, like if one Probability is 0.
Speaking of floating point I bet you could find uses of not that get you below 0.0, if ever so slightly. That's something to take a look at.
In your particular case, the code seems straight forward for the most part. Try to focus on testing the behavior of the code.
Here are some test scenarios for equals method.
Pass in a non-Probability object
String test = "foo";
assertTrue(!p1.equals(test));
Should the test pass? Should the test expect an exception?
Pass in null
assertTrue(!p1.equals(null));
Should the test pass? Should the test expect an exception?

Categories