Java: How to code for items to inherit raw materials' properties? - java

I am a Java beginner. My problem is, for example:
Fire: DMG +1
Stone: DEF +1
By combining to:
Fire-stone: fire + stone, and inherit both their properties (DMG 1, DEF 1).
Flame: fire + fire, and inherit 2 fire properties (DMG +2).
I've played around with classes and interfaces but doesn't seem to work. It seems to me that Java doesn't support multiple inheritance but multiple interfaces. I wonder how I could code each class/interface for this to work?
public static int DMG, DEF = 0;
public static String DESC = "";
interface fire {
DMG = 1; }
interface stone {
DEF = 1; }
class firestone implements fire, stone {
DESC = "Born in fire and stone";
//DMG and DEF calculations
}

You better use composition, here is what you could do:
public class Main {
public static void main(String[] args) {
Tool firestone = new Tool(new Fire(), new Stone());
}
private static interface Component {
int getDmg();
int getDef();
}
private static class Fire implements Component {
#Override
public int getDmg() {
return 1;
}
#Override
public int getDef() {
return 0;
}
}
private static class Stone implements Component {
#Override
public int getDmg() {
return 0;
}
#Override
public int getDef() {
return 1;
}
}
private static class Tool implements Component {
List<Component> components;
int dmg;
int def;
public Tool(Component... component) {
components = new ArrayList<>();
components.addAll(Arrays.asList(component));
dmg = 0;
def = 0;
for (Component c : components) {
dmg += c.getDmg();
def += c.getDef();
}
}
#Override
public int getDmg() {
return dmg;
}
#Override
public int getDef() {
return def;
}
}}
My implementation may be an overkill :P but it is extendable and you add more components that are more and more complicated.

Related

Inheritance var java

this is the qa:
Define a class called MoreSpeed which extends the following class, and which provides a new method called incSpeed() which adds 1 to the inherited variable length.
this is my answer:
public class Speed {
private int length = 0;
public int getSpeed () { return length; }
public void setSpeed (int i) {
if (i > 0) {
length = i;
}
}
}
public class MoreSpeed extends Speed {
private int length;
public int incSpeed() {
return length+1;
}}
its says that the syntax is good but the class operation is wrong.
please help me,thanks.
No. You are shadowing the length from Speed. Instead, implement incSpeed with getSpeed() like
public int incSpeed() {
return getSpeed() + 1;
}
If you are supposed to modify it as well then use setSpeed(int) to do so
public int incSpeed() {
int s = getSpeed() + 1;
setSpeed(s);
return s;
}

How to detect whether the screen is off in OS X?

I'm making an application that should only try to run if the display is on (among other things), but I couldn't find a way to check via commandline. Checking how long the user has been idle and their preferred idle time via pmset -g doesn't always work either, because of various programs that can change this.
Is there a way (via commandline, or in Java) to check whether the screen is currently off in OS X?
This bit of C will detect if the screens are asleep or awake:
CGDirectDisplayID ids[20];
uint32_t num_ids;
if (kCGErrorSuccess != CGGetActiveDisplayList(20, ids, &num_ids)) {
printf("Oops\n");
return 1;
}
boolean_t asleep = true;
for (int i = 0; i < num_ids; i++) {
asleep &= CGDisplayIsAsleep(ids[i]);
}
if (asleep) {
printf("Asleep\n");
return 1;
} else {
printf("Awake\n");
return 0;
}
This can be horridly translated to some JNA using:
CoreGraphics.java:
import com.sun.jna.*;
import com.sun.jna.ptr.IntByReference;
public interface CoreGraphics extends Library {
CoreGraphics INSTANCE = (CoreGraphics)Native.loadLibrary("CoreGraphics", CoreGraphics.class);
class int32_t extends IntegerType {
public static final int SIZE = 4;
public int32_t() {
this(0);
}
public int32_t(long value) {
super(SIZE, value, false);
}
};
public static class CGError extends int32_t {
public static final CGError Success = new CGError(0);
public CGError() { this(0); }
public CGError(int value) { super(value); }
};
public static class CGDirectDisplayID extends int32_t {
};
CGError CGGetActiveDisplayList(int maxDisplays, CGDirectDisplayID[] activeDisplays, IntByReference displayCount);
boolean CGDisplayIsAsleep(CGDirectDisplayID disp);
}
Example program making use of the interface - jna_monitors_run.java:
import com.sun.jna.*;
import com.sun.jna.ptr.IntByReference;
public class jna_monitors_run {
static final int MAX_DISPLAYS = 20;
public static void main(String[] args) {
IntByReference ib = new IntByReference();
CoreGraphics.CGDirectDisplayID ids[] = new CoreGraphics.CGDirectDisplayID[MAX_DISPLAYS];
if (! CoreGraphics.CGError.Success.equals(CoreGraphics.INSTANCE.CGGetActiveDisplayList(
MAX_DISPLAYS, ids, ib))) {
System.exit(2);
}
boolean is_asleep = true;
int i = ib.getValue();
while (--i >= 0) {
is_asleep &= CoreGraphics.INSTANCE.CGDisplayIsAsleep(ids[i]);
}
System.out.println(is_asleep);
System.exit(is_asleep ? 1 : 0);
}
}

