(EDITED CODE)
I am having a bit of an issue I hope I can get some help on. Here are my conditions:
You are developing a program to keep track of team standings in a league. When a game is played, the winning team (the team with the higher score) gets 2 points and the losing team gets no points. If there is a tie, both teams get 1 point. The order of the standings must be adjusted whenever the results of a game between two teams are reported. The following class records the results of one game.
public class GameResult
{
public String homeTeam() // name of home team
{ /* code not shown */ }
public String awayTeam() // name of away team
{ /* code not shown */ }
public int homeScore() // score for home team
{ /* code not shown */ }
public int awayScore() // score for away team
{ /* code not shown */ }
// instance variables, constructors, and other methods not shown
}
The information for each team is stored by an instance of the class TeamInfo whose partial definition is below.
public class TeamInfo
{
public String teamName()
{ /* code not shown */ }
public void increasePoints(int points)
{ /* code not shown */ }
public int points()
{ /* code not shown */ }
// instance variables, constructors, and other methods not shown
}
The class TeamStandings stores information on the team standings. A partial declaration is shown below.
public class TeamStandings
{
TeamInfo[] standings; // maintained in decreasing order by points,
// teams with equal points can be in any order
public void recordGameResult(GameResult result)
{ /* to be completed as part (c) */ }
private int teamIndex(String name)
{ /* to be completed as part (a) */ }
private void adjust(int index, int points)
{ /* to be completed as part (B)/> */ }
// constructors and other methods not shown
}
And here is the actual question:
Write the method adjust. The method adjust should increment the team points for the team found at the index position in standings by the amount given by the parameter points. In addition, the position of the team found at index in standings should be changed to maintain standings in decreasing order by points; teams for which points are equal can appear in any order.
And here is what I have so far:
private void adjust(int index, int points)
{
int Score[] = new int[standings.length]
for ( int i=0; i < standings.length; i++)
{
Score[i] = points;
Arrays.sort(Score);
}
}
I realize this is very wrong and need a little guidance to solve this. Thank you!
Something like this should work:
private void adjust(int index, int points) {
// increase points of winning team
TeamInfo curr = standings[index];
curr.increasePoints(points);
// get the new score of the winning team
int points = curr.points();
// perform an insertion sort on the modified portion
int i = index;
while (i > 0 && standings[i-1].points() < points) {
// shift teams with lower scores rightwards
standings[i] = standings[i-1];
i--;
}
standings[i] = curr;
}
Basically, it just gets the winning team (curr) at the specified index parameter and increments its points. Since the list must be ordered by team points in descending order, just insert the team in their correct position after adjusting the points.
problem is :
for ( int i=0; i <= standings.length; i++)//here index out of bounds
{
Score[i] = index, points;//here
}
write like :
for ( int i=0; i <standings.length; i++)
{
Score[i] = points;
}
Here's how to adjust the points for a team in the standings.
private void adjust(int index, int points)
{
/* 'index' is by definition an index into the standings array
* 'points' is by definition how many points to give to the team at 'index'
* each TeamInfo object has a method called increasePoints()
* therefore, to increase the number of points for a team in the standings... */
standings[index].increasePoints(points);
}
make sense?
Now, to sort the standings in order of point value, I imagine the exercise wants you to do something that uses TeamStandings.teamIndex() in combination with the other methods in your TeamInfo class. But since the code is either hidden or not written yet, I can't do much more.
Related
I'm trying to create game achievements in Java. I have class Player and field int level. In game each time when player gets exp he can reach new level. How to trigger when player reaches a level 10?(without if operator because as I understand it's not correct to check all time on exp gain if player reaches level 10 or not. Becase if I will have more than one achievement?).
My suggestion is to use own event? I'm looking for correct way to perform this task.
package testMyAchievements;
public class AchievementTestMain {
private static class Player {
private int level = 1;
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
#Override
public String toString() {
return "Player{" +
"level=" + level +
'}';
}
}
public static void main(String[] args) {
Player player = new Player();
for (int i = 0; i < 100; i++) {
player.setLevel(player.getLevel() + 1);
/*how to trigger when player reaches a level 10?(without if operator)
* and say "You reached level 10!"*/
}
}
}
To be honest I don't think you can achieve what you're looking for without a conditional check. Your requirement is explicitly stating "If you get to level 10 then show an achievement". I think you're worried about the scaling of your achievement system. How about you build a hashmap. Where the key is the level and the value is the list of achievement(s) that are granted for that level?
Here is an example where you can have a hashmap pointing to a a singular achievement but ofcourse you can also use List<String> for multiple achievs.
If the level is contained in the hashmap then you show it's corresponding achievement.
Here is an example:
int level = 10;
Map<Integer, String> levelToAchievMap= new HashMap<>();
levelToAchievMap.put(10,"Congrats you've reached level 10");
if(levelToAchievMap.containsKey(level)){
System.out.println(levelToAchievMap.get(level);
}
I have a player which can feed a dog or chop a tree.
Below are the classes I have written:
public class Dog {
private int health;
public void feed(Food food){
health = health + food.getNutritionalValue();
}
}
public class Player{
public void feed(Dog dog, Food food) {
dog.feed(food);
}
Player and Dog both have methods that are "active".
Player feeds the dog and dog starts eating the food (I am not really sure if it is good to couple methods in this way).
On the other hand, I have tree. And player is able to chop the tree.
public class Player{
public void chop(Tree tree) {
//At this point I am not sure
}
I am not sure if I would use getters and setters of Tree class to interact with the Tree.
Or if I should write an own method for this because the tree gets chopped so it is nothing really active I would call.
So, in the end, there would be two or more kinds of implementations but the two I am thinking of are:
tree.setAmountofWood = x
or
tree.gettingChopped(Damage int)
I think I should make an own method for this chopping-process.
Or is there any design principle I should follow?
I see 3 principles here,
SRP - It is the responsibility of the Tree to get chopped and fall down, but to cut is the responsibility of the Person!
Demeter's law - looks good from my POV.
OCP - The tree must be able to do further actions when get cut.
So you must use
tree.gettingChopped(Damage damage)
To your code:
The method Dog.feed is wrong, rename it to Dog.eat because the Dog is not feeding, the dog is eating. By the way, the food must reduce its NutritionalValue.
The health is an integer value, this is bad because in reality there is nothing like a numeral health. We may have a handicapped numeral value in percent, but this is more a byte who not can be in negative value. You should create a custom class for the Health! This way your code is open(OCP) for extensions like to be toxified or depresive.
I would start from something like this.
Tree can grow and receive damage.
public class Tree {
private int lumber;
public Tree(int size) {
this.lumber = size;
}
public void grow() {
this.lumber++;
}
public void grow(int size) {
this.lumber += size;
}
public int receiveDamage(int damage) {
int lumber = 0;
if (damage > this.lumber) {
lumber = this.lumber;
this.lumber = 0;
} else {
lumber = damage;
this.lumber -= damage;
}
return lumber;
}
}
Food just stores nutritional value.
public class Food {
private int nutrition;
public Food(int nutrition) {
this.nutrition = nutrition;
}
public int getNutritionalValue() {
return this.nutrition;
}
}
I'm not sure if all types of player can chop trees, so I created a class to separate responsibilities. You can move methods to the Player class if you like.
public class Woodcutter extends Player {
public int chop(Tree tree) {
// lumber amount may depend on a tool,
// i.e. axe, chainsaw, etc.
return tree.receiveDamage(10);
}
// fell down the tree
public int fell(Tree tree) {
int result = 0;
int lumber = 0;
do {
lumber = chop(tree);
result += lumber;
} while (lumber > 0);
return result;
}
}
Somewhere in your code
// create a tree and let it grow for a while
Tree tree = new Tree(10);
tree.grow(90);
// Start chopping
Woodcutter woodcutter = new Woodcutter();
System.out.println("Lumber received: " + woodcutter.chop(tree));
System.out.println("Lumber received: " + woodcutter.fell(tree));
Dog dog = new Dog();
Food food = new Food(5);
woodcutter.feed(dog, food);
I wouldn't dive into passive/active methods here. An 'active tree' may indeed be a misnomer.
I would rather consider calling an object's method as passing a message to the object. And you apparently need to send the message to the tree that it is currently being cut by someone, and let the tree decide when to e.g. fall() or to bend(), or to shake().
The tree has some internal state (strength? thickness of its trunk? health?). 'Sending a message' to the tree means to call its method, e.g. beingCut(), which in turn deteriorates the state of the tree. After the state of the tree reaches a certain limit, other actions (=consequences of tree's bad state) may be started by the tree.
Of course, as in every iteration of your main loop you tree has also the chance to get the message to grow(), so its state may improve a little each time, so eventually it may even recover from being only partially cut and reach its initial, perfect state back.
So, yes, while trees seem rather passive, they still react to messages/stimulus. :-)
I'm writing a program that acts as a 'pocket' where the user is able to enter a kind of coin, such as, a quarter and the amount of quarters it has. I was assigned to do 3 different class, the Coin Class in which the coins and their values can be instatiated from, a Pocket Class, where I have to write a method that can add the coins of the user (basically the method would act like ArrayList .add() ) and the PocketClass tester. I have already written most of the code, but I am stuck as to how I could write the following method:
public void addCoin(String s, int i)
{
// s is type of coin, you are using s to instantiate a Coin and get value
// i is number of coins, you are using i to keep adding value to the totalValue
}
My question is how should I approach this? I am not quite clear on how to create method. Would I use a for-loop in order to keep track of the number of coins? I understand that the addCoin method works a lot like .add() from ArrayList.
Here is the code from my other classes:
public class Coin
{
private final String DOLLAR = "DOLLAR";
private final String QUARTER = "QUARTER";
private final String DIME = "DIME";
private final String NICKEL = "NICKEL";
private final String PENNY = "PENNY";
private int value;
private String coinName;
public Coin(String s,int count)//name of the coin and also the number of the coins you have
{
//Use if or switch statement to identify incoming string and provide value
double value=0;
if(DOLLAR.equalsIgnoreCase(s))
{
value=100.0;
}
else if(QUARTER.equalsIgnoreCase(s))
{
value=25.0;
}
else if(DIME.equalsIgnoreCase(s))
{
value=10.0;
}
else if(NICKEL.equalsIgnoreCase(s))
{
value=5.0;
}
else if(PENNY.equalsIgnoreCase(s))
{
value=1.0;
}
}
public int getValue()
{
return value;
}
}
and how the Pocket class is structured:
public class Pocket
{
private int currentValue;
private int totalValue;
private Coin quarter;
private Coin dime;
private Coin nickle;
private Coin penny;
public Pocket()
{ //Set initial value to zero
totalValue = 0;
currentValue = 0;
}
public void addCoin(String s, int i)
{
// s is type of coin, you are using s to instantiate a Coin and get value
// i is number of coins, you are using i to keep adding value to the totalValue
}
public int getValue()
{
return totalValue;
}
public void printTotal()
{
//print out two different output
}
}
I'm assuming you're adding the addCoin method in the Pocket class.
If you intend to keep track of the number of coins of each type within a Pocket, the simplest way to do so would be to declare a Hashmap that is keyed by the coin type (say, a "quarter" or a "dollar") and valued by the number of coins of that type. An invocation of the addCoin(type, count) method, say addCoin("dollar", 5) can then check if the hashmap already contains a key named "dollar" and if present, increment it's value by count.
I would suggest storing coins in a list so that you can add unlimited number of them.
Example:
class Coin{
//Same as your code....
public Coin(String coinType){
//..Same as your code, but removed number of coins
}
}
public class Pocket
{
private int currentValue;
private int totalValue;
//Create a list of coins to store unlimited number of coins
// A pocket can half 5 dimes
List coins;
public Pocket(){
//Set initial value to zero
totalValue = 0;
currentValue = 0;
coins = new ArrayList<Coin>();
}
/**
* This method will take only one coin at a time
**/
public void addCoin(String s){
Coin c = new Coin(s);
coins.add(c);
totalValue+=c.getValue();
}
/**
* This method will take any number of coins of same type
**/
public void addCoin(String s, int c){
//Add each one to array
for(int i=0;i<c;i++)[
addCoin(s);
}
}
}
I am not in favor of keeping multiple coin values in one Coin object because of the fact it is not a true representation of an object. What does that mean is tomorrow if you want to store other Coin attributes like "Printed Year", "President Picture on the coin" etc, you will have hard time. In my opinion it is better to represent one real world object (one coin here) using one object instance in the program,
I am in the process of updating my game to Java, but the only minor bug I have left is this:
Every time a dead player's name is "added" to the dead player name list, it adds the Player object's hashcode instead.
EDIT: Here is a link to a zip folder with the source code:
https://dl.dropboxusercontent.com/u/98444970/KarmaSource.zip
The code in question is the two places where the line gets the player object and gets the object's name. When it is used in println, it works fine and prints the player's name. However, in the second part where it does the same thing, but it prints the hashcode of the player object instead of calling its get_name method and returning the String. I'm not sure if it has to do with the third part, where it adds the "name" to dead player list pdead.
If you'd like a link to the compiled version, let me know. It's compiled under JDK 7 Update 51 64-bit.
EDIT: I got it working, I was originally referencing the players list instead of the pdead list. Thanks to all who contributed to helping. If you still want the game, let me know and I'll put a download link :D
Answering your question:
This code is wrong:
if (karma.pdead.isEmpty())
{System.out.println("None");}
else
for (int index = 0;index < karma.pdead.size();index++)
System.out.println(pdead.get(index));
What is karma? Whatever that is, looks like you're referring to 2 different things there.
Try this:
if (pdead.isEmpty()) {
System.out.println("None");
} else {
for (String deadPlayer : pdead) {
System.out.println(deadPlayer);
}
}
Pretty sure this will work :)
Some further, constructive advice:
Your code is breaking pretty much all conventions/good-practices I know in Java. But I am here to help, not to criticize, so let's try to improve this code.
Never keep state in static fields. This is a recipe for causing memory leaks.
your main function won't even compile. Should look like this:
public static void main(String[] args)
Always wrap the body of for loops with braces.
Be consistent: if you open braces in a new line, then do it every time. NEVER write code on the same line as the opening bracket.
GOOD:
public void doSomething()
{
// body
}
GOOD:
public void doSomething() {
// body
}
BAD:
public void doSomething() {
// body
}
public void somethingOther()
{
// inconsistent!
}
public void terribleCode()
{ System.out.println("Never do this"); }
Do not use underscores to separate words. In Java, the favoured convention is to use camelCase. getName(), not get_name().
class names ALWAYS start with a capital letter, whereas variable names generally start with a lower-case letter.
if you're iterating over all items of a list, just use the forEach construct (shown above) not index navigation.
I wanted to check to see if there was some subtle syntax error, so I cut/paste your code into an editor and tried to massage it to get it running. After my massaging, I ran it and it ran fine. Here is the code I ran and the results I got:
Code:
import java.util.ArrayList;
public class Game {
private static ArrayList<Player> players = new ArrayList<Player>();
private static ArrayList<String> pdead = new ArrayList<String>();
public static void main(String[] args) {
// Some Test Data
Player p1 = new Player("George");
p1.setHp(10);
players.add(p1);
Player p2 = new Player("Bob");
p2.setHp(10);
players.add(p2);
// Print Current State of data
System.out.println("Current Players");
for(Player p: players) {
System.out.println(p.getName() + ": " + p.getHp());
}
System.out.println("Dead Players");
if (pdead.isEmpty()) {
System.out.println("None");
} else {
for (int index=0; index < pdead.size(); index++) {
System.out.println(pdead.get(index));
}
}
// Kill Bob
p2.setHp(0);
// Do work to add names to dead players data structure
for (int index2=0; index2 < players.size(); index2++) {
if ((players.get(index2).getHp() <= 0) && !(pdead.contains(players.get(index2).getName()))) {
pdead.add(players.get(index2).getName());
}
}
// Print Current State of data
System.out.println("Current Players");
for(Player p: players) {
System.out.println(p.getName() + ": " + p.getHp());
}
System.out.println("Dead Players");
if (pdead.isEmpty()) {
System.out.println("None");
} else {
for (int index=0; index < pdead.size(); index++) {
System.out.println(pdead.get(index));
}
}
}
}
class Player {
private String name = "";
private int hp = 0;
public Player(String n) {
name = n;
}
public String getName() {
return name;
}
public int getHp() {
return hp;
}
public void setHp(int h) {
hp = h;
}
}
Here are the results that code gives me:
javac Game.java
java Game
Current Players
George: 10
Bob: 10
Dead Players
None
Current Players
George: 10
Bob: 0
Dead Players
Bob
I've been working at this for a couple hours now and I feel (I hope) I'm right on the verge of figuring it out. This program reads in a bunch of values from an external file and places them in an array of objects which seems to be working just fine.
The Objects properties are:
Bank Account #
Customer Name
Bank Account Balance
1. I can output them in order of Account # (That's how their read in from the file, no sorting is necessary)
2. I've setup a method from implementing Comparable to sort by Bank Account Balance and it's working fine.
3. I need a second sort method, to sort by Customer Name.
- The problem I'm having with this is based on the research I've done and what I've tried I've come to the conclusion that the only way to make this work will be to build my own Comparable Objects (sorry if my terminology is skewed.) I've attempted this as well multiple times with both Java Doc and some similar questions on SE.
When all is said and done I'm going to throw some Listeners into my checkbox group to allow the user to toggle the different sort methods.
Here's the chunks i'm working on:
public class bankAccounts implements Comparable<bankAccounts> {
/* PRIVATE FIELDS HERE, FOLLOWED BY TYPICAL GET AND SET METHODS */
/*SORTS BY ACCOUNT BALANCE WORKING GREAT*/
public int compareTo(bankAccounts b) {
if (accountBalance < b.accountBalance)
{
return -1;
}
if (accountBalance > b.accountBalance) {
return 1;
}
return 0;
}
/* BEGIN SNIPPET OF MAIN CLASS */
/*METHOD I CALL FROM MAIN CLASS, SORTS BY BALANCE ^^ AS SEEN ABOVE */
Arrays.sort(retrievedAccounts);
for (int i=0; i<retrievedAccounts.length; i++) {
String resultFull = Integer.toString(retrievedAccounts[i].getAccountNumber()) + retrievedAccounts[i].getAccountLastName() + Double.toString(retrievedAccounts[i].getAccountBalance());
box.append(resultFull + "\n");
}
/* NORMAL METHOD WHICH OUTPUTS IN ORDER OF ACCOUNT NUMBER, NO SORTING HAPPENING HERE */
for(int x = 0; x < retrievedAccounts.length; ++x)
{
String resultFull=Integer.toString(retrievedAccounts[x].getAccountNumber()) + retrievedAccounts[x].getAccountLastName() + Double.toString(retrievedAccounts[x].getAccountBalance());
box.append("\n\n\n" + resultFull + "\n\n");
}
I'm hoping someone will have some insight towards a next step which might allow me to finish this up. If you have suggestions to take this a completely different direction I'm open to that as well.
This is an idea haven't tested.
Create a another private method to store compareType
public class bankAccounts implements Comparable<bankAccounts> {
private int compareType = 0; // 0 - compare by balance 1-compare by name
In your compare method
public int compareTo(bankAccounts b) {
if(this.compareType == 0){
if (accountBalance < b.accountBalance)
{
return -1;
}
if (accountBalance > b.accountBalance) {
return 1;
}
return 0;
}else{
return customerName.compareTo(b.customerName)
}
Use an implementation of Comparator<bankAccounts> that compares the names of your objects and pass that into the Arrays.sort() method.
Use an anonymous class like this:
Arrays.sort(retrievedAccounts, new Comparator<bankAccounts>() {
public int compare(bankAccounts a, bankAccounts b) {
return a.getName().compareTo(b.getName());
}
});
This code assumes you have a getter method on bankAccounts for customer name called getName()
You would do well to follow java naming conventions:
class names start with a capital letter
class names are singular, not plurals