How does one set a number of spaces based on user input? - java

The assignment is asking me to create a class named Vehicle that stimulates a car moving along a 40 block stretch of road.
Here's more information:
Your class will build a vehicle and keep track of its location on the road. Location values may range from -20 to 20. A location value of 0 represents block 0, a location value of 1 represents block 1, a location value of 2 represents block 2, etc. If the user tries to move the vehicle beyond block +20 or -20, set the location to +/- 20 respectively.(I dont understand how to do this part)
Variable
int location - An integer that holds the current block location of the car on the road, with possible values ranging from -20 to 20.
Methods
Vehicle () - Sets location to 0.
Vehicle (int loc) - If loc is between -20 and 20 inclusive, sets location to loc. Otherwise, sets location to 0.
void forward () - Increments the vehicle forward one block. Do not let the user move past block 20.
void backward () - Increments the vehicle backward one block. Do not let the user move past block -20.
int getLocation () - Returns an integer representing the block location of the car.
String toString () - Returns a String representation showing the vehicle as an # character, with spaces to show its location. When the vehicle is at location -20 the # character appears at the start of the String. When the vehicle is at a higher position, one space for each number from -20 to the car's current location appears before the #. For example if the car is at block -10, the method will return " #" (10 spaces then the '#'). If the car is at block 5 the method will return " #" (25 spaces then the '#').
Here's my code so far(this is in my Vehicle.java file) :
public class Vehicle
{
private int location;
public Vehicle(int loc)
{
return location;
}
public void forward()
{
if (location>=-20 && location <=20)
{
location++;
}
}
public void backward()
{
if (location>=-20 && location <=20)
{
location--;
}
}
public int getLocation()
{
return location;
}
public String toString()
{
return "";
}
}
Here is the runner file:
import java.util.Scanner;
public class runner_Vehicle
{
public static void main (String str[]){
Scanner scan = new Scanner(System.in);
Vehicle v = new Vehicle ();
String instruction = "";
while(!instruction.equals("q")){
System.out.println(v);
System.out.println("Location: " + v.getLocation());
System.out.println("Type \"f\" to move forwards, \"b\" to move backwards, \"n\" for new vehicle, \"q\" to quit.");
instruction = scan.nextLine();
if(instruction.equals("f")){
v.forward();
}
else if(instruction.equals("b")){
v.backward();
}
else if(instruction.equals("n")){
System.out.println("Starting location for new vehicle?");
int start = scan.nextInt();
v = new Vehicle(start);
scan.nextLine();
}
else if(!instruction.equals("q")){
System.out.println("Instruction not recognized.");
}
}
}
}

If the user tries to move the vehicle beyond block +20 or -20, set the location to +/- 20 respectively. (I dont understand how to do this part)
Simply check it and cap the value
public void forward()
{
location++;
if (location > 20) location = 20;
}
public void backward()
{
location--;
if (location < 20) location = -20;
}
Regarding the toString method - Look at the StringBuilder class
StringBuilder sb = new StringBuilder();
for (int i = -20; i <= 20; i++) {
if (i == getLocation()) {
sb.append("#");
}
else sb.append(" ");
}
return sb.toString();

First time answering a question, but hope I can be of some help:
I've tried to explain what each thing does in places I thought you might have been confused. If you are going to hand this in, please remove the comments.
class Vehicle {
private int location;
public Vehicle() {
// Known as the constructor.
// Creates an instance of the class, meaning it creates the vehicle object when you say
// Vehicle car = new Vehicle();
location = 0;
}
public Vehicle(int loc) {
// known as a parameterized constructor, which is just a constructor but you give it some default values.
// It does not return a value, all it does it make the object in question.
// In this case, it would be a Vehicle object.
if (loc >= -20 && loc <= 20) {
location = loc;
}
}
public void forward() {
location++;
if (location >= 21) {
location = -20;
}
}
public void backward() {
location--;
if (location <= -21) {
location = 20;
}
}
public int getLocation() {
return location;
}
public String toString() {
String output = "";
for (int i = -20; i < location; i++) {
output += ' ';
}
return output + '#';
}
}
Hopefully that helps!

Related

Car is not moving right?

