In [135]:
import numpy as np
from random import shuffle

####################################################################################################
#########################################SETUP######################################################
####################################################################################################
numbers=(1,1,1,2,2,3,3,4,4,5)
colors=('r','y','g','b','w')           #possibly add multi... "m"
ManyCol=len(colors)

#CREATE AN ARRAY OF FIVE HANDS, ONE ON EACH ROW WITH CARDS REPRESENTED BY SERIAL NUMBERS FROM
#THE ORIGINAL DECK, TOP TO BOTTOM, STARTING AT 0. WE DEAL EACH HAND FROM THE TOP OF THE DECK.
table=np.arange(20).reshape(5,4)
#[A,B,C,D,E]=table  #MAY USE LETTERING OF PLAYERS, BUT PRLY NOT

#CREATE A FULL SHUFFLED DECK WITH NOMENCLATURE AS IN [2,0] FOR "3 red." THINK OF THE INDICES IN deck
#AS SERIAL NUMBERS WRITTEN ON THE BACKS OF THE CARDS. DeckOut CONVERTS TO EXTERNAL FORMAT LIKE "r3".
def CreateDeck():
    deck=[]
    for color in range(ManyCol):
        for number in numbers:
            deck.append([color,number-1])    #internal format numbers range 0-4; colors are numbered
    shuffle(deck)
    #deck=tuple(deck)        #converts deck from list to tuple (mutable to immutable)
    return deck             #...maybe keep as list if want multiple deals

deck=CreateDeck()
def PrintDeck(deck):
    DeckOut=[colors[card[0]]+str(card[1]+1) for card in deck]
    for i in range(int(len(deck)/4)+1):          #PRINTS DECK 4 AT A TIME
        print(DeckOut[4*i:4*(i+1)])
####################################################################################################
#####################################PUBLIC DATA####################################################
####################################################################################################

#############           stacks/extras******************for logging played/publicly visible cards 
#THE ARRAY stacks GIVES THE LAST NUMBER SUCCESSFULLY PLAYED FOR EACH COLOR AND extras IS A
#ManyColx5 ARRAY TELLING THE NUMBER OF EXTRAS OF EACH CARD. FOR EXAMPLE, A 5 COLOR GAME WITH ONLY
#A 1R DISCARD AND 1Y PLAYED MIGHT LOOK LIKE stacks=[0,1,0,0,0] AND
#extras=[[1,1,1,1,0],[1,1,1,1,0],[2,1,1,1,0],[2,1,1,1,0],[2,1,1,1,0]]. 
stacks=[[0 for i in range(5)] for i in range(ManyCol)]
extras=[[2,1,1,1,0] for i in range(ManyCol)]

#THE ROWS IN THE ARRAY priority TELL THE CARDS SERIAL NUMBERS IN THE ORDER THAT PLAYERS
#WILL SEARCH. TOP PRIORITY ARE CARDS CLUED BOTH NUMBER AND COLOR. NEXT COME NUMBER OR COLOR. THEN,
#UNCLUED CARDS. CHRONOLOGICAL ORDER BREAKS TIES. FOR EXAMPLE, IF A PLAYER HAS BEEN TOLD CARDS 6
#AND 8 ARE 4's, BUT DOESN'T KNOW ABOUT THE OTHER CARDS 21, 22, THEN HER SEARCH PRIORITY WILL BE
#priority[2]=[8,6,22,21]. 6 AND 8 HAVE BEEN CLUED, SO THEY GET PRIORITY OVER 21 AND 22. THEN, THE NEWER
#CARDS 8 AND 22 GET PRIORITY OVER 6 AND 21 (RESP.) THEN PLAYER 2 WILL SEARCH FOR PLAYS FROM 8 TO 21. 
#PRIORITY CAN CHANGE IN CERTAIN SITUATIONS, SUCH AS A CLUED CARD MOVING TO THE LOWEST PRIORITY WHEN IT IS
#KNOWN TO BE DEAD. THE LOWEST PRIORITY CARD IS CALLED CHOP BECAUSE IT IS UP NEXT FOR DISCARD.
priority=np.copy(table[:,::-1])

