OOP Java how to increase hit point and decrease mp? - java

How do I reference hit_point in the useSkill method? What I have now isn't increasing hit_point at all.
public int hit_point() {
int total_power = this.power + this.weapon.getPower();
return total_power;
}
//------------------------------------------------------why isn't this increasing the hit point at all?
public int useSkill() {
this.mp=this.mp-1;
this.skill--;
return hit_point() +30;
}
public int getSkill() {
return skill;
}

When returning values, a method isn't storing the return value unless you tell your program to store the value as so: int totalHitPoint = useSkill(). Then useSkill() would not only add to the total hit points already calculated, but it will be stored in a variable you can use on demand.

Related

How to access the initial value of an initialized object?

I'm learning java at the moment and I've got a question about an object that got initialized and got a variable changed during the program execution.
public class Char {
private String name;
private int skill;
private int defense;
private int life;
private Weapon weapon = Weapon.FISTS;
private Potion potion = null;
So, I want this code to get the initial value of life that got initialized, but how would I access it?
public boolean isWeak() {
return life < this.life * 0.25;
}
So, this method is located in the Char class. I'm trying to get it to return a true value when it gets lower than 25%.
while (hero.isAlive() && monster.isAlive()) {
if (hero.isWeak() && hero.hasPotion()) {
hero.sip();
} else if (monster.isWeak() && monster.hasPotion()){
monster.sip();
} else {
System.out.println(monster.isWeak());
hero.attack(monster);
if (monster.isAlive()) {
monster.attack(hero);
}
System.out.println();
}
}
Here is the execution program. All the other methods work just fine, but as pointed out, it'll never return true because it can't be a quarter of itself. Don't mind the prints, I'm just testing it.
To do this, you need to create a second variable that stores the value passed into the constructor:
public class Char {
private String name;
private int skill;
private int defense;
private int initialLife;
private int life;
private Weapon weapon = Weapon.FISTS;
private Potion potion = null;
public Char(int initialLife //I am excluding all the other parameters you want to pass in
) {
this.life = initialLife;
this.initialLife = initialLife;
}
public boolean isWeak() {
return life < this.initialLife * 0.25;
}
}
As you can see, I store the initial life and I don't ever modify it. Since I modify the life variable, I can't use it to keep track of the initial value. Modifying a variable is a destructive process, and Java doesn't have a way to keep track of the history of variable values (unless you do it yourself as shown above).

Immutable keys - fixed length map in Java

Is there a way in Java to create a collection (map) with fixed size and length?
I.e., I would like to initialize it with K constant keys (e.g. strings) but still want to be able to change the values.
Edit:
The test case has a fixed number of objects, each one corresponds to a number (float). Each time a specific event in the application occurs, I would like to multiply all the numbers in the collection, except the number that corresponds to the object that "caused" the event.
The number is not logically an attribiute of the object.
I suggest you first look at Mike's answer to get an idea of how to go about solving this problem, then make some changes to the code he provided so it will work in your situation:
import java.util.HashMap;
public class InstrumentedHashMap<K> extends HashMap<K, Float> {
private static final long serialVersionUID = 1L;
private int MAX;
public InstrumentedHashMap(int capacity) {
super();
MAX = capacity;
}
#Override
public Float put(K key, Float value) {
if (super.size() >= MAX && !super.containsKey(key)) {
return null;
} else {
super.put(key, value);
return value;
}
}
public void event(K trigger, int multiplyAmount, float subtractAmount) {
super.entrySet().stream().forEach(e -> {
if (!e.getKey().equals(trigger))
e.setValue(e.getValue() * multiplyAmount);
else
e.setValue(e.getValue() - subtractAmount);
});
}
}
You can use the InstrumentedHashMap#event method to handle your "specific event", with the multiplyAmount parameter being the value that you want to multiply your floats by.

Setting a value to zero

Ok so in my cs class we have an assignment that requires us to return a value and then set it to zero. I can't figure out how to do this without using a secondary variable(which would break requirements) so I would appreciate some help. here are the exact requirements.
"Has a use() method that returns the value contained in the points field. It also resets the points field to zero. You’re going to have to think about the order of operations here to make this work correctly."
package Game;
import java.util.Random;
public class HealthPotion
{
private int points;
boolean Haspotion;
HealthPotion()
{
Random num1 = new Random();
int num = num1.nextInt(10)+1;
points=num*10;
}
public int Use()
{
return points;
}
public int getPoints()
{
return points;
}
}
That's not really possible without abusing a finally block, i.e.
try {
return points;
} finally {
points = 0;
}
However it's really hard to believe that would be what's wanted, since it's not a good idea to write code like that.
Include a setter method like this.
public void setValue(){
this.points=0;
}
Call this method after you get the value.
How about this?
public int Use()
{
int tmp = points;
points = 0;
return tmp;
}
It has limitations, especially if points can be changed by a different thread while this method executes. But if you are working in a single-threaded environment this should be ok.
This should work
int points = 5;
public void test(){
System.out.println(use() +" " + points);
}
private int use(){
return points - (points = 0);
}
returning 5 0

Creating a method that works like ArrayList .add()

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,

Using Generics of Subclasses of Number to Create a Rollover Counter

I'm trying to create a counter that will rollover whenever it reaches a preset ceiling and resets back to its floor value upon reaching said ceiling. I have implemented the class and it works just fine. However, on my way to my solution, I wanted to experiment with Java Generics. I want to try and extend my counter so that it doesn't only use integers, but instead can use any type of number. I know that counters typically call for just the use of integers anyway, but I wanted to see if it could be done.
I figured that the code would be similar to below. However, java.lang.Number doesn't have a "generic" way of getting/setting its value. Do I need to create my own number class to enable this? Also, I know that if I do get this working, I need to alter my equals checks so that they have an error threshold for floating point values, this is more or less a modified version of my int counter with what I figured would work for generics.
Edit:
It's been suggested that I take a mapping approach where I store an integer counter and keep a increment value so that when I want to spit out a number, I just multiply my current count by the increment value. However, I don't believe this will fill my exact needs because I don't want to necessarily increment by the same amount every time. The main focus of this counter is more of a way to have a fixed range number that, when added to or subtracted from, knows how to handle wrapping back around.
I guess the best way to describe it (although probably improperly) would be like an Integer that automatically handles over/underflow.
package com.math;
public class GenericRolloverCounter<T extends Number> {
private T value;
private T lowValue;
private T highValue;
public GenericRolloverCounter(T l_startValue, T l_highValue) {
this.lowValue = l_startValue;
this.highValue = l_highValue;
this.value = l_startValue;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public void increment(T valToIncrementBy) {
this.value += valToIncrementBy;
if (this.value > this.highValue) {
this.value = (this.lowValue + (this.value - (this.highValue + 1)));
}
}
public void increment() {
this.increment(1);
}
public void decrement(T valToDecrementBy) {
this.value -= valToDecrementBy;
if (this.value < this.lowValue) {
this.value = ((this.value + this.highValue + 1) - this.lowValue);
}
}
public void decrement() {
this.decrement(1);
}
#Override
public String toString() {
return Integer.toString(this.value);
}
}
You might want to also specify an amount by which to count. Default value would be 1.
You can get around some of this by using the Number method .doubleValue() and doing double arithmetic.
Here is one of the methods converted to use this idea.
public void decrement(double valToDecrementBy) {
double work = this.value.doubleValue();
work -= valToDecrementBy;
// should use some value related to incrementing amount
if ((this.value.doubleValue() - this.lowValue.doubleValue()) < 0.1D) {
work = ((this.value.doubleValue() + this.highValue.doubleValue() + 1) - this.lowValue.doubleValue());
}
// ... no way to put it back
}
But, there is still no way to put the value back that's clean and easy. Since 'Number' only has a few commonly used non-abstract subclasses, you could do some ugly instanceof stuff to store the value back. It would look something like this:
if (theValue instanceof Double) { // depends on it having a non-null value prior
theValue = (T)(new Double(work));
}
Or you could convert the starting values to double when you start and just work with doubles.
private double value;
private double lowValue;
private double highValue;
public GenericRolloverCounter(T l_startValue, T l_highValue) {
this.lowValue = l_startValue.doubleValue();
this.highValue = l_highValue.doubleValue();
this.value = l_startValue.doubleValue();
}
That does introduce the issues of incrementing floating point values and the rounding/evaluation problem there.
Oh ... and your toString() should be:
return value.toString();
To use the native toString() method on the T class.
#Crusher's comments suggest another way to do it. Map everything to 'int' and keep a multiplier. Here's some bits of code to show what I mean. (Thanks Crusher)
private int value;
private int lowValue;
private int highValue;
private double incr;
public GenericRolloverCounter(T l_startValue, T l_highValue, T incrementAmount) {
double incr = incrementAmount.doubleValue();
this.lowValue = Math.round(l_startValue.doubleValue() / incr);
this.highValue = Math.round(l_highValue.doubleValue() / incr);
this.value = Math.round(l_startValue.doubleValue() / incr);
}
public void increment(int valToIncrementBy) {
this.value += valToIncrementBy;
if (this.value > this.highValue) {
this.value = (this.lowValue + (this.value - (this.highValue + 1)));
}
}
#Override
public String toString() {
return String.valueOf(incr * this.value);
}

Categories