Got a design patterns question (some terminology related to Java as that's my current project).
Current layout of code:
class Game - holds game state and manages logic,
Super abstract class Player
Player has subclasses for different types of players (AI, human, etc).
Each player can make up to three moves (A, B, C) but they must be in that order. Hence a player may on their turn choose any of the following move sequences:
(A,B),
(B,C),
(A, B, C)
(A, C),
(a),
etc
Players should receive feedback between each move so that they may decide whether to execute another or end their turn.
Assuming set of type abstract Player here are two designs I have:
Solution 1:
for all players in set call player.takeTurn(game). So every player knows when it is their turn and they have a reference to the current Game object. Their turn ends when takeTurn() returns. Player.takeTurn is overridden by all subclasses of player. Within the method, any player who wishes to carry out moves can reference the passed in Game object. example:
game.makeMoveA(),
game.makeMoveB(),
etc
Game.makeMove() can return ok/error values to tell the player whether the move was legal or not. Also, the updated game state is available by the Game object that is still in scope within the takeTurn() method.
Problem is that you are relying on all subclasses to remember to call makeMove() What if they don't or what if they call them in the wrong order? I guess that calling methods in the wrong order could be handled by exceptions/error messages but we still have the problem that nothing enforces the instantiated class to actually respond and make a move.
Solution 2:
Abstract class Player contains three abstract methods getMoveA getMoveB and getMoveC.
Hence all inheritors must implement these methods.
The abstract super class Player contains a method takeTurn().
takeTurn(Game game) {
game.makeMove(this.getMoveA())
game.makeMove(this.getMoveB());
etc
}
This is nice as behaviour is enforced but now we have a messy problem of how to give feedback to the player who made the move. What if it was an illegal move, etc. You could enforce another method handleMoveResponse() but then every player has to keep track of what move the success/error message refers to.
Any ideas? Would love to hear your opinion on this.
Many thanks
It looks to me like you are trying to get your requirements to fit a pattern rather than breaking down the requirements until you see the pattern.
A brief attempt at implementing your requirements produced this. There's a Strategy pattern and a Template pattern in there that doesn't seem to have the issues you mention.
enum Move {
A, B, C;
}
class Strategy {
final List<Move> moves;
public Strategy(List<Move> moves) {
// TODO: Make sure it is valid.
this.moves = moves;
}
}
class Game {
}
abstract class Player {
// Call before each move.
abstract Strategy getStrategy(Game game);
void move(Game game, Move move) {
// By default do nothing.
}
}
/**
* The rules control the game.
*/
class Rules {
public void play(Game game, Player player) {
while (!gameOver(game)) {
Strategy strategy = player.getStrategy(game);
for (Move move : strategy.moves) {
player.move(game, move);
// Do your feedback here.
}
}
}
private boolean gameOver(Game game) {
return false;
}
}
Related
I am creating the board game Tic Tac Toe in Java.
A cell will have three states: empty, X or O.
What is the best practice for representing this in Java? Should I create its own Cell class or just use integers (0/1/2) to represent the three states? If it had two states then I could use for example boolean to represent the two states, is there a similar already defined class for something with three states?
I would use an enum for this:
enum CellState {
EMPTY,
X,
O
}
And then in your code:
public static void main(String[] args) {
CellState[][] cellStates = new CellState[3][3];
cellStates[0][0] = CellState.X;
// Do other stuff
}
I just defined the board structure as CellState[][] as example but this can be whatever.
About the most important thing when using an OO language is that objects model behaviour and, where possible, contain the data required to implement the behaviour. Behaviour is what the objects do, not what is done to them.
So unless there is a reason to in a requirement you haven't stated, the cell itself doesn't have any behaviour, it is just a place that the players mark.
So you could have a simple array of marks that both players update, with an enum with three values, or you could have each player update their own data of the marks they have made, in which case each player would have either a boolean array or a short bit mask to indicate their goes. In the latter case, each player then only changes the state of their own 'goes' and can implement the test for their winning condition rather than having shared state - the only sharing is they have to ask the other player whether the chosen cell is valid. It depends how strictly OO you want your design to be as to whether this is 'best practice' or not - for such a simple problem you could write in COBOL and the users would be as happy.
I would use an enum :
public enum CellState {
EMPTY,
X,
O;
}
And a Cell class that has a field of type CellState
You could use an enum which contains the three values, like:
public enum CellState {
EMPTY,
X,
O
}
And use it like in a way like this:
board.setCell(cellposition, CellState.X);
There are multiple approaches but in this case I prefer using an enum to represent your state.
public enum State {
EMPTY,
X,
O
}
And then your cell class would look something like this.
public class Cell {
private State state;
public Cell(State state) {
this.state = state;
}
public State getState {
return state;
}
public void setState(State state) {
this.state = state;
}
}
The other way is just to use Boolean object and to use null as third state.
Boolean state = null; // => empty state
state = Boolean.TRUE // => X state
state = Boolean.FALSE // => O state
Suppose I'm making a game:
public class Game {
Board board;
public ArrayDeque<Player> players;
//Players can have 'knights' and the one with the largest number
//is referenced by the game.
public Player playerWithLargestArmy;
...
}
At the beginning, when a game like this is initialised, no player can have the largest army (a player only has an 'army' once they have a certain number of knights). I want to assign the playerWithLargestArmy a value, but I'm not sure what. I also don't want to use null since I could just leave the implicit assignment to do that (and using null is bad practice anyway).
I am looking for someone to explain to me how I can resolve this issue. I looked up factories and builders but I'm not sure they handle this kind of delayed assignment. For context, each player has an int field specifying how many knights they have.
I could resolve this with a boolean for each player saying whether or not they have the largest army, but then you'd need to iterate through the players to find that player, which isn't ideal. Even if, in my case, that isn't a huge sacrifice, I'd still like to know for future reference.
There is java.util.Optional<T> class for such case.
It have isPresent() and get() (and several other) methods which give you ability to check that object is present and get instance of underlying object.
Examples
Declaration
Optional<Player> playerWithLargestArmy = Optional.empty();
Assignment of value
playerWithLargestArmy = Optional.of(newValue);
Usage of value
if(playerWithLargestArmy.isPresent()) {
Player p = playerWithLargestArmy.get();
}
or even better
playerWithLargestArmy.map(p -> doSomethingWithIt(p));
which will invoke doSomethingWithIt only if value is present.
Null Object Pattern
https://en.wikipedia.org/wiki/Null_Object_pattern
public class Army {
public static final Army NullArmy = new Army(0);
private int size;
public Army(int size) {
this.size = size;
}
}
Now when you create a new Army, just set the initial value to Army.NullArmy.
In Factory method pattern there are 2 lead implementation (correct me if I'm wrong):
When Creator class is being abstract and not providing an implementation for the Factory method:
public abstract class CasinoGameCreator {
public void playGame() {
ICasinoGameType gameType = createGame();
gameType.play();
}
public abstract ICasinoGameType createGame();
Or, we can have the Creator class be a concrete class that provides implementation for the Factory method:
public class CasinoGame {
public static CasinoGame createGame(GameType type) {
if (type == GameType.BlackJack) {
return new BlackJackGame();
} else if (type == GameType.Poker) {
return new PokerGame();
} else {
return null;
}
}
}
Is there any strong preference when to use each implementation? if there is, in what general situations we whould prefer using the 1st approach over the 2nd?
Option 1 is following the Open/closed principle. This means: it is open for extensions (as different subclasses can implement different ways of creating a game); but it is closed for modification - the behavior of playGame() is fixed. Well, it is not; but if you use this pattern, you really would want to make playGame() to be final. If you have such an abstract class with an implementation X; and an abstract method Y (used within the other method X); than it doesn't much sense to allow subclasses to change X.
Option 2 is helpful when you are really sure about the different type of games; meaning: chances that this enum will ever change are small. Given the idea of games in casino; I very much doubt that this would be true here. Probably you could add a new game every other day. And then, you have to turn to each place that switches over the GameType and adapt that code.
So, given those thoughts, option 1 would be the first choice - because you can simply add a new game type by creating a new subclass of your creator class. This means: you can add a new game without touching the code responsible for other games.
Of course: if you would pick a different example, the requirements might be different, and then option 2 might have certain benefits.
So apologies if this question has been answered already, although I did have an extensive look but couldnt quite find the answer. To sum up the situation I am trying to create a simulator program that deals with different predator and prey creatures and currently have the issue of getting each creature to check what type of creature it is next to, which I would prefer to do checking if the instance belongs to the same object.
So say for example I did this:
private class Creature {
...
Creature [] fish = new Creature();
Creature [] shark = new Creature();
Creature [] penguin = new Creature();
}
and then created several instances (creatures) of each type in a loop like so:
for (int f=1;f<rnd;f++) {
fish[f] = new Creature();
//set attributes of creature
and then so the program can tell where they are located in relation to each other I created a grid system like so:
Creature [][] gridloc = new Creature[x][y]; //relates to number of spaces tiles that determines movement.
Creature [] crloc = new Creature[tc]; //stores a reference to all creatures created.
...
crloc[tc] = fish[f]; gridloc[x][y]=crloc[tc] //or fish[f]
}
Anyway to sum even tho I summarised the code there quite a lot, that all works but when getting each creature to check next to it in gridloc for what is there e.g. a predator I am unsure of a way to check if it finds another creature to determine if that is an instance of the same object type or a different one. So something like:
if (!gridloc[x][y].getObject().equals(gridloc[x+1][y].getObject()) //if the current creature is not the same as the one next to it.
I am aware of things like instanceof but that only works with checking if an object is an instance of a class, not if a instance belongs to the same type of object. I also can't simply use fish[1].equals(fish[2]) because they have different attributes and that would check if they are exactly the same.
Any ideas/suggestions would be welcome. Thanks!
You need to look into Polymorphism (http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html). You declare a Creature as a base class (or interface) and extend/implement from Creature class for each type of a creature you have. Each subclass will implement it's own methods to override Creature and allow you to correctly use the methods and also to detect the type using the class metadata that each instance will have.
It's an issue with your design. You have to create a Super class called Creature and sub classes for fish , penguin and all others. Then create the arrays with those sub class types. Then you can do the instanceof checks with your adjacent objects of the grid.
This design is based on Polymorphism.
In the long run this is the best approach since code is more clean and structured. If you do this way, even after few years when you take a look at the code; still it will make sense.
One option (and perhaps the best in the long run, see answers by #AlexC and #Don) would be to make subclasses of Creature, called Fish, Shark, Penguin etc. Then you can use instanceof.
To combine that with polymorphism, you'd add a method public boolean eats(Creature other) As an aside, when I helped babysit a 4 year old his favorite game with little plastic animal figures was "what eats what" with loud screams of delight.
In Creature, the code would be return false; (though arguably fish eat fish?)
In Penguin, the code would be return other instanceof Fish;
In Shark, the code would be return true;
Another option would be to have a field of Creature that describes it. Maybe an enum, or a String for the latin classification names. Then, you could use something like genus.equals("Carcharodon") for Shark or latinName.contains("Spheniscidae") for Penguin.
Maybe creature should be an enum...
public enum Creature {
FISH(false), SHARK(true), PENGUIN(true);
private boolean isPredator;
private Point gridLocation;
Creature(boolean isPredator) {
this.isPredator = isPredator;
}
// ...getters/setters
}
with a separate world class for grid locations...
public class World {
List<Creature> creatures = new LinkedList<>();
public boolean isNearPredator(Creature c) {
for (Creature i : creatures) {
if (i.getGridLocation().distance(c.getGridLocation()) < 2
&& i.isPredator()) {
System.out.println("About to get eaten!");
}
}
}
}
I'm building a basic game from a brief, and have been given some code to look at. All characters in the game are game objects, some are moveable ones, and some aren't. The moveable ones have a position and direction.
I have been given a MoveableObject class (below). Moveable GameObjects instantiate this class in their own constructor. I have not been guaranteed this code is right, so I'm trying to grasp the theory behind it.
public class MoveableObject {
int speed;
String direction;
public MoveableObject(){
speed = 0;
direction = "unknown";
}
public MoveableObject(int iSpeed, String sDirection){
speed = iSpeed;
direction = sDirection;
}
and all the moveable characters create an instance of this class in a constructor. For example, from a vampire class.
public class Vampire
public Vampire(){
MoveableObject thisObject = new MoveableObject(30, "South-East");
}
}
To my knowledge, this is known as aggregation. I thought this was to be used in a HAS-A relationship, and not an IS-A. Since a character IS-A moveable object, should I not use inheritance or an interface? I also don't understand why you need to create an instance of a MoveableObject, if each character either is or isn't moveable, surely, you should give them the ability to be moveable or not (through inheritance or interface) and then instantiate the character?
Thanks in advance.
That depends if the MoveableObject class also takes care of the actual movement of the object (i.e. update its position according to the speed and direction members) or just holds the speed and direction members so that the engine module of the game will use it to calculate the object's position.
In the latter case I would change the name of the MoveableObject class to something more appropriate and stick with the aggregation. Otherwise an inheritance will be more appropriate for movable objects. That way the moving logic will be implemented once and the sub classes can take care only for their own specific need.
To explain further if the MoveableObject is just a data container you can create an interface :
public Interface Moveable {
public MoveableObject getMovementData();
}
and each moveable class will look like :
public class Vampire implements Moveable {
.
.
private MoveableObject movementData; //
.
.
public MoveableObject getMovementData() {
return movementData;
}
}
and in your game engine hold an array of all moving objects (Type moveable) and in the update method get the movement data and process it:
public Class GameEngine {
.
.
private ArrayList<Moveable> movableObjects = .....
.
.
public void gameUpdate() {
for (Moveable moveableObj : movableObjects) {
MoveableObject movementData = moveableObj.getMovementData();
// Process and update as required using the given data
}
}