#############           PubInfo/ClueKinds*********************for logging public clue information
#THE COORDINATES (i,j,k) IN THE ARRAY PubInfo TELL WHETHER THE HOLDER OF THE CARD WITH SERIAL NUMBER
#i THINKS IT'S POSSIBLE, BASED ONLY ON PUBLIC INFORMATION (STACKS, CLUES, AND DISCARDS) FOR CARD i
#TO BE COLOR j AND NUMBER k. THE COORDINATES (i,j) IN THE ARRAY ClueKinds TELLS WHETHER CARD i HAS
#BEEN CLUED COLOR (j=0) OR NUMBER (j=1). IF A CLUED CARD IS KNOWN TO BE DISCARDABLE, THE COLOR VALUE
#CHANGES TO -1. ALL THIS AIDS IN DETERMINING priority WHEN INGENSTING A NEW CLUE OR DRAWING A NEW CARD.
PubInfo=np.ones(shape=(len(deck),ManyCol,5), dtype='uint8', order='C')
ClueKinds=np.zeros(shape=(len(deck),2),dtype='int8',order='C')

LastClued=[]   #???

 
####################################################################################################
#####################################PRIVATE DATA###################################################
####################################################################################################

#THE COORDINATES (i,j,k) IN THE ARRAY AllClues TELLS WHETHER PLAYER i CAN SEE THAT A COLOR j/NUMBER k
#CARD WAS EVER CLUED. WHEN A CLUED CARD IS DISCARDED, AllClues FORGETS IT WAS EVER CLUED.
AllClues=np.zeros(shape=(5,ManyCol,5),dtype='uint8',order='C')

#tasks keeps track of pending plays and saves
tasks=[{} for i in range(5)]    #CANT UPDATE ONE DICTIONARY AT A TIME


#THE ROWS IN THE ARRAY status DESCRIBE EACH PERSPECTIVE ABOUT CARDS.
#NUMBERS AND STATUSES ARE TENTATIVE.
# -900) DISCARDED TO TRASH OR UNSUCCESSFULLY PLAYED
# -800) SURVIVOR, UNSAVED
# -700) ENDANGERED TWINLESS OR DOUBLE CHOP, UNSAVED
# -125) DEAD (UNKNOWN TO PLAYER)
# -100) DEAD (KNOWN TO PLAYER)
#  000) DEFAULT (DRAW PILE OR UNNOTEWORTHY)
#  025) MARKED (NUMBER AND/OR COLOR)
#  050) TWINLESS 4 (NOT ENDANGERED)
#  075) TWINLESS 3 (NOT ENDANGERED)
#  100) EXPECTED TO PLAY IN QUEUE
#  125) EXPECTED TO PLAY NEXT (NOT 250)
#  250) EXPECTED TO IGNITE CHAIN (UNMARKED)
#  900) PLAYED TO STACK
##################################status=np.zeros((5,len(deck)))



#THE ARRAY info HOLDS THE PERSPECTIVES OF EACH OF THE FIVE PLAYERS.
#COORDINATES (i,j,k) POINT TO AN 8 BIT STRING CORRESPONDING TO INFORMATION
#THAT PLAYER i KNOWS ABOUT PLAYER j'S HAND WITH RESPECT TO CLUE k. THE FIRST
#4 BITS HAVE NEGATIVE INFORMATION FOR THE CORRESPONDING 4 CARDS IN PLAYER j'S
#HAND. THE LAST 4 BITS HAVE POSITIVIE INFORMATION.
###################################info=np.ndarray(shape=(5,5,10), dtype=np.uint8, order='C')
#For 6 colors, need shape=5,11

#THE ARRAY metainfo HOLDS METAINFORMATION ABOUT EACH HAND, SIMILAR TO info.
#COORDINATES (i,j,k,l) DESCRIBE IN THE SAME WAY AS info WHAT PLAYER i THINKS
#PLAYER j KNOWS ABOUT PLAYER k'S HAND WITH RESPECT TO CLUE l.
#####################################metainfo=np.ndarray(shape=(5,5,5,10), dtype=np.uint8, order='C')

