what is wrong with my code?

BlitzMax Forums/BlitzMax Beginners Area/what is wrong with my code?

B(Posted 2010) [#1]
I am trying to create 52 cards that are suited and have denominations of 1 through 13 meaning Ace through King

Its probly something quite simple that im missing.

Thanks for your help guys. :)

Global card_list	:TList = New TList
Global pone_list	:TList = New TList
Global ptwo_list	:TList = New TList

Global crd:card[53]


Type card
	Field name	:String
	Field num		:Int
EndType

Global suit:String
Global w:Int
For w = 1 To 4

Global i:Int
For i = 1 To 13
If w = 1
	suit$ = " clubs"
Else If w = 2
	suit$ = " diamonds"
Else If w = 3
	suit$ = " hearts"
Else If w = 4
	suit$ = " spades"
EndIf
	crd[i*w] = New card

	crd[i*w].name$	= i + suit$
	crd[i*w].num%		= i
Next
Next
Global e:Int
For e = 1 To 52
	Print crd[e].name$ + " = " + crd[e].num%
	Print " "
Next



Last edited 2010

Last edited 2010


GfK(Posted 2010) [#2]
crd[i*w]

...should be...
crd[(i*w)+i]

You've got several occurrences of that.

Last edited 2010


B(Posted 2010) [#3]
thanks for your help.

but that did not seem to do anything. :(

is there a better way of doing this?

as one might notice i am trying to work with Tlists for the first time.

here is what I want to do.
make Tlists
make cards
add all 52 cards to Tlist
pick a random number from 1 to the total number of cards in Tlist
give that card to player 1

repeat process and give it to player 2

untill all cards are given out.



however I cannot seem to get over the make cards step.

I have programed before, but have taken a while off and have forgotten how to do alot.


GfK(Posted 2010) [#4]
The problem in your original code (which I didn't spot before), is that in Blitzmax, arrays are always numbered 0-n, but you seem to be ignoring the first (0) element. 1-basing arrays is mucking up the maths.

Gimme five minutes...


GfK(Posted 2010) [#5]
This works, plus a couple of little tidy-ups.
Global card_list	:TList = New TList
Global pone_list	:TList = New TList
Global ptwo_list	:TList = New TList

Global crd:card[52]


Type card
	Field name	:String
	Field num		:Int
EndType

Global suit:String
Global w:Int
For w = 0 To 3

For i:Int = 0 To 12
	Select w
		Case 0; suit$ = " clubs"
		Case 1; suit$ = " diamonds"
		Case 2; suit$ = " hearts"
		Case 3; suit$ = " spades"
	End Select

	crd[(w*13)+i] = New card
	crd[(w*13)+i].name$	= i + suit$
	crd[(w*13)+i].num%		= i
Next
Next
Global e:Int
For e = 0 To 51
	Print crd[e].name$ + " = " + crd[e].num%
Next



GfK(Posted 2010) [#6]
Same result, output to TList instead of Array:
Global card_list	:TList = New TList
Global pone_list	:TList = New TList
Global ptwo_list	:TList = New TList

Global card:tCard


Type tCard
	Field name	:String
	Field num		:Int
EndType

Global suit:String
Global w:Int
For w = 0 To 3

For i:Int = 0 To 12
	Select w
		Case 0; suit$ = " clubs"
		Case 1; suit$ = " diamonds"
		Case 2; suit$ = " hearts"
		Case 3; suit$ = " spades"
	End Select

	card = New tCard
	card.name$	= i + suit$
	card.num%		= i
	card_list.AddLast(card)
Next
Next

For card = EachIn card_list
	Print card.name$ + " = " + card.num%
Next



B(Posted 2010) [#7]
ya i know that arrays work like that, i just dont like to use the 0.
I should probably get used to that.
i just put a (i+1) when assigning the card variables,
and i get a nice 1 - 13 instead of 0 - 12

thanks for going the extra mile for me and redoing the whole thing with Tlists :)

this helped me understand how they work.

thanks again GfK!!! :) :) :)

also thanks for changing the large and uneeded if block to the select block.

Im going to start using those instead of those large and messy if - else if blocks.

B


B(Posted 2010) [#8]
ok so now i am trying to pick a random card from the Tlist card_list and give it to a player

how do i pick a random card from the card_list and give it to pone_list and delete it from card_list?

sorry for asking for so much help.

B


H&K(Posted 2010) [#9]
Type tCard

	Global card_list	:TList = New TList
	Global pone_list	:TList = New TList
	Global ptwo_list	:TList = New TList

	Field name	:String
	Field num		:Int

	Function Create:Tcard (Number:Int,Suit:String)
	
		Temp:tCard	= New TCard
		Temp.Name	= Number +Suit
		Temp.Num	= Number
		Temp.Card_List.AddLast(Temp)
		Return Temp
		
	End Function
	
	Function CreateAll()
	
		Local suit:String
		
		For Local w:Int = 0 To 3
			For Local i:Int = 0 To 12

				Select w
					Case 0; suit$ = " clubs"
					Case 1; suit$ = " diamonds"
					Case 2; suit$ = " hearts"
					Case 3; suit$ = " spades"
				End Select

				tCard.Create(i,Suit)
			Next
		Next
	
	EndFunction
	
	Function TestPrint ()
	
		For Local Card:Tcard = EachIn Tcard.card_list
			Print Card.Name + " = " + Card.num
		Next 
	
	EndFunction
	
EndType

tCard.CreateAll
tcard.TestPrint

Ok, so not any real difference to what GFK Posted, just trying to show how to use objects a little bit more.

Basicly naming the card should be part of card. and so maybe naming all the cards should be part of card. Etc.

Edit. To be honest Id be tempted to have another type -> Pack of card (Tpack) and stick the create all in that, and test print

Last edited 2010


Czar Flavius(Posted 2010) [#10]
Here is some nice base code for you. Try running it :)

Strict

'black is negative, red is positive
Const hearts = 1, diamonds = 2, clubs = -1, spades = -2, none = 0

'these are ids and not value of the card
Const ace = 1, jack = 11, queen = 12, king = 13

'for ease of use in this special case, we're starting the array at 1 and ignoring 0
'i don't recommend ignoring the 0 value for arrays in the general case
Global values[14]

Function get_value:Int(card)
	Return values[card]
End Function

Function load_values()
	'you might not want the values to go up in the same order
	'in this example, ace is worth 11 and royal cards are 12
	For Local i = 2 To 10 ' for each card number
		values[i] = i 'make that card worth its number value
	Next
	values[ace] = 11
	values[jack] = 12
	values[queen] = 12
	values[king] = 12
End Function

'english names of the card value
Global names:String[14]

Function load_names()
	names[ace] = "Ace"
	names[2] = "Two"
	names[3] = "Three"
	'......
	names[10] = "Ten"
	names[jack] = "Jack"
	'.........
End Function

Function get_kind_name:String(kind)
	Return names[kind]
End Function

Function get_suit_name:String(suit)
	Select suit
		Case none
			Return "None"
		Case hearts
			Return "Hearts"
		Case diamonds
			Return "Diamonds"
		Case clubs
			Return "Clubs"
		Case spades
			Return "Spades"
	End Select
End Function

Type TCard
	'trumps always win against other suit
	Global trumps = none
	
	Function get_trumps:Int()
		Return trumps
	End Function
	
	Function set_trumps(suit:Int)
		trumps = suit
	End Function
	
	Field kind:Int
	Field suit:Int
	
	Method get_kind:Int()
		Return kind
	End Method
	
	Method get_suit:Int()
		Return suit
	End Method
	
	Method is_royal:Int()
		Return kind = jack Or kind = queen Or kind = king
	End Method
	
	Method is_black:Int()
		Return suit < 0
	End Method
	
	Method is_red:Int()
		Return suit > 0
	End Method
	
	Method matches_suit(other:TCard)
		Return get_suit() = other.get_suit()
	End Method
	
	Method is_trumps:Int()
		Return get_suit() = get_trumps()
	End Method
	
	Method get_name:String()
		Return get_kind_name(get_kind()) + " of " + get_suit_name(get_suit())
	End Method
	
	Method compare_value:Int(other:TCard)
		'returns 1 if a higher value, -1 if a lower value
		Local me = get_value(self.get_kind()), him = get_value(other.get_kind())
		If me > him Return 1
		If me < him Return -1
		Return 0 'they are identical
	End Method
	
	Function battle_cards:Int(first:TCard, second:TCard)
		'battles the two cards and returns -1 for the first card wins,
		'1 for second card wins, 0 for draw
		'adjust depending upon your game rules
		
		'trumps always win against other suits
		If first.is_trumps() And Not second.is_trumps() Then Return -1
		If Not first.is_trumps() And second.is_trumps() Then Return 1
		
		If first.get_suit() <> second.get_suit() Then Return 0 'different suits, draw
		
		'both are same suit, compare value
		Return -first.compare_value(second)
	End Function
	
	Function Create:TCard(kind, suit)
		Local card:TCard = New TCard
		card.kind = kind
		card.suit = suit
		Return card
	End Function
End Type

Function card_sort:Int(o1:Object, o2:Object)
	Local c1:TCard = TCard(o1), c2:TCard = TCard(o2)
	'just a debugging test, in case the list contains a non-card
	If (Not c1) Or (Not c2) Return 0
	'we want cards of the same suit to appear together
	If c1.get_suit() > c2.get_suit() Return 1
	If c1.get_suit() < c2.get_suit() Return -1
	'within a suit, we want cards in order of number
	If c1.get_kind() > c2.get_kind() Return 1
	If c1.get_kind() < c2.get_kind() Return -1
	Return 0
End Function

Type THand
	Field contents:TList = New TList
	
	Method sort_hand()
		contents.Sort(True, card_sort)
	End Method
	
	Method add_card(card:TCard)
		contents.AddLast(card)
		sort_hand()
	End Method
	
	Method remove_card(card:TCard)
		contents.Remove(card)
	End Method
	
	Method get_all_suit:TList(suit:Int)
		Local list:TList = New TList
		For Local card:TCard = EachIn contents
			If card.get_suit() = suit
				list.AddLast(card)
			End If
		Next
		Return list
	End Method
	
	Method get_contents:TList()
		Return contents
	End Method
End Type





load_values()
load_names()

Local hand:THand = New THand

hand.add_card(TCard.Create(jack, clubs))
hand.add_card(TCard.Create(ace, clubs))
hand.add_card(TCard.Create(10, diamonds))
hand.add_card(TCard.Create(3, hearts))
hand.add_card(TCard.Create(10, hearts))
hand.add_card(TCard.Create(2, hearts))


For Local card:TCard = EachIn hand.get_contents()
	Print card.get_name()
Next

Print ""

TCard.set_trumps(hearts)
Print "Trumps are Hearts"
Print ""

Local c1:TCard = TCard.Create(10, diamonds), c2:TCard = TCard.Create(3, diamonds)
Print "Battle between " + c1.get_name() + " and " + c2.get_name()
Print "Result: " + TCard.battle_cards(c1, c2)
Print ""

c1 = TCard.Create(10, diamonds)
c2 = TCard.Create(3, hearts)
Print "Battle between " + c1.get_name() + " and " + c2.get_name()
Print "Result: " + TCard.battle_cards(c1, c2)




B(Posted 2010) [#11]
@Czar

WOW! thanks! that is pretty much what i wanted to do.

I am still going through all your code, it is a bit advanced for me, but it all makes sense.
I am going to try to incorporate small images that relate to each card and then have two players, each with hands that are visible on screen and have then play war.

I like the trumps you put in too.

Well this shall be a nice new project for my downtime between work and school.

Thanks everyone!

ill post my new code up for everyone to see when I get each advance working.
(tho most likely not anytime too soon) :P

Thanks again! :)

B