patternjavaMinor
Card arithmetic game
Viewed 0 times
gamecardarithmetic
Problem
There was a task on Stack Overflow which quite obviously was too broad (it didn't have a solution provided or anything!) which was the following:
Give an object oriented design for a game that has the following
requirements:
They are Hearts - Sum, Diamonds - Subtract, Clubs - Multiply, Leaves - Divide.
-
The score of the player would be calculated by carrying out the particular operation on the card.
E.g. if a player has 1 of hearts, 2 of Diamonds, 4 of hearts,
the score would be calculated as +1 -2 +4, which is equal to 3.
-
Precedence of the operators would be given as input.
Give a design for the same.
Technically, I've just realized as I was writing this that I'm not providing the precedence of the operators as input and just evaluating them in order of the cards, but please excuse me for that.
Otherwise, I've implemented a possible solution to this given task:
```
public interface Operator {
double evaluate(double carrier, double newValue);
}
public enum Operations implements Operator {
ADDITION {
@Override
public double evaluate(double carrier, double newValue) {
return carrier + newValue;
}
},
SUBTRACTION {
@Override
public double evaluate(double carrier, double newValue) {
return carrier - newValue;
}
},
MULTIPLICATION {
@Override
public double evaluate(double carrier, double newValue) {
return carrier * newValue;
}
},
DIVISION {
@Override
public double evaluate(double carrier, double newValue) {
return carrier / newValue;
}
}
}
public enum CardTypes {
HEART(Operation
Give an object oriented design for a game that has the following
requirements:
- It is a game of cards.
- Cards can have four symbols - Hearts, Diamonds, Clubs, Leaves
- Cards have numbers from A to 10. These are the values of the cards.
- There is an operation associated with each symbol.
They are Hearts - Sum, Diamonds - Subtract, Clubs - Multiply, Leaves - Divide.
- Each Player would be dealt 3 cards.
-
The score of the player would be calculated by carrying out the particular operation on the card.
E.g. if a player has 1 of hearts, 2 of Diamonds, 4 of hearts,
the score would be calculated as +1 -2 +4, which is equal to 3.
-
Precedence of the operators would be given as input.
Give a design for the same.
Technically, I've just realized as I was writing this that I'm not providing the precedence of the operators as input and just evaluating them in order of the cards, but please excuse me for that.
Otherwise, I've implemented a possible solution to this given task:
```
public interface Operator {
double evaluate(double carrier, double newValue);
}
public enum Operations implements Operator {
ADDITION {
@Override
public double evaluate(double carrier, double newValue) {
return carrier + newValue;
}
},
SUBTRACTION {
@Override
public double evaluate(double carrier, double newValue) {
return carrier - newValue;
}
},
MULTIPLICATION {
@Override
public double evaluate(double carrier, double newValue) {
return carrier * newValue;
}
},
DIVISION {
@Override
public double evaluate(double carrier, double newValue) {
return carrier / newValue;
}
}
}
public enum CardTypes {
HEART(Operation
Solution
-
Tip: If Java 8 is available for you, you should instead implement
-
This is a personal preferences thing, but I'm not a fan of
You also don't really need a
One more thing,
-
Since a
-
You can probably inline
You can also consider removing the temporary variable
There's also another approach you may want to consider, which is to pre-shuffle your
-
To avoid the double
OperatorTip: If Java 8 is available for you, you should instead implement
DoubleBinaryOperator. This will be useful if you're dealing with DoubleStream.-
CardValuesThis is a personal preferences thing, but I'm not a fan of
_ prefix in variable names, since this is not exactly a recommended Java naming convention. I understand your usage here is to let you conveniently name your enum values as numbers, so it's really up to you whether to stick with it, or go with ACE, ONE, TWO, ... etc.You also don't really need a
value field for it, since you can always return (double)ordinal() + 1 (or ordinal() + 1.0, shorter due to the implicit casting of 1.0) from getValue().One more thing,
enum types' names are usually singular, but since you have consistently used the plural form, I think this is fine too. Generally, consistency over convention, over chaos.-
CardSince a
Card must have both a value and type, you should remove your no-args constructor.-
DeckYou can probably inline
new Card(...) below:// Card card = new Card(cardValues, cardTypes);
// cards.add(card);
cards.add(new Card(cardValues, cardTypes));You can also consider removing the temporary variable
currentDeckSize inside getCardFromDeck(), since the repeated method call is likely to be optimal enough.There's also another approach you may want to consider, which is to pre-shuffle your
Deck first (using Fisher-Yates perhaps, or one of the two available Collections.shuffle() method?), and then simply take from either the head or tail of your Deck. This would be more optimal in cases where you use an implementation that lets you perform an item removal without having to resize/shift its internal state, but then this is a minor point to consider for a simple 40-element Deck.-
GameTo avoid the double
for-loop, you can already start checking for the highest score in the first loop:double maxScore = Double.MIN_VALUE;
int winningId = -1;
for(int i = 0, n = players.size(); i maxScore) {
maxScore = result;
winningId = i;
}
System.out.println("Player " + (i + 1) + " had a score of " + result);
}
System.out.println("\nPlayer " + (winningId + 1) + " won with a score of " + maxScore);Code Snippets
// Card card = new Card(cardValues, cardTypes);
// cards.add(card);
cards.add(new Card(cardValues, cardTypes));double maxScore = Double.MIN_VALUE;
int winningId = -1;
for(int i = 0, n = players.size(); i < n; i++) {
double result = players.get(i).evaluateCards();
if (result > maxScore) {
maxScore = result;
winningId = i;
}
System.out.println("Player " + (i + 1) + " had a score of " + result);
}
System.out.println("\nPlayer " + (winningId + 1) + " won with a score of " + maxScore);Context
StackExchange Code Review Q#92393, answer score: 3
Revisions (0)
No revisions yet.