Creating boats in battleship game - java

I am creating a battleship game in one of my classes. I am having trouble on creating the "PTBoat" and placing it on the screen. I have a 10x10 board and need help creating an initializing the boats. The size of the PTBoat needs to be 2 spots on the board. I think I have the random direction, column, and row figured out but am stuck on how to call it in the board class. The first portion is the PTBoat class and the second half of code is the Board Class. The main method has been fully written for me so I did not include that.
/**
* Class for the PT Boat of the Battleship Game.
* Superclass: Ship
* Subclasses: none
* Attributes: String name
* int charges;
* name = "PT Boat"
* size = 2
* charges - number of depth charges on this PT Boat
* You must declare the attributes, complete the constructors and
* write any necessary getters and setters
*/
public class PTBoat extends Ship
{
// instance variables
public String PTBoat;
public int charges = 2;
public int size = 2;
/**
* Constructors for objects of class Carrier
*/
public PTBoat(String name, int size)
{
}
public PTBoat(int row, int col, int dir)
{
row = (int)(Math.random() * 10 + 1);
col = (int)(Math.random() * 10 + 1);
dir = (int)(Math.random() * 2 + 1);
}
}
/**
* Board class for the Battleship game.
*
* A board is an nxn array containing one each of: Carrier
* Battleship
* Destroyer
* Submarine
* PTBoat
*/
import java.util.Scanner;
public class Board
{
// class variables
// If the number of ships is changed, the constructor must be
// updated as well
// When debug is true, positions of ships will be shown when the
// board is displayed. This is helpful when testing the game since
// you won't have to guess the ships' locations.
final static boolean debug = true;
final static int board_size = 10;
final static int num_ships = 5;
// Characters printed when the board is displayed. Not all are used.
final static char hit = 'H';
final static char miss = 'M';
final static char used = 'S';
final static char blank = ' ';
final static char sunk = 'X';
// instance variables - replace the example below with your own
private char[][] board = new char[board_size][board_size];
private int num_sunk;
private Ship[] ships = new Ship[num_ships];
private Scanner scanIn;
/**
* Default constructor for objects of class Board
*/
public Board(Scanner s)
{
// initialise instance variables
scanIn = s;
num_sunk = 0;
initializeBoard();
// create the ships
ships[0] = new PTBoat();
hideShip(0);
ships[1] = new Submarine();
hideShip(1);
ships[2] = new Destroyer();
hideShip(2);
ships[3] = new Battleship();
hideShip(3);
ships[4] = new Carrier();
hideShip(4);
}

You have some misconceptions for the class PTBoat, let's start with a few:
One of the attributes should be the name of the ship, in this case, "PT Boat", but you defined this:
public String PTBoat;
So your variable is named PTBoat, the same that the class which is wrong. It should be named "name", like this:
public String name;
The first constructor has two arguments so when called it will be used to give values to the related attributes, like this:
public PTBoat(String name, int size)
{
this.name = name;
this.size = size;
}
The second constructor looks like it's intended to set up the attributes row, col and dir, that you should define in the class. With your code you are reassigning the value of the variables that you receive, which is useless. Later when you instantiate the ship from the Board you should use one of the constructors like this:
ships[0] = new PTBoat("MyAwesomePTBoat", 2);
In your instructions is also mentioned that you need to create getters and setters, so your variables look like they should be private, not public. A getter is a simple method that returns the value of the variable, a setter is used to set the value to a value given. Those methods are public so they can be called from outside the class where they are defined.
Anyway, I would recommend you have a look at any basic Java tutorial to understand better all those concepts.

Related

How do I test my method in another class?

I just started taking Computer Science (Java) about 5 weeks ago and I am still having trouble creating methods. I was assigned to create an NFL statistic class and then create a method to show a calculation. Everything went smooth until I went to call my method in a test class. What seems to be missing here?
NFLPlayer CLASS (Containin the method):
private int touchdowns;
private int interceptions;
private int passingAttempts;
private int completedPasses;
private int passingYards;
private int runningYards;
private int recievingYards;
private int tackles;
private int sacks;
// Method for Quarterback rating
public double QBRating(int touchdowns, int passingAttempts, int completedPasses,
int passingYards, int interceptions) {
double a = (completedPasses / passingAttempts - 0.3) * 5;
double b = (passingYards / passingAttempts - 3) * 0.25;
double c = (touchdowns / passingAttempts) * 25;
double d = 2.375 - (interceptions / passingAttempts * 25);
double ratingQB = ((a + b + c + d) / 6) * 100;
{
return ratingQB;
}
}
Now here is my test class where I am having trouble displaying my calculations
class MyTest {
public static void main(String[] args) {
NFLPlayer playerStats = new NFLPlayer();
//Player1 finding quarterback rating
int touchdowns = 2;
int passingAttempts = 44;
int passingYards = 285;
int interceptions = 1;
int completedPasses = 35;
// Call QB rating method
playerStats.QBRating(touchdowns, passingAttempts, completedPasses,
passingYards, interceptions);
System.out.println(QBRating);
}
}
Instead of passing so many int arguments (easy to mix them up) to your method you could give your NFLPlayer class private fields for each value:
public class NFLPlayer {
private final String name;
private int touchdowns;
private int passingAttempts;
private int completedPasses;
private int passingYards;
private int interceptions;
public NFLPlayer(String name) {
this.name = name;
}
// Method names start with a lower case character in Java
// The name should usually be an imperative 'do something' not a noun ('something')
// although there are exceptions to this rule (for instance in fluent APIs)
public double calculateQbRating() {
double a = (completedPasses / passingAttempts - 0.3) * 5.0;
double b = (passingYards / passingAttempts - 3.0) * 0.25;
// an AritmeticException will occur if passingAttempts is zero
double c = (touchdowns / passingAttempts) * 25.0;
double d = 2.375 - (interceptions / passingAttempts * 25.0);
return ((a + b + c + d) / 6.0) * 100.0;
}
public String getName() {
return name;
}
// setter for the touchdowns field
public void setTouchdowns(int value) {
touchdowns = value;
}
// TODO: add other setters for each private field
#Override
public String toString() {
return String.format("Player %s has QB rating %s", name, calculateQbRating());
}
}
Your application (this is not called a test):
class NFLApplication {
public static void main(String[] args) {
NFLPlayer playerStats = new NFLPlayer("johnson");
playerStats.setTouchdowns(2);
playerStats.setPassingAttempts(44);
playerStats.setPassingYards(285);
playerStats.setInterceptions(1);
playerStats.setCompletedPasses(35);
double qbRating = playerStats.calculateQbRating();
System.out.println(qbRating);
}
}
A test for your NFLPlayer class using the JUnit framework (JUnit is usually included by default within your IDE):
public class NFLPlayerTest {
// instance of the class-under-test
private NFLPlayer instance;
// set up method executed before each test case is run
#Before
public void setUp() {
instance = new NFLPlayer();
}
#Test
public void testCalculateQbRatingHappy() {
// SETUP
instance.setTouchdowns(2);
instance.setPassingAttempts(44);
instance.setPassingYards(285);
instance.setInterceptions(1);
instance.setCompletedPasses(35);
// CALL
double result = playerStats.calculateQbRating();
// VERIFY
// assuming here the correct result is 42.41, I really don't know
assertEquals(42.41, result);
}
#Test
public void testCalculateQbRatingZeroPassingAttempts() {
// SETUP
// passingAttempts=0 is not handled gracefully by your logic (it causes an ArithmeticException )
// you will probably want to fix this
instance.setPassingAttempts(0);
// CALL
double result = playerStats.calculateQbRating();
// VERIFY
// assuming here that you will return 0 when passingAttempts=0
assertEquals(0, result);
}
}
This test class should go in your test source directory (normally in yourproject/src/test/yourpackage/). It requires some imports which should be easily resolvable within the IDE since JUnit is usually available by default.
To run the test, right click on it and select something like 'Run test', 'Test file' or the like, depending on which IDE you are using (IDE's are development tools such as Eclipse, NetBeans or IntelliJ). You should see some test output indicating if the test succeeded (green) or if there were failures (red). Having such tests is useful because it forces you think about your design and write better code. (testable code is usually better than hard-to-test code) and because it warns you if new changes cause bugs in existing code (regression).
EDIT:
To create two players with different stats you have to create two instances (I added a name field so we can more easily distinguish the players):
NFLPlayer player1 = new NFLPlayer("adams");
NFLPlayer player2 = new NFLPlayer("jones");
And give them each their own statistics:
player1.setTouchdowns(2);
player1.setPassingAttempts(4);
player1.setPassingYards(6);
player1.setInterceptions(8);
player1.setCompletedPasses(10);
player2.setTouchdowns(1);
player2.setPassingAttempts(3);
player2.setPassingYards(5);
player2.setInterceptions(7);
player2.setCompletedPasses(9);
You could even create a list of players:
List<NFLPlayer> players = new ArrayList<>();
players.add(player1);
players.add(player2);
And then you could for instance print out all player ratings in a loop:
for(NFLPlayer player : players) {
// this uses the `toString` method I added in NFLPlayer
System.out.println(player);
}
you should not call the method name inside SOP instead System.out.println(playerStats.QBRating(touchdowns, passingAttempts, completedPasses,
passingYards, interceptions));
or override toString() method in your class and assign the method call to a local variable and print the value.
Also use some frameworks(Junit) instead of writing stubs

Creating a player class that can be used by two different games

I have to write some classes for snakes and ladders and tic tac toe.
I am trying to create a Player class which is the super class of Player_Piece and Player_Symbol.
Player class has to: Create the player objects, stores the player object states:Name,Score.
Player_Piece has to assign the color and position to the objects which is the player piece on the game board of snakes and ladders. It also has to move the pieces
Player_Symbol is the class for the tic tac toe game it assigns and holds the players symbol, (either a nought or a cross) and positions.
I am not sure if I have done these classes correctly and I would appreciate some advice on anything I should change. I am very new to java and I have been thrown into the deep end with this
Player Class
public class Player {
private String PlayerName;
public Player(String name) {
PlayerName = name;
}
/**
* This set method sets the name of the player.
*
* #param Takes in a String as name.
*/
public void setName(String name) {
this.PlayerName = name;
}
/**
* This get method returns the String value of player name.
*
* #return PlayerName, a String value.
*/
public String getName() {
return PlayerName;
}
}
Player_Piece Class
public class Player_Piece extends Player {
// class constants
// Colors for the players piece
public static final String BLUE = "Blue";
public static final String RED = "red";
public static final String YELLOW = "Yellow";
public static final String BLACK = "Black";
// Types for each players piece.
public static final String PLAYER1PIECE = "player one's piece";
public static final String PLAYER2PIECE = "player two's piece";
public static final String PLAYER3PIECE = "player three's piece";
public static final String PLAYER4PIECE = "player four's piece";
// fields
private String color;
private String type;
private int row;
private int column;
// constructors
/**
* Constructs a new player piece with a colour and type at the given position.
* #param color The piece's color must be one of the following: BLUE, RED, YELLOW or BLACK.
* #param type The piece's type must either PLAYER1PIECE, PLAYER2PIECE, PLAYER3PIECE, PLAYER4PIECE.
*/
public Player_Piece(String color, String type, int row, int column) {
this.color = color;
this.type = type;
this.row = row;
this.column = column;
}
// methods for the class
/**
* Returns this players piece color.
* #return the color; either BLUE, RED, YELLOW or BLACK.
*/
public String getColor() {
return this.color;
}
/**
* Returns this player piece's type.
* #return the type; either PLAYER1PIECE, PLAYER2PIECE, PLAYER3PIECE, PLAYER4PIECE.
*/
public String getType() {
return this.type;
}
/**
* Returns this player's piece row position.
* #return the position of the piece.
*/
public int getRow() {
return this.row;
}
/**
* Returns this player's piece column position.
* #return the position of the piece at the column
*/
public int getColumn() {
return this.column;
}
/**
* Returns a String of this piece.
* #return a three letter String, such as "P1P" for player one's piece.
*/
public String toString() {
return this.type.substring(0, 1);
}
/**
* Moves the piece to the position.
*
* #param row The row position for the piece to move to.
* #param column The column position for the piece to move to.
*/
public void move(int row, int column) {
this.row = row;
this.column = column;
}
}
Player_Symbol Class
public class Player_Symbol extends player {
private String symbolChoice;
private int[][] symbolPosition;
public void setSymbol (String symbol) {
this.symbolChoice = symbol;
}
public void setSymbolPos(int[][] position) {
this.symbolPosition = position;
}
public String getSymbol() {
return symbolChoice;
}
public int[][] getSymbolPos() {
return symbolPosition;
}
}
I don't know what do you expect from our answers. But if you wanna know how to create good structure of your app. There are some points related to Java.
Inheritance is not so good pattern. If you have really many same attributes use it. It is rather useful for extending some existing components.
What is important and useful is interface. For example you need methods getName, getScore, saveState etc. You create interface with these methods and then implemet it in your classes.
Encapsulation is also important, your attributes should be private if not necessary to be protected or public.
OOP - Use static attributes and methods only if it is good in that situation. For example library of math operations or logging.
MVC (Model View Controller) - You should separate logic, user interface and collecting user actions.
You can also look at some patterns like singleton or decorators.
You wrote you are new to Java so I hope you understand it.
In future your app could have structure like this:
Entity classes mapped from your database tables
DAO classes for accessing database (CRUD operations)
Service classes contaning main logic of your app
Controller classes that should colletct actions
from user and validate data.
UI - user interface, it depends if it is web app(jsp, jstl, jsf) or desktop app (swing, fx)
Of course there are many alternatives, that depends on your requirements and technology.
The inheritance is not a good idea. Player_Piece extends Player implies 'a player's piece is a player', in other words 'a pawn is a human'. The fact that this is not a good representation of the real world is not even the worst part; my biggest concern is the fact that you are introducing 'code smell'.
The subclasses combine multiple responsibilities: name and position. This may sound like a total non-issue since the two responsibilities are so small. What harm is there in combining the two? Well, in my experience, every maintenance nightmare started out small. Refactor while it is still easy to do so; the longer you wait, the bigger the pain. In general, it is a violation of the single responsibility principle. For this specific case, here's why this is bad.
Lifetime
Name and position are likely to have different lifetime. Position only has meaning for the duration of a single game, whereas name could persist across multiple games. This is typically a sign that there should be two different objects.
Reusability
Position is not only relevant for the player, but also for the snakes and the ladders. Right now, position is implemented in class Player_Piece by two integer properties row and column. Move these properties to a separate class Position and you will soon find that the snakes and the ladders benefit from this class too. If you don't, then you'll soon find some code duplication creeping in; obj1.row == obj2.row && obj1.column == obj2.column will become a recurring expression in your code. With the proper abstractions, this can be reduced to the more readable obj1 == obj2.
Talking of abstractions, please stop using strings for colors, types and symbols; enums are more appropriate.

How do I pull value from method designated with "this."

I have information like this:
xxx 0 1 2 ...
Name Fred0 Fred1 Fred2
Stamina 2 6 7
Intel 5 4 1
Heart 4 8 2
Speed 5 3 6
So, I was informed previously that creating a 2D ArrayList to store something like this is "archaic" and was provided with a different way to set my code up. The reason I was using ArrayList<> is because I want to be able to generate new racers as needed, rather than designating an array to a size. If I could just use a simple array this would have been done a week ago. Now I've been screwing with it for a week and I still don't get how it works.
public class test {
public String name;
private int stamina;
private int heart;
private int intel;
private int speed;
public ArrayList<String> racers = new ArrayList<String>();
private void racerInfo(String name) {
this.name = name;
this.stamina = (int) Math.floor(Math.random()*10);
this.heart = (int) Math.floor(Math.random()*10);
this.intel = (int) Math.floor(Math.random()*10);
this.speed = (int) Math.floor(Math.random()*10);
}
public void generate() {
for ( int i=0; i<=10; i++) {
String name = "Fred" + i;
System.out.println(name);
racerInfo(name);
racers.add(name);
}
}
public int getStamina() {
return this.stamina;
}
public int getHeart() {
return this.heart;
}
public int getIntel() {
return this.intel;
}
public int getSpeed() {
return this.speed;
}
}
public class main {
public static test test = new test();
public static void main(String[] args) {
test.generate();
//Put stuff here to pull stamina of Fred2 for example.
}
}
Now, in the main class. How would I do something that should be relatively simple like pulling the Stamina value for Fred2.
I've been following the exact directions I've been given by others here to write most of this code. But at this time, I'm getting to the point of just re-writing it all so that each stat (name, stamina, intel, speed, etc.) is just logged as a separate ArrayList<>. But I can't figure out how to make a 2D ArrayList containing the original ArrayLists ie.
ArrayList<String> name = new ArrayList<String>();
ArrayList<Integer> stamina = new ArrayList<Integer>();
ArrayList<ArrayList<Object>> arrayOfArray = new ArrayList<ArrayList<Object>>();
Yes, I know the arrayOfArray is probably done wrong, but, again, I just get told it's Archaic and nobody'll tell me how I can do it right so I can just go. arrayOfArray.get(2,1) and pull information that I want/need.
Sorry for the information overload here. but I'm trying to just find the best possible solution for what I want to do. If you can tell me how to correctly pull off either way I will be eternally grateful you you and all of your descendants.
First of you should refactor your class test to class Racer, which is a meaningful name and follows the convention to start classnames with an uppercase letter. Furthermore you should add Stamina, Intel, Heart and Speed to the constructor:
public Racer(String name, int stamina, int intel, int heart, int speed) {
this.name = name;
this.stamina = stamina;
this.intel = intel;
this.heart = heart;
this.speed = speed;
}
Now you can create your racer as following:
Racer fred2 = new Racer("Fred2", 7, 1, 2, 6);
You can store your values in a HashMap. HashMap is a collection consisting of key-value pairs. For the key you can use a string (the name of the racer) and as value you take an instance of your class Racer:
HashMap<String, Racer>() racerMap = new HashMap<>();
racerMap.put("Fred2", fred2);
This you can do in a for-loop for all of your racers. Now you can get the racer objects from your HashMap by calling the getMethod and putting the name as parameter in it. This will return an object of class Racer and you can call the getter methods on this object:
racerMap.get("Fred2").getSpeed();
or
racerMap.get("Fred2").getIntel();
Edit: I just saw your generate method. This method should return the HashMap of racers. In your main method you create a new HashMap:
HashMap<String, Racer> racerMap = generate();
Now you can use the map as described above.

(Simple) Add different types to ArrayList <class>

So I need to get the int and the boolean into the contractor so I can calculate different things through methods. Is there a way I could do this through an ArrayList, or two. I just need help getting it there!
Thank you for any help.
Main Method:
import java.util.ArrayList;
public class Tester
{
public static void main(String[] args)
{
ArrayList<Contructor> cO2 = new ArrayList<Constructor>();
// add households to the arraylist
CO2FromWaste homeData = new CO2FromWaste();
cO2.add();
for(Contructor dataRecord : cO2)
{
dataRecord.calcGrossWasteEmission();
dataRecord.calcWasteReduction();
dataRecord.calcNetWasteReduction();
}
Constructor:
public class Contructor
{
private int myNumPeople;
private boolean myPaper, myPlastic, myGlass, myCans;
private double myEmissions, myReduction, myNetEmissions;
/**
* Constructor for objects of type CO2FromWaste
* #param numPeople number of people in a household
* #param paper whether or not paper is recycled
* #param plastic whether or not plastic is recycled
* #param glass whether or not glass is recycled
* #param cans whether or not cans are recycled
*/
Contructor(int numPeople, boolean paper, boolean plastic, boolean glass, boolean cans)
{
myNumPeople = numPeople;
myPaper = paper;
myPlastic = plastic;
myGlass = glass;
myCans = cans;
myEmissions = 0.0;
myReduction = 0.0;
myNetEmissions = 0.0;
}
You were almost there. The ArrayList#add method takes an Object as parameter. In this case, your Object is a CO2FromWaste.
ArrayList<CO2FromWaste> cO2 = new ArrayList<CO2FromWaste>();
CO2FromWaste homeData = new CO2FromWaste();
cO2.add(homeData);

How to add a runner to an array of results

I have been trying to figure out how to add runner information into an array of runner information. It should contain at most 100 runners.
This is part of a larger project that must fulfill these requirements:
Operations (methods):
• A constructor that takes in a race name and distance.
• Getters and setters for both the name and distance instance variables.
• Method to return the count of the number of RunnerResult objects added to the array.
• Method to add a RunnerResult to the array (given an instance of Runner and the runner’s finishing time).
• Methods to get a RunnerResult object; one that takes in the position in which the RunnerResult was added (to directly access the object from the array) and one that takes in a runner name (to use to search for the matching runner). The first runner’s index is 0, the second is 1, etc.
• A method with conditional logic to give a count of all runners for a certain category (youth, adult, senior, male, female, all) triggered by a flag passed in as a whole number (1, 2, 3, 4, 5, 6, respectively, implemented as public constants). A similar method provides the average race result (time to finish race) for each potential category.
• A method with conditional logic finds runners with a race time less than the specified minutes per mile. For example, find all runners who finished the race with a time of less than 8 minutes per mile.
• A toString method that simply gives the race name, race distance, a count of total runners in the race, and the average time of all runners in the race.
So far, this is what I have:
public class Race
{
// instance variables
private String name;
private double distance;
private int nextPos;
private RunnerResult [] results;
// public constants
/**
* Flag to signify YOUTH.
*/
public static final int YOUTH = 1;
/**
* Flag to signify ADULT.
*/
public static final int ADULT = 2;
/**
* Flag to signify SENIOR.
*/
public static final int SENIOR = 3;
/**
* Flag to signify MALE.
*/
public static final int MALE = 4;
/**
* Flag to signify FEMALE.
*/
public static final int FEMALE = 5;
/**
* Flag to signify ALL.
*/
public static final int ALL = 6;
/**
* Array limit.
*/
public static final int MAX_COUNT = 100;
/**
* Constructor for objects of class Race.
*
* #param inName the race name.
* #param inDist the distance of the race.
*
*/
public Race(String inName, double inDist)
{
// initialize the instance variables and
// empty array of results, initalize nextPos
this.name = inName;
this.distance = inDist;
RunnerResult[] results = new RunnerResult[100];
}
/**
* Set the race Name.
*
* #param inName the race name.
*
*/
public void setName(String inName)
{
this.name = inName;
}
/**
* Get the race Name.
*
* #return String The race name.
*
*/
public String getName()
{
return this.name;
}
/**
* Set the race distance.
*
* #param inDist the distance of the Race.
*
*/
public void setDist(double inDist)
{
this.distance = inDist;
}
/**
* Get the race distance.
*
* #return double the distance of the race.
*
*/
public double getDist()
{
return this.distance;
}
/**
* Add a runner to the results
* (runners are NOT entered in order of finish).
*
* #param inChip the runner's chip id.
* #param inRunner a Runner object.
* #param inStart the start time for the runner.
* #param inEnd the end time for the runner.
*
*/
public void addRunner(String inChip, Runner inRunner, Time inStart, Time inEnd)
{
if (this.nextPos < MAX_COUNT)
{
// set the instance field element to a "copy" of passed-in object
// add to array, increment counter
for(int i = 0; i < results.length; i++);
{
RunnerResult[] results = { copyinChip, copyinRunner, copyinStart,
copyinEnd };
i++;
}
}
}
}
I just cannot figure out how to get these values into the array. (I get an incompatible type error. Any input would be greatly appreciated.
two things here.
1.) when you re-declare results, you are not referencing the same object that you declare as a field, but an entirely new object that then has no purpose, because it only lives within addRunner.
2.) When you assign results = { ---, ---, ---, ---}; You aren't adding a new runner to the array. Rather, you are reassigning the entire array every single time you do that loop. You would want to create a new RunnerResult object, add the necessary data to it, and then put that at results[];
An example here:
public void addRunner(String inChip, Runner inRunner, Time inStart, Time inEnd)
{
if (this.nextPos < MAX_COUNT)
{
// set the instance field element to a "copy" of passed-in object
// add to array, increment counter
for(int i = 0; i < results.length; i++);
{
results[i] = new RunnerResult(<your params>);
}
}
}

Categories