In [136]:
#TEST 5 COLOR CASE
def TEST():
    global deck, stacks, status, priority
    deck=[[0,4],[3,2],[1,1],[1,0],
          [0,1],[2,0],[2,3],[4,2],
          [4,0],[4,0],[3,3],[1,2],
          [1,4],[0,3],[0,2],[4,1],
          [0,0],[2,2],[1,3],[2,0]]+[[0,0]]*10
    #status edit?
    PrintDeck(deck)

In [137]:
#WHEN A CARD IS SUCCESSFULLY PLAYED, THE CORRESPONDING COLOR ROW IN stacks M SHIFT FORWARD.
#WHEN A 5 IS PLAYED, THAT COLOR ROW BECOMES A ROW OF ZEROS.
def play(color):
    stacks[color]=[1]+stacks[color][:-1]

#IN CASES OF AMBIGUITY, THE LATEST PLAYERS AFTER A CLUE ARE BEST TO RESPOND. Mod5SkipBack
#IS USED TO BACKWARD TRAVERSE PLAYERS WHO CAN RESPOND (CURRENTLY EXCLUDING skip, THE CLUE GIVER).
def Mod5SkipBack(value, skip, SkipAlso=-1):
    while True:
        value=(value-1)%5
        if value not in {skip,SkipAlso}:
            return value

#UPDATES PubInfo, ClueKinds, AND priority AFTER A CLUE IS GIVEN.
def RecordClue(player, value, ColOrNum):
    #LastClued=[]
    gather=[]                                  #gather will collect the clued cards
    if ColOrNum:                               #ColOrNum: =0 is color, =1 is number
        print('Recording Number %u to player %u'%(value+1, player)) #value+1 is external format
    else:
        print('Recording Color %c to player %u'%(colors[value], player))
    for card in range(4):                      #goes by pure chronological order to record clued cards
        serial=table[player,card]
        if deck[serial][ColOrNum]==value:
            gather.append(1)
            print('Recording serial as',value,ColOrNum,'and appending serial to LastClued')
            LastClued.append(serial)
            print(LastClued)
            ClueKinds[serial,ColOrNum]=1       #ClueKinds tracks whether cards are clued color or number
        else: gather.append(0)

        if ColOrNum and np.all(np.transpose(stacks)[value]):
            ClueKinds[serial]=[-1,0]           #When a card is already played, it is marked as kind [-1,0]
        elif not ColOrNum and np.all(stacks[value]):
            ClueKinds[serial]=[-1,0]           #...to mean discard - wait for private info updates for better
        elif np.all(ClueKinds[serial]==[1,1]) and stacks[deck[serial][0],deck[serial][1]]:
            ClueKinds[serial]=[-1,0]                         
    print('RecordClue updated which cards are clued and gathered:')
    print('ClueKinds:',[list(ClueKinds[card]) for card in table[player]])
    print('gather:',gather)
    if ColOrNum:                               #upd is the 2D array for how to update each card
        upd=[np.subtract([1,1,1,1],gather) for i in range(5)]  #depending on color or number, it has to be applied
        upd[value]=gather                      #across all numbers and colors(resp.), hence the *5
        upd=np.transpose([upd for i in range(ManyCol)],axes=(2,0,1))  #and *ManyCol
    else:
        upd=[np.subtract([1,1,1,1],gather) for i in range(ManyCol)]
        upd[value]=gather
        upd=np.transpose([upd for i in range(5)],axes=(2,1,0))
    PubInfo[table[player],:,:]=np.logical_and(PubInfo[table[player],:,:],upd)
    print('update array for player', player,':\n', upd)
    surry=[]                                   #surry is a surrogate for priority
    for s in [2,1,0,-1]:                       #possible numbers of clues; higher sum = higher priority 
        for card in [3,2,1,0]:                 #loop over cards in reverse chronological order
            serial=table[player,card]
            #print(serial, deck[serial],sum(ClueKinds[card]))
            if np.sum(ClueKinds[serial])==s:
                surry.append(serial)
    priority[player]=surry
    print('New priority for player %u is'%(player),surry,'\n\n')

