patternjavaMajor
Texas Hold'em in Java
Viewed 0 times
holdjavatexas
Problem
I have been a programmer for 12 years, mainly ERP software and C development and
am looking to make a career/specialty change to Java. I've read it countless
times if you want to learn a new language you need to write code, then write
some more code and then finally write more code. So I've written some code!
I love Poker, so I have written a small Texas Hold'em program. Here is the overview of what it does:
There are 6 .java files (see below for links). I used an interface, created my own comparators, even implemented some try/catch blocks (although I'm still learning how to use these properly).
Player.java
```
public class Player {
private Card[] holeCards = new Card[2];
//constructor
public Player(){
}
public Player(Card card1, Card card2){
am looking to make a career/specialty change to Java. I've read it countless
times if you want to learn a new language you need to write code, then write
some more code and then finally write more code. So I've written some code!
I love Poker, so I have written a small Texas Hold'em program. Here is the overview of what it does:
- Asks the user for the number of players
- Create a deck of cards
- Shuffle
- Cut the deck
- Deal players hole cards
- Burns a card
- Deals flop
- Burns a card
- Deals turn
- Burns a card
- Deals river
- Prints the deck to console to show random deck was used
- Prints the 'board'
- Prints burn cards
- Printers players cards
- Evaluates the value of each players hand (Royal flush, full house, etc...)
There are 6 .java files (see below for links). I used an interface, created my own comparators, even implemented some try/catch blocks (although I'm still learning how to use these properly).
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TexasHoldEm {
public static void main(String[] args) throws Exception {
// variables
Deck holdemDeck = new Deck();
int numPlayers = 0;
int cardCounter = 0;
int burnCounter = 0;
int boardCounter = 0;
Board board = new Board();
// initializations
numPlayers = getNumberOfPlayers();
Player[] player = new Player[numPlayers];
/* 3 shuffles just like in real life. */
for(int i=0;i9)){
throw new Exception("Error: Number of players must be an integer between 1 and 9");
}
return intPlayers;
}
}Player.java
```
public class Player {
private Card[] holeCards = new Card[2];
//constructor
public Player(){
}
public Player(Card card1, Card card2){
Solution
Let's start with the most basic, the
Except during development, it's custom to explicitly import only the classes you need instead of using wildcards.
It's is most certainly a valid choice to store rank and suit as
IMHO cards are a prime example for immutable objects. There is no reason to need to change the rank or the suit of a card, so I would drop the setters.
It's very unusual to use underlines in variable names in Java, especially two as a prefix. I would simple name the parameters
It may be worth thinking about, if these actually need to be class methods and shouldn't be instance methods. If you have other classes which need to convert
The Java community is split over the question, if the
BTW, it's custom to have annotations before the method modifiers.
Instead of implementing your own method it's probably a good idea to override
(Although it may be safer to compare rank and suit as a fall back.)
EDIT 1:
First a quick digression about Enumerations. The Enums have an ordinal number and a
The offical language guide has examples for suit and rank enumations and for extending enumerations with your own properties using planets as an example: http://download.oracle.com/javase/1.5.0/docs/guide/language/enums.html
When/if I get to the hand ranking (I haven't looked at it yet) I may be able to give some suggestions have to implement it with enums.
Next are the
Next up, is the Board. First off, I'd like to say, that I'm nor sure if I'd use a Board class like this in a real world Poker application. However off the top of my head I can't think of a different way to do it and for practice this is perfectly fine.
The only thing I would change is instead of explicitly setting each card by index with
EDIT 2:
Regarding sorting suits: Ok, that makes sense. I haven't looked at hand evaluation yet. However that is more a case of grouping that sorting, so maybe there is a different (bette
Card class.import java.util.*;Except during development, it's custom to explicitly import only the classes you need instead of using wildcards.
public class Card{
private short rank, suit;It's is most certainly a valid choice to store rank and suit as
shorts, since it's most likely the fastest and most efficient way, but if you want to learn the specifics of Java you may want to look into enumerations.protected void setSuit(short suit){
this.suit = suit;
}
protected void setRank(short rank){
this.rank = rank;
}IMHO cards are a prime example for immutable objects. There is no reason to need to change the rank or the suit of a card, so I would drop the setters.
public static String rankAsString(int __rank){
return ranks[__rank];
}
public static String suitAsString(int __suit){
return suits[__suit];
}It's very unusual to use underlines in variable names in Java, especially two as a prefix. I would simple name the parameters
rank and suit especially since these are class (static) methods and not instance methods, so there is no confusion with the fields.It may be worth thinking about, if these actually need to be class methods and shouldn't be instance methods. If you have other classes which need to convert
short into the corresponding names independently from the Card class, then it would be ok. But in your case I would say it's not the case, and one should try and hide the fact that suits and ranks are implemented as shorts as much as possible.public @Override String toString(){
return rank + " of " + suit;
}
// Print card to string
protected String printCard(){
return ranks[rank] + " of " + suits[suit];
}The Java community is split over the question, if the
toString() method should be overridden purely for debugging reasons, or if it should be used in the "business logic". In this "simple" application I don't think you need to distinguish between the two uses, so I would drop printCard() and only use toString().BTW, it's custom to have annotations before the method modifiers.
public static boolean sameCard(Card card1, Card card2){
return (card1.rank == card2.rank && card1.suit == card2.suit);
}Instead of implementing your own method it's probably a good idea to override
equals() (or at least make this an instance method). If you make Card immutable as I suggested before, it simplifies the implementation to comparing the references, to see if they are the same, because you should only have one instance of each possible card. @Override public boolean equals(Object that) {
return this == that;
}(Although it may be safer to compare rank and suit as a fall back.)
EDIT 1:
First a quick digression about Enumerations. The Enums have an ordinal number and a
compareTo method, allowing you to sort them. You also can assign them properties and create your own order based on those.The offical language guide has examples for suit and rank enumations and for extending enumerations with your own properties using planets as an example: http://download.oracle.com/javase/1.5.0/docs/guide/language/enums.html
When/if I get to the hand ranking (I haven't looked at it yet) I may be able to give some suggestions have to implement it with enums.
Next are the
Comparators. I don't have much experience with them, so I can only give some general suggestions:- Classes should always start with a capital letter in Java.
- You should extend them from
Comparatorinstead ofComparator, since you only need to compare cards with each other and not with any other objects.
- While it is good extra practice, you may want to skip the suit comparator, because it's not really needed in Poker in general (and Texas Hold'em specifically). Suits never have an order in hand ranking usually only needed in some "meta" contexts (such as randomly determinating the position of the button), that currently don't apply to your program. However if you do keep it, then you should correct the order of the suits, because the official ranking is (from lowest to highest) "Clubs", "Diamonds", "Hearts" and "Spades".
Next up, is the Board. First off, I'd like to say, that I'm nor sure if I'd use a Board class like this in a real world Poker application. However off the top of my head I can't think of a different way to do it and for practice this is perfectly fine.
The only thing I would change is instead of explicitly setting each card by index with
setBoardCard(Card card, int cardNum), I would let the Board class track the index internally itself and just use addBoardCard(Card card), because you shouldn't be able to "go back" and change the board cards (ditto for the burn cards). EDIT 2:
Regarding sorting suits: Ok, that makes sense. I haven't looked at hand evaluation yet. However that is more a case of grouping that sorting, so maybe there is a different (bette
Code Snippets
import java.util.*;public class Card{
private short rank, suit;protected void setSuit(short suit){
this.suit = suit;
}
protected void setRank(short rank){
this.rank = rank;
}public static String rankAsString(int __rank){
return ranks[__rank];
}
public static String suitAsString(int __suit){
return suits[__suit];
}public @Override String toString(){
return rank + " of " + suit;
}
// Print card to string
protected String printCard(){
return ranks[rank] + " of " + suits[suit];
}Context
StackExchange Code Review Q#1382, answer score: 38
Revisions (0)
No revisions yet.