(How to manipulate)Poker Positioning using ENUM

3

Let's say I created the following class:

public enum Position {

   Dealer(1), //1
   SB(2),     //2
   BB(3),     //3
   UTG(4),    //4
   UTG1(5),   //5
   UTG2(6),   //6
   UTG3(7),   //7
   HJ(8),     //8
   CO(9);     //9

   //Constructor
   int code;

   Position(int code) {
     this.code = code;
   }
}

How do I manipulate ENUM by using the numbers in parenthesis? For example, in my Poker Table class, I initiate new players. Each player passes the parameter Position. So initially,

player[1].getPosition() = Dealer  
player[2].getPosition() = SB  
player[3].getPosition() = BB   
etc etc etc 

After the hand is over, all the positions need to be shifted over by one.
So player[1] needs to have the CO(9) position.
player[2] needs to have the Dealer(1) position.
player[3] needs to have the SB(2) position.
etc etc

I understand that I can just make a for loop with a variable cycling through the numbers 1 through 9, but how do I access the position based on the integer inside the PositionENUM?


EDIT: I already have the getters and setters.

    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }

However the getters and the setters do not provide me with the correctly change the Positions of the players each round.

After every betting round, I need to change the Position of each player, so I need to figure out how to shift the ENUM Position of each player after each betting round.

krikara

Posted 2011-08-17T03:34:55.470

Reputation: 1 411

Answers

2

It's possible to choose an enum instance based on the value of its code. You can use a static Map<Integer, Position> to do this. The only gotcha is that it has to be housed in a static inner class:

public enum Position {

    ...

    Position(int code) {
        this.code = code;
        MapHolder.BY_CODE.put(code, this);
    }

    private static class MapHolder {
        private static final Map<Integer, Position> BY_CODE = new HashMap<Integer, Position>();
    }

    public static Position findByCode(int code) {
        return MapHolder.BY_CODE.get(code);
    }

I'd also recommend delegating the logic of picking the next position to the enum itself. Just add this method to the Position enum:

public Position nextPosition() {
     return findByCode((this.code + 1) % Position.values().length);
}

Then, your client code can simply go:

for (Player player : players) {
    player.setPosition(player.getPosition().nextPosition());
}

oksayt

Posted 2011-08-17T03:34:55.470

Reputation: 3 632

Ahh yes, the logic of this inner class seems to make sense. Clever way of creating a hashmap to bind the ENUM to their integers inside.

Too bad there was not an easier/simpler way of manipulating the ENUM with the numbers inside. – krikara – 2011-08-17T04:55:50.020

Yeah, as far as I know java doesn't have an easier way of mapping enum instances by a member field value. Actually for this specific case, since you're interested in just the order and not the actual integer values, Ray's solution may be a better choice. – oksayt – 2011-08-17T06:34:23.510

What's all this static map stuff? They are numbered 1 to n, so just use Enum.ordinal() + 1! – Bohemian – 2011-08-17T10:54:36.977

1

Look here is an onlinepoker game sample

    #include <iostream>
#include <stdlib.h>
#include <cctype>
#include <memory.h>
#include "logic.h"

using namespace std;
// & means location
// * value of location

struct Cards {

enum Value {Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace};
Value V;
int Suite;
enum Suite {Hearts, Diamonds, Clubs, Spades};
};

struct Hand {
Cards [5];

};

struct Deck {
Cards [52];

};

char * personsName [20]; //this means location with *
int numNames = 0;
char * Name;
char * search;
bool Continue;

int main ()
{
do {
for(int x = 0; x < 20; x++){
cout << "Enter a name, type END to stop: ";
Name = readString ();

if(strcmp (Name, "END") != 0){
personsName [x] = Name;
numNames++;
}
else{
Continue = (strcmp (Name, "END") != 0);
break;
}

}
cout << "Pre-sorted Names" << endl;
printNames(personsName,numNames);

bubbleSort(personsName,numNames);

cout << "Post-sorted Names" << endl;
printNames(personsName,numNames);

cout << "What would you like to find?" << endl;
search = readString();
cout << "The name is at index " << binarySearch(personsName,search,numNames) << endl;

} while (Continue);
delete [] * personsName;
return 0;
}

najlepsze kasyno

Posted 2011-08-17T03:34:55.470

Reputation: 11

0

I am not sure if I understand your question correctly, but you can declare a getCode() method for your enum:

public enum Position {

  Dealer(1), //1
  SB(2),     //2
  BB(3),     //3
  UTG(4),    //4
  UTG1(5),   //5
  UTG2(6),   //6
  UTG3(7),   //7
  HJ(8),     //8
  CO(9);     //9

  int code;

  //Constructor
  Position(int code) {
    this.code = code;
  }

  public int getCode() {
    return code;
  }
}

Behrang

Posted 2011-08-17T03:34:55.470

Reputation: 27 735

0

code is package access scope.

If you are calling from within the package, then you may do a

Position.BB.code

If you are calling from outside the package, then you may need to provide an accessor inside the enum class.

public int getCode(){
    return this.code;
}

Oh Chin Boon

Posted 2011-08-17T03:34:55.470

Reputation: 12 939

I am calling it from the package, but I do not want to write
Position.BB.code
Position.SB.code etc..

I need a method that returns the ENUM based on number inside – krikara – 2011-08-17T03:43:42.007

0

you could just use the ordinal() for the position (starts at 0 like subscripts). also it might be easier if the enums were in reverse order (since the deal passes to the left) like the code below. this will not work in a short game (you would need to do a modulo the number of players).

enum Position {
    Dealer, CO, HJ, UTG3, UTG2, UTG, BB, SS;
    Position next() {
        return values()[(ordinal() + 1) % values().length];
    }
}
class Player {
    Player(Position position) {
        this.position = position;
    }
    void next() {
        position = position.next();
    }
    Position position;
}
public class Main {
    public static void main(String[] args) {
        Player[] players = new Player[Position.values().length];
        for (Position position : Position.values())
            players[position.ordinal()] = new Player(position);
        for (Player player : players)
            System.out.println(player.position);
        for (int i = 0; i < Position.values().length; i++)
            for (Player player : players)
                player.next();
        for (Player player : players)
            System.out.println(player.position);
    }
}

Ray Tayek

Posted 2011-08-17T03:34:55.470

Reputation: 7 073

0

I'm not quite sure if this is your requirement.See if the code given below helps :

public enum Position {

    Dealer(1), // 1
    SB(2), // 2
    BB(3), // 3
    UTG(4), // 4
    UTG1(5), // 5
    UTG2(6), // 6
    UTG3(7), // 7
    HJ(8), // 8
    CO(9); // 9

    // Constructor
    int code;

    Position(int code) {
        this.code = code;
    }

    private static Position[] currentPosition = Position.values();

    public static Position[] getCurrentPosition() {
        return currentPosition;
    }

    private static List<Position> positionWrap = Arrays.asList(currentPosition);

    public static void shiftPostion() {
        Collections.rotate(positionWrap, 1);
        updatePositions();
    }

    private static void updatePositions() {
        for (int i = 0; i < currentPosition.length; i++){
            currentPosition[i].code = i + 1;
        }
    }

    public static void main(String[] args) {
        Position[] pos = getCurrentPosition();
        System.out.println(Arrays.toString(pos));
        Position.shiftPostion();
        System.out.println(Arrays.toString(pos));
        Position.shiftPostion();
        System.out.println(Arrays.toString(pos));

    }

    @Override
    public String toString() {

        return this.name() + "(" + code + ")";
    }
}

Emil

Posted 2011-08-17T03:34:55.470

Reputation: 8 241