Doing OO card game

BlitzMax Forums/BlitzMax Beginners Area/Doing OO card game

ragtag(Posted 2006) [#1]
I'm doing a basic card game to try to teach myself OOP in BlitzMax. To begin with I just want very basic functionality, such as the abillity to deal cards to players and shuffel the deck. I just need some pointers to see if I'm going about this the right way.

The way I'm thinking of doing it is have a type called TCard, for every card and initalize it with all 52 cards of the deck at the start of the game. Then have a type called TCardHolder, with a field that can contain TCard objects. TCardHolder would then have several derived types such as TPlayer, TOpponent, TDeck, TDiscardPile and so on.

The idea is that the TCard objects can get passed around between the different TCardHolder objects (players,deck etc.). So that I can tell a deck object to deal five cards to a player. It will then take the top five card objects in it's TList field and give them to that player (i.e. add the to the TList of that player and remove them from it's own).

Would this be a logical way to do it?

Ragnar


LarsG(Posted 2006) [#2]
Oi... that's kinda scary...

this is what a buddy of mine and me was working on a month ago:
Strict


Type TCard
	Field _symbol:Int
	Field _value:Int
	
	Method Draw(deckimage:TImage, x:Int, y:Int)
		DrawImage(deckimage, x, y, ((_symbol * 13) + _value))
	EndMethod
	
	Method SetValue(family:Int, value:Int)
		self._symbol	= family
		self._value		= value
	EndMethod
		
	Method GetFamily:Int()
		Return self._symbol
	EndMethod
	
	Method GetValue:Int()
		Return self._value
	EndMethod
	
	Method AsText:String()
		Local s:String
		
		If self._value = 0
			s = "Ace"
			Else If self._value < 10
			s = ""+ (self._value + 1)
			Else If self._value = 10
			s = "Knight"
			Else If self._value = 11
			s = "Queen"
			Else If self._value = 12
			s = "King"
			EndIf 
			
			If self._symbol = 0
			s:+ " of Clubs"
			Else If self._symbol = 1
			s:+ " of Diamonds"
			Else If self._symbol = 2
			s:+ " of Hearts"
			Else If self._symbol = 3
			s:+ " of Spades"
		EndIf 
			
		Return s
	EndMethod
		
EndType

Type TDeck
	Field _image:TImage
	Field _card:TCard[52]
	
	Method New()
		self.InitImage("gfx/cardset1m2.jpg")
		Local family:Int, value:Int
		Local i:Int = 0
		For family:Int = 0 To 3
			For value:Int = 0 To 12
				Local crd:TCard = New TCard
				crd.SetValue(family, value)
				self._card[i] = crd
				i :+ 1
			Next
		Next
	EndMethod
			
	Method Shuffle(rec:Int = 3)
		Local buffercard:TCard = New TCard
		' lage nytt utgangspunkt for random
		SeedRnd(MilliSecs())
		
		' stokk kortene "rec" antall ganger
		For Local a = 0 To rec
			For Local i = 0 To 51
				' finne et tilfeldig kort
				Local random:Int = Rand(0,51)
				' bytte ut dette kortet med det på den aktuelle plassen
				buffercard			= self._card[random]
				self._card[random]	= self._card[i]
				self._card[i]		= buffercard
			Next
		Next
	EndMethod
			
	Method InitImage(s:String)
		self._image = LoadAnimImage(s,93,135,0,55, MASKEDIMAGE | FILTEREDIMAGE | MIPMAPPEDIMAGE)
		If Not(self._image)
			DebugLog "Couldn't load image: " + s
		EndIf
	EndMethod

	Method GetImage:TImage()
		Return self._image
	EndMethod
		
	Method Debug()
		DebugLog ""
		For Local i = 0 To 51
			DebugLog self._card[i].AsText()
		Next
	EndMethod

	
EndType

' cardholder er bare en "boks" som kan inneholde kort
' f.eks. kan det være en spiller, eller bordet, eller en "OUT" boks
Type TCardholder
	Field _cards:TList
	
	Method AddCard(card:TCard)
		' her skal vilegge til et kort i listen
	EndMethod
	
	Method RemoveCard(num:Int)
		' her fjerner vi kort "num" fra lista
		' "num" er da pekeren til kortet i listen
	EndMethod
	
	Method ListCards()
		' her spytter vi bare ut alle kortene som er i listen.
		For Local i:TCard = EachIn _cards
			i.AsText()
		Next
	EndMethod
	
EndType

Type TPlayer Extends TCardholder
	Field name:String

	Method Deal(numofcards:Int, player:TList)
		' dette legger til numofcards antall kort til listen som er gitt
		For Local i = 0 To numofcards
			' gi kort
		Next
	EndMethod

EndType


' åpne er skjerm
Graphics 640,480

Global stokk:TDeck = New TDeck
stokk.Debug()


Repeat
	Cls
	' bare vis kortstokken nå til å begynne med
	If KeyHit(KEY_SPACE)
		stokk.Shuffle()
		stokk.Debug()
	EndIf
	
	stokk._card[0].Draw(stokk.GetImage(),100,100)
	stokk._card[1].Draw(stokk.GetImage(),200,100)
	stokk._card[2].Draw(stokk.GetImage(),300,100)
	stokk._card[3].Draw(stokk.GetImage(),400,100)
	stokk._card[4].Draw(stokk.GetImage(),500,100)

		Flip
Until KeyHit(KEY_ESCAPE)


now, never mind the comments... and the code in itself might not be the best.. but look at the type layout.. hehe


FlameDuck(Posted 2006) [#3]
Would this be a logical way to do it?
Sure. However it does seem a little over-engineered.

As a rule of thumb, you should never have an object, for something that can be represented as a number, or a name. A playing card, can be represented by either, so shouldn't be an object.


Scott Shaver(Posted 2006) [#4]
Here is a playing card module that might give you some ideas.

http://www.scottshaver2000.com/forum/viewtopic.php?t=131


Cartman(Posted 2006) [#5]
I'm currently working on a video poker game. I use a card, hand, deck object. Each object has its own properties like card rank, color, value, etc. The deck object has a method for shuffling. It works very well for me and it's easy to deal to a hand, etc.

I also have an evaluator object that you can pass a hand object to. This evaluator object then updates the rank of the hand. Works very well for me.


ragtag(Posted 2006) [#6]
Thanks for the feedback. With your help, the BegnnerBlitzMax.pdf and some Googling this is what I came up with. It's got some basic functionality, that would be easy to add more to I think. It's also my first attempt with OOP, I think I'm slowly getting my head around it. :-)

If there is anything I should do differently, please let me know.

'=========='
' CARDDECK '
'=========='

' - deck of cards test.


Strict

'Global Deck:TList = CreateList()
Global Suits:String[] = [ "clubs","diamonds","hearts","spades" ]


' Base class for anything that can hold cards (i.e. the deck, players, discard pile, the table etc.)
Type THolder
	Field Card:TList = CreateList()
	
	Method GetCard:TCard( Number )
		Local n=0
		For Local c:TCard = EachIn Card
			n:+1
			If n = Number Then Return c
		Next
	End Method
	
	Method PullCard:TCard()
		Local TempCard:TCard = Self.GetCard(1)
		Self.Card.Remove( TempCard)
		Return TempCard
	End Method
	
	Method PutCard:TCard( inCard:TCard )
		Self.Card.AddLast( inCard )
	End Method
End Type


' Base class for the deck of cards.
Type TDeck Extends THolder
	' Creates a deck of cards.
	'  From:Int=2	-> The card to start building the deck from. Used to create decks without the lowest cards.
	Function Create:TDeck( From:Int=2 )
		Local Deck:TDeck = New TDeck
		For Local Suit:String = EachIn Suits
			For Local n=From To 14
				Deck.Card.AddLast(TCard.Create(Suit,n))
			Next
		Next
		Return Deck
	End Function	
End Type


' Base class for hand of cards
Type THand Extends THolder
	Function Create:THand( Number:Int, inDeck:TDeck )
		Local TempHand:THand = New THand
		For Local n=1 To 5
			TempHand.PutCard(inDeck.PullCard())
		Next
		Return TempHand
	End Function
End Type


' Base class for each playing card.
Type TCard
	Field Suit:String		' clubs, diamonds, hearts, spades
	Field Value:Int		' 2..14  ( 11=jack, 12=queen, 13=king, 14=ace)
	
	Method GetSuit:String()
		Return Self.Suit
	End Method
	
	Method GetValue:Int()
		Return Self.Value
	End Method

	Function Create:TCard( inSuit:String, inValue )
		Local Card:TCard = New TCard
		Card.Suit = inSuit
		Card.Value = inValue
		Return Card
	End Function
End Type



Local myDeck:TDeck = TDeck.Create()
Print myDeck.GetCard(1).GetSuit()
Print myDeck.GetCard(1).GetValue()

Local myHand:THand = THand.Create( 5, myDeck )
Print myHand.GetCard(1).GetSuit()
Print myHand.GetCard(1).GetValue()



p.s. LarsG: De kommentarene dine hjalp ogsaa, selv om de ikke var paa Engelsk. :-)


ragtag(Posted 2006) [#7]
Oh...and btw. Is it possible to do a Constant array. Wasn't able to figure out how to make one for the suits.


Cartman(Posted 2006) [#8]
Some other things you might want to add(just a suggestion) are a Shuffle and a Deal method to the Deck. You could also put an Rank method in the Hand object to determine a hand ranking for evaluating who has the best hand.