Pairs in Middle Suits in End Solitaire

TrustyTony 0 Tallied Votes 357 Views Share

One solitaire game practice until the first win or 'q' after game.

""" Pairs in the Middle, Suits on the Ends solitaire

    Rules:

    Shuffle the entire deck and deal out four cards face up.

    Remove cards as follows: If you have a pair in the middle of the four cards, you may remove them.
    If the first card and the fourth card are the same suit, you remove the two middle cards.
    If all four cards are the same suit, remove all four cards.

    Add another card to the right end of your row.
    If it is the same suit as the fourth card to the left, remove the two middle cards.
    If you paired up in the middle, you can remove the two middle cards.
    And if all four cards are in the same suit, remove all four cards.

    Continue adding cards as in Step 3, looking for both of the following:
    cards with matching suits with two cards between them and pairs in the middle of four cards.
    Remember to also look for four cards in a row of the same suit.

    Win the game if you are left with no cards.

"""
from __future__ import print_function
import random
from collections import namedtuple


try:
    input = raw_input
except:
    pass

def can_take_out(pos, cards):
    if pos < 3:
        return 0
    elif cards[pos-2].value==cards[pos-1].value:
        return 2
    elif cards[pos].suit==cards[pos-3].suit:
        return 4 if (cards[pos-2].suit == cards[pos-1].suit == cards[pos].suit) else 2
    else:
        return 0


def print_cards(pos, cards):
    """ Concise printing format for cards """
    print("Card %i. Current cards:" % (pos+1),
          ','.join(card.suit+('%02i' % card.value ) for card in reversed(cards)))

    
if __name__ == '__main__':
    Card = namedtuple('Card', 'value suit')
    game = 0

    while True:
        cards = [Card(value,suit)
                 for value in range(2,15)
                 for suit in 'DHSC']

        random.shuffle(cards)

        pos, took = -1, True
        game += 1
        # winning test with two of same value left in end
        ##cards = [
        ##Card(value=4, suit='D'),
        ##Card(value=4, suit='S'),
        ##Card(value=5, suit='C'),
        ##Card(value=6, suit='C'),
        ##Card(value=14, suit='C'),
        ##Card(value=2, suit='C')
        ##]

        while len(cards)>3:
            if pos < 3:
                if not took:
                    print('='*80)
                    print("\nNot possible to take out anything")
                    break
                print()
                print('='*60)
                pos = len(cards) - 1
                took = False

            out = can_take_out(pos, cards)
            print_cards(pos, cards[pos-3:pos+1])

            if out:
                print(("Can take out %s" % out).center(20,'*'))
                if out == 4:
                    del cards[pos-3:pos+1]
                else:
                    del cards[pos-2:pos]
                took = True
                pos -= out

            else:
                pos -= 1


            #if out: input()

        if (len(cards) == 2 and ((cards[0].suit == cards[1].suit) or
           (cards[0].value == cards[1].value))):
            print('Can take out last cards because they are same suit or value.')
            print_cards(0, cards)
            cards = []

        if cards:
            print_cards(0, cards)
            q = input('\nYou lost game %i, with %i cards left!' % (game,len(cards)))
            if q.lower() =='q':
                print('Bye, bye')
                break
        else:
            print('\nYou won on game %i.' % game)
            break