How to inherit static field and change it's value?

I'm working on program/game where I have static utility class with params.
class ParamsGeneral {
public static final int H_FACTOR = 100;
public static int MAX_SCORE = 1000;
...
}
then I need to override this values in some specific cases, for example playing on map with limited score. So I did following:
class ParamsLimited extends ParamsGeneral {
public static int MAX_SCORE = 500;
// other params stay same
}
And the intended usage is following:
class Player {
ParamsGeneral par;
public Player() {
if(onLimitedMap()){
par = new ParamLimited();
}
}
public boolean isWinner() {
if(this.score == par.MAX_SCORE) {
return true;
}
return false;
}
}
I haven't actually tested this code, because IDE is complaining about calling static field through instance and also about field hiding. I clearly see that this code is stinks, so is there a way to achieve this or do I have to write each param class separately?
PS: I know I shoud make the default class abstract and use getters, I'm just curious if there is a way to make the values accesible statically.
You cannot override static members - in Java, neither methods nor fields could be overriden. However, in this case it does not look like you need to do any of that: since you have an instance of ParamsGeneral in the par variable, a non-static method would do what you need with the regular override.
class ParamsGeneral {
public int getMaxScore() {
return 1000;
}
}
class ParamsLimited extends ParamsGeneral {
#Override public int getMaxScore() {
return 500;
}
}
...
public boolean isWinner() {
// You do not need an "if" statement, because
// the == operator already gives you a boolean:
return this.score == par.getMaxScore();
}
I wouldn't use subclassing for a general game vs a limited game. I would use an enumeration, like:
public enum Scores {
GENERAL (1000),
LIMITED (500),
UNLIMITED (Integer.MAX_INT);
private int score;
private Scores(int score) { this.score = score; }
public int getScore() { return score; }
}
Then, when constructing a game, you can do:
Params generalParams = new Params(Scores.GENERAL);
Params limitedParams = new Params(Scores.LIMITED);
And so forth.
Doing it this way allows you to change the nature of your game while keeping your values centralized. Imagine if for every type of parameter you think of you have to create a new class. It could get very complicated, you could have hundreds of classes!
Simplest solution is to do this:
class ParamsGeneral {
public static final int H_FACTOR = 100;
public static final int MAX_SCORE = 1000;
public static final int MAX_SCORE_LIMITED = 500;
...
}
class Player {
int maxScore;
public Player() {
if(onLimitedMap()){
maxScore = ParamsGeneral.MAX_SCORE_LIMITED;
}
else {
maxScore = ParamsGeneral.MAX_SCORE;
}
}
public boolean isWinner() {
if(this.score == this.maxScore) {
return true;
}
return false;
}
}
No need to have an instance of ParamsGeneral, it is just a collection of static definitions for your game.
Have MAX_SCORE be private static with public static getters; then you can call ParamsGeneral.getMaxScore and ParamsLimited.getMaxScore and you'll get 1000 and 500 respectively