def react(player, color, number=5, queue=[]):
    if number==5 and queue:                     ###############CHANGE?????????
        number=deck[queue[-1]][1]+1              ###
    elif number==5:                             ###
        number=stacks[color].index(0)            ###
    print('Looking for color %c and number %u in player %u'%(colors[color], number+1, player))
                                               #number+1 is external format
    print('and skipping serials', queue,'... priority is ', priority[player]) 
    for suspect in priority[player]:
        if suspect in queue:                   #skips cards already queued to play; Omitting queue mostly
            continue                           #takes care of disallowing chaining multiple unclueds per hand
        elif PubInfo[suspect,color,number]:    #returns highest priority card that is possibly color&number
            print('Returning', suspect)
            return suspect
    return -1

#Start at clue giver going backward to look for a possible chain starting at the next color
#card that needs to be played on color and ending at number-1. Once a card is found, look at
#that same player for the next card and keep going backward until number-1 is reached.
def respond(player, giver, color, number=5):
    if number==5:
        print('Player %u responds to color %c from player %u'%(player,colors[color],giver))
    else:                                       #...number +1 is external format
        print('Player %u responds to color %c and number %u from player %u'%(player, colors[color], number+1, giver))
    i=stacks[color].index(0)
    queue=[]
    virgins=0                                   #number of virgins(unclued cards) needed from player's hand
    other=Mod5SkipBack(giver, player)
    print('The next card is numbered %u and the first player to search is %u'%(i+1, other)) #i+1 is external format
    fail=0                          ##Would like to allow giver to make chains involving cards in his hand
    while i<=number:    ######<= seems correct and it should not leak private info... check to make sure???
        WouldPlay=react(other, color, i, queue)  #card that player 'other' would try to play if he thought
        print('Player %u would play %u in response'%(other, WouldPlay)) #...he was told to play [color,i]
        if deck[WouldPlay]==[color,i]:
            print('It matches color %c and number %u'%(colors[color], i+1)) #i+1 is external format
            queue.append(WouldPlay)
            i+=1                                 #success=traverse all hands looking for next number.
            fail=0
            print('New searching number is %u'%(i+1))  #i+1 is external format
        else:
            print('It did not match color %c and number %u'%(colors[color], i+1)) #i+1 is external format
            other=Mod5SkipBack(other,player,giver)
            fail+=1
            print('New fail count is', fail)
        if fail==3 and number==5:
            print('Did not find needed card in any visible hands. Appending next color card to player %u then quitting'%(player))
            DeductCard=react(player, color, i, queue)
            queue.append(DeductCard)
            break
        elif fail==3:
            print('Did not find needed card in any visible hands. Appending next card to player', player)
            DeductCard=react(player, color, i, queue)
            queue.append(DeductCard)
            if np.all(ClueKinds[DeductCard]==[0,0]):     #must use np.all???
                virgins-=1
            i+=1
            fail=0
            print('Looking for color %c and number %u.'%(colors[color],i+1)) #i+1 is external format
    
    if queue:
        print('Player %u is told that %s should play first'%(player,deck[queue[0]]))
    if len(queue)>1:
        print('Then, %s should play second'%(deck[queue[1]]))
    if len(queue)>2:
        print('Then, %s should play third'%(deck[queue[2]]))
    if len(queue)>3:
        print('Then, %s should play fourth'%(deck[queue[3]]))
    if len(queue)>4:
        print('Finally, %s should play last'%(deck[queue[4]]))
    print('Returning queue', queue, '\n\n')
    return (queue,virgins)

