|  | 
|  03-23-2005, 10:30 AM | #1 (permalink) | 
| Guest | 
				
				[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? | 
|  03-23-2005, 11:12 AM | #2 (permalink) | 
| Once upon a time... | you could make sure the cards are always sorted, then check the run length from [0] to length. 
				__________________ -- Man Alone ======= Abstainer: a weak person who yields to the temptation of denying himself a pleasure. Ambrose Bierce, The Devil's Dictionary. | 
|   | 
|  03-23-2005, 11:34 AM | #4 (permalink) | 
| Tilted | 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; | 
|   | 
|  03-23-2005, 11:45 AM | #6 (permalink) | 
| Guest | 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 | #7 (permalink) | 
| Guest | 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. | 
|  03-24-2005, 09:40 AM | #11 (permalink) | 
| Guest | 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;
	} | 
| Tags | 
| array, contiguous, java, test | 
| 
 |  |