How to write a method that returns an instance of an abstract class?

I am a beginner in Java and i trying to understand the abstract classes.
Below is the code that I've written; the question is: how do i write a method that will return an instance of that class.
public abstract class VehicleEngine
{
protected String name;
protected double fabricationCons;
protected double consum;
protected int mileage;
public VehicleEngine(String n, double fC)
{
name = n;
fabricationCons = fC;
mileage = 0;
consum = 0;
}
private void setFabricationCons(double fC)
{
fabricationCons = fC;
}
public abstract double currentConsum();
public String toString()
{
return name + " : " + fabricationCons + " : " + currentConsum();
}
public void addMileage(int km)
{
mileage += km;
}
public double getFabricationConsum()
{
return fabricationCons;
}
public String getName()
{
return name;
}
public int getMileage()
{
return mileage;
}
//public VehicleEngine get(String name){
//if(getName().equals(name)){
//return VehicleEngine;
//}
//return null;
//}
}
public class BenzinVehicle extends VehicleEngine
{
public BenzinVehicle(String n, double fC)
{
super(n, fC);
}
#Override
public double currentConsum()
{
if (getMileage() >= 75000) {
consum = getFabricationConsum() + 0.4;
} else {
consum = getFabricationConsum();
}
return consum;
}
}
public class DieselVehicle extends VehicleEngine
{
public DieselVehicle(String n, double fC)
{
super(n, fC);
}
#Override
public double currentConsum()
{
int cons = 0;
if (getMileage() < 5000) {
consum = getFabricationConsum();
} else {
consum = getFabricationConsum() + (getFabricationConsum() * (0.01 * (getMileage() / 5000)));
}
return consum;
}
}
This is the main.
public class Subject2
{
public static void main(String[] args)
{
VehicleEngine c1 = new BenzinVehicle("Ford Focus 1.9", 5.0);
DieselVehicle c2 = new DieselVehicle("Toyota Yaris 1.4D", 4.0);
BenzinVehicle c3 = new BenzinVehicle("Citroen C3 1.6",5.2);
c1.addMileage(30000);
c1.addMileage(55700);
c2.addMileage(49500);
c3.addMileage(35400);
System.out.println(c1);
System.out.println(c2);
System.out.println(VehicleEngine.get("Citroen C3 1.6")); //this is the line with problems
System.out.println(VehicleEngine.get("Ford Focus "));
}
}
And the output should be:
Ford Focus 1.9 : 5.0 : 5.4
Toyota Yaris 1.4D : 4.0 : 4.36
Citroen C3 1.6 : 5.2 : 5.2
null
You can not return an instance of an abstract class, by definition. What you can do, is return an instance of one of the concrete (non-abstract) subclasses that extend it. For example, inside the VehicleEngine you can create a factory that returns instances given the type of the instance and the expected parameters, but those instances will necessarily have to be concrete subclasses of VehicleEngine
Have a look at the Factory Method pattern. Your concrete classes will implement an abstract method that returns a class instance.
Abstract classes do not keep a list of their instances. Actually no Java class does that. If you really want to do that, you could add a static map to VehicleEngine like this:
private static Map<String, VehicleEngine> instanceMap = new HashMap<String, VehicleEngine>();
and change your get method to a static one like this:
public static VehicleEngine get(String name) {
return instanceMap.get(name);
}
and add this line to the end of the constructor of VehicleEngine:
VehicleEngine.instanceMap.put(n, this);
this way every new instance created puts itself into the static map. However this actually is not a good way to implement such a functionality. You could try to use a factory to create instances, or you could consider converting this class into an enum if you will have a limited predefined number of instances.

Add weapons to inventory

I am trying to add weapons to a player inventory. It's kind of hard to explain, so I'll try my best. What I have are a class for each weapon, a class for Combat, and a class for the Player. I am trying to get it to where when the Random number equals a certain number, it will add a weapon to the player inventory. I will put my code Below.
Combat Class:
public class Combat {
M4 m4 = new M4();
M16 m16 = new M16();
M9 m9 = new M9();
Glock glock = new Glock();
SCAR Scar = new SCAR();
Player player = new Player();
final int chanceOfDrop = 3;
static boolean[] hasWeapon = {false, true};
public static int ranNumberGen(int chanceOfDrop) {
return (int) (Math.random()*5);
}
private void enemyDead() {
boolean canDrop = false;
if(ranNumberGen(chanceOfDrop)==0){
canDrop = true;
}
if(canDrop == true){
if(ranNumberGen(0) == 1) {
Player.addInvetory(m4.weaponName(wepName), m4.weaponAmmo(wepAmmo)); //Issues here. wepName & wepAmmo cannot be resolved into variable
//Should I just delete the line?
//Trying to get it to add the weapon M4 to the player inventory.
//Maybe use an ArrayList? If so I need a couple pointers on how to implement this.
}
}
}
}
M4 Class:
public class M4 implements Armory {
//Weapon classes are practically identical except for differences in the name wepDamage and wepAmmo.
public Integer weaponAmmo(int wepAmmo) {
wepAmmo = 10;
return wepAmmo;
}
public Integer weaponDamage(int wepDamage) {
wepDamage = 5;
return wepDamage;
}
public String weaponName(String wepName) {
wepName = "M4";
return wepName;
}
Player Class:
public class Player {
public static int health = 100;
//Player Class.
public static void addInvetory(String wepName, int wepAmmo) {
Player.addInvetory(wepName, wepAmmo);
}
public static void removeInventory(String wepName, int wepAmmo) {
Player.addInvetory(wepName, wepAmmo);
}
public static void removeAll(String wepName, int wepAmmo) {
Player.removeAll(wepName, wepAmmo);
}
Interface:
public interface Armory {
//Interface implemented by all of the weapons classes.
public Integer weaponAmmo(int wepAmmo);
public Integer weaponDamage(int wepDamage);
public String weaponName(String wepName);
Hope you can help!
class Weapon {
private final String name;
private final int damage;
private final int ammo;
public Weapon(final String name,final int damage,final int ammo) {
this.name = name;
this.damage = damage;
this.ammo = ammo;
}
public Weapon clone() {
return new Weapon(this.name,this.damage,this.ammo);
}
public String getName() {
return this.name;
}
public int getAmmo() {
return this.ammo;
}
public int getDamage() {
return this.damage;
}
}
class WeaponFactory {
static WeaponFactory factory;
public static WeaponFactory getWeaponFactory() {
if(factory == null) {
factory = new WeaponFactory();
}
return factory;
}
private ArrayList<Weapon> weapons = new ArrayList<Weapon>();
private Random random;
private WeaponFactory() {
//TODO: Fix Ammo and Damage
weapons.add(new Weapon("M4",0,0));
weapons.add(new Weapon("M16",0,0));
weapons.add(new Weapon("M9",0,0));
weapons.add(new Weapon("Glock",0,0));
weapons.add(new Weapon("SCAR",0,0));
}
public Weapon getWeapon() {
int w = random.nextInt(weapons.length);
return weapons.get(w).clone();
}
}
class Combat {
...
private void enemyDead() {
if(ranNumberGen(chanceOfDrop)==0){
Player.addInventory(WeaponFactory.getWeaponFactory().getWeapon());
}
}
}
You can use an array of Armory and the generate a random number from 0 to the size of the array as an index to the array to decide which weapon to add.
Okay dude, since your question about creating a programming language was closed, I'm answering it through here:
I think that your idea is great! Don't give up on it, yet don't get too excited. I would try all the options that you have heard of(interpreted route AND the Compiled route). If you can get either of those to work, then you may proceed to go into further detail with the language creation. It's going to take a while though. Be patient!

Categories