def clue(receiver, giver, value, ColOrNum):
    candies=[[] for i in range(ManyCol)]
    SaveColors=[]
    record=-8
    chop=priority[receiver,3]
    
    print('doing RecordClue', receiver,value,ColOrNum)
    RecordClue(receiver,value,ColOrNum)
    if LastClued==[]:
        print('errrrr... or maybe advanced null clue if allowed. Dont let me down')

    for serial in priority[receiver]:
        if serial in LastClued:
            print('found bottom card:', serial)
            bottom=serial
            break

    if ColOrNum==0:   #Receiver doubts elaborate chaining possibilities in own hand with color clue
        tasks[receiver][bottom]=respond(receiver,giver,value)[0]
    else:
        for color in range(ManyCol):
            candy=respond(receiver,giver,color,value)
            if candy[1]>record:
                record=candy[1]
                candies=[[] for i in range(ManyCol+1)]
                candies[color]=candy[0]
                print('beat virgins record. old record/new record/candies:',record,candy[1],candies)
            elif candy[1]==record:
                print('matched virgins record. old record/new record/candies:',record,candy[1],candies)
                candies[color]=candy[0]
            else:
                print('The %c chain was beaten by a previous color:old record/new record/candies:'%(colors[color]),record,candy[1],candies)
        #If it looks like a save, record possible colors and number, include in candies.
        if chop in LastClued:
            SafeCards=np.array(extras)+stacks
            DangerCards=np.invert(SafeCards.astype('bool_'))
            print(DangerCards)
            SaveColors=list(np.logical_and(DangerCards[:,value],PubInfo[chop,:,value]))
            if np.any(SaveColors):
                candies[5]=[SaveColors,value]
                print('recording possible save clue',candies)
            if DangerCards[deck[chop][0],deck[chop][1]]==1:
                surry=[0 for i in range(ManyCol)]
                surry[deck[chop][0]]=1
                #candy=[[] for i in range(ManyCol)]
                #candy.append(surry)
                for player in np.setdiff1d(range(5),[receiver,giver]):
                    candy=respond(player,giver,deck[bottom][0],deck[bottom][1])[0]
                    candy=[candy,[surry,value]]
                    tasks[player][bottom]=candy
        tasks[receiver][bottom]=candies

In [138]:
TEST()              #TEST() is a good place to modify the deck, stacks, priorities, etc. and
                    #test out different scenarios.

play(0)             #Colors are valued 0=r,y,g,b,w=4.
play(0)             #Playing two reds makes r3 the next playable.

play(3)             #Playing three blues makes b4 the next playable
play(3)
play(3)

#print(deck[0][1])
#respond(1,4,0,4)
#RecordClue(2,4,0)   #RecordClue(i,j,k) updates the arrays pertaining to public clue information
#RecordClue(2,3,1)   #...when clue type k (k=0:color; k=1:number) of value j is given to player i.
#RecordClue(4,1,0)   #Colors and Numbers are ordered 0=r,y,g,b,w=4 and 0=1,2,3,4,5=4(resp.).
                    #e.g. The first RecordClue updates public information pertaining to a
                    #...w clue to player 2.

                    #e.g. The second RecordClue updates public information pertaining to a
                    #...4 clue to player 2.

clue(0,4,4,1)       #clue(i,j,k,l) records four interpretations when player j gives clue
                    #(type l/value k) to player i.
                    #e.g. player 4 gives number 5 clue to player 0.
print(tasks)        #tasks consists of five dictionaries, one for each player. The keys are the
                    #bottom cards for different clues, i.e. the highest priority cards positively
                    #affected by the clue. This example should display that player 0 thinks the above
                    #clue was either a blue chain, a white chain, or a save clue for any color
                    #of 5. Player 0 will know whether it was a white chain when card 9 has the
                    #opportunity to play. If card 9 doesn't play and nothing more important could
                    #have overriden that play, player 0 knows it was either a blue chain or a save.
                    #The only way the blue chain will be contradicted is if someone clues b4 or both
                    #b4's become visible. Otherwise, the two possibilities hang in limbo and the 
                    #clue acts as a save.


['r5', 'b3', 'y2', 'y1']
['r2', 'g1', 'g4', 'w3']
['w1', 'w1', 'b4', 'y3']
['y5', 'r4', 'r3', 'w2']
['r1', 'g3', 'y4', 'g1']
['r1', 'r1', 'r1', 'r1']
['r1', 'r1', 'r1', 'r1']
['r1', 'r1']
doing RecordClue 0 4 1
Recording Number 5 to player 0
Recording serial as 4 1 and appending serial to LastClued
[0]
RecordClue updated which cards are clued and gathered:
ClueKinds: [[0, 1], [0, 0], [0, 0], [0, 0]]
gather: [1, 0, 0, 0]
update array for player 0 :
 [[[0 0 0 0 1]
  [0 0 0 0 1]
  [0 0 0 0 1]
  [0 0 0 0 1]
  [0 0 0 0 1]]

 [[1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]]

 [[1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]]

 [[1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]
  [1 1 1 1 0]]]
New priority for player 0 is [0, 3, 2, 1] 


