card value

Blitz3D Forums/Blitz3D Programming/card value

Rook Zimbabwe(Posted 2004) [#1]
I am stuck at having a think at this and I hope someone can help me reason this out. I don't really want someone to code for me... no... I want to try to d it myself but I just can't reason it well.

Situation: I am thinking of coding a matching type game in B3D... it's what I have... and lets say the entities are cards.

I have a routine that creates a deck and shuffles it. It can even output to a file if needed.

The thing is I want the computer to be able to compare the values of a card... to know the values of a card so it can tell if the values is proper for the gemaplay.

Should I define the cards as a TYPE or???

I mean you can put a lot of dta into a TYPE... but can you compare them???

I need help... I have been away too long.

RZ


Ross C(Posted 2004) [#2]
Have an array, representing the board. In each array slot, is a number. That number is the value of the card. If the user picks 2,3 and 5,8, then compare the values in the array slots. :o)


WolRon(Posted 2004) [#3]
Here is some code snippets from a 5 card draw Jacks or Better Poker game I made once. You can see how it basically worked and then apply whatever you need to your game.

Set up the types and arrays:
Type Card
	Field suit
	Field value
End Type

Dim NewDeck.Card(52)
Dim Deck.Card(52)
Dim Hand.Card(5)
Dim NewHand.Card(5)
Dim Hold(5)

NewDeck is all 52 cards in order. Used only for shuffling.
Deck is the current (shuffled) deck that is in play.
Hand is the current 5-card hand that the player holds.
NewHand is the new hand being dealt to the player after he draws.
Hold is an array that keeps track of which cards the player is keeping or throwing.


Load the arrays with NEW instances of the card types (only need to do once). Suits are 1-4. Values are 1-13.
For iter = 1 To 52
	Deck(iter) = New Card
	NewDeck(iter) = New Card
	NewDeck(iter)\suit = Ceil((53 - Float(iter)) / 13)
	NewDeck(iter)\value = iter Mod 13
	If NewDeck(iter)\value = 0 Then NewDeck(iter)\value = 13
Next
For iter = 1 To 5
	Hand(iter) = New card
	NewHand(iter) = New card
Next

Shuffling the deck is done by setting up the array "NewDeck" with all of the 52 cards (in order), and then randomly pulling them out and placing them in the shuffled deck "Deck".
Function ShuffleDeck()
	channel = PlaySound(sndShuffle)
	For iter = 1 To 52 
		NewDeck(iter)\suit = Ceil((53 - Float(iter)) / 13)
		NewDeck(iter)\value = iter Mod 13
		If NewDeck(iter)\value = 0 Then NewDeck(iter)\value = 13
	Next
	For iter = 1 To 52
		Repeat
			Randomcard = Rnd(1, 52)
		Until NewDeck(Randomcard)\value <> 0
		Deck(iter)\suit = NewDeck(Randomcard)\suit
		Deck(iter)\value = NewDeck(Randomcard)\value
		NewDeck(Randomcard)\value = 0
	Next
	While ChannelPlaying(channel)
	Wend
End Function

Cards are dealt into the hand one at a time off of the deck. If "entirehand" is true then all 5 cards are replaced, otherwise only the cards that are not being 'held' by the player are replaced. If the deck is near the end (>47), then it is reshuffled first.
Function Deal(entirehand)
	nextcard = 0
	Repeat
		nextcard = nextcard + 1
		If nextcard > 47
			nextcard = 1
			ShuffleDeck()
		EndIf 
	Until Deck(nextcard)\value <> 0
	If entirehand = True 
		For iter = 1 To 5
			NewHand(iter)\suit = Deck(nextcard)\suit
			NewHand(iter)\value = Deck(nextcard)\value
			Deck(nextcard)\value = 0
			nextcard = nextcard + 1
		Next
	Else
		For iter = 1 To 5
			If Hold(iter) = False 
				NewHand(iter)\suit = Deck(nextcard)\suit
				NewHand(iter)\value = Deck(nextcard)\value
				Deck(nextcard)\value = 0
				nextcard = nextcard + 1
			Else
				NewHand(iter)\suit = Hand(iter)\suit
				NewHand(iter)\value = Hand(iter)\value
			EndIf 
		Next
	EndIf 
End Function

The players hand is checked for winning combinations. Note that they are checked in order of importance (for example, so that a full house is detected before a pair).
Function EvaluateHand()
	CheckForRoyalFlush()
	If Rank > 0 Then Return
	CheckForStraightFlush()
	If Rank > 0 Then Return
	CheckForFourOfAKind()
	If Rank > 0 Then Return
	CheckForFullHouse()
	If Rank > 0 Then Return
	CheckForFlush()
	If Rank > 0 Then Return
	CheckForStraight()
	If Rank > 0 Then Return
	CheckForThreeOfAKind()
	If Rank > 0 Then Return
	CheckForTwoPair()
	If Rank > 0 Then Return
	CheckForJacksOrBetter()
End Function

And here is where the real magic happens.
Rank equals 0. If a match is found then the Rank is set to equal 1 - 9. If no match is found then it simply returns (leaving the rank of the hand equal to 0).
Function CheckForRoyalFlush()
	;check for flush
	For iter = 2 To 5
		If Hand(1)\suit <> Hand(iter)\suit Then Return 
	Next
	;check for royals
	For iter = 1 To 5
		If Hand(iter)\value = 1 Then ace = ace + 1
	Next
	If ace <> 1 Then Return
	For royal = 13 To 10 Step -1
		For iter = 1 To 5
			If Hand(iter)\value = royal Then thisroyal = thisroyal + 1
		Next
		If thisroyal <> 1 Then Return
		thisroyal = 0
	Next
	Rank = 9
End Function

Function CheckForStraightFlush()
	;check for flush
	For iter = 2 To 5
		If Hand(1)\suit <> Hand(iter)\suit Then Return 
	Next
	;check for high card
	highcard = Hand(1)\value
	For iter = 2 To 5
		If Hand(iter)\value > highcard Then highcard = Hand(iter)\value
	Next
	If highcard < 5 Then Return
	;check for straight
	For thiscard = highcard To highcard - 4 Step -1
		For iter = 1 To 5
			If Hand(iter)\value = thiscard Then thisstraight = thisstraight + 1
		Next
		If thisstraight <> 1 Then Return
		thisstraight = 0
	Next
	Rank = 8
End Function

Function CheckForFourOfAKind()
	For compare = 1 To 5
		thiscard = Hand(compare)\value
		For iter = 1 To 4
			If thiscard = Hand((compare + iter) - 5 * ((compare + iter) > 5))\value Then count = count + 1
		Next
		If count = 3
			Rank = 7
			Return 
		EndIf
		count = 0
	Next
End Function

Function CheckForFullHouse()
	Check(0) = 0
	Check(1) = 0
	For compare = 1 To 5
		thiscard = Hand(compare)\value
		For iter = 1 To 4
			If thiscard = Hand((compare + iter) - 5 * ((compare + iter) > 5))\value
				count = count + 1
			Else
				Check(checkcount) = ((compare + iter) - 5 * ((compare + iter) > 5))
				checkcount = checkcount + 1
			EndIf
		Next
		If count = 2
			threeOfAKind = True 
		EndIf
		count = 0
		checkcount = 0
		If threeOfAKind = True Then Exit 
	Next
	If Not threeOfAKind Then Return
	If Hand(Check(0))\value = Hand(Check(1))\value Then Rank = 6
End Function

Function CheckForFlush()
	;check for flush
	For iter = 2 To 5
		If Hand(1)\suit <> Hand(iter)\suit Then Return 
	Next
	Rank = 5
End Function

Function CheckForStraight()
	;check for ace in hand
	For iter = 1 To 5
		If Hand(iter)\value = 1 Then ace = ace + 1
	Next
	If ace > 1 Then Return
	If ace = 1
		;check for ace through 10 straight
		For thiscard = 13 To 10 Step -1
			For iter = 1 To 5
				If Hand(iter)\value = thiscard Then thisstraight = thisstraight + 1
			Next
			If thisstraight <> 1 Then noHighStraight = True 
			thisstraight = 0
		Next
		If noHighStraight = False
			Rank = 4
			Return 
		EndIf 
	EndIf
	;no high straight so check for regular straight
	;check for high card
	highcard = Hand(1)\value
	For iter = 2 To 5
		If Hand(iter)\value > highcard Then highcard = Hand(iter)\value
	Next
	If highcard < 5 Then Return
	;check for straight
	For thiscard = highcard To highcard - 4 Step -1
		For iter = 1 To 5
			If Hand(iter)\value = thiscard Then thisstraight = thisstraight + 1
		Next
		If thisstraight <> 1 Then Return
		thisstraight = 0
	Next
	Rank = 4
End Function

Function CheckForThreeOfAKind()
	For compare = 1 To 5
		thiscard = Hand(compare)\value
		For iter = 1 To 4
			If thiscard = Hand((compare + iter) - 5 * ((compare + iter) > 5))\value Then count = count + 1
		Next
		If count = 2
			Rank = 3
			Return 
		EndIf
		count = 0
	Next
End Function

Function CheckForTwoPair()
	Check(0) = 0
	Check(1) = 0
	Check(2) = 0
	For compare = 1 To 5
		thiscard = Hand(compare)\value
		For iter = 1 To 4
			If thiscard = Hand((compare + iter) - 5 * ((compare + iter) > 5))\value
				count = count + 1
			Else
				Check(checkcount) = ((compare + iter) - 5 * ((compare + iter) > 5))
				checkcount = checkcount + 1
			EndIf
		Next
		If count = 1
			pair = True 
		EndIf
		count = 0
		checkcount = 0
		If pair = True Then Exit 
	Next
	If Not pair Then Return
	If Hand(Check(0))\value = Hand(Check(1))\value Then Rank = 2
	If Hand(Check(1))\value = Hand(Check(2))\value Then Rank = 2
	If Hand(Check(2))\value = Hand(Check(0))\value Then Rank = 2
End Function

Function CheckForJacksOrBetter()
	For compare = 1 To 5
		thiscard = Hand(compare)\value
		For iter = 1 To 4
			If thiscard = Hand((compare + iter) - 5 * ((compare + iter) > 5))\value
				If thiscard > 10 And Hand((compare+iter)-5*((compare+iter)>5))\value > 10
					Rank = 1
					Return
				EndIf
				If thiscard = 1 And Hand((compare+iter)-5*((compare+iter)>5))\value = 1
					Rank = 1
					Return
				EndIf
			EndIf
		Next
	Next
End Function



Rook Zimbabwe(Posted 2004) [#4]
I can see how this could be modified to fit almost any puzzle instance game as well... Once match values have been set. Hmmm... lots to learn. Thanks WolRon! Thanks Ross C!
RZ