Java Shooting targets - java

I have been working on this for almost one week. The question is mainly about shooting the target. So we ask the user to input v0, degree, x0, and y0. We will be setting two targets(500,0)&(1000,0).
I think I did all the methods correctly except for the main methos.
The question I am having now is I have no idea about how to put the "return"s back to the main method.(For example, I got the time and I returned it, but how can I output "The time it took to get to the groud is +time+".
It is my first time working with method questions, I would be happy to see some advice!!
Also I've been told to give the user 4 chances to play this game and give the user to choose whether they are going to start again or exit. I saw many people useing boolean to work this part, but I have no idea about how to use it.
The following is what I got so far:
import java.io.*;
public class AngryBirdGame{
public static void main(String[] args) throws IOException{
int vo,degree = 0,xo = 0,yo = 0;
System.out.println("This game is the Angry Bird Game. You will be trying to hit the target.");
System.out.println("One of the targets of the game is (500,0)");
System.out.println("The other target of the game is (1000,0)");
System.out.println("Please enter the initial velocity");
vo=velocity();
System.out.println("Please enter the angle of elevation(0-90 degrees)");
degree=degree(degree);
System.out.println("Please enter the horizontal starting point(50-500)");
xo=horizontal(xo);
System.out.println("Please enter the vertical starting point");
yo=vertical(yo);
result(0);
}

In order to allow the user to play multiple games, you need a loop in your main() method. Also, as a matter of organization, it would be convenient to define a class that encapsulated all the data the user needs to provide to get a game started. (The class AngryBirdGame probably works just fine for that.) You can then extract all the logic for obtaining the user's input into a separate method that returns an instance of the game data class, or null if the user doesn't want to play any more. Similarly, you should define a method that returns the result of the game so you can report the result to the user each time through the loop.
Finally, my guess is that your input variables should be floating point numbers (or maybe even double) rather than int values. It's hard to do trajectory calculations accurately using integer values only.
Putting all that together, here's an outline of what it might look like:
public class AngryBirdGame {
float vo, degree, xo, yo;
public static void main(String[] args) {
printOneTimeIntro();
Scanner in = new Scanner(System.in);
for (int i = 0, AngryBirdGame game = getGameInfo(in);
i < 4 && game != null;
i++, game = getGameInfo()) {
float time = game.play();
System.out.format("The time it took to get to the ground is %f%n", time);
}
}
/**
* A static method to print a one-time introduction to the program.
*/
private static void printOneTimeIntro() {
System.out.println("This game is the Angry Bird Game. You will be trying to hit the target.");
}
/**
* A static method to check whether the user wants to play and, if so,
* to collect all the game info.
*
* #return a game object, or {#code null} if the user no longer wants to play.
*/
private static AngryBirdGame getGameInfo(Scanner in) {
// first check if the user wants to play
System.out.println("Do you want to play (y/n)? ");
String input = in.next();
if (input.toLowerCase().startsWith("n")) {
return null;
}
// if so, create a game object and get all the input
AngryBirdGame game = new AngryBirdGame();
System.out.println("One of the targets of the game is (500,0)");
System.out.println("The other target of the game is (1000,0)");
System.out.println("Please enter the initial velocity");
game.v0 = in.nextFloat();
// TODO: get rest of input
return game;
}
/**
* An instance method that plays the game once everything is initialized.
*
* #return the time it takes for the trajectory to complete
*/
private float play() {
float time;
// TODO: calculate the game time to reach the ground
return time;
}
}
Note that if you want to return more information than just the trajectory time, you might want to define a second class to contain everything you want returned and use that as the return value from play().

Related

OOP Ticket Price Program

So this one is a bit lengthy. I'm trying to finish off a program where ticket price varies depending on purchase date. I need the Tester.Java to take the info from the objects, and output the proper price depending on the ticket type. I have already set a set of if statements in the Tester, but I am now at an impass on how to finish this program off. I will paste my code below.
Tester (contains the main method):
package tester;
import java.util.Scanner;
public class Tester extends Ticket{
/**
* #param args the command line arguments
*/
public static void main(String[] args){
Scanner db = new Scanner(System.in);
Ticket firstTicket = new Ticket();
System.out.println("The first ticket: "+firstTicket.toString());
int x = 0;
while(x!=2){
if(x==2){
System.out.println("Goodbye.");
}
else{
System.out.println("What type of ticket are you purchasing?");
System.out.println("1.Walk Up");
System.out.println("2.Advance");
System.out.println("3.Student Advance");
int t = db.nextInt();
if(t==1){
}
if(t==2){
}
if(t==3){
}
}
System.out.println("Do you need another ticket?");
x= db.nextInt();
}
}
}
Ticket (Super class):
package tester;
import java.util.Scanner;
public class Ticket {
public int ticket;
public double price;
/**
* holds default values for ticket number and price
*/
public Ticket(){
super();
this.ticket=1;
this.price=15.0;
}
/**
* Stores the values for ticket number and the price, based upon ticket type
* #param ticket
* #param price
*/
public Ticket(int ticket, double price){
this.ticket=ticket;
this.price=price;
}
/**
* returns the value of price
* #return price
*/
public double getPrice(){
return price;
}
#Override
public String toString(){
return "Ticket #" + ticket + " Ticket price: $"+ price;
}
}
Walkup Ticket:
package tester;
/**
*
* #author dylan
*/
public class WalkupTicket extends Ticket{
/**
* holds the price of a walkup ticket 50$
*/
public WalkupTicket(){
this.price=50;
ticket++;
}
}
Advance Ticket:
package tester;
import java.util.Scanner;
public class AdvanceTicket extends Ticket {
/**
* stores the values of an advance ticket, depending on how many days before
* the event it is purchased
*/
public AdvanceTicket(){
Scanner db = new Scanner(System.in);
System.out.println("How many days before the event are you purchasing your ticket?");
int days = db.nextInt();
// days before is 10 or less days
if(days >= 10){
price=30;
ticket++;
}
// days before is more than 10
else{
this.price=40;
ticket++;
}
}
}
Student Advance Ticket:
package tester;
import java.util.Scanner;
public class StudentAdvanceTicket extends AdvanceTicket{
/**
* stores the values of an advance ticket, depending on how many days before
* the event it is purchased, with student discount.
*/
public StudentAdvanceTicket(){
Scanner db = new Scanner(System.in);
System.out.println("How many days before the event are you purchasing your ticket?");
int days = db.nextInt();
System.out.println("Are you a student?");
System.out.println("1. Yes");
System.out.println("2. No");
int stud = db.nextInt();
// days before is 10 or less days
if(days >= 10 && stud == 1){
price=15;
ticket++;
}
// days before is more than 10
if(days <= 10 && stud == 1){
this.price=20;
ticket++;
}
}
}
I feel like I'm making a simple mistake, but I am new to OOP so I'm having bit of trouble with this.
Are you supposed to be saving a total for all tickets bought or just the one ticket at a time total?
For walk-up tickets you don't have to do anything. Its a flat $50 total.
For Advance and StudentAdvance you would create a new object of that type and the way you have it the constructor will display the menu for how many days in advance and what not. You can then get the total from that.
As for the structure of your code it is not ideal. The object's constructor should not have all that code in it. They should have a ShowMenu function that will display the menu to the user and read their input. The constructor should be blank for the most part.
You also don't need three different ticket objects. One ticket object should be able to handle all this by itself. The ticket object can show the menu and handle the different prices based on user input. If you need to save a total or the different tickets you can have an array of ticket objects on the main method. You can then loop through that array to display or sum the tickets.
Hope this helps.
Your question is pretty broad, but well, some thoughts on your input:
Names matter. It is good that you made a first step and that you are using a specific package (instead of the default package); but tester says nothing. You could call it dylan.tickets for example: to make clear A) its your thing and B) it is about that ticket system
It seems that you are serious about your work, thus: do not use a static main to drive testcases. Using JUnit and simple testcases is really easy. And beyond that: driving tests "manually" using a main is cumbersome and error prone. Unit tests are almost automatically automated.
More importantly: tests that just print something are almost useless. If your code behaves unexpectedly, you might only notice when you carefully check that printed output. As said: use unit tests, and Junit assert calls to check expected versus actual results of method calls. Because then you will be told when you make changes that break functionality which was previously working.
You absolutely avoid to ask for user input in so many different places. Meaning: the reasonable thing is that a class has a constructor or setter methods; and that all the arguments required to instantiate the new object are given to that object. If at all, your main uses a scanner and asks the user for input. But all your "business logic" objects do not require any "user interaction" at all. You see, you actually want to start the whole project without using a scanner. You want to hardcode things like AdvancedTicket at = new AdvancedTicket(100); - because now you can easily code all kinds of different objects; and start your program again and again. Your current solution requires you to enter all such data manually ... every time you re-start your program! So: no scanner usage in constructors. Never!
Then: good OO is about behavior, not about state. Meaning: you dont use public fields to spread information. If at all, your fields should be protected; but even that is most often not a good idea. You want to isolate your classes from each other ...
The core problem: it seems that nobody told you yet about FCoI. You should favor composition over inheritance. Meaning: you dont just put A extends B everywhere. There is absolutely no reason that your Tester class extends Ticket. The tester is a Tester, not a ticket!
As said: that last point is the most important one. You are careful about making A a subclass of B; very often, it is more appropriate to maybe have A own a B object, but not to make A a B!