found bottom card: 0
Player 0 responds to color r and number 5 from player 4
The next card is numbered 5 and the first player to search is 3
Looking for color r and number 5 in player 3
and skipping serials [] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color r and number 5
New fail count is 1
Looking for color r and number 5 in player 2
and skipping serials [] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color r and number 5
New fail count is 2
Looking for color r and number 5 in player 1
and skipping serials [] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color r and number 5
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color r and number 5 in player 0
and skipping serials [] ... priority is  [0 3 2 1]
Returning 0
Looking for color r and number 6.
Player 0 is told that [0, 4] should play first
Returning queue [0] 


beat virgins record. old record/new record/candies: 0 0 [[0], [], [], [], [], []]
Player 0 responds to color y and number 5 from player 4
The next card is numbered 1 and the first player to search is 3
Looking for color y and number 1 in player 3
and skipping serials [] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color y and number 1
New fail count is 1
Looking for color y and number 1 in player 2
and skipping serials [] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color y and number 1
New fail count is 2
Looking for color y and number 1 in player 1
and skipping serials [] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color y and number 1
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color y and number 1 in player 0
and skipping serials [] ... priority is  [0 3 2 1]
Returning 3
Looking for color y and number 2.
Looking for color y and number 2 in player 3
and skipping serials [3] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color y and number 2
New fail count is 1
Looking for color y and number 2 in player 2
and skipping serials [3] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color y and number 2
New fail count is 2
Looking for color y and number 2 in player 1
and skipping serials [3] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color y and number 2
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color y and number 2 in player 0
and skipping serials [3] ... priority is  [0 3 2 1]
Returning 2
Looking for color y and number 3.
Looking for color y and number 3 in player 3
and skipping serials [3, 2] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color y and number 3
New fail count is 1
Looking for color y and number 3 in player 2
and skipping serials [3, 2] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It matches color y and number 3
New searching number is 4
Looking for color y and number 4 in player 2
and skipping serials [3, 2, 11] ... priority is  [11 10  9  8]
Returning 10
Player 2 would play 10 in response
It did not match color y and number 4
New fail count is 1
Looking for color y and number 4 in player 1
and skipping serials [3, 2, 11] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color y and number 4
New fail count is 2
Looking for color y and number 4 in player 3
and skipping serials [3, 2, 11] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color y and number 4
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color y and number 4 in player 0
and skipping serials [3, 2, 11] ... priority is  [0 3 2 1]
Returning 1
Looking for color y and number 5.
Looking for color y and number 5 in player 2
and skipping serials [3, 2, 11, 1] ... priority is  [11 10  9  8]
Returning 10
Player 2 would play 10 in response
It did not match color y and number 5
New fail count is 1
Looking for color y and number 5 in player 1
and skipping serials [3, 2, 11, 1] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color y and number 5
New fail count is 2
Looking for color y and number 5 in player 3
and skipping serials [3, 2, 11, 1] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color y and number 5
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color y and number 5 in player 0
and skipping serials [3, 2, 11, 1] ... priority is  [0 3 2 1]
Returning 0
Looking for color y and number 6.
Player 0 is told that [1, 0] should play first
Then, [1, 1] should play second
Then, [1, 2] should play third
Then, [3, 2] should play fourth
Finally, [0, 4] should play last
Returning queue [3, 2, 11, 1, 0] 


