Search code examples
pythonarraysvariable-names

Set a variable to a random element from an array and not the elements value. ---python---


This is for a text-based card game.

I have been trying to get python to randomly select a variable from a array and store the name of the variable in Fa. However it only stores the value of the variable Fa and not the name of the variable.

My code:

 import random

 k='King'
 q='Queen'
 j='Jack'
 t='Ten'
 n='Nine'
 e='Eight'
 s='Seven'
 i='Six'
 f='Five'
 u='Four'
 h='Three'
 w='two'
 a='ace'
 c='of clubs'
 d='of diamonds'
 p='of spades'
 r='of hearts'
 #clubs
 A1=k+' '+c
 B1=q+' '+c
 C1=j+' '+c
 D1=t+' '+c
 E1=n+' '+c
 F1=e+' '+c
 G1=s+' '+c
 H1=i+' '+c
 I1=f+' '+c
 J1=u+' '+c
 K1=h+' '+c
 L1=w+' '+c
 M1=a+' '+c
 #diamonds
 A2=k+' '+d
 B2=q+' '+d
 C2=j+' '+d
 D2=t+' '+d
 E2=n+' '+d
 F2=e+' '+d
 G2=s+' '+d
 H2=i+' '+d
 I2=f+' '+d
 J2=u+' '+d
 K2=h+' '+d
 L2=w+' '+d
 M2=a+' '+d
 #spades
 A3=k+' '+p
 B3=q+' '+p
 C3=j+' '+p
 D3=t+' '+p
 E3=n+' '+p
 F3=e+' '+p
 G3=s+' '+p
 H3=i+' '+p
 I3=f+' '+p
 J3=u+' '+p
 K3=h+' '+p
 L3=w+' '+p
 M3=a+' '+p
 #hearts
 A=k+' '+r
 B=q+' '+r
 C=j+' '+r
 D=t+' '+r
 E=n+' '+r
 F=e+' '+r
 G=s+' '+r
 H=i+' '+r
 I=f+' '+r
 J=u+' '+r
 K=h+' '+r
 L=w+' '+r
 M=a+' '+r

 clubs=[A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1]
 diamonds=[A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2]
 hearts=[A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3]
 spades=[A,B,C,D,E,F,G,H,I,J,K,L,M]

 CardTotal=len(clubs)

 X=''
 Da=''
 Fa=''
 sep='\n And \n'
 hand=''

 Cardhand=7

 while(Cardhand != 0):
    Cardhand=Cardhand-1
    Da=random.choice(['1', '2', '3','4'])
    if(Da=='1'):
        Fa=random.choice(clubs)
    elif(Da=='2'):
        Fa=random.choice(hearts)
    elif(Da=='3'):
        Fa=random.choice(spades)
    elif(Da=='4'):
        Fa=random.choice(diamonds)

    hand=hand+sep+Fa+sep

    if(Fa in clubs):
        clubs.pop(Fa)
    elif(Fa in diamonds):
        diamonds.pop(Fa)
    elif(Fa in hearts):
        hearts.pop(Fa)
    elif(Fa in spades):
       spades.pop(Fa)

    Da=''
    Fa=''


 cards=[clubs,diamonds,hearts,spades]    

Solution

  • You need to realize that python does not pass "variable names" when you create a list.

    By doing:

    spades=[A,B,C,D,E,F,G,H,I,J,K,L,M]
    

    the list only consists of the values that those variables pointed to, you can see this by just printing out the list:

    >>> spades
    ['King of hearts', 'Queen of hearts', 'Jack of hearts', 'Ten of hearts', 'Nine of hearts', 'Eight of hearts', 'Seven of hearts', 'Six of hearts', 'Five of hearts', 'Four of hearts', 'Three of hearts', 'two of hearts', 'ace of hearts']
    

    If you want to instead get the variable names you can store them as strings without the values:

    spades=['A','B','C','D','E','F','G','H','I','J','K','L','M']
    

    or a list of tuples with the name and value:

    spades=[('A',A),('B',B),('C',C),('D',D),('E',E),('F',F),('G',G),('H',H),('I',I),('J',J),('K',K),('L',L),('M',M)]
    

    then the value and name can be extracted with:

    name, value = Fa
    

    Although this is really a much better fit for a mapping, instead of a list of elements that is retrieved by indices you associate each value with a name:

    spades = {'A':A, 'B':B, 'C':C, 'D':D, 'E':E, 'F':F, 'G':G, 'H':H, 'I':I, 'J':J, 'K':K, 'L':L, 'M':M}
    

    Although this stops random.choice from working, you would then have to change it to:

    Fa=random.choice(tuple(spades))
    

    Since random.choice relies on using indices to select a random element so it needs a sequence to work correctly

    Then you can get the text of the card by catching the return value of .pop:

    card_text = spades.pop(Fa)
    

    You might not like the idea of passing the value of a variable instead of the variable name but you will realize that it can greatly simplify code, for example instead of doing:

    Da=random.choice(['1', '2', '3','4'])
    if(Da=='1'):
        Fa=random.choice(clubs)
    elif(Da=='2'):
        Fa=random.choice(hearts)
    elif(Da=='3'):
        Fa=random.choice(spades)
    elif(Da=='4'):
        Fa=random.choice(diamonds)
    

    you can just choose one of the list / dicts for the suit, like this:

    Da=random.choice([clubs,diamonds,hearts,spades])
    #Da is now the dict for the selected suit
    Fa = random.choice(tuple(Da))
    

    Then the whole while loop could just be this:

    spades   = { 'A': A,  'B': B,  'C': C,  'D': D,  'E': E,  'F': F,  'G': G,  'H': H,  'I': I,  'J': J,  'K': K,  'L': L,  'M': M}
    clubs    = {'A1':A1, 'B1':B1, 'C1':C1, 'D1':D1, 'E1':E1, 'F1':F1, 'G1':G1, 'H1':H1, 'I1':I1, 'J1':J1, 'K1':K1, 'L1':L1, 'M1':M1}
    diamonds = {'A2':A2, 'B2':B2, 'C2':C2, 'D2':D2, 'E2':E2, 'F2':F2, 'G2':G2, 'H2':H2, 'I2':I2, 'J2':J2, 'K2':K2, 'L2':L2, 'M2':M2}
    hearts   = {'A3':A3, 'B3':B3, 'C3':C3, 'D3':D3, 'E3':E3, 'F3':F3, 'G3':G3, 'H3':H3, 'I3':I3, 'J3':J3, 'K3':K3, 'L3':L3, 'M3':M3}
    while(Cardhand != 0):
        Cardhand=Cardhand-1
        Da=random.choice([clubs,diamonds,hearts,spades])
        #Da is now the dict for the selected suit
        Fa = random.choice(tuple(Da))
        #Fa is the key in that dict, so A or B2 or similar
        card_text = Da.pop(Fa)
        hand=hand+sep+card_text+sep