Car is moving but as it reaches column 5 it stops there and does not move.
Car has the move() method, in which Car instances drive forwards with the amount of cells equivalent to speed in each time step (from left to right).
Car shall accelerate its speed by 1 after each time step and the speed for the next time step will be higher
public class Car extends Actor {
public final int MAXSPEED= 5;
private int speed = 3;
public void move() {
Grid<Actor> gr = this.getGrid();
if (gr != null) {
Location loc = this.getLocation();
Location next = new Location(0,this.speed);
if (gr.isValid(next)) {
this.moveTo(next);
} else {
this.removeSelfFromGrid();
}
}
}
public void accelerate(){
if (this.speed <5) {
// move();
this.speed++;
} else {
this.speed = MAXSPEED;
}
}
public void dawdle(){
if(Math.random() <= 0.3){
this.speed= speed--;
}else{
this.speed=speed;
}
}
public Car(){
if (speed==1){
this.setColor(Color.red);
}
else if (speed==5){
this.setColor(Color.green);
}
}
#Override
public void act(){
this.move();
this.accelerate();
this.dawdle();
}
}
Your accelerate function allows the car to have a maximum speed of 5.
Together with your move function, which contains
Location next = new Location(0,this.speed);
the car will never go beyond position 5. I think you know what needs to be changed:
newlocation = currentLocation + speed
I do not see anything like this in your code.
To move the car i needed the car current position so speed can be added into the current position to move the car.
Location next = new Location(loc.getRow(),loc.getCol()+this.speed);

The "if" condition in "set" method isn't working

So which floor the lift is on should be able to be read and changed, but only within the allowed range for just that house the lift is installed in. I'm trying to get an "If" condition working looking for a boolean true value from method "validFloor".
Based on my very beginner knowledge of Java, I assume putting an "If" condition in the set-method is a proper attempt?
private int currentFloor = 0;
private int numberOfFloors;
private boolean validFloor = false;
public Elevator(int numberOfFloors) {
this.numberOfFloors = numberOfFloors;
}
//Sets the allowed number of floors (0 to 100)
public void allowedNumberOfFloors() {
if (numberOfFloors < 2) {
numberOfFloors = 2;
} else if (numberOfFloors > 100) {
numberOfFloors = 100;
}
}
//Checks validity of the elevator floor in relation to total floors.
public void validFloor() {
if (currentFloor > numberOfFloors && currentFloor < 0) {
this.validFloor = false;
}
}
//Checks whether the specified floor is in reasonable range.
public void setFloor(int currentFloor) {
if (validFloor) {
this.currentFloor = currentFloor;
}
}
public int getFloor() {
return currentFloor;
}
public String toString() {
return "Number of floors: " + numberOfFloors + "\nCurrent floor: " + currentFloor;
}
For example, if you try to move the lift to floor 74 in a house that only has 5 floors, it should not work. I want the hiss to start at bottom floor 0, hence the 0 value in class variable "currentFloor".
The If condition in the "validFloor" method doesn't seem to be recognized at all. Instead all that matters is the boolean value I put on the class variable validFloor.
You never call the validFloor() method, so the value of validFloor is never changed. Also, you code never sets validFloor to true anywhere, so it wouldn't even matter if you called validFloor(), because it can only set validFloor to false, or leave it at the initial value of false.
The "correct" way to do something like this is:
public boolean isValidFloor(floor) {
// It seems weird to me that 0 is a valid floor. Is that correct?
// If floors are zero-indexed, the top floor should actually be numberOfFloors-1.
return floor >= 0 && floor <= this.numberOfFloors;
}
public void setFloor(int newFloor) {
if (isValidFloor(newFloor)) {
this.currentFloor = newFloor;
}
}
Notice that there's no need to even keep around a validFloor variable. We can just check whether or not a floor is valid every time we need to without saving the result.

trying to call a toString method in different Java Class