The y chain was beaten by a previous color:old record/new record/candies: 0 -3 [[0], [], [], [], [], []]
Player 0 responds to color g and number 5 from player 4
The next card is numbered 1 and the first player to search is 3
Looking for color g and number 1 in player 3
and skipping serials [] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color g and number 1
New fail count is 1
Looking for color g and number 1 in player 2
and skipping serials [] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color g and number 1
New fail count is 2
Looking for color g and number 1 in player 1
and skipping serials [] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color g and number 1
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color g and number 1 in player 0
and skipping serials [] ... priority is  [0 3 2 1]
Returning 3
Looking for color g and number 2.
Looking for color g and number 2 in player 3
and skipping serials [3] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color g and number 2
New fail count is 1
Looking for color g and number 2 in player 2
and skipping serials [3] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color g and number 2
New fail count is 2
Looking for color g and number 2 in player 1
and skipping serials [3] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color g and number 2
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color g and number 2 in player 0
and skipping serials [3] ... priority is  [0 3 2 1]
Returning 2
Looking for color g and number 3.
Looking for color g and number 3 in player 3
and skipping serials [3, 2] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color g and number 3
New fail count is 1
Looking for color g and number 3 in player 2
and skipping serials [3, 2] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color g and number 3
New fail count is 2
Looking for color g and number 3 in player 1
and skipping serials [3, 2] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color g and number 3
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color g and number 3 in player 0
and skipping serials [3, 2] ... priority is  [0 3 2 1]
Returning 1
Looking for color g and number 4.
Looking for color g and number 4 in player 3
and skipping serials [3, 2, 1] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color g and number 4
New fail count is 1
Looking for color g and number 4 in player 2
and skipping serials [3, 2, 1] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color g and number 4
New fail count is 2
Looking for color g and number 4 in player 1
and skipping serials [3, 2, 1] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color g and number 4
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color g and number 4 in player 0
and skipping serials [3, 2, 1] ... priority is  [0 3 2 1]
Looking for color g and number 5.
Looking for color g and number 5 in player 3
and skipping serials [3, 2, 1, -1] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color g and number 5
New fail count is 1
Looking for color g and number 5 in player 2
and skipping serials [3, 2, 1, -1] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color g and number 5
New fail count is 2
Looking for color g and number 5 in player 1
and skipping serials [3, 2, 1, -1] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color g and number 5
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color g and number 5 in player 0
and skipping serials [3, 2, 1, -1] ... priority is  [0 3 2 1]
Returning 0
Looking for color g and number 6.
Player 0 is told that [1, 0] should play first
Then, [1, 1] should play second
Then, [3, 2] should play third
Then, [0, 0] should play fourth
Finally, [0, 4] should play last
Returning queue [3, 2, 1, -1, 0] 


The g chain was beaten by a previous color:old record/new record/candies: 0 -4 [[0], [], [], [], [], []]
Player 0 responds to color b and number 5 from player 4
The next card is numbered 4 and the first player to search is 3
Looking for color b and number 4 in player 3
and skipping serials [] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color b and number 4
New fail count is 1
Looking for color b and number 4 in player 2
and skipping serials [] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color b and number 4
New fail count is 2
Looking for color b and number 4 in player 1
and skipping serials [] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color b and number 4
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color b and number 4 in player 0
and skipping serials [] ... priority is  [0 3 2 1]
Returning 3
Looking for color b and number 5.
Looking for color b and number 5 in player 3
and skipping serials [3] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color b and number 5
New fail count is 1
Looking for color b and number 5 in player 2
and skipping serials [3] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color b and number 5
New fail count is 2
Looking for color b and number 5 in player 1
and skipping serials [3] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color b and number 5
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color b and number 5 in player 0
and skipping serials [3] ... priority is  [0 3 2 1]
Returning 0
Looking for color b and number 6.
Player 0 is told that [1, 0] should play first
Then, [0, 4] should play second
Returning queue [3, 0] 


