Weird ArrayList Behaviour - java

I create 3 objects of ChipSet and put them in an ArrayList. The arraylist does not contain the right values. The debug messages are quite clear on what happening but I have no explanation for this behaviour at all. Could someone tell me my error(s)?
Here is my code:
import java.util.ArrayList;
import java.util.Arrays;
public class WierdArrayBehaviour {
public static void main(String[] args) {
ArrayList<ChipSet> chipSetCombos = createComboExample();
System.out.printf("\n\n---- Show created combolist ----");
System.out.printf("\nCombo 1: " + Arrays.toString(chipSetCombos.get(1).getChips()));
System.out.printf("\nCombo 2: " + Arrays.toString(chipSetCombos.get(1).getChips()));
System.out.printf("\nCombo 3: " + Arrays.toString(chipSetCombos.get(2).getChips()));
}
private static ArrayList<ChipSet> createComboExample() {
ArrayList<ChipSet> combos = new ArrayList<ChipSet>();
System.out.printf("---- Creating possible combos ----");
ChipSet combo1 = new ChipSet(new int[]{1, 1, 1, 1, 2});
System.out.printf("\nCombo 1: " + Arrays.toString(combo1.getChips()));
ChipSet combo2 = new ChipSet(new int[]{1, 1, 1, 1, 3});
System.out.printf("\nCombo 2: " + Arrays.toString(combo2.getChips()));
ChipSet combo3 = new ChipSet(new int[]{1, 1, 1, 1, 4});
System.out.printf("\nCombo 3: " + Arrays.toString(combo3.getChips()));
combos.add(combo1);
combos.add(combo2);
combos.add(combo3);
return combos;
}
}
class ChipSet {
public static final int WHITE_VALUE = 1;
public static final int RED_VALUE = 2;
public static final int GREEN_VALUE = 5;
public static final int BLUE_VALUE = 10;
public static final int BLACK_VALUE = 20;
public static final int[] VALUES = new int[]{WHITE_VALUE, RED_VALUE, GREEN_VALUE, BLUE_VALUE, BLACK_VALUE};
protected static int[] chips;
public ChipSet(int[] chips) {
if (chips == null || chips.length != 5) {
throw new IllegalArgumentException("ChipSets should contain exactly 5 integers!");
}
// store a copy of passed array
this.chips = new int[5];
for (int i = 0; i < this.chips.length; i++) {
this.chips[i] = chips[i];
}
}
public int getSum() {
return chips[0] * WHITE_VALUE
+ chips[1] * RED_VALUE
+ chips[2] * GREEN_VALUE
+ chips[3] * BLUE_VALUE
+ chips[4] * BLACK_VALUE;
}
public int[] getChips() {
return this.chips;
}
}

What happens is that your attribute chips is static, which means that it exists once per class.
Every time you create a new Chipset instance, you are overwriting the previous created chips.
What can you do? Don't declare it as static:
protected int[] chips;

You are printing combo1 every time. Change it to
System.out.printf("\nCombo 2: " + Arrays.toString(combo2.getChips())); // <-- 2
ChipSet combo3 = new ChipSet(new int[]{1, 1, 1, 1, 4});
System.out.printf("\nCombo 3: " + Arrays.toString(combo3.getChips())); // <-- 3
from
System.out.printf("\nCombo 2: " + Arrays.toString(combo1.getChips()));
ChipSet combo3 = new ChipSet(new int[]{1, 1, 1, 1, 4});
System.out.printf("\nCombo 3: " + Arrays.toString(combo1.getChips()));
Edit
Change
protected static int[] chips;
to
protected int[] chips;
As it is there are only one array of Chips for all of your instances.

Related

Method returning null no matter what

