Copy type values to another type

Previous topic - Next topic

okee

is there a quick way to copy a value in an array of types to another array of types ?

I have 2 arrays of types both with the same fields and the same size
was trying

Code (glbasic) Select
FOR i=0 TO 51
    LOCAL a=RND(LEN(CardList[])-1), b=RND(LEN(Deck[])-1)
Deck[b] = CardList[a]
NEXT


but get "wrong argument type" error
Android: Samsung Galaxy S2 -  ZTE Blade (Orange San Francisco) - Ainol Novo 7 Aurora 2
IOS: 2 x Ipod Touch (1G)

MrTAToad

This works fine for me :

Code (glbasic) Select
LOCAL Deck[]; DIM Deck[52]
LOCAL CardList[]; DIM CardList[52]

LOCAL i

FOR i=0 TO 51
CardList[i]=i
NEXT

FOR i=0 TO 51
      LOCAL a=RND(LEN(CardList[])-1), b=RND(LEN(Deck[])-1)
    Deck[b] = CardList[a]
NEXT


FOR i=0 TO 51
DEBUG Deck[i]+" "+CardList[i]+"\n"
NEXT


As you got a wrong argument error, I suspect you might be using a TYPE with a slight difference between the two variables (or you tried Deck[]=CardList)

If you want to copy the contents of one array to another use :

Deck[]=CardList[]

This will work as long as both Deck and CardList are the same type of variable :

Code (glbasic) Select
LOCAL Deck%[]; DIM Deck[52]
LOCAL CardList%[]; DIM CardList[52]

LOCAL i

FOR i=0 TO 51
CardList[i]=i
NEXT

FOR i=0 TO 51
      LOCAL a=RND(LEN(CardList[])-1), b=RND(LEN(Deck[])-1)
NEXT

Deck[]=CardList[]

FOR i=0 TO 51
DEBUG Deck[i]+" "+CardList[i]+"\n"
NEXT

okee

I'll explain a little better
Basically i want to copy the value of CardList[No] to Deck[No]
So say it's Deck[5] = CardList[10]
this should copy the values  in CardList[10].Card to Deck[5].Card
and CardList[10].Value to Deck[5].Value



here's a cut down example of what i want to do,

Code (glbasic) Select
SETSCREEN 800, 600,1
GLOBAL GameOver

// the cards used to create the deck---
TYPE TCardList
Card
        Value
ENDTYPE
GLOBAL CardList[] AS TCardList
DIM CardList[52]

// deck type
TYPE TDeck
Card
        Value
ENDTYPE

GLOBAL Deck[] AS TDeck
DIM Deck[52]


// main loop
WHILE GameOver <> 1

LOCAL i

FOR i = 0 TO 51

    LOCAL a=RND(LEN(CardList[])-1), b=RND(LEN(Deck[])-1)
Deck[b] = CardList[a] // gives [error : wrong argument type : ]

NEXT

WEND
Android: Samsung Galaxy S2 -  ZTE Blade (Orange San Francisco) - Ainol Novo 7 Aurora 2
IOS: 2 x Ipod Touch (1G)

Slydog

#3
Interesting.  I guess you can't assign two different type instances to each other even though the types are identically defined.  It must treat them as two completely different types.

But, my question is why are you doing this?
Why not just declare both CardList[] and Deck[] as type TDeck, and get rid of TCardList, as they are the exact same?

And I'm not sure why you have two arrays/types to begin with.
Can't you just have one array called Deck[] as type TDeck?
Then have a Shuffle() function that assigns random values to each array position.
If you defined your type as
TYPE TDeck
  suit
  value
ENDTYPE

Then nest two loops such as:
FOR suit = 1 to 4
  FOR value = 1 to 13
    Pick a random position between 0 and 51 (card_index for example)
    If that position is already taken, try another random number until you find one that is available
    Then assign the value such as:
    Deck[card_index].suit = suit
    Deck[card_index].value = value

    Better yet, have a counter 'cards_left' (intialized to 51) and decrease it by one each inner loop, and pick a random value between 0 and this value, then count from the start of your deck that many times, skipping already initialized cards.  This ensures each card (suit/value) gets assigned to a random position in the Deck with no wasted random values waiting for a valid one.
  NEXT
