Tilted Forum Project Discussion Community

Tilted Forum Project Discussion Community (https://thetfp.com/tfp/)
-   Tilted Technology (https://thetfp.com/tfp/tilted-technology/)
-   -   [java] Contiguous Array Test (https://thetfp.com/tfp/tilted-technology/85964-java-contiguous-array-test.html)

03-23-2005 10:30 AM

[java] Contiguous Array Test
 
I'm writing a client-server poker-tournament game (which I later want to extend to playing other games) and have started on the part where the system analyses the hand a given player has.

I have a jCard object that represents a card. A player's hand is represented by a jHand object that contains a Stack, which contains a set of jCards.

jCard properties are:
String suit; (Text version of suit, i.e. "Clubs", "Diamonds" etc)
String code; (2 char code 1st Char = suit, 2nd char = value - i.e. HK = King of Hearts)
int value; 1-13 (Aces through Kings)

So, I've another object called a jHandAnalyser that has a number of methods for checking what a hand might be worth. The main property of this object is a jHand reference called myHand.

Calling the constructor of jHandAnalyser passes in the hand you want to analyse. e.g.

jHandAnalyser aPlayer = new jHandAnalyser(aHand);

This jHandAnalyser needs to look at the jHand object it's given and decide what the hand is worth.

So far I have a method called isFlush() that returns true if the cards are all of the same suit, but am wondering how to implement the isStrait (sp?) method. i.e. I want to check that all the cards are in a sequential run. Has anyone got any ideas how I can do this nice and cleanly?

manalone 03-23-2005 11:12 AM

you could make sure the cards are always sorted,
then check the run length from [0] to length.

03-23-2005 11:31 AM

OK, yes, I've got that working fine - except where Aces being hi, low or Hi+Low - I converted the Stack(I want to preserve the order of dealing) to a list sorted by value and checked that after the lowest card, that the value increments by 1 each iteration.

a-j 03-23-2005 11:34 AM

I would say if you sort the hand it may be easier, but here is a non-sorted method I came up with, in honor of the IOCCC -- meaning it isn't obvious what I'm doing, maybe you can figure it out.

This is assuming a 5 card hand, if you are doing other sized hands You'll need to modify the check phase steps 7+. I haven't tested this, but I think it is correct

Code:

1. int val = 0;
2. int lowest = Integer.MAX_VALUE;
3. for each card value {
4.  val = val | (1 << card.value);
5.  lowest = Math.min(card.value, lowest);
6. }
7. if (val == 0x3C02) return true;
8. val = val >> lowest;
9. return val == 0x1F;


a-j 03-23-2005 11:35 AM

If I recall a ace cannot be high and low in a straight. Q K A 2 3 is not a valid straight.

03-23-2005 11:45 AM

it can't be high and low in a straight, but it can be high or low in a hand - so A2345 and TJQKA could both be valid straights.

If an ace is given value 1 (i.e. aces are low), then i can start increment-testing my card-values from 1, it it's high, then I can assume a value of 14, and expect it at the end of any straights - but if it's simultaneously 1 and 14, I'm going to need to do some special coding for it (which I'd rather avoid, but which looks unavoidable at the mometn)

a-j is that bit-shifting you're doing there? That's not a bad idea at all - any hand could be held as a 52 bit bitmask. The only problem is squeezing in cards of the same value but different suits...

03-23-2005 12:03 PM

I've just gone away and had a think about this, and think that using a bitmask is genius!
so each card value is assigned a bit i.e.
Code:

[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][1] = Ace
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][1][ ] = Duece
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][1][ ][ ] = 3
[ ][ ][ ][ ][ ][ ][ ][ ][ ][1][ ][ ][ ] = 4
[ ][ ][ ][ ][ ][ ][ ][ ][1][ ][ ][ ][ ] = 5
[ ][ ][ ][ ][ ][ ][ ][1][ ][ ][ ][ ][ ] = 6
[ ][ ][ ][ ][ ][ ][1][ ][ ][ ][ ][ ][ ] = 7
[ ][ ][ ][ ][ ][1][ ][ ][ ][ ][ ][ ][ ] = 8
[ ][ ][ ][ ][1][ ][ ][ ][ ][ ][ ][ ][ ] = 9
[ ][ ][ ][1][ ][ ][ ][ ][ ][ ][ ][ ][ ] = 10
[ ][ ][1][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] = Jack
[ ][1][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] = Queen
[1][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] = King

Then, all the cards in a hand are ORed into a hand array

[ ][ ][ ][ ][ ][ ][1][ ][ ][ ][ ][ ][ ] = 7
[ ][ ][ ][ ][ ][1][ ][ ][ ][ ][ ][ ][ ] = 8
[ ][ ][ ][ ][1][ ][ ][ ][ ][ ][ ][ ][ ] = 9
[ ][ ][ ][1][ ][ ][ ][ ][ ][ ][ ][ ][ ] = 10
[ ][ ][1][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] = Jack

[ ][ ][1][1][1][1][1][ ][ ][ ][ ][ ][ ] = All Cards

Now by finding the first 1 and the last one, and filling in the gaps, I should be able to make a mask.

[ ][ ][1][1][1][1][1][ ][ ][ ][ ][ ][ ] = Mask

Now if I XOR the mask and the card array, I should always get zero if there is a straight, or something else if not.

It also solves the roaming Ace problem too.

03-23-2005 12:04 PM

What's the significance of the number 0x3C02 ?

a-j 03-23-2005 12:23 PM

I special cased the the A high/low problem.

In binary it is 11 1100 0000 0010
Using the value of the card as the offset in the bitmask (A=1, K=13), the above number represents K Q J T A.

03-23-2005 12:31 PM

I like it - thanks for the idea - again, genius!

03-24-2005 09:40 AM

OK, I've got it to work and put in an acesHiLow variable (-1 for low, 0 for either or 1 for high) and this should work as a test to see if all the cards in a given hand are in a run.

Where aces are high or low, the thing only works for 5-card hands, but hopefully I'll work out a way to fix it so it will work for any number of cards.

Code:

public boolean isStrait(int acesHiLow){
                boolean isstrait = false;
                int maskval = 1;
                int val = 0;
                int lowest = Integer.MAX_VALUE;
                for (int i = 0; i< myHand.size();i++) {
                        if (acesHiLow == -1 || myHand.card(i).value != 1){
                        val = val | (1 << myHand.card(i).value);
                        maskval = maskval << 1;
                        lowest = Math.min(myHand.card(i).value, lowest);}
                        if (acesHiLow == 0 && myHand.card(i).value == 1){
                                val = val | (1 << myHand.card(i).value);
                                val = val | (1 << 14);
                                maskval = maskval << 1;
                                maskval = maskval << 1;
                                lowest = Math.min(myHand.card(i).value, lowest);}
                        if (acesHiLow == 1 && myHand.card(i).value == 1){
                                val = val | (1 << 14);
                                maskval = maskval << 1;
                                lowest = Math.min(14, lowest);}                       
                        }
                val = val >> lowest;

                if (val + 1 == maskval){return true;}
                if ((acesHiLow == 0 && val == 8223) || (acesHiLow == 0 && val == 15873)){return true;}
                // System.out.println(val + " " + maskval );
                return false;
        }

Thanks again.


All times are GMT -8. The time now is 10:32 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2025, vBulletin Solutions, Inc.
Search Engine Optimization by vBSEO 3.6.0 PL2
© 2002-2012 Tilted Forum Project


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76