Beginning Java: Utilizing user's input

I am new to learning Java and in my class i have an assignment ive been struggling with:
You need to create three classes: Duck, Dog, and DuckDogApp. DuckDogApp would use Duck and Dog objects. You may use three separate different files or just one file to contain three classes. Your program:
1.Prompt a user to input “duck” or “dog” from keyboard (ask a question)
The output should display “Quack! Quack!” if the user’s input is “duck”, and followed by a new question “dog or duck?” and give a program to end the program
If the user chooses to end the program, then game is over. If the user’s input is “dog”, next prompt should be: “what size is your dog?”
if the user’s input is negative or 0, the program would tell the user to enter a correct number:
once the user typed in a number and hit enter:
-the output should be “Yip! Yip! Yip!” if the number is between 1 and 14;
-the output should be “Ruff! Ruff! Ruff!” if the number is between 15 and 59;
-the output should be “Woof! Woof! Woof!” if the number is more than 60.
End of the program
If the user input is “dog”, output should follow the step 2.
I am having difficulties understanding what to do next or if what i have is even right. I dont know how to go about utilizing the users input from "what size is your dog" to the bark. This is my first Java class so again, im new- any tips would be greatly appreciated- im having difficulties getting the hang of it. So far this is my code:
import java.util.*;
class Duck{
}
class Dog{
private int size;
public int getSize(){
return size;
}
public void setSize(int n){
size=n;
}
public void bark(){
if (size>60){
System.out.println("Woof! Woof!");
}
else if (size>14){
System.out.println("Ruff! Ruff!");
}
else{
System.out.println("Yip! Yip!");
}
}
}
class DogDuckApp{
public static void main (String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Dog or Duck?");
String userinput = input.nextLine();
/*If user inputs dog (disregarding case) it will ask what size the dog is*/
if("Dog".equalsIgnoreCase(userinput))
{
System.out.println("what size is your dog?")
}
}
/*If user inputs duck (disregarding case) it will display Quack! Quack!*/
if("Duck".equalsIgnoreCase(userinput))
{
System.out.println("Quack! Quack!");
}
}
}

