I have for the past few days been trying to get an example of the state pattern working. The task has been set as part of the module for the master course ive been doing. I did find a thread on here that used the same example however, in my opinion doesnt do it correctly, as the program should work with any sort of test criteria which i am trying to do. Thread here: state design pattern . I have narrowed it down to, i believe the if-statement in the normal state class, so ive cut out the set/getters for the state and ammo, however i can add it in later if they are needed
At the moment it is completing the first assertEquals perfectly fine, however one it goes to the second it throws a nullpointexception. SO my question is, what have i done wrong, or missed out, with the if-statement to return a nullpointexception for the second part of the if-statement? and the sarky reply i got wasn't helpful, as all i want is a fresh pair of eyes to look over what I have done to find the mistake, not to do my entire assignment as i just need a little bit of help to fix this small problem. Also I already knew what a NPE and in this case its happening because the 2nd part of the statement is not being initialised with the criteria specified.
Thank You in advance
public class Railgun {
static int MAX_AMMO = 10;
public String fire(Point p, int round){
System.out.println(p + " " + round);
// System.out.println("ASA W " + state.fire(p, round));
return state.fire(p, round);
}
}
Fire method in the normal state:
public String fire(Point p, int round) {
// NormalState normal = new NormalState();
NeedAmmoState needAmmo = new NeedAmmoState();
System.out.println("akhdka " + round);
ammo-= round;
int round1 = round;
int result1 = 0 + round1;
if(ammo >= 0 && result1 == round1)
{
System.out.println(result1);
return "Fire order: Success "+ result1 + "/" + round1;
}
else if((ammo < 0) && (ammo != -result1))
{
railgun.ammo = 0;
return "Fire order: Partial success " + result1 + "/" + round1;
}else
{ System.out.println("Fail: " + ammo);
railgun.setState(needAmmo);
return "Fire order: Failure "+ result1 + "/" + round1;
}
}
Junit Test:
public void testFire() {
final Railgun railgun = new Railgun();
final int numRounds = 6;
final int x = 100;
final int y = 340;
// This fire mission should be completely successful
String actualResult = railgun.fire(new Point(x, y), numRounds);
String expectedResult = "Fire order: Success 6/6";
System.out.println("ASAS " + actualResult);
assertEquals(expectedResult, actualResult);
// This fire mission should be partially successful
actualResult = railgun.fire(new Point(x, y), numRounds);
//System.out.println(actualResult);
expectedResult = "Fire order: Partial success 4/6";
assertEquals(expectedResult, actualResult);
// This fire mission should fail
actualResult = railgun.fire(new Point(x, y), numRounds); expectedResult = "Fire order: Failure 0/6";
assertEquals(expectedResult, actualResult);
// Check state change to NeedAmmo state
assertEquals(railgun.getState().getClass(), NeedAmmoState.class);
}
Related
I'll preface by saying that this is a project for a class. The logic of the code all functions and, as it stands, currently outputs close to the correct solution (I stopped working on the output when I learned that I had used the wrong interface). The problem is, the requirements very explicitly state we must use comparator. Being new to Java, I used Comparable, not realizing there was an explicit difference. This is an algorithms class in Java, my background is in Python and there are definitely some differences that are going over my head - I'm sure that will be apparent in my code.
I've sort of come to understand the difference between the two, but if you asked me to ELI5, I don't think I could. Please help me understand how exactly to implement Comparator as opposed to Comparable. I get that I need a separate class but then I'm not exactly sure how that should be formatted and what to do with it once I have it.
I'm including below the code of the working solution that implements comparable. Any guidance would be extremely appreciated. TIA.
EDIT: Also, by all means, anything else in particular about my code that stands out as going against Java conventions, I'm happy to hear about.
import java.util.PriorityQueue;
import java.util.ArrayList;
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class ProcessScheduling {
public static class Process implements Comparable<Process> {
private Integer priority;
private int id;
private int arrivalTime;
private int duration;
public Process(int ID, Integer Priority, int Duration, int ArrivalTime) {
this.id = ID;
this.priority = Priority;
this.duration = Duration;
this.arrivalTime = ArrivalTime;
}
public Integer getPriority() {return priority;}
public int getId() {return id;}
public int getArrivalTime() {return arrivalTime;}
public int getDuration() {return duration;}
public void setPriority(Integer priority) {this.priority = priority;}
#Override
public String toString() {
return "Process ID = " + getId()
+ "\n\tPriority = " + getPriority()
+ "\n\tArrival = " + getArrivalTime()
+ "\n\tDuration = " + getDuration();
}
#Override
public int compareTo(Process P) {
if (this.getPriority() > P.getPriority()) {return 1;}
else if (this.getPriority() < P.getPriority()) {return -1;}
return 0;
}
}
public static void main(String[] args) {
// Create ArrayList D to store new processes
ArrayList<Process> D = new ArrayList<Process>();
// Read the input file
try {
File f = new File("process_scheduling_input.txt");
Scanner reader = new Scanner(f);
while (reader.hasNextLine()) {
// Create new Processes and add them to ArrayList D
String[] data = reader.nextLine().split(" ");
Process newProcess = new Process( Integer.valueOf(data[0]),
Integer.parseInt(data[1]),
Integer.parseInt(data[2]),
Integer.parseInt(data[3])
);
D.add(newProcess);
}
reader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occured. File does not exist.");
e.printStackTrace();
}
// Print all processes
for (int i = 0; i < D.size(); i++) {
Process current = D.get(i);
System.out.print("Id = " + current.getId());
System.out.print(", priority = " + current.getPriority());
System.out.print(", duration = " + current.getDuration());
System.out.println(", arrival time = " + current.getArrivalTime());
}
// Instantiate priorityQueue and some parameters
int currentTime = 10;
boolean running = false;
int maxWaitTime = 30;
float totalWaitTime = 0;
int currentEndTime = 0;
Process current = null;
PriorityQueue<Process> Q = new PriorityQueue<Process>();
// Print maxWaitTime
System.out.println("\nMaximum wait time = " + maxWaitTime);
// While D still has a process in it
while (D.isEmpty() == false) {
// Check if current running process has finished
if (running == true && currentEndTime <= currentTime) {
// Print that Process finished
System.out.print("Process " + current.getId());
System.out.println(" finished at time " + currentTime + "\n");
// Update running flag
running = false;
// Update priority of Processes in Q that have been waiting longer than max wait time
System.out.println("Update priority:");
if (Q.isEmpty() == false) {
for (Process p : Q) {
int waitTime = currentTime - p.getArrivalTime();
if (waitTime >= maxWaitTime) {
Integer priority = p.getPriority();
int id = p.getId();
System.out.print("PID = " + id);
System.out.print(", wait time = " + waitTime);
System.out.println(", current priority = " + priority);
priority -= 1;
p.setPriority(priority);
System.out.print("PID = " + id);
System.out.println(", new priority = " + priority);
}
}
}
}
// Find process with earliest arrivalTime in D
Process earliest = D.get(0);
for (int i = 1; i < D.size(); i++) {
if (D.get(i).getArrivalTime() < earliest.getArrivalTime()) {
earliest = D.get(i);
}
}
// Check if arrivalTime of earliest is <= to currentTime
if (earliest.getArrivalTime() <= currentTime) {
// Add to Q and remove from D if yes
Q.add(earliest);
D.remove(earliest);
}
// Check if Q is not empty and running flag is false
if (Q.isEmpty() == false && running == false) {
// Remove process in Q with smallest priority
current = Q.poll();
int waitTime = currentTime - current.getArrivalTime();
totalWaitTime += waitTime;
currentEndTime = currentTime + current.getDuration();
// Process removed from priority queue, print info
System.out.print("\nProcess removed from queue is: id = " + current.getId());
System.out.print(", at time " + currentTime);
System.out.print(", wait time = " + waitTime);
System.out.println(" Total wait time = " + totalWaitTime);
System.out.println(current);
running = true;
}
if (D.isEmpty() == true) {
System.out.println("\nD becomes empty at time " + currentTime + "\n");
}
currentTime++;
}
// D is now empty, all processes are in Q
while (Q.isEmpty() == false) {
// Check if current running process has finished
if (running == true && currentEndTime >= currentTime) {
// Update running flag
running = false;
// Update priority of Processes in Q that have been waiting longer than max wait time
System.out.println("Update priority:");
if (Q.isEmpty() == false) {
for (Process p : Q) {
if (p.getArrivalTime() - currentTime >= maxWaitTime) {
p.priority = p.getPriority() - 1;
}
}
}
}
// If no Process running, start a new one
if (running == false){
current = Q.poll();
int waitTime = currentTime - current.getArrivalTime();
totalWaitTime += waitTime;
currentEndTime = currentTime + current.getDuration();
// Process removed from priority queue, print info
System.out.print("\nProcess removed from queue is: id = " + current.getId());
System.out.print(", at time " + currentTime);
System.out.print(", wait time = " + waitTime);
System.out.println(" Total wait time = " + totalWaitTime);
System.out.println(current);
running = true;
}
currentTime++;
currentTime++;
}
}
}
The biggest differences between Comparator and Comparable is that a Comparator can order objects of different classes. Comparable generally can only order the same type of objects.
So, I'd say you're well on your way, it's not as big a jump as you expected.
tl;dr
Comparator.comparing( Process :: getPriority )
Details
You said:
how exactly to implement Comparator as opposed to Comparable. I get that I need a separate class
Yes, that is the difference, a separate class.
Implementing Comparable is done by adding a method compareTo within the class of the objects being sorted. That means you are limited one single approach to sorting.
Implementing Comparator is done in a separate class. So we can more than one such Comparator implementation, for as many ways as we wish to sort our objects.
For example, a class Student representing people enrolled in a school might implement Comparable by adding a compareTo method that sorts by last name, and secondarily by first name. But in some contexts we might want to sort students by their grade level, and in other contexts by the date in which they first enrolled, and in yet other contexts we might sort by the distance between their home and the schoolhouse. For this other contexts we would write various classes implementing Comparator.
If you want to compare by a getPriority method that returns an int primitive, then your separate Comparator class might look like this.
class ProcessByPriorityComparator implements Comparator< Process > {
public int compare( Process p1 , Process p2 ){
if( p1.getPriority() == p2.getPriority() )
{
return 0;
}
else if ( p1.getPriority() > p1.getPriority() )
{
return 1;
}
else
{
return -1;
}
}
}
Or simplify:
class ProcessByPriorityComparator implements Comparator< Process > {
public int compare( Process p1 , Process p2 ){
return Integer.compare( p1.getPriority() , p2.getPriority() ) ;
}
}
Example usage:
Comparator< Process > processByPriorityComparator =
new ProcessByPriorityComparator() ;
Collections.sort( listOfProcesses , processByPriorityComparator ) ;
Or simply:
Collections.sort( listOfProcesses , new ProcessByPriorityComparator() ) ;
The lambda functional functional features in Java makes it quite easy to define a Comparator locally rather than formally defining a separate class.
Greatly helping to simplify this work are the static methods on Comparator such as comparing. So defining a Comparator can be as simple as using a method reference for an accessor “getter” method to sort by a particular property of the object.
This is quite appropriate in your particular case. We can use a method reference for the Process#getPriority method.
Comparator< Process > processByPriorityComparator =
Comparator.comparing( Process :: getPriority );
Collections.sort( listOfProcesses , processByPriorityComparator ) ;
Or, more simply, drop the named variable holding the comparator.
Collections.sort( listOfProcesses , Comparator.comparing( Process :: getPriority ) )
By the way, other issues with your code…
Do yourself a favor and move that huge main method out to its own class. Create a separate class named something like Main or App.
public class App {
public static void main( String[] args ) {
…
}
}
And I see no need for Process to be static nor be nested.
I suspect you feel some compulsion to have everything squeezed into a single class or file. Not so in Java. In Java you should generally have many classes, smaller and separate.
Eventually, as your app grows, organize the many classes by using packages and possible modules.
I have a problem with the execution of the methods in a for loop. I want my program to execute the programmedMoving() method 5 times.
This programmedMoving() method consists of two methods:
the first one ( chooseTheDirection() ) executes some algorithm and returns the Point2D towards which the object should move;
the second one ( moveToThePoint() ) should get this point and move the object.
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_H) {
for(int i=0; i<5; i++{
programmedMoving();
}
}
}
//////////////////////////////////////////////////////////////////
private void programmedMoving(){
chooseTheDirection(); //returns the Point2D
moveToThePoint();//according to the direction starts moving the point
}
The problem is that it executes chooseTheDirection() method 5 times without waiting for the moveToThePoint() method to finish it's execution. So, by the time the object on the JPanel starts actually moving, the chooseTheDirection() method already provides 5 Point2D points, whereas I need it to provide only one, and wait for the end of the next method.
Could anyone tell me what am I doing wrong? Thank you.
ADDITIONALLY:
private Direction chooseDirection(){
final List<Direction> directionList = Collections.unmodifiableList(Arrays.asList(Direction.values()));
int pick = random.nextInt(directionList.size());
dir = directionList.get(pick);
directionsArchive.add(dir);
System.out.println("dir " + dir + " " + directionsArchive);
if(directionsArchive.size() == 1){
dir = directionsArchive.get(0);
System.out.println("equal to one taken " + dir + " size of dir " + directionsArchive.size());
directionsArchive.add(dir);
}
if(directionsArchive.size() > 1){
int last = directionsArchive.size()-1;
System.out.println("index of last " + last);
if(directionsArchive.get(last).equals(dir)){
pick = random.nextInt(directionList.size());
dir = directionList.get(pick);
directionsArchive.add(dir);
}
System.out.println("more than one taken " + dir + " size of dir " + directionsArchive.size());
directionsArchive.add(dir);
}
else{
directionsArchive.add(dir);
System.out.println(" size of dir " + directionsArchive.size());}
return dir;
}
private void moveToThePoint(){
if(dir.equals(Direction.NORTH)){
this.robot.turnUp();
this.robot.go();
}
if(dir.equals(Direction.SOUTH)){
this.robot.turnDown();
this.robot.go();
}
if(dir.equals(Direction.EAST)){
this.robot.turnRight();
this.robot.go();
}
if(dir.equals(Direction.WEST)){
this.robot.turnLeft();
this.robot.go();
}
}
// SOME EXAMPLES TO THE MOVING METHODS. I PROVIDED ONLY ONE, CAUSE THEY ARE PRETTY SIMILAR
public void turnDown()
{
//System.out.println("Robot - Turn Down!");
this.m_nXDir = 0;
this.m_nYDir = 1;
}
public void go()
{
this.m_nStep = 1;
//System.out.println("Robot - Go!");
}
public void move(int d, int e)
{
//from start to finish
int x = d + this.m_nStep * this.m_nXDir;
int y = e + this.m_nStep * this.m_nYDir;
int w = getWidth();
int h = getHeight();
setBounds(x, y, w, h);
}
moveToThePoint doesn't actually move the object, it merely sets the step size to 1. I assume the actual move() function is called on a timer.
Here are 2 suggestions on how to fix it:
Re-run the decision algorithm (programmedMoving) for every step.
or
Queue up future moves. You store a queue of future moves for the object, and each times it is scheduled to move() you remove the next move from the queue and execute it.
I'm Making a game which uses a parent to run an attack class as shown below
public String attack(int damage, int extradamage, String type) {
int hitpossibility;
hitpossibility = (int) ((Math.random() * 100) + 1);
if (type.compareTo("Ranged") == 0) {
weaponnoise = "twang!";
}else{
weaponnoise = "swing!";
}
if (chancetohit >= hitpossibility) {
for (int x = 0; x < damage; x++) {
result = result + (int) ((Math.random() * 6) + 1);
}
result = result + extradamage;
return weaponnoise + " The " + name + " did " + +result + " damage";
}
return weaponnoise +"The " +name+" missed!";
}
I have multiple different weapons which i want to use and have succeded in this however i have a dagger which i would like to attack twice per turn instead of once like the others. This is the class which i use to set the daggers damage values:
public class Dagger extends Blade {
public Dagger() {
super();
damage = 1;
extradamage = -1;
chancetohit = 75;
}
public String attack(int damage, int extradamage, String type) {
return super.attack(damage, extradamage, type);
}
I then have a class that runs it and currently it does this:
for (int l = 0; l < 2; l++) {
System.out.println(pointy.attack(pointy.damage, pointy.extradamage, pointy.getType()));
monsterhealth = monsterhealth - pointy.result;
System.out.println(monsterhealth);
pointy.result = 0;
}
Instead of it printing the attack twice, i want it to attack twice on the same line. I was wondering what i can change in the dagger class which would allow me to do so.
Any help is of course appreciated thank you!
This answer is an explanation of #Arnav 's comments. Here Dagger is a sub-class of the main weapon class and you want to invoke super-class' attack twice when the attack method of Dagger is called.
For this you need to call super.attack twice from Dagger attack method:
public class Dagger extends Blade {
public Dagger() {
super();
damage = 1;
extradamage = -1;
chancetohit = 75;
}
public String attack(int damage, int extradamage, String type) {
String result1 = super.attack(damage, extradamage, type);
String result2 =super.attack(damage, extradamage, type);
return // You can return result1 or result2 based on your requirement
}
Note: I deleted my earlier answer, because this approach is better than the other one.
So I did search and read abut every factorial listing on this site but I cannot seem to figure out what is wrong with my code. Iv tried multiple different return methods but they all keep failing. Any ideas?
public class RecursivelyPrintFactorial {
public static void printFactorial(int factCounter, int factValue) {
int nextCounter = 0;
int nextValue = 0;
if (factCounter == 0) // Base case: 0! = 1
System.out.println("1");
}
else if (factCounter == 1) // Base case: print 1 and result
System.out.println(factCounter + " = " + factValue);
}
else { // Recursive case
System.out.print(factCounter + " * ");
nextCounter = factCounter - 1;
nextValue = nextCounter * factValue;
}
return factValue * printFactorial(factValue - factCounter);
}
}
public static void main (String [] args) {
int userVal = 0;
userVal = 5;
System.out.print(userVal + "! = ");
printFactorial(userVal, userVal);
}
}
I have a feeling I have the equation incorrect in my return but iv tried every combination I can think of. Its driving me insane. Every one reports an error. Any ideas?
return factValue * printFactorial(factValue - factCounter);
I assume that you should be using the "next" values instead of these.
Edit: Also note that the function takes two parameters and is void. Returning factValue times void doesn't make sense.
Is it possible to convert the function go into the non-recursive function? Some hints or a start-up sketch would be very helpful
public static TSPSolution solve(CostMatrix _cm, TSPPoint start, TSPPoint[] points, long seed) {
TSPSolution sol = TSPSolution.randomSolution(start, points, seed, _cm);
double t = initialTemperature(sol, 1000);
int frozen = 0;
System.out.println("-- Simulated annealing started with initial temperature " + t + " --");
return go(_cm, sol, t, frozen);
}
private static TSPSolution go(CostMatrix _cm, TSPSolution solution, double t, int frozen) {
if (frozen >= 3) {
return solution;
}
i++;
TSPSolution bestSol = solution;
System.out.println(i + ": " + solution.fitness() + " " + solution.time() + " "
+ solution.penalty() + " " + t);
ArrayList<TSPSolution> nHood = solution.nHood();
int attempts = 0;
int accepted = 0;
while (!(attempts == 2 * nHood.size() || accepted == nHood.size()) && attempts < 500) {
TSPSolution sol = nHood.get(rand.nextInt(nHood.size()));
attempts++;
double deltaF = sol.fitness() - bestSol.fitness();
if (deltaF < 0 || Math.exp(-deltaF / t) > Math.random()) {
accepted++;
bestSol = sol;
nHood = sol.nHood();
}
}
frozen = accepted == 0 ? frozen + 1 : 0;
double newT = coolingSchedule(t);
return go(_cm, bestSol, newT, frozen);
}
This is an easy one, because it is tail-recursive: there is no code between the recursive call & what the function returns. Thus, you can wrap the body of go in a loop while (frozen<3), and return solution once the loop ends. And replace the recursive call with assignments to the parameters: solution=bestSol; t=newT;.
You need to thinkg about two things:
What changes on each step?
When does the algorithm end?
Ans the answer should be
bestSol (solution), newT (t), frozen (frozen)
When frozen >= 3 is true
So, the easiest way is just to enclose the whole function in something like
while (frozen < 3) {
...
...
...
frozen = accepted == 0 ? frozen + 1 : 0;
//double newT = coolingSchedule(t);
t = coolingSchedule(t);
solution = bestSol;
}
As a rule of thumb, the simplest way to make a recursive function iterative is to load the first element onto a Stack, and instead of calling the recursion, add the result to the Stack.
For instance:
public Item recursive(Item myItem)
{
if(myItem.GetExitCondition().IsMet()
{
return myItem;
}
... do stuff ...
return recursive(myItem);
}
Would become:
public Item iterative(Item myItem)
{
Stack<Item> workStack = new Stack<>();
while (!workStack.isEmpty())
{
Item workItem = workStack.pop()
if(myItem.GetExitCondition().IsMet()
{
return workItem;
}
... do stuff ...
workStack.put(workItem)
}
// No solution was found (!).
return myItem;
}
This code is untested and may (read: does) contain errors. It may not even compile, but should give you a general idea.