I have a Streets and Alleys card game and I'm currently having trouble making a new game when the user inputs "r" or if they win a game. Every time, it returns None for every card. I'm not quite sure if it has something to do with my function initialize() or if it's something I have to rewrite in my main(). Here's my code:
import cards, random, re
random.seed(100) #random number generator will always generate
#the same 'random' number (needed to replicate tests)
MENU = '''
Input options:
MTT s d: Move card from Tableau pile s to Tableau pile d.
MTF s d: Move card from Tableau pile s to Foundation d.
MFT s d: Move card from Foundation s to Tableau pile d.
U: Undo the last valid move.
R: Restart the game (after shuffling)
H: Display this menu of choices
Q: Quit the game
'''
the_deck = cards.Deck()
def initialize():
'''Establishes two lists and deals the cards
to the tableau with even lists having 7 cards
and odd lists having 6 cards'''
foundation = [[], [], [], []]
tableau = [[], [], [], [], [], [], [], []]
checker = False
while checker == False:
the_deck.shuffle()
for i in range( 7 ):
tableau[0].append(the_deck.deal())
for i in range (8, 14):
tableau[1].append(the_deck.deal())
for i in range( 15, 22 ):
tableau[2].append(the_deck.deal())
for i in range (23, 29):
tableau[3].append(the_deck.deal())
for i in range( 30, 37):
tableau[4].append(the_deck.deal())
for i in range (38, 44):
tableau[5].append(the_deck.deal())
for i in range( 45, 52 ):
tableau[6].append(the_deck.deal())
for i in range (53, 59):
tableau[7].append(the_deck.deal())
checker = True
continue
return tableau, foundation
def display(tableau, foundation):
'''Each row of the display will have
tableau - foundation - tableau
Initially, even indexed tableaus have 7 cards; odds 6.
The challenge is the get the left vertical bars
to line up no matter the lengths of the even indexed piles.'''
# To get the left bars to line up we need to
# find the length of the longest even-indexed tableau list,
# i.e. those in the first, leftmost column
# The "4*" accounts for a card plus 1 space having a width of 4
max_tab = 4*max([len(lst) for i,lst in enumerate(tableau) if i%2==0])
# display header
print("{1:>{0}s} | {2} | {3}".format(max_tab 2,"Tableau","Foundation","Tableau"))
# display tableau | foundation | tableau
for i in range(4):
left_lst = tableau[2*i] # even index
right_lst = tableau[2*i 1] # odd index
# first build a string so we can format the even-index pile
s = ''
s = "{}: ".format(2*i) # index
for c in left_lst: # cards in even-indexed pile
s = "{} ".format(c)
# display the even-indexed cards; the " 3" is for the index, colon and space
# the "{1:<{0}s}" format allows us to incorporate the max_tab as the width
# so the first vertical-bar lines up
print("{1:<{0}s}".format(max_tab 3,s),end='')
# next print the foundation
# get foundation value or space if empty
found = str(foundation[i][-1]) if foundation[i] else ' '
print("|{:^12s}|".format(found),end="")
# print the odd-indexed pile
print("{:d}: ".format(2*i 1),end="")
for c in right_lst:
print("{} ".format(c),end="")
print() # end of line
print()
print("-"*80)
def valid_tableau_to_tableau(tableau,s,d):
'''Checks to see if you can move a card
from one tableau to another'''
if len(tableau[s]) == 0:
return False
card_source = tableau[s][len(tableau[s])-1]
if d > 7: #makes sure destination isn't greater than 7
return False
if card_source.rank() >= 1 and len(tableau[d]) == 0:
return True
try:
card_destination = tableau[d][len(tableau[d])-1]
except:
return False
if card_source.rank() == card_destination.rank()-1:
return True
else:
return False
def move_tableau_to_tableau(tableau,s,d):
'''Moves the selected card from a tableau to another'''
if valid_tableau_to_tableau(tableau, s, d):
tableau[d].append(tableau[s].pop()) #move the card
return True
else: #figure out when to return True or False
print("Error in move: {} , {} , {}".format("MTT", s, d))
return False
def valid_foundation_to_tableau(tableau,foundation,s,d):
'''Checks to see if you can move a card
from the foundation to a tableau'''
if len(foundation[s]) == 0:
return False
card_source = foundation[s][len(foundation[s])-1]
if len(tableau[d]) == 0: #checks that foundation can move to empty tableau
return True
try: #checks that tableau destination has a card
card_destination = tableau[d][len(tableau[d])-1]
except:
return False
if card_source.rank() == card_destination.rank()-1: #source code is one lower than the destination card
return True
else:
return False
def move_foundation_to_tableau(tableau,foundation,s,d):
'''Moves the selected card from the foundation to a tableau'''
if valid_foundation_to_tableau(tableau, foundation, s, d):
tableau[d].append(foundation[s].pop())
return True
else:
print("Error in move: {} , {} , {}".format("MFT", s, d))
return False
def valid_tableau_to_foundation(tableau,foundation,s,d):
'''Checks to see if you can move a card
from one tableau to the foundation'''
if len(foundation[d]) == 0:
card_source = tableau[s][len(tableau[s])-1]
if card_source.rank() == 1:
return True #True if source card is an Ace
else:
return False
else:
try: #checks if destination and source has card
card_source = tableau[s][len(tableau[s])-1]
card_destination = foundation[d][len(foundation[d])-1]
except:
return False
if (card_source.rank()-1 == card_destination.rank() and card_source.suit() == card_destination.suit()):
return True #checks if suits match as well as ranked accordingly
else:
return False
def move_tableau_to_foundation(tableau, foundation, s,d):
'''Moves the selected card from a tableau to the foundation'''
if valid_tableau_to_foundation(tableau, foundation, s, d):
foundation[d].append(tableau[s].pop())
return True
else:
print("Error in move: {} , {} , {}".format("MTF", s, d))
return False
def invalid_tableau_to_foundation(tableau, foundation, s, d):
''''Undo a move from tableau to foundation'''
foundation[d].append(tableau[s].pop())
return True
def invalid_tableau_to_tableau(tableau, s, d):
''''Undo a move from tableau to another tableau'''
tableau[d].append(tableau[s].pop())
return True
def invalid_foundation_to_tableau(tableau, foundation, s, d):
''''Undo a move from the foundation to a tableau'''
tableau[d].append(foundation[s].pop())
return True
def check_for_win(foundation):
'''Checks to see if all lists of the foundation
are filled with 13 cards each (Full suit).'''
#checks if all foundation lists have all 13 cards in them
if (len(foundation[0]) == 13) and (len(foundation[1]) == 13) and (len(foundation[2]) == 13) and (len(foundation[3]) == 13):
return True
else:
return False
def get_option():
'''Prints option menu and takes
user input to determine which
option will follow'''
user_input = input("\nInput an option (MTT,MTF,MFT,U,R,H,Q): ").upper()
if not (re.search('M[A-Z][A-Z] [0-9] [0-9]', user_input) \
or user_input == "U" or user_input == "R" or user_input == "H" or user_input == "Q"):
print("Error in option:", user_input)
return None
else:
if (user_input == "U" or user_input == "R" or user_input == "H" or user_input == "Q"):
return [user_input]
else:
option_list = user_input.split()
mode = option_list[0]
source = int(option_list[1])
destination = int(option_list[2])
if mode[1] == "T":
if source not in range(0, 8):
print("Error in Source.")
return None
if mode[1] == "F":
if source not in range(0, 4):
print("Error in Source.")
return None
if mode[2] == "T":
if destination not in range(0, 8):
print("Error in Destination")
return None
if mode[2] == "F":
if destination not in range(0, 4):
print("Error in Destination")
return None
return [mode, source, destination]
def main():
c = ""
option_list = None
win = False
continuing = False
turn = True
redo = []
print("\nWelcome to Streets and Alleys Solitaire.\n")
tableau, foundation = initialize()
while c != "Q":
if turn:
display(tableau, foundation)
print(MENU)
turn = False
option_list = get_option()
while option_list == None:
option_list = get_option()
moving_string = option_list[0]
if len(option_list) == 1:
c = option_list[0]
else:
c = moving_string
if moving_string == "MTT":
continuing = move_tableau_to_tableau(tableau, option_list[1], option_list[2])
if continuing:
list_of_moves = ["MTT", option_list[1], option_list[2]]
redo.append(list_of_moves)
elif moving_string == "MTF":
continuing = move_tableau_to_foundation(tableau, foundation, option_list[1], option_list[2])
if continuing:
list_of_moves = ["MTF", option_list[1], option_list[2]]
redo.append(list_of_moves)
else:
continuing = move_foundation_to_tableau(tableau, foundation, option_list[1], option_list[2])
if continuing:
list_of_moves = ["MFT", option_list[1], option_list[2]]
redo.append(list_of_moves)
if continuing:
win = check_for_win(foundation)
if not win:
display(tableau, foundation)
if win:
print("You won!\n")
display(tableau, foundation)
print("\n- - - - New Game. - - - -\n")
tableau, foundation = initialize()
display(tableau, foundation)
turn = True
if c == "R":
tableau, foundation = initialize()
display(tableau, foundation)
if c == "H":
print(MENU)
if c == "U":
if len(redo) == 0:
print("No moves to undo.")
else:
newer_move = redo.pop()
if newer_move[0] == "MTT":
invalid_tableau_to_tableau(tableau, newer_move[2], newer_move[1])
if newer_move[0] == "MTF":
invalid_tableau_to_foundation(tableau, foundation, newer_move[2], newer_move[1])
if newer_move[0] == "MFT":
invalid_foundation_to_tableau(tableau, foundation, newer_move[2], newer_move[1])
x = newer_move[0]
y = str(newer_move[1])
z = str(newer_move[2])
print("Undo:", x, y, z)
display(tableau, foundation)
print("Thank you for playing.")
if __name__ == '__main__':
main()
CodePudding user response:
You didn't show us cards
, but I'm betting that returns a generator, and after you've gone through it once, there's nothing left. You should generate a new deck every time. I don't know what you were trying to do with checker
, but clearly that was silly. I'm also not sure why you were dealing 8 columns; the 8th column is never going to have any cards.
def initialize():
'''Establishes two lists and deals the cards
to the tableau with even lists having 7 cards
and odd lists having 6 cards'''
foundation = [[], [], [], []]
tableau = [[], [], [], [], [], [], [], []]
the_deck = cards.Deck()
the_deck.shuffle()
for i in range(7):
for j in range(7 - i%2):
tableau[i].append(the_deck.deal())
return tableau, foundation