Making a program repeat within itself, but you can't make a method(?): Java

I have a project for my computer science class and we're making battleship. Part of the program is that we have make sure that the piece the player puts down does not go off of the board.
I've made a method to check to see whether it goes off the board:
private static boolean test(String s, int row, int column,int spaces)
{
if(s.equals("right")&&column+5<=10)
{
return true;
}
if(s.equals("up")&&row-spaces>=0)
{
return true;
}
if(s.equals("left")&&column-spaces>=0)
{
return true;
}
if(s.equals("Down")&&row+spaces<=10)
{
return true;
}
return false;
}
But once I've gotten it to print out an error message, I'm not sure how to make it so that the program can re-recieve the new position for the piece, without putting an if statement in and if statement in an if statement (and on and on), because you need to check the new position to make sure it doesn't go off of the board.
Here is the part where I get the position of the playing piece (although I don't think you need it)
Scanner sonic= new Scanner(System.in);
System.out.println("Please input the row where you want the aircraft carrier (5 spaces) to begin: ");
int beginrow = sonic.nextInt();
System.out.println("Please input the column where you want the aircraft carrier (5 spaces) to begin: ");
int begincolumn = sonic.nextInt();
System.out.print("Please input what direction (up, down, left, right) \nyou want your battle ship to face, making sure it doesn't go off of the board.");
String direction = sonic.next();
And here's one of the if statements that I use to check/place the pieces
if(direction.equals("left")&&test("left",beginrow,begincolumn,5))
{
for(int i = beginrow; i>beginrow-5; i--)
{
battleship[begincolumn-1][i-1] = ('a');
}
}
else if(!test("left",beginrow,begincolumn,5))
{
System.out.println(" ");
System.out.println("*****ERROR: your piece goes off the board, please re-enter your position and direction*****");
}
This may be a duplicate, but I didn't know how to reword my search to find what I wanted. (So if anyone could direct me to the right article, that'd be nice as well)
What you should do is split your code appropriately into methods and call that methods repeatedly until your program is satisfied with the outcome.
For example:
create a method startGame() which has the job call methods getting user input until satisfied
make a method to request the user to input all the different ships and other required data
That might look something like
public void startGame() {
// do some setup
while(!requestShipInput()) { // request ship data until the data is valid
System.out.println(" ");
System.out.println("*****ERROR: your piece goes off the board, please re-enter your position and direction*****");
}
// do some more ship setup
// get the actual playing started
}
public boolean requestShipInput() {
Scanner sonic= new Scanner(System.in);
System.out.println("Please input the row where you want the aircraft carrier (5 spaces) to begin: ");
int beginrow = sonic.nextInt();
System.out.println("Please input the column where you want the aircraft carrier (5 spaces) to begin: ");
int begincolumn = sonic.nextInt();
System.out.print("Please input what direction (up, down, left, right) \nyou want your battle ship to face, making sure it doesn't go off of the board.");
String direction = sonic.next();
if(direction.equals("left")&&test("left",beginrow,begincolumn,5)) {
for(int i = beginrow; i>beginrow-5; i--) {
battleship[begincolumn-1][i-1] = ('a');
}
return true; // valid ship data
}
return false; // invalid ship data
}
As a first step, separate input validation from taking the action based on that input - you already have the validation logic in a separate function, so this is easy. Then figure out what needs to be done in case of invalid input - in your case, you need to ask for new input until you get a valid position:
do {
System.out.println("Please input the row where you want the aircraft carrier (5 spaces) to begin: ");
beginrow = sonic.nextInt();
System.out.println("Please input the column where you want the aircraft carrier (5 spaces) to begin: ");
begincolumn = sonic.nextInt();
System.out.print("Please input what direction (up, down, left, right) \nyou want your battle ship to face, making sure it doesn't go off of the board.");
direction = sonic.next();
} while (!test(direction, beginrow, begincolumn, 5))
After that, you know you've got a valid position.
My next step would probably be to group the information required to describe a ship on the board (i.e. beginrow,begincolumn,direction, probably also size) in a separate Object - possibly named Ship.
I think you could pretty naturally use recursion here:
public void getInput() {
// scanner code to get input
if (!test("left",beginrow,begincolumn,5)) { // test failed
getInput()
return
}
// test succeeded, continue
}
You already have something to the limits of you board? If you execute the check first, you don't need to execute a cascade of if-else
if(!test(direction,beginrow,begincolumn,size))
{
System.out.println(" ");
System.out.println("*****ERROR: your piece goes off the board, please re-enter your position and direction*****");
} else {
// check for collision with already placed ships
}
Keep in mind that there is a chance to combine up/down and left/right. The calculation rules are nearly the same and you only have to decide if you have to look to the one or the other direction.

