Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
I am writing a class to represent cricket players. There are four types of cricket players
1 wicket player
2 batsman
3 bowler
4 allrounder
I'm not sure if I am representing the players in the right way
public class Player {
final static int WICKETPLAYER=1;
final static int BATSMAN=2;
final static int BOWLER=3;
final static int ALLROUNDER=4;
int currentbatting;
int bowlerbating;
int playertype;
public Player(int i,int currentbatting){
this.currentbatting=currentbatting;
playertype=i;
}
public String whatTypeOFplayer(){
switch(playertype){
case WICKETPLAYER:
return "wicketplayer" ;
case BATSMAN:
return " batsman";
case BOWLER:
return "bowler";
case ALLROUNDER:
return "allrounder";
default:
return "error";
}
}
}
First of all, you should use enums to represent the player types instead of ints, like
enum PlayerType {
WICKETPLAYER,
BATSMAN,
BOWLER,
ALLROUNDER
}
Then you could use the name() method to get a string representation of the PlayerType.
If there's more to the player types that just the name (e.g. different behaviour, methods etc.), you might consider creating subclasses of Player, like class WicketPlayer extends Player.
A third way would be to use composition and add components like PlayerBehaviour etc. to the basic player class.
I terms of complexity, I'd say no. 1 is the easiest, whereas no. 3 might be too complex for you right now. So you might try and either use no. 1 or no. 2, depending on your requirements.
You are likely to be better off with an enum and an EnumSet.
public Role {
WICKET_KEEPER, BATSMAN, BOWLER, FIELDER
}
public static final Set<Role> ALL_ROUNDER = EnumSet.allOf(Role.class);
private final EnumSet<Role> roles;
private Role position;
public Player(EnumSet<Role> roles) { this.role = roles; }
public void setPosition(Role role) { this.position = role; }
public String whatTypeOFplayer(){
return roles.equals(ALL_ROUNDER) ? "allrounder" : roles.toString();
}
BTW Its a Wicket Keeper not a Wicket Player http://www.cricketscotland.com/system/files/images/13_13.jpg
A better way is to inherit from the class Player, it will allow you a simpler treatment for each player and different behaviors for common actions. for example:
Player.java
public class Player {
int currentbatting;
int bowlerbating;
int playertype;
public Player(int i,int currentbatting){
this.currentbatting=currentbatting;
playertype=i;
}
public abstract String whatTypeOFplayer() {
return playertype;
}
}
WicketPlayer.java
public WicketPlayer extends Player {
public WicketPlayer(int i,int currentbatting){
super(int i,int currentbatting);
playertype = "wicketplayer";
}
}
Batsman.java
public Batsman extends Player {
public Batsman(int i,int currentbatting){
super(int i,int currentbatting);
playertype = "batsman";
}
}
And so on.
use Java Enums: http://download.oracle.com/javase/tutorial/java/javaOO/enum.html
In this case - and because I smell homework - you should use one base class Player and a subclass for each player type.
Example:
public abstract class Player {
// some attributes and methods all players share
public abstract String whatTypeOfPlayer();
}
public WicketPlayer extends Player {
#Override
public String whatTypeOfPlayer() {
return "Wicket Player";
}
}
Bonus - then I'd use a factory to create players:
public PlayerFactory {
enum PlayerType {WICKETPLAYER, BATSMAN, BOWLER, ALLROUNDER}
public static Player createPlayer(PlayerType type, String name) {
switch(type) {
case WICKETPLAYER : return new WicketPlayer(name);
//...
}
}
}
If you are using Java 5+ use Enum Types Java Enum Types. According to Effective Java it's not a good practice to use a bunch of constants, instead use Enum.
public class Player {
public enum Role{
WICKETPLAYER,
BATSMAN,
BOWLER,
ALLROUNDER;
}
final int currentbatting;
final Role playerRole;
public Player(final Role role, final int currentbatting){
this.currentbatting=currentbatting;
this.playerRole=role;
}
public String whatTypeOFplayer(){
return this.playerRole.toString();
}
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm tryin to develop a small text-based fighting game and I'm using eclipse to help me out. I have two classes a Hero and Villian.
Hero Code so far:
public class Hero
{
// instance variables - replace the example below with your own
private int Health;
private int Punch;
private int Kick;
private int Special;
/**
* Constructor for objects of class Hero
*/
public Hero()
{
// initialise instance variables
Health = 100;
Punch = -30;
Kick = -25;
Special = -55;
}
Villian Code so far:
public class Villian
{
// instance variables - replace the example below with your own
private int Health;
private int Punch;
private int Kick;
private int Special;
/**
* Constructor for objects of class Villian
*/
public Villian()
{
// initialise instance variables
Health = 100;
Punch = -25;
Kick = -30;
Special = -50;
}
I want to make it turn-based as well so that when the hero attacks, it's the villian's turn. But I'm having trouble trying to construct a suitable method for the attacks. Can someone please help me with this?
The best way to solve this problem is to use inheritance.
You want to have one class called Entity which holds everything all things need on the game field:
public abstract class Entity {
private int Health;
private int attackDmg;
public Entity(int health, int attackDamage) {
this.health = health;
this.attackDamage = attackDamage;
}
}
Then the two classes you currently have simply inherent everything from Entity:
public class Hero extends Entity {
public Hero() {
super(100, 30);
}
}
and Villian:
public class Villian extends Entity {
public Villian() {
super(100, 20);
}
}
Now you probably want to have some methods that makes the Entity take damage. Because everybody should be able to take damage it comes into the Entity class. Also you probably want to have an attack method, that tells you how much damage the entities does:
public abstract class Entity {
// [...]
public void takeDamage(int damage) {
health -= dmg;
}
public void attack() {
return attackDamage;
}
}
Now you can write in your controller class (that handles all of the turn based logic):
player.takeDamage(villian.attack()); (Given that playeris your Playerand villian your Villian).
Of course this only is a small example, you could also make a method that take a String as an argument, which represents the method of the attack (like "kick" or "punch") and then return different amounts depending on the attack type.
Further infos to inheritance:
http://www.tutorialspoint.com/java/java_inheritance.htm and http://beginnersbook.com/2013/05/java-inheritance-types/
You might also be interested in a game making tutorial:
http://www.gametutorial.net/
You might take a variable like flag and set its value to 1 when hero's turn and its value to 0 when villan's turn
if(flag==1)
{
villans turn;
flag=0;
}
else if(flag==0)
{
heros turn;
flag=1;
}
This works
I'm trying to track class stats for an android game I'm working on.
public static class characterClasses {
public String class_name;
public int base_hp;
public int base_attack;
public float base_defense;
}
I want to access these directly by name so I won't have to iterate over them repeatedly. From my research it looks like a hashmap or map would be what I need but everything I've seen is only for a single key/value pair. I need to access each stat value directly by class and value, something like
classList.get("warrior").get("base_hp");
Can someone point me in the right direction?
You are correct to think of using HashMap. You can use the characterClass String names as keys and the characterClasses as values. You can then use your getter methods to access your specific fields i.e.
classList.get("warrior").getBase_HP();
You could also forget maps entirely since these stats seem constant by using inheritance
public class Character {
int hp;
int attack;
int defense;
public Character (int hp, int attack, int defense) {
this.hp = hp;
this.attack = attack;
this.defense = defense;
}
public int getHP() {
return hp;
}
...
}
For your Character subclasses, you can preset those values in the constructor
public class Warrior extends Character {
public Warrior() {
super(2, 10, 8);
}
public int getHP() {
return super.getHP();
}
}
public class Wizard extends Character {
public Wizard() {
super(10, 3, 1);
}
public int getHP() {
return super.getHP();
}
}
This way all your Warrior and Wizard Objects will have the same stats that can be accessed any time simply by invoking their getters.
I've been working on a game, and in the game I'm a summoner that has tamed monsters (much like pokemon).
What I want to do , is have a backpack of 5 tamed monsters, of which I can spawn 1 at a time.
Someone recommended me to use enums (I can't contact that person anymore :(), so I've been looking at a few enum tutorials and examples, and I can't figure out how this would help me.
Let us say that the enum would look like this :
public enum TamedMonsterStats {
ELF(0,"res/siren_monster_girl_sprite_by_tsarcube-d52y2zu.png",0,100);
DRAGON(0,"res/dragon.png",0,100);
private int haveit;
private String photoname;
private int typeOfDamage;/*
* 0: dark
* 1: light
* 2:
*/
private int HP;
TamedMonsterStats(int haveit,String photoname,int typeOfDamage,int HP){
this.haveit = haveit;
this.photoname = photoname;
this.typeOfDamage = typeOfDamage;
this.HP = HP;
}
public int getHaveIt(){
return haveit;
}
public String getPhotoName(){
return photoname;
}
public int getTypeOfDamage(){
return typeOfDamage;
}
public int getHP(){
return HP;
}
public void setHp(int hp) {
HP = hp;
}
}
This would kind of work, but as daveychu pointed out, this makes it impossible for me to have 2 instances of the same creature, so my idea was to have an enum backpack with monster1,monster2,monster3,monster4,monster5 , and then filling them with the values dynamically, but I feel like doing this means I shouldn't be requiring enums at all, is this true?
You can add a setter method on your enum:
public void setHp(int hp) {
HP = hp;
}
However, I'm a bit wary of your use of enum. In this situation, only one "DRAGON" instance could exist at any time so I wonder what you would do if the user wants to have more of them or if the enemy has one at the same time.
Your typeOfDamage on the other hand is an excellent candidate for an enum:
public enum DamageType {
DARK,
LIGHT,
NORMAL
}
You can then use this enum:
ELF(0, "res/siren_monster_girl_sprite_by_tsarcube-d52y2zu.png", DamageType.DARK, 100),
DRAGON(0, "res/dragon.png", DamageType.LIGHT, 100);
private DamageType typeOfDamage;
TamedMonsterStats(int haveit, String photoname, DamageType typeOfDamage, int HP) {
this.typeOfDamage = typeOfDamage;
}
public DamageType getTypeOfDamage() {
return typeOfDamage;
}
It makes it a lot more readable than having to pass some random integers.
For now, I have a class with fields.
#Entity
public class Fuel {
#Id #GeneratedValue
private Long id;
private boolean diesel;
private boolean gasoline;
private boolean etanhol;
private boolean cng;
private boolean electric;
public Fuel() {
// this form used by Hibernate
}
public List<String> getDeclaredFields() {
List<String> fieldList = new ArrayList<String>();
for(Field field : Fuel.class.getDeclaredFields()){
if(!field.getName().contains("_") && !field.getName().equals("id") && !field.getName().equals("serialVersionUID") ) {
fieldList.add(field.getName());
}
Collections.sort(fieldList);
}
return fieldList;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isDiesel() {
return diesel;
}
public void setDiesel(boolean diesel) {
this.diesel = diesel;
}
public boolean isGasoline() {
return gasoline;
}
public void setGasoline(boolean gasoline) {
this.gasoline = gasoline;
}
public boolean isEtanhol() {
return etanhol;
}
public void setEtanhol(boolean etanhol) {
this.etanhol = etanhol;
}
public boolean isCng() {
return cng;
}
public void setCng(boolean cng) {
this.cng = cng;
}
public boolean isElectric() {
return electric;
}
public void setElectric(boolean electric) {
this.electric = electric;
}
}
I think it makes sense, but when I asked another question (maybe a stupid example since there can only be either automatic or manual gearbox) https://stackoverflow.com/questions/11747644/selectonemenu-from-declared-fields-list-in-pojo , a user recommend me to use enums instead. Like this way:
public enum Fuel {
DIESEL("diesel"),
GASOLINE("gasoline"),
ETANHOL("etanhol"),
CNG("cng"),
ELECTRIC("electric");
private String label;
private Fuel(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
}
However, since there exists hybrids on the market (like Toyota Prius) the parent class would implement the boolean class at this way:
private Fuel fuel = new Fuel();
and if using enumerated list at this way:
private List<Fuel> fuelList = new ArrayList<Fuel>();
What is the best practice? Keep in mind that I might have 100 different fuels (just for example =). Do not forget that it is an entity and hence persisted in a database.
Thanks in advance =)
It sounds to me like you want an EnumSet, yes, definitely over a bunch of bool's.
This reminds me a lot of the design patterns for flags and I recently posted an SO question on exactly that: Proper design pattern for passing flags to an object
This supports having 100 different fuel types easily. However it doesn't support a car using 100 different fuel types simultaneously easily. But that to me sounds perfectly fine - it would be very hard to build such a car and this is perfectly reflected in the programmatic complexity of coding this :) (Unless of course it really was just supporting all corn-based fuels - in which you might prefer a polymorphic pattern.)
You should definetly use enums.
Image you want to get the fuel-type of an object.
If you would use bools you would end up with something like this:
if (myClass.IsGasoline())
else if (myClass.IsOtherFuel())
else if
...
If you use enums you can simply do something like:
Fuel fuel = myClass.GetFuelType()
(This is just pseudo-code ;))
If the number of hybrids is low, and I guess it will be better to use Enums, and include hybrids as a different case.
Otherwise you will have to manage the logic in a way that can be cumbersome, as when you set a certain Fuel to true you, most likely, will have also to set to false the current one set to true. I am saying this as you have setters for your fuel categories and you don't only define at construction.
EDIT: the way on how to ask for the type of fuel you are using would also be an argument in favor of enums.
I have a year object. For now lets say only two years and its getters and setters
private String mYearOne;
private String mYearTwo;
public String getmYearOne() {
return mYearOne; }
public void setmYearOne(String mYearOne) {
this.mYearOne = mYearOne; }
public String getmYearTwo() {
return mYearTwo; }
public void setmYearTwo(String mYearTwo) {
this.mYearTwo = mYearTwo; }
Then each year has three insurance plans. And its getters and setters.
private String healthPlan;
private String carPlan;
private String housePlan;
private String healthPlanTwo;
private String carPlanTwo;
private String housePlanTwo;
public String getHealthPlan() {
return healthPlan; }
public void setHealthPlan(String healthPlan) {
this.healthPlan = healthPlan; }
public String getCarPlan() {
return carPlan; }
public void setCarPlan(String carPlan) {
this.carPlan = carPlan; }
public String getHousePlan() {
return housePlan; }
public void setHousePlan(String housePlan) {
this.housePlan = housePlan; }
public String getHealthPlan() { //For the second year
return healthPlan; }
public void setHealthPlan(String healthPlan) {
this.healthPlan = healthPlan; }
public String getCarPlan() {
return carPlan; }
public void setCarPlan(String carPlan) {
this.carPlan = carPlan; }
public String getHousePlan() {
return housePlan; }
public void setHousePlan(String housePlan) {
this.housePlan = housePlan; }
public String getHealthPlanTwo() {
return healthPlanTwo; }
public void setHealthPlanTwo(String healthPlanTwo) {
this.healthPlanTwo = healthPlanTwo; }
public String getCarPlanTwo() {
return carPlanTwo; }
public void setCarPlanTwo(String carPlanTwo) {
this.carPlanTwo = carPlanTwo; }
public String getHousePlanTwo() {
return housePlanTwo; }
public void setHousePlanTwo(String housePlanTwo) {
this.housePlanTwo = housePlanTwo; }
You will notice the code is bulky. I need to define them in a <list> of year. So that if 10 years are considered, I would have 10 multiplied
by 3 = 30 plans and its getters and setters respectively.
How could this be done?
I think your best bet will be to maintain a count of number of years and arraylists for the insurance plans. This way, you can get the arraylist once and get the insurance plan details for whatever year you actually want. This will be characterized by a single insurance plan arraylist and a single arraylist for years.
private ArrayList mYear;
private ArrayList healthPlan;
private ArrayList carPlan;
private ArrayList housePlan;
public String getHousePlanForYear(String year){
return housePlan.get(mYear.indexOf(year));
}
public void setHousePlanForYear(String housePlan, String year){
this.housePlan.set(mYear.indexOf(year), housePlan);
}
Similarly for the other plans. Of course, all this is assuming that the year is always present and other boundary conditions. Just add your boundary checks in these getters and setters and you will be good to go. :)
I see a design/domain modelling problem here. A person can ideally have multiple "plans" and "riders" attached to each plan. This should clearly be abstracted away properly by creating a "PlanCollection" class or simply maintaining a list of "plans" which all extend/implement a common "Plan" class/interface.
Each plan can have a "plan" duration and a start date. Also, logically, you don't attach plans to "year" but the timeline information is encapsulated in the Plan itself (like start and duration as mentioned above).
Take a look at enums and maps. The enum would specify car, house etc.
You could create a map that takes an enum as key and a List of years as the key. Don't be tempted to create YearThree etc.
On a note of style: if you intend to use m to prefix fields, take the m out of the setter. E.g. setYearOne not setmYearOne.
Choose your types wisely, don't use a String if an int is better.