The b chain was beaten by a previous color:old record/new record/candies: 0 -1 [[0], [], [], [], [], []]
Player 0 responds to color w and number 5 from player 4
The next card is numbered 1 and the first player to search is 3
Looking for color w and number 1 in player 3
and skipping serials [] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color w and number 1
New fail count is 1
Looking for color w and number 1 in player 2
and skipping serials [] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color w and number 1
New fail count is 2
Looking for color w and number 1 in player 1
and skipping serials [] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color w and number 1
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color w and number 1 in player 0
and skipping serials [] ... priority is  [0 3 2 1]
Returning 3
Looking for color w and number 2.
Looking for color w and number 2 in player 3
and skipping serials [3] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It matches color w and number 2
New searching number is 3
Looking for color w and number 3 in player 3
and skipping serials [3, 15] ... priority is  [15 14 13 12]
Returning 14
Player 3 would play 14 in response
It did not match color w and number 3
New fail count is 1
Looking for color w and number 3 in player 2
and skipping serials [3, 15] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color w and number 3
New fail count is 2
Looking for color w and number 3 in player 1
and skipping serials [3, 15] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It matches color w and number 3
New searching number is 4
Looking for color w and number 4 in player 1
and skipping serials [3, 15, 7] ... priority is  [7 6 5 4]
Returning 6
Player 1 would play 6 in response
It did not match color w and number 4
New fail count is 1
Looking for color w and number 4 in player 3
and skipping serials [3, 15, 7] ... priority is  [15 14 13 12]
Returning 14
Player 3 would play 14 in response
It did not match color w and number 4
New fail count is 2
Looking for color w and number 4 in player 2
and skipping serials [3, 15, 7] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color w and number 4
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color w and number 4 in player 0
and skipping serials [3, 15, 7] ... priority is  [0 3 2 1]
Returning 2
Looking for color w and number 5.
Looking for color w and number 5 in player 1
and skipping serials [3, 15, 7, 2] ... priority is  [7 6 5 4]
Returning 6
Player 1 would play 6 in response
It did not match color w and number 5
New fail count is 1
Looking for color w and number 5 in player 3
and skipping serials [3, 15, 7, 2] ... priority is  [15 14 13 12]
Returning 14
Player 3 would play 14 in response
It did not match color w and number 5
New fail count is 2
Looking for color w and number 5 in player 2
and skipping serials [3, 15, 7, 2] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color w and number 5
New fail count is 3
Did not find needed card in any visible hands. Appending next card to player 0
Looking for color w and number 5 in player 0
and skipping serials [3, 15, 7, 2] ... priority is  [0 3 2 1]
Returning 0
Looking for color w and number 6.
Player 0 is told that [1, 0] should play first
Then, [4, 1] should play second
Then, [4, 2] should play third
Then, [1, 1] should play fourth
Finally, [0, 4] should play last
Returning queue [3, 15, 7, 2, 0] 


The w chain was beaten by a previous color:old record/new record/candies: 0 -2 [[0], [], [], [], [], []]
[[False False False False  True]
 [False False False False  True]
 [False False False False  True]
 [False False False False  True]
 [False False False False  True]]
recording possible save clue [[0], [], [], [], [], [[True, True, True, True, True], 4]]
Player 1 responds to color r and number 5 from player 4
The next card is numbered 5 and the first player to search is 3
Looking for color r and number 5 in player 3
and skipping serials [] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color r and number 5
New fail count is 1
Looking for color r and number 5 in player 2
and skipping serials [] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color r and number 5
New fail count is 2
Looking for color r and number 5 in player 0
and skipping serials [] ... priority is  [0 3 2 1]
Returning 0
Player 0 would play 0 in response
It matches color r and number 5
New searching number is 6
Player 1 is told that [0, 4] should play first
Returning queue [0] 


Player 2 responds to color r and number 5 from player 4
The next card is numbered 5 and the first player to search is 3
Looking for color r and number 5 in player 3
and skipping serials [] ... priority is  [15 14 13 12]
Returning 15
Player 3 would play 15 in response
It did not match color r and number 5
New fail count is 1
Looking for color r and number 5 in player 1
and skipping serials [] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color r and number 5
New fail count is 2
Looking for color r and number 5 in player 0
and skipping serials [] ... priority is  [0 3 2 1]
Returning 0
Player 0 would play 0 in response
It matches color r and number 5
New searching number is 6
Player 2 is told that [0, 4] should play first
Returning queue [0] 


Player 3 responds to color r and number 5 from player 4
The next card is numbered 5 and the first player to search is 2
Looking for color r and number 5 in player 2
and skipping serials [] ... priority is  [11 10  9  8]
Returning 11
Player 2 would play 11 in response
It did not match color r and number 5
New fail count is 1
Looking for color r and number 5 in player 1
and skipping serials [] ... priority is  [7 6 5 4]
Returning 7
Player 1 would play 7 in response
It did not match color r and number 5
New fail count is 2
Looking for color r and number 5 in player 0
and skipping serials [] ... priority is  [0 3 2 1]
Returning 0
Player 0 would play 0 in response
It matches color r and number 5
New searching number is 6
Player 3 is told that [0, 4] should play first
Returning queue [0] 


[{0: [[0], [], [], [], [], [[True, True, True, True, True], 4]]}, {0: [[0], [[1, 0, 0, 0, 0], 4]]}, {0: [[0], [[1, 0, 0, 0, 0], 4]]}, {0: [[0], [[1, 0, 0, 0, 0], 4]]}, {}]

In [ ]: