I am never quite sure that I am using static methods correctly. I understand how they work.
Let's say I have this class called Player(Java):
private int money;
private int lot;
private String piece;
private int playerNum;
public Player(String _piece, int _playerNum)
{
piece = _piece;
lot = 0;
playerNum = _playerNum;
money = 20000;
}
public int getMoney()
{
return money;
}
public int getLot()
{
return lot;
}
public String getPiece()
{
return piece;
}
There are some other methods + setters, but they are specific to the player object I create, now let's say I have a static method like this:
private static int numOfPlayers;
public static int numPlayers()
{
return numOfPlayers;
}
Where should this numOfPlayers method be placed?
Should it be put in my Player class? And should I increment the numOfPlayers varible everytime a new isntance of the player object is created?(via the constructor)
Or, should I have I have the method in my Game class as non-static and just call the method everytime I create a new Player.
Static fields and methods are supposed to represent stateless attributes of a class; i.e. not pertinent to a particular object.
But be careful with multithreading with statics since the whole class has to be locked rather than just one object. This can lead to concurrency bottlenecks.
As for your numOfPlayers, you'll probably end up having a collection of players developed somewhere else, in which case that function will be a method on that collection not in the player class.
Ideally, in my opinion at least, an individual player should not really be concerned about the players collection. Therefore a static function such as the one you propose would not be good design.
It is a matter of design, which obviously includes a lot of personal preference.
You really should have a look at the factory design pattern, which is a good way of handling such cases. Here, you could have a
public class PlayerFactory {
private int numPlayers = 0;
public int getNumPlayers() { ... }
public Player makeNewPlayer(...) { ... }
}
that takes care of A) incrementing the player count appropriately.
Depending on your exact use case and code style, you may prefer one variation or another. But it is good to know these patterns and recognize them. And document them. By calling a class SomethingFactory you do hint for other developers that this class follows the factory pattern, for example.
Note that I did not need to use static in above example, assuming that the factory may only be instantiated once. It is common to see the constructor private and instead the class then has a public static final instance only.
You could also call this class Game or Players...
how about you have a List of Players in your game and the number of players is the size of the List.
When you think you should use static for some functionality, don't do it!
Just play along the old rule to never use anything static until you are old and wise and where you perhaps can use it for some very special corner case.
You can create it like this:
Have class Player like you have
Create class Players
class Players
{
private List<Player> players = new List<Players>;
public void AddPlayer(Player pl)
{
this.players.add(pl);
}
public int GetPlayersCount()
{
return this.players.size();
}
}
If you want, you can make this class "static" using Singleton. But try to avoid static classes.
class Players
{
private List<Player> players = new List<Players>;
private static Players instance;
private Players () {};
public static Players getInstance()
{
if (instance == null)
{
instance = new Players ();
}
return instance;
}
public void AddPlayer(Player pl)
{
this.players.add(pl);
}
public int GetPlayersCount()
{
return this.players.size();
}
}
And use it like this
Players players = Players.getInstance();
players.AddPlayer(....)
I would have the list of Players in another class, e.g. Game as you suggested.
Something like
class Game {
private final List<Player> players = new ArrayList<Player>();
public int getNumOfPlayers() {
return players.size();
}
public void addPlayer(final Player player) {
players.add(player);
}
...
You add a player via your instance of Game, game via game.addPlayer(newPlayer), and get the number of players via game.getNumOfPlayers().
The List of players is dynamically allocated.
As for static or not static, I prefer here the non static version, as the players are part of a Game, and one could consider they may be several games - and players would be part of an instance of Game.
Related
Some background on the project: I am attempting to craft a space/sci-fi combat sim game with tabletop rpg style dice mechanics cranked up to 11 on the complexity scale, but still being transparent about the die rolls going on under the hood. I'm currently using the Star Wars Saga Edition combat rules as a basis.
Currently I'm trying to figure out a way to assign traits to vehicle.(possibly stored as a class for each vehicle) Each trait is an enum so that it can store multiple pieces of information. Here is the code I have for size categories:
public enum VehicleSize {
LARGE(1,"Speeder bike",5),HUGE(2,"Small Fighter",10),GARGANTUAN(5,"Tank, Medium Fighter",20),COLOSSAL(10,"Imperial Walker, Light Freighter",50),
COLLOSSALfrigate(10,"Corvette, Frigate",100),COLLOSSALcruiser(10,"Imperial-class Star Destroyer, Cruiser",200),
COLLOSSALstation(10,"The Death Star, Space Station",500);
private final int refMod;
private final int threshMod;
private final String desc;
VehicleSize(int reflexModifier,String example,int thresholdModifier)
{
refMod = reflexModifier;
desc = example;
threshMod = thresholdModifier;
}
public int getRefMod() {
return refMod;
}
public String getDesc() {
return desc;
}
public int getThreshMod() {
return threshMod;
}
}
My question is such: How do create vehicle profiles in such a way that I can assign this and similar enums as traits?
For practically all purposes, a field whose type is an enum class is no different than a field of any other object type, like Integer or String.
Create a private field, add a getter and setter, or if the field is final (likely in your case, because a vehicle instance can't change its type), add it as a constructor parameter and remo e the setter.
public class Vehicle {
private final VehicleSize vehicleSize;
// other fields
public Vehicle(VehicleSize vehicleSize) {
this.vehicleSize = vehicleSize;
}
public VehicleSize getVehicleSize() {
return vehicleSize;
}
// rest of class
}
There is nothing mysterious about an enum, other than the number of different instances of it are known at compile time (and a few more things, but nothing scary).
To add this into a class, you can use it like any user defined type.
public class MyClass {
private MyEnum myEnum;
}
Suppose I have the following two classes to start off with:
public class Game {
private final Player self;
private final Player opponent;
public Game(final Player self, final Player opponent) {
this.self = Objects.requireNonNull(self);
this.opponent = Objects.requireNonNull(opponent);
}
}
public class Player {
private final String name;
public Player (final String name) {
this.name = Objects.requireNonNull(name);
}
}
Now I have discovered that I need access to the other players (thus to the Game object) in my Player class.
One way to do it is the following, add this to the Player class:
private Game game;
public void setGame(final Game game) {
this.game = Objects.requireNonNull(game);
}
However now it breaks immutability of the game object, are there ways to preserve immutabiity of mutually created objects?
Or do I need to resort to manually imposed mutability and safety (from a regular client perspective, not from a multithreaded synchronization perspective)? Such as throwing an exception whenever someone attempts multiple setGame.
To summarize, this is the mutual dependency I am trying to solve:
Player playerSelf = new Player(/* non-existing game */, "Self");
Player playerOpponent = new Player(/* non-existing game */, "Opponent");
Game game = new Game(playerSelf, playerOpponent);
versus
Game game = new Game(/* non-existing player */, /* non-existing player */);
Player playerSelf = new Player(game, "Self");
Player playerOpponent = new Player(game, "Opponent");
Does there exist a Pattern such as for example the Builder Pattern which aids against an explosion of constructor arguments, which could be solved in a way that breaks immutability if one wanted to avoid the exposion without using the Builder Pattern?
Whenever you have a circular dependency, break it. It will help reduce your code's coupling, increase testability, and keep you sane. Why does Player need access to the other player in the first place? You might be trying to put too much functionality into it. Perhaps you could move that into the Game? Or into, say, a Strategy that's inserted into the Player object?
Also, bear in mind that immutability isn't always the answer. Some things, like the game state, are inherently mutable. Trying to shoehorn them into immutable objects is bound to make life miserable.
Immutablity is a great goal, but 100% immutability is really hard in Java:
Erlang makes every data structure immutable, which is great when the language supports it at that level. Unfortunately Java doesn't support this at the level that it needs to make it effortless and painless.
That said there are multiple solutions to this construction ordering:
Following something similar to the MVC pattern where the Game and Player objects don't even know about each other at all is probably your best solution. But it is the most complex and probably more code than is feasible for an answer here. I might post another answer on that solution by itself, until then.
Here are just a couple of the simpler solutions.
Inner Class Solution :
In this solution, the inner class always has an implicit reference to its outer class. There is no need to pass in the Game object because it is always in scope of the instances of the Player class.
import javax.annotation.Nonnull;
public class Q23726363B
{
public static void main(final String[] args)
{
final Game game = new Game(args[0], args[1]);
}
public static class Game
{
private final Player p1;
private final Player p2;
public Game(#Nonnull final String p1, #Nonnull final String p2)
{
this.p1 = new Player(p1);
this.p2 = new Player(p2);
}
public class Player
{
private final String name;
private Player(#Nonnull final String name) {this.name = name;}
public Game getGame() { return Game.this; }
}
}
}
Factory Method Solution:
Make the Game object the Player object factory. By making the constructors of both objects private you can guarantee that they are constructed correctly and make references functionally immutable by not providing a way to change them publicly.
Use a FactoryMethod, something like the following:
import javax.annotation.Nonnull;
public class Q23726363A
{
public static void main(final String[] args)
{
final Game game = Game.startGame(args[0], args[1]);
}
public static class Game
{
public static Game startGame(#Nonnull final String playerOneName, #Nonnull final String playerTwoName)
{
final Player p1 = new Player(playerOneName);
final Player p2 = new Player(playerTwoName);
final Game game = new Game(p1, p2);
p1.setCurrentGame(game);
p2.setCurrentGame(game);
return game;
}
private final Player player1;
private final Player player2;
private Game(#Nonnull final Player player1, #Nonnull final Player player2)
{
this.player1 = player1;
this.player2 = player2;
}
}
public static class Player
{
private final String name;
private Game currentGame;
private Player(#Nonnull final String name)
{
this.name = name;
}
private void setCurrentGame(#Nonnull final Game currentGame)
{
this.currentGame = currentGame;
}
}
}
Notes:
You might be tempted to create the Player objects in the Game constructor and pass this into the Player objects constructors to set the reference to the Game object.
Resist this temptation, this is called leaking the this reference which in the constructor is bad because it loses all the guarantees that the Game object is completely formed.
Also both of these solutions still have a circular dependency on each other.
The first isn't so bad because the Player class is an inner class of Game. The second is a simple but naive solution that works for small scale applications but not for larger more complex applications.
For example, there is a class Warrior which have linked class Sword. In class Sword defined field: public static int hp = 100; which shows the health points consumed by this type of weapon. There is need for a few classes Warrior. I think I need to define in class Warrior the link Sword (only once) to be able to get static field hp. How can I link it properly?
class public Warrior{
public String name;
public Sword s = new Sword(); // ???
}
class public Sword{
public static int hp = 100;
}
Will new Sword() create link to class each time new Warrior created?
Can I define Sword class as static inside another Weapon class? (There is a need for multiple classes like Sword)
Is following structure correct? Can outer class be static and hold inside another static?
class public Warrior{
public String name;
public int SwordHp = Weapon.Sword().hp;
public int BowHp = Weapon.Sword().hp;
}
(abstract?) public static class Weapon{
public static class Sword{
public static int hp = 100;
}
public static class Bow{
public static int hp = 90;
}
Yes, every time you will get a new Sword.
But, because hp is a static field, you will only get one of those.
Take a look at this link for more information:
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
I'm not sure what you exactly want, but as your code example is now, the construction of a Warrior causes the construction of a Sword.
It depends on what you mean by "health points consumed by". If you want to keep track of all the damage this type of weapon has caused, you are good with your static HP field. If this is what you want, I would recommend using a system that keeps track of all sort of statistics. Something like this:
Statistics.getStatisticsForPlayer(playerName). // Get the statistics for a player
increaseValue("damage_caused_by_sword", extraDamage); // increase that property
If you want to keep track of the health points per sword (which looks the most realistic to me, because a Sword isn't sharp forever), you should create the field non-static. This makes the field a property of every Sword instance.
For getting Static field hp you do not need to create
public Sword s = new Sword();
In warrior class. Static variables initialize on load. So you can access you hp anywhere without declaring in the specific classes by just using
Sword.hp ;
This do not have any impact on static variables.
Sword s = new Sword()
As i understand you Have a warrior and different weapons as currently Sword.Every weapon has health points hp and Every Warior has its own weapon and health points. If you use static fields then these health points will be shared among all warriors if 50 wariors then all will using just 100 points togather which i expect you do not want so you should use:
class public Warrior{
public String name;
public Sword s = new Sword(); // ???
}
class public Sword{
public int hp = 100;
}
It will create a new sword with 100 health points every time a warrior is created and every warior will consume his own health points. Hope it will help.
If hp is static, you don't need a member Sword at all. You can access that field with Sword.hp.
If the number of weapon types is constant then enum would work well.
enum Weapon {
Sword(100),
Bow(90);
private final int hp;
private Weapon(int hp) {
this.hp = hp;
}
int getHp();
}
public class Warrior {
public String name;
public Weapon weapon = Weapon.Sword;
}
I am a first year programming student. I have coved the basics of precedual programming in c++. I am now fairly new to Java.
Recently i have taken a keen interest into game programming.
my situation:
my situation:
I have a hero class and a rival class. each with thier own members and methods.
how can i make it possible for the hero to interact with the rival, do i do this through the use of interfaces? for example an interface with an undefined attack method
and have both the class implement that interface?
if so
what should the code look like in the attack method of both classes
something likes this
example:
// heros version of implemented method
public int attack()
{
// idealy when hero attacks, the health value will be reduced by 15 of what it is.
rival1.getHealth(- 15)
}
// rival version of implemented method
public int attack()
{
// idealy when rival attacks, the health value will be reduced by 15 of what it is.
hero1.getHealth(- 15)
}
Please help me understanding why we use interefaces and , the anwser to my question
any help or suggestions will be greatly appreciated :) .
I would say you should not use an interface. A better approach would be to use a superclass. With a superclass you can avoid redefining many of the methods that will, presumably, be shared by both the rival and the hero. Here is an example implementation:
Superclass:
public abstract class ExampleFighter {
private String name;
private int health;
private boolean isDead = false;
public ExampleFighter(String name, int health) {
this.name = name;
this.health = health;
}
public void attack(ExampleFighter ef) {
int damage = 0;
//calculate damage dealt
damage = 10;
ef.takeDamage(damage);
}
public void takeDamage(int damage) {
//manipulate the amount of damage taken
if(health - damage <= 0) {
health = 0;
isDead = true;
} else {
health -= damage;
}
}
public boolean isDead() {
return isDead;
}
}
Subclasses:
public class ExampleHero extends ExampleFighter {
int reputation; //the general opinion of the hero
public ExampleHero() {
super("Hero Oreh of Herosville", 100);
reputation = 0;
}
public void improveReputation() {
reputation++;
}
}
public class ExampleRival extends ExampleFighter {
public ExampleRival() {
super("Your greatest rival", 101);
}
}
The side effect of this system is that it requires a fourth class to actually play the game:
public class ExampleGame {
private ExampleHero hero;
private ExampleRival rival;
public static void main(String... args) {
ExampleGame game = new ExampleGame();
game.start();
}
public ExampleGame() {
hero = new ExampleHero();
rival = new ExampleRival();
//what ever other game setup you need to do.
//alternately you could have a load() method
//that takes care of most of this.
}
private void start() {
//make your run loop or query the user for input
//or whatever you need to do. I will create an
//example run loop
boolean running = true;
while(running) {
//this whole block should be moved
//to another method called gameUpdate()
//or something similar but since this
//is a quick example I'll just leave it
//here
hero.attack(rival);
rival.attack(hero);
if(rival.isDead()) {
hero.improveReputation();
System.out.println(“Your rival is dead!");
running = false;
} else if(hero.isDead()) {
System.out.println("you died :(");
running = false;
}
}
}
}
Now this might seem a bit complicated but it illustrates a very important concept: separation of concerns. Separation of concerns involves putting code and making classes that make sense. A player should not know who it’s rival is, player might not even know that enemies exist or what sort of terrain it’s standing on. But a player should know how to manage it's health, it's name, how to take damage, etc. In contrast a Game object would need to know about all the players and enemies so it can tell them to fight and move around on the screen. This is an informal definition of seperation of concerns, for more accurate information read the wikipedia page. In this example I separated the hero and the rival so that, later, you can add more enemies without having to modify your hero code every time. This system also allows you to expand on the game's UI without affecting the player or rival. If you wanted to add a GUI to your game you could add an initialize() method in ExampleGame that setup the GUI. Then in the game loop you could call methods to draw images and graphics onto the GUI. With seperation of concerns you can make the system far more modular and easy to use.
Your second question is: why do we use interfaces? Interfaces are a way of making sure that other classes have a behavior you need them to have, without specifying exactly how they should do it. A classic example of the use of interfaces is the Comparable interface. The Comparable interface has one method that it’s must be implemented: compareTo(). The purpose of this method is to allow a ranking of value objects (think String or File) that cannot use the standard boolean mathematical operations (<, >, ==, etc.) You can think of it as like signing a contract. You (the class implementing the interface) agree to have a certain set of functionality however you make that functionality is up to you. For more information read the java tutorial
I should add a caveat to this answer: Inheritance is not the best option. If you want to know how to do it right you should look up MVC (Model View Controller) and Component Based Design. Even these may not the best choice for what you're doing but they're good starting points.
I think you're going to want to break it up into a Fighter class and a FightController class. Then the Fighter would be assigned to either the hero or the rival in the FightController.
So, it would essentially be something like the following (don't mind the sloppy rudimentary code, I haven't written Java in ~2 years, I just slapped this together and I'm not sure it will compile):
public class Fighter {
private int health;
private boolean isTheHero;
public Fighter(int startHealth, boolean hero) {
health = startHealth;
isTheHero = hero;
}
public void adjustHealth(int change) {
if (change > health) {
return 0;
}
health -= change;
return health;
}
public boolean isHero() {
return is_hero;
}
public boolean wasBeaten() {
return health <= 0;
}
}
public class FightController {
private Fighter hero;
private Fighter rival;
private boolean isHerosTurn;
public FightController() {
hero = new Fighter(startHealth, true);
rival = new Fighter(startHealth, false);
isHerosTurn = true;
}
public void takeATurn() {
int hitValue = 15; //Do something to figure out the hit
remainder = 0;
if (hero.wasBeaten() or rival.wasBeaten()) {
sys.out.println("This match is already over");
} else {
if (isHerosTurn) {
remainder = rival.adjustHealth(hitValue);
if (remainder == 0) {
sys.out.println("The HERO wins!!!");
}
} else {
remainder = hero.adjustHealth(hitValue);
if (remainder == 0) {
sys.out.println("The Rival wins. Boo!");
}
}
isHerosTurn = !isHerosTurn;
}
}
}
Then you can do something like:
controller = new FightController();
controller.takeATurn();
controller.takeATurn();
controller.takeATurn();
controller.takeATurn();
on and on until the game is over.
You need to think in terms of a framework for java gaming.
Here's another post addressing the issue,
Game programming in Java?
Objects interact by sending messages. Look at it this way: when a player attacks, then he sends it's violent message to another players reveiveHit method.
Or, to implement it with a common design pattern: a player could send out attacks and other players observe it's behaviour and determine, if they have been hit.
What you shouldn't do: make one player depend on another one (like in your example). If you want to model a match, then add some sort of manager/referee that does the bookkeeping of attacks and effects.
Please help me understanding why we
use interfaces
Implementing an interface allows a class to become more formal about the behavior it promises to provide also they form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.
1 . Why we are implementing interfaces ?
2. Why do we need interfaces in Java?
and , the anwser to my question
Since your code has common attack( ) method in both the classes i.e Rival and Hero, best way would be to declare the method in an interface.
Remember, following is just a code-snippet, not the complete code. You can complete it yourself.
public interface Fight {
public int attack();
}
public class Hero implements Fight {
public int attack() {
rival1.getHealth(-15);
}
}
public class Rival implements Fight {
public int attack() {
hero1.getHealth(-15);
}
}
This is the interface for the character in the game which interact with each other.
public interface Character{ ... }
This is the interface if the character is able to attack or not.
public interface Fightable{
public void attack(Character character);
}
These are the two classes in your game which implements both the interfaces.
public class Hero implements Character, Fightable
{
// heros version of implemented method
public int attack(Character character)
{
// idealy when hero attacks, the health value will be reduced by 15 of what it is.
character.setHealth(-15);
}
}
public class Villon implements Character, Fightable
{
// rival version of implemented method
public int attack(Character character)
{
// idealy when rival attacks, the health value will be reduced by 15 of what it is.
character.setHealth(- 15);
}
}
My personal mini project was to learn arrays here, doing a slightly big jump by making an Array of Objects. What I wanted to do was a mini RPG system where I create a class called monster and give it a couple parameters, and create an array of objects of the Monster class. So far I believe I created that Monster class and the Object of Arrays inside the main method class (Exec_Monster) listed below.
It took me a while initially, but I finally got to a point where I can create the array of Monsters and access them inside the Main class. But is there a way for me to create this Array of Objects and access each object from another class (and their individual values)? For Example, I would create a "Battle" class and then I would pull the "Health" value from an object of Monster.
I'm new to Arrays but I have had some experience with classes for the past two weeks here.
Class:
public class Monster
{
public int hp;
public String n;
public Monster(String name,int health){
n=name;
hp=health;
}
public int returnHealth(){
return hp;
}
public String returnName(){
return n;
}
}
Exec_Monster:
public class Exec_Monster{
public static void main(String args[])
{//Define Monsters
Monster[] monsterid=new Monster[]{
new Monster("Goblin",10),
new Monster("Elf", 8),
new Monster("Ant", 3),
new Monster("Worm", 2),
new Monster("Black Widow",6)};
Random chooser;
int chosenmonster=(chooser.nextInt()*5);
//Start
//while (Battle.wonloss==true) {
// Battle.battle();
}
}
You'd need to pass the monsters into the Battle object somehow (or into another object that you pass into the Battle object). You could pass it as an argument to a method, but in an Object Oriented world, if the monsters really belong to a battle, you could pass them in the constructor and make them available in all the methods of the Battle class.
Example:
public class Battle {
private Monster[] monsters;
private boolean wonloss;
public Battle(Monster[] monsters) {
this.monsters = monsters;
}
public boolean isWonloss() {
return wonloss;
}
public void battle() {
// Do something with monsters,
// and then check if there is any life left in the monsters
int totalHp = 0;
for (Monster monster : monsters) {
totalHp += monster.hp;
}
if (totalHp == 0) {
wonloss = false;
}
}
}
The "battle" part of your main method would then look like:
// Start
Battle battle = new Battle(monsterid);
while (battle.isWonloss()) {
battle.battle();
}