need to figure out how to manipulate the mutator to figure out a class according to professor, I am confusd on how to do that

I know we aren't suppose to post homework problems but I am having issues I have talked with him and after 45 minutes I am more confused then I was before he said that this was suppose to be confusing.
So we are working on making our own classes and one of them was making a class to later be used in a weight converter on other planets (mainly the Moon, Mercury, Venus, Jupiter and Saturn) I have managed to make the class (code below)
/*
* WeightConverter class
* Class Description - A Java class for converting weight on different plants
* Author: J. Wilson
* Date: 2/24/2015
* Filename: WeightConverter.java
*/
// class beginning
class WeightConverter {
//create the variable that stores the conversion rate
private double weightchange;
//the constructor
public WeightConverter(double weight){
weightchange=weight;
}
//accessor
public double smallstep(){
return weightchange;
}
//mutator for the needed variable
public void setweightratio(double number){
weightchange=number;
}
//and the method convert.
public double convert(double planet){
return planet*weightchange;
}
}
//end of class
but he added the stipulation that "In this WeightCalculator class, I expect you to use each method you created at least once.or lose a point for each one your don't use " I asked him how I go about it and after a 45 minute talk i'm more confused then before after he mentioned I can take my mutator and just manipulate that here is what I have currently and it works so far
/*
* WeightConverter on other planets
* Program Description - weightchanger
* Author: J.Wilson
* Date: 2/24/2015
* Filename: WeightCalculator.java
*/
//import statements
import java.util.*; //example
// class beginning
class WeightCalculator {
public static void main(String[] args ) {
//Declare variables area
WeightConverter test;
Scanner scan = new Scanner ( System.in );//reads what is entered into the keyboard by the user
double pounds;
//Program beginning messages to user here
System.out.println("Hello! Welcome to my weight converter program");
System.out.println();//blank space
System.out.println("Please enter your weight (in pounds): ");
pounds=scan.nextDouble();
WeightConverter moon = new WeightConverter(.167);
System.out.println("Your weight on the moon is " + moon.convert(pounds));
//Collect inputs from user or read in data here
//Echo input values back to user here
//Main calculations and code to
//Output results here
//End program message
System.out.println();
System.out.println("Hope you enjoyed using this program!");
}// end main method
}// end class
can anyone explain by what he means by using my mutator more than once? or in laymans terms how to go about doing it?
It sounds like you should be using setWeightRatio() each time you want to get the weight on a new planet.
You first created the moon object and set its weight and then later used that set weight in moon.convert()
Next you should setWeightRatio() to a different amount (for Jupiter or Venus or whatever) and that will set the weightChange variable to the new double you just passed in. Then when you use convert() it will access the new weightChange variable and compute based on that.
I would create a single planet object and then reset its weightChange variable through the mutator as necessary. Then use convert() between setting new weight ratio.
You professor said that you have to use all the methods in your class at least once, correct?
your setweightratio method is useless (this should be obvious, as you havent used it !). it sets the class variable weightchange to its input argument, but the same thing happens in the constructor, so you would not need to call it again.
You have two options:
You've already returned moon weight to the user. When the next planet is in question, keep your WeightConverter instance and call moon.setweightratio(ratio of Venus or whatever). Using moon.convert(pounds) will then use the new ratio.
Alternatively, remove the setweightratio method all together (so you don't get points off for not using it) and create WeightConverter objects for each planet. This is less elegant.

Getting a string from one class to write to a front screen class

I'm create an air traffic control system, where it generates a random amount of fuel and also a random amount of planes. I have these two elements done, however the issue is, in the output box it all shows and works perfectly. My issue is that I'm telling it, if there is no planes coming in to call the string no planes and if there is a plane then KLM. I can't get it to write to the main class with all the front end.
I've edited out some of the coding in the screen as I'm using Netbeans drag and drop front end:
enter public void StartSimulation()
{
Start pointer = new Start();
Plane incoming = new Plane();
//Needs a condition in here that checks if the plane and fuel has been
//Generated and also loop to keep up with the constant generated planes and fuel
jTextArea1.setText(incoming.planeName);
I have tried where the condition thing is the following:
if (incoming.nextPlaneLanding != 167) this generates the first thing over and over again in the output box. I've also tried setting a boolean in the plane class but again, it has had no effect even with the following condition around it. if (incoming.completed = true)
This is the stuff I have in my plane class:
class Plane
extends TimerTask
{
public int nextPlaneLoop = 0;
public int planes;
public int fuel;
public String planeName;
#Override
public void run()
{
if(nextPlaneLoop <=167)
{
//Currently only running 1 or 0 planes...
planes = (int) (Math.random()*((2-1)+1));
System.out.println("Random generated plane amount: "+planes);
System.out.println("Method called, one whole day loop");
//Adds to the plane in the airspace loop
nextPlaneLoop++;
System.out.println("Loop incrementing: "+nextPlaneLoop);
if(planes == 0)
{
System.out.println("No fuel is required as no planes are coming in");
planeName = "No incoming plane";
System.out.println("Planes name is: "+planeName);
System.out.println(" ");
}
else
{
//Amount of fuel
fuel = 30 + (int)(Math.random()*((120-30)+1));
System.out.println("Random fuel: "+fuel);
planeName = "KLM AirFrance";
System.out.println("Planes name is: "+planeName);
System.out.println(" ");
}
}
else
{
this.cancel();
System.out.println("Not in loop any more. End of day");
}
}
}
Can anyone suggest have to how to get the names to display on to the screen so I can then try and add them into a queue in the actual airport class.
I think the Observer pattern might work well for you. In Java, this is implemented via Observer and Observable.

Categories