The assignment is to create a class called Temp that runs against the instructors TestTemp class which he provided to us for free. So far everything seems to test out pretty well except for my out put in the toString that we are supposed to use. It is supposed to format like the commented out section but doesn't seem to be working. I posed the TestTemp class and my code for the Temp class. I feel like I am missing something little but just need a nudge in the right direction and my instructor doesn't have office hours again until after the assignment is due. I also pasted the assignment instructions he added to the assignment.
The class will be called Temp
Add a compareTo method. (returns -1 if the invoking object has a lower
temp, 0 if the same, 1 if larger)
Add a static counter (object id)to keep track of how many Temperature
objects have been created(1,2,3,...)
Add a static method to tell you how many Temperature objects have been
created.
Include a toString method that displays the object as follows(assumes
3rd one created):
Object Id: 3 Temperature in F: 32.0 Temperature in C: 0.0
Note that calling getF or getC returns the value only. They do not
change the native data.
To be clear the only methods are as follows: 4 constructors, getF,
getC, setDegrees, setScale, equals, toString, compareTo and a static
getTempCount that returns the total number of objects that have been
created.
Note that the getters will return the degrees in the requested scale
rounded to a tenth of a degree. Never round the native data.
Note that the equals method will return true if the temperatures are
the same when compared in celsius (that was rounded to a tenth of a
degree).
Be sure to make great use of this() and have only one contructor do
any real work.
Besure to validate the scale and follow the default (C) if a "bad
scale" is sent in
No need to validate the degrees and worry about things such as
absolute zero and so on.
NOTE: Your Temp class must work correctly with the TestTemp class
supplied in UNIT-04-CodeSamples
//32 - 212 180 ticks
//
//0-100 1/10
//
public class TestTemp
{
public static void main(String [] args)
{
// only one constructor does any real work
Temp temp1 = new Temp(); // 0 C
Temp temp2 = new Temp(32); // 32 C
Temp temp3 = new Temp('F'); // 0 F
Temp temp4 = new Temp(32, 'F'); // 32 F
Temp temp5 = new Temp(); // 0 C
temp5.setDegrees(10);
temp5.setScale('F'); // 10 F
System.out.println("C: " + temp1.getC() ); // C: 0.0
System.out.println("F: " + temp1.getF() ); // F: 32.0
System.out.println(temp1.equals(temp4)); // true
System.out.println(temp1.equals(temp2)); // false
System.out.println("You have " + Temp.getTempCount() ); // You have 5
if( temp3.compareTo(temp5)< 0 ) //temp3 is lower than than temp5
{
System.out.println("temp3 is lower than than temp5");
}
else
{
System.out.println("temp3 is same or larger than temp5");
}
System.out.println(temp1);
/*
TEMP OBJECT #1
IN C: 0.0
IN F: 32.0
*/
}
}
public class Temp implements Comparable<Temp>
{
private double degrees;
private char scale;
private static int tempCount = 0;
private int id;
public Temp()
{
this.degrees = 0;
this.scale = 'C';
// this(0.0, 'C');
}
public Temp(double degrees)
{
this.degrees = degrees;
this.scale = 'C';
// this(degrees, 'C');
}
public Temp(char scale)
{
this.degrees = 0;
this.scale = scale;
// this(0.0, scale);
}
public Temp(double degrees, char scale)
{
this.id = ++tempCount;
this.degrees = degrees;
this.scale = scale;
//(degrees, scale);
}
public static int getTempCount()
{
return tempCount;
}
public int getId()
{
return this.id;
}
public void setScale(char scale)
{
if(scale == 'C')
{
this.scale = scale;
}
else
{
this.scale = 'F';
}
}
public void setDegrees(double degrees)
{
this.degrees = degrees;
}
public double getC()
{
if(scale == 'C')
{
return degrees;
}
else
{
return (double)(5.0 * (degrees-32)/9.0);
}
}
public double getF()
{
if(scale == 'F')
{
return (double) degrees;
}
else
{
return (double)(9.0*(degrees)/5.0)+32;
}
}
#Override
public int compareTo(Temp obj)
{
if(this.getC() < obj.getC() )
{
return -1;
}
if(this.getC() > obj.getC() )
{
return 1;
}
return 0;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Temp))
{
return false;
}
Temp other = (Temp)obj;
return this.getC() == other.getC();
}
**public String toString()
{
return String.format("TEMP OBJECT ", this.id) + "\n" +
String.format("IN C: ", this.getC() ) + "\n" +
String.format("IN F: ", this.getF() );
}**
}
You need place holders in the formatter, Your toString method should be like
public String toString()
{
return String.format("TEMP OBJECT %d", this.id) + "\n" +
String.format("IN C: %.2f", this.getC() ) + "\n" +
String.format("IN F: %.2f", this.getF() );
}
Here %d for integers and %f for decimals. and the .2f limits the number of decimal places to 2. See some more examples here
Your use of String.format shouldn't require multiple creations. Just use one.
return String.format("TEMP OBJECT: $d, %nIN C: %.2f, %nIN F: %.2f", this.id, this.getC(), this.getF());
Modify the precision of the floating points by altering the value after the decimal point %.2f to %.5f will print 0.00000 instead of 0.00 for example.
If you have anymore questions on the use of format, I recommend reading the documentation for it as well to see what else it can do. Link
Edit: Added newline breaks. Forgot to mention just put %n for a newline. Do not space, after them, unless you want your newline to start with a space.