NEXT

Good luck!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Moru

Or you could do something inbetween. Take that suit/card loop but instead of taking a random number each card, just count up all the cards in the deck. Just like a normal deck when you buy it new, it's sorted perfectly. Then you make a loop that runs x number of times, each loop it selects two positions in this deck and swap the values like this:

Code (glbasic) Select
for x = 0 to 100
    a = rnd(52)
    b = rnd(52)
    suit = Deck[a].suit
    value = Deck[a].value
    Deck[a].suit = Deck[b].suit
    Deck[a].value = Deck[b].value = value
    Deck[b].suit = suit
    Deck[b].value = value
next


(example code, might be typos :-)

Slydog

#5
Ya, that's much better!
The last time I programmed a card game (black jack) was 25 years ago in high school, and I can't remember how I did it. It would be nice to review some code from your past to see how far you've come!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

matchy

Just to point out; this doesn't look right, as 'a' just needs to be declared once, at the top of the function.

Code (glbasic) Select

FOR i = 0 TO 51
       LOCAL a=RND(LEN(CardList[])-1), b=RND(LEN(Deck[])-1)
       Deck[b] = CardList[a] // gives [error : wrong argument type : ]
NEXT

Kitty Hello

Why are you making 2 types that are identical? The purpose of a type is to be used for various stuff. In your case the deck and the cardlist should be of the same type.

okee

Ok thanks to everyone that responed. as suggested when i use TDeck as the type
for CardList and Deck it works fine, so it seems you can't copy the data from one type
to another type like that.
You know i honestly don't know why i didn't use TDeck as the base type for both
momentary lapse of reason i guess.
Anyway this works fine

Code (glbasic) Select
SETSCREEN 800, 600,1
// deck type
TYPE TDeck
   Card
   Value
ENDTYPE

GLOBAL CardList[] AS TDeck
DIM CardList[52]

GLOBAL Deck[] AS TDeck
DIM Deck[52]

// main loop
WHILE KEY(1) <> 1

LOCAL i
LOCAL a , b

   FOR i = 0 TO 51

       a=RND(LEN(CardList[])-1)
       b=RND(LEN(Deck[])-1)
       Deck[b] = CardList[a]

   NEXT

    SHOWSCREEN


WEND


QuoteThen you make a loop that runs x number of times, each loop it selects two positions in this deck and swap the values like this:
Thanks Moru I think i'll use that bit of code, makes things neater

QuoteJust to point out; this doesn't look right, as 'a' just needs to be declared once, at the top of the function.
matchy that's the first time a and b are declared, not very readable but it does work :)

Code (glbasic) Select
LOCAL a=RND(LEN(CardList[])-1), b=RND(LEN(Deck[])-1)

Anyway I'm sorted, thanks to everyone who responded, all comments are helpful, having not coded for many
years i'm finding it a bit more difficult than i thought to delve back into it again.


okee
Android: Samsung Galaxy S2 -  ZTE Blade (Orange San Francisco) - Ainol Novo 7 Aurora 2
IOS: 2 x Ipod Touch (1G)

Moru

Just a tip for your sanity. Never do anything else than declare a value to a variable. Don't do any fancy stuff, it will break either reason or the program sooner or later :-)

Is fine:
LOCAL a% = 5
GLOBAL b$ = "Hello"

Avoid:
LOCAL c% = RND(5)

It might work now but next update it might not. I have been there, don't go that way :-)

Kitty Hello

For LOCAL it should be pretty OK. (There was a bug, I know, and I get sweat wet hands everytime I do that myself now, too.) But I force myselt to do this to ensure it on't happen again to locals.

okee

Moru I never normally do that it's a piece of code i got from another post
which so happens to be Kitty's :)
Android: Samsung Galaxy S2 -  ZTE Blade (Orange San Francisco) - Ainol Novo 7 Aurora 2
IOS: 2 x Ipod Touch (1G)