I have two classes I have posted here (plus a computer class that the objects are being created from).
When I try to use my findSys method, my method returns "null" no matter what. I am trying to compare the "search" variable the user inputs as a findSys parameter against null, and if it's null, it should output the message I have underneath the "else" clause. But instead, its just returning null no matter what. Stuck here.
import java.util.Scanner;
public class SystemTester {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
String search;
ComputerStore cpu1 = new ComputerStore();
cpu1.add("Pentium II", 32, "2080", "Asus 370", "Corsair", 5, 123, 5);
cpu1.add("Pentium I", 16, "Nvidia 1080", "Asus 270", "CoolerMaster1", 5, 123, 5);
cpu1.add("Pentium III", 4, "GTX 1060", "Gigabyte", "Corssair 2", 5, 123, 5);
cpu1.add("AMD", 4, "GTX 980", "Gigabyte", "Corssair 2", 5, 123, 5);
cpu1.add("AMD Ryzen", 4, "GTX 680", "Gigabyte", "Corssair 2", 5, 123, 5);
cpu1.add("Core I5", 4, "GTX 1080ti", "Gigabyte", "Corssair 2", 5, 123, 5);
cpu1.add("Core I7", 4, "GTX 1060 SLI", "Gigabyte", "Corssair 2", 5, 123, 5);
cpu1.add("Core I9", 4, "GTX 780", "Gigabyte", "Corssair 2", 5, 123, 5);
cpu1.add("AMD Ryzen 2", 4, "Voodoo2", "Gigabyte", "Corssair 2", 5, 123, 5);
cpu1.add("I7 5820k", 4, "Voodoo1", "Gigabyte", "Corssair 2", 5, 123, 5);
ComputerStore cpu2 = new ComputerStore();
cpu2.add("Haswell", 64, "Nvidia 1080", "Aztek", "Corsair", 3.5, 455, 5.5);
System.out.println("Please enter a CPU to search for (Press q to quit)");
search = scan.nextLine();
while (!"q".equals(search)) {
if (search != null) {
System.out.println(cpu1.findSys(search));
}
else {
if (search.equals(null))
System.out.println("test");
}
System.out.println("Please enter a CPU to search for (Press q to quit)");
search = scan.nextLine();
}
}
}
public class ComputerStore {
private Computer[] systems;
private int sysNumbers;
public ComputerStore() {
systems = new Computer[200];
sysNumbers = 0;
}
public void add(String c, int r, String g, String m, String p, double co, int sn, double d) {
systems[sysNumbers++] = new Computer(c, r, g, m, p, co, sn, d);
}
public String toString() {
String result = "";
for (int i = 0; i < sysNumbers; i++)
result += systems[i].toString() + "\n";
return result;
}
public String findSys(String c) {
for (int i = 0; i < sysNumbers; i++) {
if (systems[i] != null && systems[i].getCpu().equals(c))
return systems[i].getMotherboard();
}
return null;
}
}
//
//This program will create Computer objects with different data members
//and will also upgrade those data members based on setters. This program
//also has a depreciation function and upgrade function. This (Computer) is the class
//and the SystemBuilder class is the class used for creating the objects.
public class Computer {
// Data Members - These belong to the class and are private.
// They all go to new objects.
private String cpu;
private int ram;
private String gpu;
private String motherboard;
private String psu;
private double cost;
private int serialnumber;
private double depreciation;
// Initial constructor with no arguments
Computer() {
cpu = "";
ram = 0;
gpu = "";
motherboard = "";
psu = "";
cost = 0.0;
serialnumber = 0;
depreciation = 0.0;
}
// Constructor with data members
Computer(String c, int r, String g, String m, String p, double co, int sn, double d) {
cpu = new String(c);
ram = r;
gpu = new String(g);
motherboard = new String(m);
psu = new String(p);
cost = co;
serialnumber = sn;
depreciation = d;
}
// Getters, allow retrieval of data members from outside of class
public String getCpu() {
return cpu;
}
public int getRam() {
return ram;
}
public String getGpu() {
return gpu;
}
public String getMotherboard() {
return motherboard;
}
public String getPsu() {
return psu;
}
public double getCost() {
return cost;
}
public int getSerialnumber() {
return serialnumber;
}
public double getDepreciation() {
return depreciation;
}
// Setters, allow setting of data members from outside of class
public void setCpu(String c) {
cpu = new String(c);
}
public void setRam(int r) {
ram = r;
}
public void setGpu(String g) {
gpu = new String(g);
}
public void setMotherboard(String m) {
motherboard = new String(m);
}
public void setPsu(String p) {
psu = new String(p);
}
public void setCost(double co) {
cost = co;
}
public void setSerialnumber(int sn) {
serialnumber = sn;
}
public void setDepreciation(double d) {
depreciation = d;
}
// Boolean below will compare computers to see if equal
// based on same motherboard SN#.
public boolean equals(Computer c) {
if (this.serialnumber == (c.serialnumber)) {
return true;
} else {
return false;
}
}
// To string method will print characteristics about object.
public String toString() {
return ("CPU:\t\t" + cpu + "\n" + "RAM:\t\t" + ram + "\n" + "GPU:\t\t" + gpu + "\n" + "Motherboard:\t"
+ motherboard + "\n" + "PSU:\t\t" + psu + "\n" + "Cost:\t\t" + "$" + cost + "\n" + "SN#:\t\t"
+ serialnumber + "\n" + "Depreciation:\t" + "$" + depreciation + " (annually)");
}
// A method to depreciate the cost of the computer
// The formula is observed below, but this is a
// straight line depreciation equation, calculated based
// on the values the user passes into the function. This method
// will show an output of annual depreciation based on useful
// life, entered in "years" by the user.
public void depreciate(double purchasePrice, double salvageValue, double lifeSpanYears) {
double depreciableCost;
double annualDepreciation;
depreciableCost = purchasePrice - salvageValue;
annualDepreciation = depreciableCost / lifeSpanYears;
depreciation = annualDepreciation;
}
// A method to upgrade the ram or the video card
// The method will accpet argumetns for ram (in int) and a gpu (string).
public void upgrade(int newRam, String newGpu) {
ram = newRam;
gpu = new String(newGpu);
}
}
For me your implementation is perfectly working. Here I attached screenshot, may be you did something wrong during console input when you are taking input search text.Console out put snapshot
Ok,
Mr. Mopp was right - but I had to remove the Computer class before the searchResult variable for it to work, and make a var type of String, SearchResult. So this works for me below:
String searchResult;
while (!"q".equals(search)) {
searchResult = cpu1.findSys(search);
if (searchResult != null) {
System.out.println(searchResult);
}
else {
System.out.println("not found");
}
You don't want to compare if search == null because search is the user input. You want to check if the result of the search is null:
while (!"q".equals(search)) {
Computer searchResult = cpu1.findSys(search);
if (searchResult != null) {
System.out.println(searchResult);
}
else {
System.out.println("not found");
}
You also should change the return type of findSys to be Computer. Returning just a String limits the usefulness of the function:
public Computer findSys(String c) {
for (int i = 0; i < sysNumbers; i++) {
if (systems[i] != null && systems[i].getCpu().equals(c))
return systems[i];
}
return null;
}

Read range of values in an array with unkown dimension

I 'm looking for a way to read a range of elements in an array of unknown dimension ( not length).
The client can send a read request for an object and specify the range to read. The input String could be like this : "1:2:3:2,2:3:1:4" for example. This would mean he wants to read the elements in the range from [1][2][3][2] to [2][3][1][4] of an array.
To read a concrete element I created this function:
public Object readValue(Object obj,int[] positions ) {
Object value = null; //Result
int objDimension = getDimension(obj); //Dimesion of the array
System.out.println("Dimension: " + objDimension );
try {
Object[] aux = (Object[]) obj;
for (int i = 0; i < objDimension - 1; i++) {
int pos = positions[i];
aux = (Object[]) aux[pos];
}
value = aux[positions[objDimension - 1]];
System.out.println("Result: " + value);
} catch (ArrayIndexOutOfBoundsException e) {
// TODO: Send a fault to the client.
System.out.println("Error: "+e.getMessage());
}
return value;
}
public static int getDimension(Object value) {
Class<?> clazz = value.getClass();
String className = clazz.getName();
int dimension = 0;
for (int i = 0; i < className.length(); i++) {
if (className.charAt(i) != '[') {
dimension = i;
break;
}
}
return dimension;
}
//Example.
public static void main(String[] args) {
// TODO code application logic here
TestMultiDimensioNRead test = new TestMultiDimensioNRead();
Integer[][][][] testSubject = new Integer[5][2][4][];
testSubject[0][0][2] = new Integer[8];
testSubject[0][0][0] = new Integer[15];
testSubject[0][0][1] = new Integer[20];
testSubject[0][0][3] = new Integer[2];
testSubject[1][1][2] = new Integer[7];
testSubject[1][1][2][0] = 80;
test.readValue(testSubject,new int[]{1, 1, 2, 0});
}
I was thinking a good way may be to calculate the differens between each dimension length.
If anyone can come with a good idea, I would really appreciatee.
Thanks in advance.
EDIT 1: The code posted in this question does read the value of a given position in an array of unknown dimension. My problem is to read all the elements that are between to given points. This might not have been clear in the initial question.
You could use a recursive solution:
public class Test {
private class TestMultiDimensioNRead {
public Integer readValue(Object testSubject, int[] coordinates) {
return readValue(testSubject, coordinates, 0);
}
private Integer readValue(Object testSubject, int[] coordinates, int which) {
if (testSubject instanceof Object[]) {
Object[] subject = (Object[]) testSubject;
if (coordinates.length > which + 1) {
return readValue(subject[coordinates[which]], coordinates, which + 1);
} else {
return (Integer) subject[coordinates[which]];
}
} else {
// Throw some sort of exception?
return -1;
}
}
public Iterator<Integer> readValues(Object testSubject, int[] coordinates, int count) {
return readValues(testSubject, coordinates, count, 0);
}
private Iterator<Integer> readValues(Object testSubject, int[] coordinates, int count, int level) {
if (testSubject instanceof Object[]) {
Object[] subject = (Object[]) testSubject;
if (coordinates.length > level + 1) {
return readValues(subject[coordinates[level]], coordinates, count, level + 1);
} else {
return new Iterator<Integer>() {
int i = 0;
Integer[] intSubject = (Integer[]) subject;
#Override
public boolean hasNext() {
return i <= count;
}
#Override
public Integer next() {
return intSubject[coordinates[level] + (i++)];
}
};
}
} else {
// Throw some sort of exception?
return null;
}
}
}
public void test() {
TestMultiDimensioNRead test = new TestMultiDimensioNRead();
Integer[][][][] testSubject = new Integer[5][2][4][];
testSubject[0][0][2] = new Integer[8];
testSubject[0][0][0] = new Integer[15];
testSubject[0][0][1] = new Integer[20];
testSubject[0][0][3] = new Integer[2];
testSubject[1][1][2] = new Integer[7];
testSubject[1][1][2][0] = 80;
testSubject[1][1][2][1] = 79;
testSubject[1][1][2][2] = 78;
Iterator<Integer> them = test.readValues(testSubject, new int[]{1, 1, 2, 0}, 3);
for (Integer x = them.next(); them.hasNext(); x = them.next()) {
System.out.println(x);
}
System.out.println();
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
Prints 80 as expected.
There's probably more to do in terms of sanity checks but this seems to work.
Found the way to do it, maybe it's helpfull at somepoint for someone.
I didn't include any checks, this is more a test case to see that is works.
public class TestReadMultiDimensionArray {
private int[] startPosition; //Start position.
private int[] endPosition; //End position.
private boolean inRange = false; //If the current position is in range.
private List<Object> result; //List to store the values we find.
public TestReadMultiDimensionArray() {
result = new ArrayList<>();
}
public static void main(String[] args) {
TestReadMultiDimensionArray test = new TestReadMultiDimensionArray();
Integer[][][][] testSubject = new Integer[2][2][4][];
//(0,0,y,z)
testSubject[0][0][0] = new Integer[]{1}; //(0,0,0,0)
testSubject[0][0][1] = new Integer[]{2}; //(0,0,1,0)
testSubject[0][0][2] = new Integer[]{3}; //(0,0,2,0)
testSubject[0][0][3] = new Integer[]{4}; //(0,0,3,0)
//(0,1,y,z)
testSubject[0][1][0] = new Integer[]{5}; //(0,1,0,0)
testSubject[0][1][1] = new Integer[]{6}; //(0,1,1,0)
testSubject[0][1][2] = new Integer[]{7, 8, 9}; //(0,1,2,0) (0,1,2,1) (0,1,2,2)
testSubject[0][1][3] = new Integer[]{10}; //(0,1,3,0)
//(1,0,y,z)
testSubject[1][0][0] = new Integer[]{11, 12}; //(1,0,0,0)..
testSubject[1][0][1] = new Integer[]{13, 14, 15};
testSubject[1][0][2] = new Integer[]{16, 17, 18};
testSubject[1][0][3] = new Integer[]{19, 20, 21}; //..(1,0,3,2)
//(1,1,y,z)
testSubject[1][1][0] = new Integer[]{22, 23}; //(1,1,0,0)..
testSubject[1][1][1] = new Integer[]{24, 25, 26};
testSubject[1][1][2] = new Integer[]{27, 28, 29, 30, 31, 32, 33, 34};
testSubject[1][1][3] = new Integer[]{35, 36}; //..(1,1,3,1)
//Launch the test.
test.readValue(testSubject);
}
/**
*
* #param obj The Array from where we want to get the data.
*/
public void readValue(Object obj) {
//Where should it start.
startPosition = new int[]{0, 1, 0, 0};
//Where should it stop.
endPosition = new int[]{1, 1, 1, 2};
System.out.println("Start Position:" + Arrays.toString(startPosition) + " End Position:" + Arrays.toString(endPosition));
int[] currentPosition = new int[]{-1, -1, -1, -1};
//Call to the method.
testRead((Object[]) obj, 0, currentPosition);
//Result to array.
Object[] arrayToReturn = result.toArray(new Object[0]);
System.out.println("Result: " + Arrays.toString(arrayToReturn));
}
/**
* Recursive method that looks for the values in a multi-dimensional array, in a given range. /!\ No checks are implemented here, wrong input can end in a
* StackOverFlow.
*
* #param obj The array in Object[] form.
* #param currentDimension The dimension we are currently in.
* #param result The reference to the list that will store all the values we found.
* #param currentPosition The current position we are in.
*/
private void testRead(Object[] obj, int currentDimension, int[] currentPosition) {
for (int i = 0; i < obj.length; i++) {
currentPosition[currentDimension] = i;
if (Arrays.equals(startPosition, currentPosition) && currentDimension == (currentPosition.length - 1)) {
//Found the start position.
System.out.println("############ START ############");
inRange = true;
}
if ((i >= startPosition[currentDimension] && i <= endPosition[currentDimension]) || inRange == true) {
//We are in the write track to get to the values we are looking for.
if (obj[i] instanceof Object[]) {
//The data contained in the cell is an array.
testRead((Object[]) obj[i], currentDimension + 1, currentPosition);
} else {
//The data contained in the cell is a scalar. This is what we where looking for.
System.out.println(Arrays.toString(currentPosition) + " Data: " + obj[i]);
result.add(obj[i]);
}
}
if (Arrays.equals(endPosition, currentPosition) && currentDimension == (currentPosition.length - 1)) {
//Found the end position.
System.out.println("############ END ############");
inRange = false;
}
}
}
}
Any question or idea to better the code is welcome.

Java - copy static arrayList from one class to a HashMap in another class

This problem is really really simple, but I have no idea why the suggested solution to a similar question in stackoverflow doesn't work in my code.
I have a static meleeWeaponList list in MeleeWeapon class, and I want to copy the content of the list to a HashMap (keys) in another class (Blacksmith). The problem is probably in the last three lines in Blacksmith class. What should I fix ? Any suggestion regarding how to deal with the data is more than welcome
public class MeleeWeapon extends Weapon {
boolean throwable;
MeleeWeapon(String name,boolean oneHaned, String reqTraining, int n, int dice, int attackBonus, int damageBonus,double weight, long cost, boolean throwable) {
super(name, weight, cost, oneHaned, reqTraining, n, dice, attackBonus, damageBonus);
this.throwable = throwable;
}
static List<MeleeWeapon> meleeWeaponList = new ArrayList<MeleeWeapon>();
static
{
meleeWeaponList.add(new MeleeWeapon("Long Sword",true, "Martial", 1, 8, 0, 0,8, 10, false));
meleeWeaponList.add(new MeleeWeapon("Short Sword",true, "Martial", 1, 6, 0, 0,5, 5, false));
meleeWeaponList.add(new MeleeWeapon("Dagger",true, "Basic", 1, 4, 0, 0,2, 3, true));
meleeWeaponList.add(new MeleeWeapon("Quarter-staff",false, "Basic", 1, 4, 0, 0,3, 2, false));
meleeWeaponList.add(new MeleeWeapon("Shield",false, "Martial", 1, 4, 0, 0,8, 8, false));
}
public void attack(Character attacker, Character defender){
int attackRoll = DiceRoller.roll(20) + attacker.getBaseAttackBonus() + attacker.getModifier(attacker.getStrength()) + getAttackBonus() ;
System.out.println(attacker.getName() + " attack Roll: " + attackRoll + "AC: " + defender.getArmorClass());
if (attackRoll >= defender.getArmorClass()){
System.out.println("Defender: " + defender.getName() + " had " + defender.getCurrentHp());
int damage = DiceRoller.roll(getN(), getDice()) + attacker.getModifier(attacker.getStrength()) + getDamageBonus() ;
System.out.println("Damage : " + damage);
defender.setCurrentHp(attacker.getCurrentHp() - damage);
System.out.println("Defender: " + defender.getName() + " has " + defender.getCurrentHp());
} else {
System.out.println("Missed Attack");
}
}
public static MeleeWeapon getItem(String itemName) {
try {
for (Iterator<MeleeWeapon> iter = meleeWeaponList.iterator(); iter.hasNext(); ) {
MeleeWeapon item = iter.next();
if (itemName.equals(item.getName())) {
return item;
}
}
} catch (Exception e){
System.out.println(itemName + " haven't been found");
return null;
}
return null;
}
}
public class Blacksmith {
private Map<MeleeWeapon,Integer> meleeMap;
private Map<RangedWeapon,Integer> rangedMap;
private Map<Armor,Integer> armorMap;
Blacksmith(){
meleeMap = new HashMap<MeleeWeapon, Integer>();
rangedMap = new HashMap<RangedWeapon, Integer>();
armorMap = new HashMap<Armor, Integer>();
}
List<MeleeWeapon> meleeList = MeleeWeapon.meleeWeaponList;
for (MeleeWeapon weapon : meleeList) {
meleeMap.put(weapon, 5);
}
}
You need to put these below statements in a method or constructor or some static block as per your need and you will be good.
List<MeleeWeapon> meleeList = MeleeWeapon.meleeWeaponList;
for (MeleeWeapon weapon : meleeList) {
meleeMap.put(weapon, 5);
}

Issues with Recursion

I am having issues with creating this recursive method. The method needs to add objects to a stack.
Notes:
This is a path finder project.
getNextBird() polls from a bird queue inside the bird object. If the queue is empty it will return null; if it is not empty it will return the next bird inside the queue.
I cannot use any loops at all. (It would have been easy if I could.)
The last element in the stack has to be Bird "end". But if the code works fine it should be done recursively.
My issue is that there is a edge-case where the checks hit a wall where getNextBird becomes null (in this instance the object bird), and I want to pop the newest object from the stack. I will get a StackOverflow error, or a EmptyCollection error.
private static boolean recurse(Stack<Bird> path, Bird current, Bird end)
{
Bird bird = null;
if (current != null) {
bird = current.getNextBird();
if (bird != null) {
path.push(current);
recurse(path, bird, end);
return true;
}
}
return false;
}
import java.util.Stack;
public class Solve2
{
public static void main(String [] args)
{
// create the maze to solve
Maze maze = new Maze();
// create a Stack of Bird objects named path here
Stack<Bird> path = new Stack<Bird>();
// call recursive method to solve the maze and print the path
recurse(path, maze.getStart(), maze.getEnd());
print(path);
}
private static boolean recurse(Stack<Bird> path, Bird current, Bird end)
{
Bird bird = null;
if (current != null) {
bird = current.getNextBird();
if (bird != null) {
path.push(current);
recurse(path, bird, end);
return true;
} else {
path.pop();
recurse(path, path.peek(), end);
return false;
}
}
return false;
}
private static void print(Stack<Bird> stack)
{
// write your code for recursively printing the stack here
System.out.println(stack.pop());
print(stack);
}
}
The Bird class:
public class Bird
{
public static final int N = 0;
public static final int NE = 1;
public static final int E = 2;
public static final int SE = 3;
public static final int S = 4;
public static final int SW = 5;
public static final int W = 6;
public static final int NW = 7;
private static final String [] directions = {"N ", "NE", "E ", "SE", "S ", "SW", "W ", "NW"};
private String name;
private int direction;
private Queue<Bird> queue;
public Bird(int row, int column, int direction)
{
this.name = "Row/Column [" + row + "][" + column + "]";
this.direction = direction;
}
public void setBirdQueue(Queue<Bird> queue)
{
this.queue = queue;
}
public String toString()
{
return "Location: " + name + ", Direction: " + directions[direction];
}
public int getDirection()
{
return this.direction;
}
public Bird getNextBird()
{
// write code to return the next Bird from the queue or null if no Birds left.
return queue.poll();
}
}
import java.util.LinkedList;
import java.util.Queue;
public class Maze
{
private Bird start;
private Bird end;
public Maze()
{
// construct the diagrammed maze
int MAX_ROW = 5;
int MAX_COL = 7;
Bird [][] maze = new Bird[MAX_ROW][MAX_COL];
// row 0
maze[0][0] = new Bird(0, 0, Bird.S);
maze[0][1] = new Bird(0, 1, Bird.SW);
maze[0][2] = new Bird(0, 2, Bird.S);
maze[0][3] = new Bird(0, 3, Bird.SE);
maze[0][4] = new Bird(0, 4, Bird.SW);
maze[0][5] = new Bird(0, 5, Bird.SW);
maze[0][6] = new Bird(0, 6, Bird.SW);
// row 1
maze[1][0] = new Bird(1, 0, Bird.S);
maze[1][1] = new Bird(1, 1, Bird.W);
maze[1][2] = new Bird(1, 2, Bird.SW);
maze[1][3] = new Bird(1, 3, Bird.S);
maze[1][4] = new Bird(1, 4, Bird.N);
maze[1][5] = new Bird(1, 5, Bird.S);
maze[1][6] = new Bird(1, 6, Bird.W);
// row 2
maze[2][0] = new Bird(2, 0, Bird.NE);
maze[2][1] = new Bird(2, 1, Bird.NW);
maze[2][2] = new Bird(2, 2, Bird.N);
maze[2][3] = new Bird(2, 3, Bird.W);
maze[2][4] = new Bird(2, 4, Bird.SE);
maze[2][5] = new Bird(2, 5, Bird.NE);
maze[2][6] = new Bird(2, 6, Bird.E);
// row 3
maze[3][0] = new Bird(3, 0, Bird.SE);
maze[3][1] = new Bird(3, 1, Bird.NE);
maze[3][2] = new Bird(3, 2, Bird.E);
maze[3][3] = new Bird(3, 3, Bird.NW);
maze[3][4] = new Bird(3, 4, Bird.NW);
maze[3][5] = new Bird(3, 5, Bird.E);
maze[3][6] = new Bird(3, 6, Bird.W);
// row 4
maze[4][0] = new Bird(4, 0, Bird.N);
maze[4][1] = new Bird(4, 1, Bird.NE);
maze[4][2] = new Bird(4, 2, Bird.N);
maze[4][3] = new Bird(4, 3, Bird.N);
maze[4][4] = new Bird(4, 4, Bird.NE);
maze[4][5] = new Bird(4, 5, Bird.W);
maze[4][6] = new Bird(4, 6, Bird.N);
start = maze[2][0];
end = maze[2][6];
// write your code here
/*snipped the logic for adding the birds in the queue, but I do know that this part is 100% functional on my end*/
}
public Bird getStart()
{
return this.start;
}
public Bird getEnd()
{
return this.end;
}
}
Okay, one thing I am seeing that you have passed the parameter end in the recursion but never used that.
One key thing of recursion is having a control statement which will cause the recursion to break and return the right thing or nothing. You have returned true and false randomly (or may be there is a logic) which does not add any value to your execution path.
So, let's do it in a different way:
Don't push anything in the stack unless you need it so that you have to only pop when you are printing. The first bird you need to push in the stack is the final bird matching the expression (current == end).
If the bird does not have return something to the previous bird indicating that the path is blocked. Now to match with this, with Step 1, if (current == end) return something to the previous bird indicating that the final bird is found and pass it on with every bird in the chain to the first bird.
Pseudocode:
recursive(stack, current, end)
{
if(current == end){
stack.push(current); //push the final bird
return true; //indication that final is found
}
else if(current.getNext() != null){
result = recurse(stack, current.getNext(), end); //recurse
if(result == true)
stack.push(current); // using indication from the chain
return result;
}
return false;
}

Bad interaction between a script and its tester

So I have this script I've written:
public class Primes {
public static void main(String[] args) {
}
//Part 4: Question 1
public static int Binary2int(String b){
int size = b.length();
double count, sum=0;
boolean binary = true;
for (int i=0; i<b.length() ; i++){
int digit = b.charAt(i)-'0';
if (digit>1){
binary = false;
i=b.length();
}
count = digit*Math.pow(2, size-i-1);
sum+=count;
}
if (!binary){
System.out.println("Error - "+b+" is not a binary number.");
}
int sum1 = (int)sum;
return sum1;
}
//Part 4: Question 2
public static boolean isBinaryString(String b){
boolean binary = true;
for (int i=0; i<b.length() ; i++){
int digit = b.charAt(i)-'0';
if (digit>1){
binary = false;
i=b.length();
}
}
return binary;
}
//Part 4: Question 3
public static String int2Binary(int n){
int count=0;
if (n<=0){
count = 1;
}
for (int i=n; i>0 ;){
i=i/2;
count++;
}
int arr[] = new int [count];
for (int i=n, t=0; i>0 ;t++){
arr[arr.length-1-t] = i%2;
i = i/2;
}
if (n<=0){
arr[0] = 0;
}
String s = Arrays.toString(arr);
return s;
}
}
4.1 is meant to take a string (which stands for a binary number) and then return an integer(which stands for the integer the binary number in the input represents).
4.2 takes a binary number in the form of a string and then returns a Boolean variable (true if it’s a binary number and false if it isn’t).
4.3 is doing the opposite of 4.1, it takes an integer in the form of an integer and returns the binary number that represents it in the form of a string.
Oh and It all works fine when I'm testing it.
Now the problem is that the one checking it will be using the following (type of)script:
/**
* This class represents a tester - to be used by students to check Ex3: <br>
* 1. call all the public functions, check compilation. <br>
* 2. test some of function of their results. <br> <br>
* note: for debug change the printFlag to true.
*/
public class BynaryTest {
/**
* if set to true - will print a trace of all the checks.
*/
public static boolean printFlag = true;//false;
/**
* number of errors the test program found
*/
public static int error = 0;
/**
* this main function runs the test of the EX3Tester class
*/
public static void main(String[] a) {
System.out.println("******* Testing Ex3 - print mode = " + printFlag + " ********");
checkEx34();
System.out.println();
System.out.println("******* U have got " + error + " errors ********");
}
public static void checkEx34() {
if (printFlag) {
System.out.println("**** Cheking Ex21 ****");
}
int[] nums = {0, 1, 12345};
for (int i = 0; i < nums.length; i = i + 1) {
String s = Primes.int2Binary(nums[i]);
int num2 = Primes.Binary2int(s);
if (nums[i] != num2) {
error++;
System.out.println("** Error in EX34:" + num2 + "!=" + nums[i] + " **");
} else {
if (printFlag) {
System.out.println("num[" + i + "]=" + nums[i] + " binary: " + s + " .. ok");
}
}
}
}
}
The interaction between the two scripts does happen and nothing crashes, but then, for some reason, the only outcome I get from using it is:
** Error in EX34:21!=0 **
Error - [1] is not a binary number.
** Error in EX34:21!=1 **
Error - [1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1] is not a binary number.
** Error in EX34:21!=12345 **
******* U have got 3 errors ********
I've tried to fix it myself or finding out what causes that sort of unwanted outcome but I couldn't come up with anything :(
Have you tested it? The mistake is quite obvious if you do.
For example for 9 your Int2Binary method returns the following binary representation: [1, 0, 0, 1] as String.
Then in your Binary2Int you check if you only have 0s and 1s like so:
int digit = b.charAt(i)-'0'; // b is [1, 0, 0, 1]
if (digit>1){
binary = false;
//... more code ...
}
See the mistake now?
In your method intToBinary, you have the following line:
String s = Arrays.toString(arr);
I think you are expecting this to take an array and concat all the values in it into a single string. Given this example:
int[] array = {1, 0, 0};
System.out.println(Arrays.toString(array));
You expect the output to be:
100
When in fact it is:
[1,0,0]

Categories