Java: EmptyQueueException being thrown before processing method

I'm working on a stock exchange program as a project and so far I've gotten about 98% of it done, the only issue I am having is when I am trying to sell more shares than a current day holds. So for example, I buy 20 shares for $30 each on day 1 and 40 shares for $20 each on day 2. I then input saying I want to sell 30 shares for $20 each. What the code is supposed to do is sell all the shares from day one, and then sell 10 shares from day 2. However, what I'm getting is an EmptyQueueException being thrown. I feel that my sellShares method might be having the error when it goes into the final else statement with the while loop. However I cannot wrap my mind around what might be the error. I've been staring the code down for quite some time and I can't seem to figure out a solution to this. Some assistance on this would greatly be appreciated. The following code is from my main class and the CircleArrayQueue class:
import java.util.Scanner;
import java.lang.Integer;
public class StockTran {
String command = "";
int gain = 0;
int totalPrice = 0; // totalPrice variable will keep of gain or loss of shares being sold
int shareTracker = 0; // shareTracker variable will keep track of shares being bought and sold
String[] stockParts = null;
CircleArrayQueue Q;
boolean quit = false;
public StockTran(String inputCommand) {
try {
Q = new CircleArrayQueue(32);
Scanner conReader = new Scanner(System.in);
this.command = inputCommand.toLowerCase();
this.stockParts = command.split("\\s"); // splits the input into three parts
while (quit == false) { // will loop until user says "q" to quit program
if (this.stockParts[0].equals("q")) { // ends transaction and terminates program
System.out.println("Share trading successfully terminated.");
quit = true;
System.exit(0); // exits the program
}
if (this.stockParts == null || this.stockParts.length > 3) {
System.out.println("That is an invalid input. Please try again.");
}
if (stockParts[0].equals("b")) { // checks to see if it is a buying of shares
int shares = Integer.parseInt(stockParts[1]); // stores share amount
int value = Integer.parseInt(stockParts[2]); // stores selling value
buyShares(shares, value); // calls buyShares method and adds share to queue
}
else if (stockParts[0].equals("s")) { // checks to see if it is a selling of shares
int shares = Integer.parseInt(stockParts[1]);
int value = Integer.parseInt(stockParts[2]);
sellShares(shares, value); // calls sellShares method
}
else if (stockParts[0].equals("c")) { // checks to see if it is capital gain
gain = capitalGain(); // calls capitalGain and calculates net gain
System.out.println("Capital gain is " + gain);
}
else {
System.out.println("That is an invalid input. Please try again."); // any other input is invalid
}
System.out.println("Enter your next command, or press 'q' to quit: ");
command = conReader.nextLine().toLowerCase();
stockParts = command.split("\\s");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void buyShares(int shareAmount, int sharePrice) { // takes in share total and values for each share
shareTracker = shareTracker + shareAmount; // adds to amount of shares bought
Node temp = new Node(shareAmount, sharePrice); // stores values into node
try {
Q.enqueue(temp); // enqueues the node into the CircularQueue
} catch (FullQueueException e) {
e.printStackTrace();
}
}
public void sellShares(int shareAmount, int sharePrice) throws Exception {
Node temp = new Node(); // stores values into node
int tempShare = 0;
try {
temp = Q.front(); // gets the first node from CircleArrayQueue and stores it in temporary node
int share = temp.getShare();
int price = temp.getPrice();
System.out.println(Q.size());
if (shareAmount > shareTracker) { // throws exception if trying to sell more shares than purchased
throw new Exception ("You don't have that many shares to sell.");
}
else if (share > shareAmount) { // checks to see if first node has a larger share amount or less
temp.setShare(share - shareAmount); // will decrease amount sold from the first days share
shareTracker = shareTracker - shareAmount;
totalPrice = shareAmount * (sharePrice - price) + totalPrice; // calculates total profit or loss
}
else if (share == shareAmount) {
Q.dequeue();
shareTracker = shareTracker - shareAmount; // updates shareTracker to show how many shares are remaining
totalPrice = shareAmount * (sharePrice - price) + totalPrice;
}
else {
while (shareAmount != tempShare) { // will loop until it sells total share amount user wanted
Node temp2 = Q.dequeue(); // removes another node from CircleArrayQueue
int newShare = temp2.getShare();
int newPrice = temp2.getPrice();
tempShare = tempShare + newShare; // adds the shares together to check if while loop condition still holds
totalPrice = shareAmount * (sharePrice - newPrice) + totalPrice;
sellShares(shareAmount - tempShare, sharePrice); // recursively calls sellShares on new amount of shares
}
}
} catch (EmptyQueueException e) {
e.printStackTrace();
}
}
public int capitalGain() { // returns the total net gain or loss in share trading
return totalPrice;
}
public static void main(String[] args) {
String inputCommand = "";
Scanner mainReader = new Scanner(System.in);
System.out.println("Enter 'b' to purchase share, 's' to sell share, 'c' for capital gain, or 'q' to quit: ");
inputCommand = mainReader.nextLine();
StockTran tran = new StockTran(inputCommand);
}
}
public class CircleArrayQueue implements Queue {
protected Node Q[]; // initializes an empty array for any element type
private int MAX_CAP = 0; // initializes the value for the maximum array capacity
private int f, r;
public CircleArrayQueue(int maxCap) {
MAX_CAP = maxCap;
Q = new Node[MAX_CAP]; // sets Q to be a specific maximum size specified
f = 0; // sets front value to be 0
r = 0; // sets rear value to be 0;
}
public int size() {
return (MAX_CAP - f + r) % MAX_CAP; // returns the size of the CircularArrayQueue
}
public boolean isEmpty() { // if front and rear are of equal value, Queue is empty
return f == r;
}
public Node front() throws EmptyQueueException { // method to get the front value of the CircularArrayQueue
if (isEmpty()) throw new EmptyQueueException("Queue is empty.");
return Q[f]; // returns object at front of CircularArrayQueue
}
public Node dequeue() throws EmptyQueueException { // method to remove from the front of the CircularArrayQueue
if (isEmpty()) throw new EmptyQueueException("Queue is empty.");
Node temp = Q[f]; // stores front object in local variable
Q[f] = null; // sets the value to be null in the array
f = (f + 1) % MAX_CAP; // sets the new front value to be this
return temp; // returns the object that was originally in the front
}
public void enqueue(Node element) throws FullQueueException { // method to add to the end of the CircualarArrayQueue
if (size() == MAX_CAP - 1) throw new FullQueueException("Queue has reached maximum capacity.");
Q[r] = element; // stores the new element at the rear of array
r = (r + 1) % MAX_CAP; // sets the new rear value to be the location after element insertion
}
}
Your sellShares routine calls front() without checking to see if there is anything in the queue. If the queue is empty(), you get your exception.

Making change recursively: How do I modify my algorithm to print all combinations?

I have an algorithm that recursively makes change in the following manner:
public static int makeChange(int amount, int currentCoin) {
//if amount = zero, we are at the bottom of a successful recursion
if (amount == 0){
//return 1 to add this successful solution
return 1;
//check to see if we went too far
}else if(amount < 0){
//don't count this try if we went too far
return 0;
//if we have exhausted our list of coin values
}else if(currentCoin < 0){
return 0;
}else{
int firstWay = makeChange(amount, currentCoin-1);
int secondWay = makeChange(amount - availableCoins[currentCoin], currentCoin);
return firstWay + secondWay;
}
}
However, I'd like to add the capability to store or print each combination as they successfully return. I'm having a bit of a hard time wrapping my head around how to do this. The original algorithm was pretty easy, but now I am frustrated. Any suggestions?
CB
Without getting into the specifics of your code, one pattern is to carry a mutable container for your results in the arguments
public static int makeChange(int amount, int currentCoin, List<Integer>results) {
// ....
if (valid_result) {
results.add(result);
makeChange(...);
}
// ....
}
And call the function like this
List<Integer> results = new LinkedList<Integer>();
makeChange(amount, currentCoin, results);
// after makeChange has executed your results are saved in the variable "results"
I don't understand logic or purpose of above code but this is how you can have each combination stored and then printed.
public class MakeChange {
private static int[] availableCoins = {
1, 2, 5, 10, 20, 25, 50, 100 };
public static void main(String[] args) {
Collection<CombinationResult> results = makeChange(5, 7);
for (CombinationResult r : results) {
System.out.println(
"firstWay=" + r.getFirstWay() + " : secondWay="
+ r.getSecondWay() + " --- Sum=" + r.getSum());
}
}
public static class CombinationResult {
int firstWay;
int secondWay;
CombinationResult(int firstWay, int secondWay) {
this.firstWay = firstWay;
this.secondWay = secondWay;
}
public int getFirstWay() {
return this.firstWay;
}
public int getSecondWay() {
return this.secondWay;
}
public int getSum() {
return this.firstWay + this.secondWay;
}
public boolean equals(Object o) {
boolean flag = false;
if (o instanceof CombinationResult) {
CombinationResult r = (CombinationResult) o;
flag = this.firstWay == r.firstWay
&& this.secondWay == r.secondWay;
}
return flag;
}
public int hashCode() {
return this.firstWay + this.secondWay;
}
}
public static Collection<CombinationResult> makeChange(
int amount, int currentCoin) {
Collection<CombinationResult> results =
new ArrayList<CombinationResult>();
makeChange(amount, currentCoin, results);
return results;
}
public static int makeChange(int amount, int currentCoin,
Collection<CombinationResult> results) {
// if amount = zero, we are at the bottom of a successful recursion
if (amount == 0) {
// return 1 to add this successful solution
return 1;
// check to see if we went too far
} else if (amount < 0) {
// don't count this try if we went too far
return 0;
// if we have exhausted our list of coin values
} else if (currentCoin < 0) {
return 0;
} else {
int firstWay = makeChange(
amount, currentCoin - 1, results);
int secondWay = makeChange(
amount - availableCoins[currentCoin],
currentCoin, results);
CombinationResult resultEntry = new CombinationResult(
firstWay, secondWay);
results.add(resultEntry);
return firstWay + secondWay;
}
}
}
I used the following:
/**
* This is a recursive method that calculates and displays the combinations of the coins included in
* coinAmounts that sum to amountToBeChanged.
*
* #param coinsUsed is a list of each coin used so far in the total. If this branch is successful, we will add another coin on it.
* #param largestCoinUsed is used in the recursion to indicate at which coin we should start trying to add additional ones.
* #param amountSoFar is used in the recursion to indicate what sum we are currently at.
* #param amountToChange is the original amount that we are making change for.
* #return the number of successful attempts that this branch has calculated.
*/private static int change(List<Integer> coinsUsed, Integer currentCoin, Integer amountSoFar, Integer amountToChange)
{
//if last added coin took us to the correct sum, we have a winner!
if (amountSoFar == amountToChange)
{
//output
System.out.print("Change for "+amountToChange+" = ");
//run through the list of coins that we have and display each.
for(Integer count: coinsUsed){
System.out.print(count + " ");
}
System.out.println();
//pass this back to be tallied
return 1;
}
/*
* Check to see if we overshot the amountToBeChanged
*/
if (amountSoFar > amountToChange)
{
//this branch was unsuccessful
return 0;
}
//this holds the sum of the branches that we send below it
int successes=0;
// Pass through each coin to be used
for (Integer coin:coinAmounts)
{
//we only want to work on currentCoin and the coins after it
if (coin >= currentCoin)
{
//copy the list so we can branch from it
List<Integer> copyOfCoinsUsed = new ArrayList<Integer>(coinsUsed);
//add on one of our current coins
copyOfCoinsUsed.add(coin);
//branch and then collect successful attempts
successes += change(copyOfCoinsUsed, coin, amountSoFar + coin, amountToChange);
}
}
//pass back the current
return successes;
}

Categories

Resources