Write a Program for winning sevens game Build a function in python that can win a Sevens game provided that there are only 2 players




Here are the instructions from Wikipedia:


  All cards are dealt to the players, even if as a result some players
  have one card more than others. The owner of the seven of hearts
  begins by playing it. Similarly, the other three sevens may later be
  played as the first cards of their respective suits. After that, cards
  may be added in sequence down to the ace and up to the king. A player
  who cannot place a card passes.
  
  You cannot pass if you have a card to play.
  
  The one who gets the seven of hearts is the first to play.


The cards will be randomly distributed to the user and the computer.

The function will have two parameter:


List of cards remaining to play for computer
List cards that have been played


The syntax of a card is like this:


  [value, suit]


For example [king, "clubs"]




  The list of suits are:
  
  
  clubs
  spades
  diamonds
  hearts
  
  
  The list of values are:
  
  
  1
  2
  3 ....
  11(jack)
  12(queen)
  13(king)
  


The remaining cards for player 1 will be stored in list named card_1_rem and the remaining cards for player 2 will be stored in list named card_2_rem

The cards that have been played will be stored in a list called played_cards



The function will have to append the played card to the list called played_cards and subtract the item for the list called card_1_rem or card_2_rem

The return of one function will be the input of the competitor

The one who finishes his cards first, wins.

Winning Condition



Step 1: Users will submit their programs.

Step 2: I will test the programs against each other.

Step 3: The first program to remain in first place (as measured by lowest total running score) for 50 consecutive games will be the winner.  This will help smooth out the effects of luck.  However, a maximum of 10000 games will be played, and if no player meets the first criterion, then the player with the lowest total score after 10000 games wins.

Step 4: All the results will be uploaded to a github repo(which I will soon make).




  The loser has to count his points as follows

Ace : 1
2 : 2
3 : 3
4 : 4
5 : 5
6 : 6
7 : 7
8 : 8
9 : 9
10 : 10
jack : 10
queen : 10
king : 10

  
  For example if a king and an ace remain in the loser's hand, he gets
  11 point.
  
  The objective is to minimize the points you have got.
  
  Winner gets 0 points


IMP : Submissions are allowed only in the Python 3 language.

The controller code of this challenge is here(major update has been done): https://gist.github.com/Salil03/19a093554205b52d05dc7dc55992375a
Synergistic

I'm not really a Python guy, but wanted to give this a go. This builds the set of playable cards at each turn, and assigns each of them a simple static score. The card with the highest score is played (assuming any playable card exists). 

def synergistic(cards_in_hand, played_cards):
    def list2dict(lst):
        d = {}
        for val, suit in lst:
            if suit in d:
                d[suit].append(val)
            else:
                d[suit] = [val]
        return d
    def play_card(card):
        cards_in_hand.remove(card)
        played_cards.append(card)

    hand = list2dict(cards_in_hand)
    if not played_cards:
        if 7 in hand['hearts']:
            play_card([7, 'hearts'])
        return (cards_in_hand, played_cards)
    table = list2dict(played_cards)

    playable_cards = {}
    for suit in hand:
        if 7 in hand[suit]:
            playable_cards[(7, suit)] = -1

        if suit not in table:
            continue
        visible = set(table[suit] + hand[suit])
        opp_hand = set(range(1,14)) - visible
        highcard = max(table[suit]) + 1

        if highcard in hand[suit]:
            if highcard+1 in opp_hand:
                playable_cards[(highcard, suit)] = 1
            else:
                playable_cards[(highcard, suit)] = 2

        lowcard = min(table[suit]) - 1
        if lowcard in hand[suit]:
            if lowcard - 1 in opp_hand:
                playable_cards[(lowcard, suit)] = 0
            else:
                playable_cards[(lowcard, suit)] = 1


    if not playable_cards:
        return (cards_in_hand, played_cards)

    best_card = list(max(playable_cards, key=playable_cards.get))
    #print(hand, "\n", table, "\n", best_card)
    play_card(best_card)

    return (cards_in_hand, played_cards)


By the way, the controller seemed to have several issues, including in score calculation and comparison. I made some changes to the controller here, please take a look  and update your version if this seems right.

Two things I haven't fixed in the controller: 


why is the loop condition (win2 &lt;= 50) and (win1 &lt;= 100) ? This should probably be symmetrical, it should exit the loop whenever either of the players has 100 consecutive wins. 
trying some runs of the controller locally, with the same function for both players, Player 2 seems to win most of the time - it can't be inherent to the game since the initial 7H requirement would smooth that out (as @Veskah mentioned in the comments), so, yet undetected controller bugs? Or my player code somehow maintaining state and having a bias this way? Per-game, it's not like Player 2 dominates heavily (from the results output txt), but somehow the overall score per controller run ends up favouring player 2 much more than random (Player 1's total scores are often more than 2x that of Player 2).