Pyro - Read All Clues (bits version)



In [40]:
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

def OutCard(card):
    return colors[card[0]]+str(card[1]+1)
deck=CreateDeck()
def PrintDeck(deck):
    DeckOut=[OutCard(card) 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/PlayNext/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)]
PlayNext=[[1,0,0,0,0] for i in range(ManyCol)]
extras=[[2,1,1,1,0] for i in range(ManyCol)]

stax=[[0 for i in range(5)] for i in range(ManyCol)]
PlayNekst=[[1,0,0,0,0] for i in range(ManyCol)]
ekstras=[[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])

pority=np.copy(table[:,::-1])   #TEST COPY

#############           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=[]   #???

PubImho=np.ones(shape=(len(deck),ManyCol,5), dtype='uint8', order='C')     #TEST COPIES
ClooKinds=np.zeros(shape=(len(deck),2),dtype='int8',order='C')
WichClood=[]
 
####################################################################################################
#####################################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')
SeePrivate=np.zeros(shape=(5,ManyCol,5),dtype='uint8',order='C')

#tasks keeps track of pending plays and saves
tasks=[{} for i in range(5)]

tasqs=[{} for i in range(5)]

#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)))
busy=[0 for i in range(5)]

shtatush=np.zeros((5,len(deck)))
bizzy=[0 for i in range(5)]
#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 [41]:
#TEST 5 COLOR CASE
def TEST():
    global deck, SeePrivate
    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
    for player in range(5):   #Move to a more central location???
        for other in np.setdiff1d(range(5),[player]):
            for serial in table[other]:
                SeePrivate[player,deck[serial][0],deck[serial][1]]+=1
    PrintDeck(deck)

In [42]:
#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):
    global stax, PlayNekst
    stax[color]=[1]+stax[color][:-1]
    PlayNekst[color]=[0]+PlayNekst[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

def reconcile(reset):
    global stacks, PlayNext, ClueKinds, PubInfo, priority, tasks
    if reset:
        stacks=stax
        PlayNext=Playnekst
        ClueKinds=ClooKinds
        PubInfo=PubImho
        priority=pority
        tasks=tasqs        
    else:
        stax=stacks
        Playnekst=PlayNext
        ClooKinds=ClueKinds
        PubImho=PubInfo
        pority=priority
        tasqs=tasks

#UPDATES PubInfo, ClueKinds, AND priority AFTER A CLUE IS GIVEN.
def RecordClue(player, value, ColOrNum):
    global WichClood, ClooKinds, PubImho, pority, stax
    WichClood=[]
    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)
            WichClood.append(serial)
            ClooKinds[serial,ColOrNum]=1       #ClooKinds tracks whether cards are clued color or number
        else: gather.append(0)

        if ColOrNum and np.all(np.transpose(stax)[value]):
            ClooKinds[serial]=[-1,0]           #When a card is already played, it is marked as kind [-1,0]
        elif not ColOrNum and np.all(stax[value]):
            ClooKinds[serial]=[-1,0]           #...to mean discard - wait for private info updates for better
        elif np.all(ClooKinds[serial]==[1,1]) and stax[deck[serial][0],deck[serial][1]]:
            ClooKinds[serial]=[-1,0]                         
    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))
    PubImho[table[player],:,:]=np.logical_and(PubImho[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]
            if np.sum(ClooKinds[serial])==s:
                surry.append(serial)
    pority[player]=surry

def react(player, color, number=5, queue=[]):
    global pority, PubImho
    if number==5 and queue:
        number=deck[queue[-1]][1]+1
    elif number==5:
        number=stax[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,'... pority is ', pority[player]) 
    for suspect in pority[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 PubImho[suspect,color,number]:    #returns highest priority card that is possibly color&number
            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, receiver=-1):
    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))
    if np.all(stax[color]):
        return [[],0]
    i=stax[color].index(0)
    if i>number:
        return[[],0]
    queue=[]
    bits=0                          ##bits estimates the order of information implied - Occam's razor suggests taking
    other=Mod5SkipBack(giver, player) ##the smallest possible value of bits (assume as little information as possible)
    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
    while i<number:
        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 WouldPlay!=-1 and deck[WouldPlay]==[color,i]:#no np.all?
            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.
        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
        if fail==3:
            print('Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player', player)
            DeduceCard=react(player, color, i, queue)
            if DeduceCard==-1:
                return [[],0]
            if queue==[]:
                bits=1
            bits*=np.sum(PubImho[DeduceCard,:,:])
            queue.append(DeduceCard)
            if number==5:
                return [queue,0]
            i+=1
            fail=0
            print('Looking for color %c and number %u.'%(colors[color],i+1)) #i+1 is external format
    if receiver!=-1:
        bottom=react(receiver,color,i,queue)
        if bottom==-1:
            return [[],0]
        queue.append(bottom)
    print('Player %u is told that %s should play first'%(player,OutCard(deck[queue[0]])))
    if len(queue)>1:
        print('Then, %s should play second'%(OutCard(deck[queue[1]])))
    if len(queue)>2:
        print('Then, %s should play third'%(OutCard(deck[queue[2]])))
    if len(queue)>3:
        print('Then, %s should play fourth'%(OutCard(deck[queue[3]])))
    if len(queue)>4:
        print('I thikn this is err')
        print('Finally, %s should play last'%(deck[queue[4]]))
    print('Returning queue', queue)
    return (queue,bits)

def clue(receiver, giver, value, ColOrNum): #Score each poss. chain here? Wait until turn?
    global pority, WichClood, PubImho, tasqs, stax
    candies=[]
    SaveColors=[]
    DangerCards=[]
    CanBottomPlay=0
    record=5**7+1
    SelfIgnite=[]
    chop=pority[receiver,3]
    
    print('Recording Clue', receiver,value,ColOrNum)
    RecordClue(receiver,value,ColOrNum)
    
    for serial in pority[receiver]:
        if serial in WichClood:
            print('found bottom card:', serial)
            bottom=serial
            CanBottomPlay=np.any(np.multiply(PubImho[chop,:,:],PlayNekst))
            break
    if WichClood==[]:
        print('errrrr... empty clue: return -1')
        return -1
    if ColOrNum==0:
        candy=respond(receiver,giver,value,5,receiver)
        if candy==[[],0]:
            return -1
        candies=[candy[0]]
    else:
        if chop in WichClood and not busy[receiver]:
            SafeCards=(np.array(ekstras)+stax).astype('bool_')
            DangerCards=np.invert(SafeCards).astype('uint8')
            SaveColors=list(np.multiply(DangerCards[:,value],PubImho[chop,:,value]))
        for color in range(ManyCol):
            print('\n\n')
            candy=respond(receiver,giver,color,value,receiver)
            print('respond for color',colors[color],candy)
            if candy==[[],0] and CanBottomPlay:
                candies=[[bottom]]
            elif candy==[[],0]:
                print('respond yielded nothing for color %c'%(colors[color]))
            elif candy[0] and candy[0][0] in table[receiver]:
                if candy[1]<record:
                    record=candy[1]
                    SelfIgnite=candy[0]
                    print('color after SelfIgnite',colors[color])
                    print('beat bits record. old record/new record/SelfIgnite:',record,candy[1],candies)
                else:
                    print('The %c chain was beat or tied by a previous color:old record/new record/SelfIgnite:'%(colors[color]),record,candy[1],candies)
            else:
                candies.append(candy[0])
        if SelfIgnite and SelfIgnite not in candies:
            candies.append(SelfIgnite)
            print('candies after selfignite',candies)
        if np.any(SaveColors):
            if not candies:
                print('recording save clue',candies)
                PubImho[chop,:,value]=SaveColors
                return -1
            else:
                print('recording possible save clue',candies)
                candies.append([SaveColors,value,chop])
    tasqs[receiver][bottom]=candies
    for player in np.setdiff1d(range(5),[receiver,giver]):
        if np.any(DangerCards) and DangerCards[deck[chop][0],deck[chop][1]]==1:
            tasqs[player][bottom]=[SaveColors,value,chop]
        else:
            surry=respond(player,giver,deck[bottom][0],deck[bottom][1],receiver)
            if surry:
                tasqs[player][bottom]=surry[0]

In [43]:
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(2)
play(2)

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

clue(0,4,4,1)       #clue(i,j,k,l) records four interpretations when player j gives clue
#2#clue(4,1,1,0)       #(type l/value k) to player i. First, a 5 clue to player 0, then a yellow to 4.
#3#ekstras[1][2]=0     #This records that a [1,2] card (y3) has either been discarded or played,
#3#RecordClue(4,0,1,0) #and affects saving decisions. RecordClue(4,0,1,0) records a 1 clue to player
#3#clue(4,0,2,1)       #4. With the deck preset in TEST(), this amounts to cluing the first and last
print(tasqs)         #cards.
                    #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. For example, clue(0,4,4,1) should display that player 0
                    #thinks the clue was either a self-ignite (red or green) 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.


['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']
Recording Clue 0 4 1
Recording Number 5 to player 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]]]
found bottom card: 0



Player 0 responds to color r and number 5 from player 4
The next card is numbered 3 and the first player to search is 3
Looking for color r and number 3 in player 3
and skipping serials [] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color r and number 3
Looking for color r and number 3 in player 2
and skipping serials [] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color r and number 3
Looking for color r and number 3 in player 1
and skipping serials [] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color r and number 3
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color r and number 3 in player 0
and skipping serials [] ... pority is  [0 3 2 1]
Looking for color r and number 4.
Looking for color r and number 4 in player 3
and skipping serials [3] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color r and number 4
Looking for color r and number 4 in player 2
and skipping serials [3] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color r and number 4
Looking for color r and number 4 in player 1
and skipping serials [3] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color r and number 4
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color r and number 4 in player 0
and skipping serials [3] ... pority is  [0 3 2 1]
Looking for color r and number 5.
Looking for color r and number 5 in player 0
and skipping serials [3, 2] ... pority is  [0 3 2 1]
Player 0 is told that y1 should play first
Then, y2 should play second
Then, r5 should play third
Returning queue [3, 2, 0]
respond for color r ([3, 2, 0], 400)
color after SelfIgnite r
beat bits record. old record/new record/SelfIgnite: 400 400 []



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 [] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color y and number 1
Looking for color y and number 1 in player 2
and skipping serials [] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color y and number 1
Looking for color y and number 1 in player 1
and skipping serials [] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color y and number 1
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color y and number 1 in player 0
and skipping serials [] ... pority is  [0 3 2 1]
Looking for color y and number 2.
Looking for color y and number 2 in player 3
and skipping serials [3] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color y and number 2
Looking for color y and number 2 in player 2
and skipping serials [3] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color y and number 2
Looking for color y and number 2 in player 1
and skipping serials [3] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color y and number 2
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color y and number 2 in player 0
and skipping serials [3] ... pority is  [0 3 2 1]
Looking for color y and number 3.
Looking for color y and number 3 in player 3
and skipping serials [3, 2] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color y and number 3
Looking for color y and number 3 in player 2
and skipping serials [3, 2] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It matches color y and number 3
Looking for color y and number 4 in player 2
and skipping serials [3, 2, 11] ... pority is  [11 10  9  8]
Player 2 would play 10 in response
It did not match color y and number 4
Looking for color y and number 4 in player 1
and skipping serials [3, 2, 11] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color y and number 4
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color y and number 4 in player 0
and skipping serials [3, 2, 11] ... pority is  [0 3 2 1]
Looking for color y and number 5.
Looking for color y and number 5 in player 0
and skipping serials [3, 2, 11, 1] ... pority is  [0 3 2 1]
Player 0 is told that y1 should play first
Then, y2 should play second
Then, y3 should play third
Then, b3 should play fourth
I thikn this is err
Finally, [0, 4] should play last
Returning queue [3, 2, 11, 1, 0]
respond for color y ([3, 2, 11, 1, 0], 8000)
The y chain was beat or tied by a previous color:old record/new record/SelfIgnite: 400 8000 []



Player 0 responds to color g and number 5 from player 4
The next card is numbered 3 and the first player to search is 3
Looking for color g and number 3 in player 3
and skipping serials [] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color g and number 3
Looking for color g and number 3 in player 2
and skipping serials [] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color g and number 3
Looking for color g and number 3 in player 1
and skipping serials [] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color g and number 3
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color g and number 3 in player 0
and skipping serials [] ... pority is  [0 3 2 1]
Looking for color g and number 4.
Looking for color g and number 4 in player 3
and skipping serials [3] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color g and number 4
Looking for color g and number 4 in player 2
and skipping serials [3] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color g and number 4
Looking for color g and number 4 in player 1
and skipping serials [3] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color g and number 4
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color g and number 4 in player 0
and skipping serials [3] ... pority is  [0 3 2 1]
Looking for color g and number 5.
Looking for color g and number 5 in player 0
and skipping serials [3, 2] ... pority is  [0 3 2 1]
Player 0 is told that y1 should play first
Then, y2 should play second
Then, r5 should play third
Returning queue [3, 2, 0]
respond for color g ([3, 2, 0], 400)
The g chain was beat or tied by a previous color:old record/new record/SelfIgnite: 400 400 []



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 [] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color b and number 4
Looking for color b and number 4 in player 2
and skipping serials [] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color b and number 4
Looking for color b and number 4 in player 1
and skipping serials [] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color b and number 4
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color b and number 4 in player 0
and skipping serials [] ... pority is  [0 3 2 1]
Looking for color b and number 5.
Looking for color b and number 5 in player 0
and skipping serials [3] ... pority is  [0 3 2 1]
Player 0 is told that y1 should play first
Then, r5 should play second
Returning queue [3, 0]
respond for color b ([3, 0], 20)
color after SelfIgnite b
beat bits record. old record/new record/SelfIgnite: 20 20 []



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 [] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It did not match color w and number 1
Looking for color w and number 1 in player 2
and skipping serials [] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color w and number 1
Looking for color w and number 1 in player 1
and skipping serials [] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It did not match color w and number 1
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color w and number 1 in player 0
and skipping serials [] ... pority is  [0 3 2 1]
Looking for color w and number 2.
Looking for color w and number 2 in player 3
and skipping serials [3] ... pority is  [15 14 13 12]
Player 3 would play 15 in response
It matches color w and number 2
Looking for color w and number 3 in player 3
and skipping serials [3, 15] ... pority is  [15 14 13 12]
Player 3 would play 14 in response
It did not match color w and number 3
Looking for color w and number 3 in player 2
and skipping serials [3, 15] ... pority is  [11 10  9  8]
Player 2 would play 11 in response
It did not match color w and number 3
Looking for color w and number 3 in player 1
and skipping serials [3, 15] ... pority is  [7 6 5 4]
Player 1 would play 7 in response
It matches color w and number 3
Looking for color w and number 4 in player 1
and skipping serials [3, 15, 7] ... pority is  [7 6 5 4]
Player 1 would play 6 in response
It did not match color w and number 4
Either bottom card ready or did not find needed card in any visible hands. Appending next card, if able, to player 0
Looking for color w and number 4 in player 0
and skipping serials [3, 15, 7] ... pority is  [0 3 2 1]
Looking for color w and number 5.
Looking for color w and number 5 in player 0
and skipping serials [3, 15, 7, 2] ... pority is  [0 3 2 1]
Player 0 is told that y1 should play first
Then, w2 should play second
Then, w3 should play third
Then, y2 should play fourth
I thikn this is err
Finally, [0, 4] should play last
Returning queue [3, 15, 7, 2, 0]
respond for color w ([3, 15, 7, 2, 0], 400)
The w chain was beat or tied by a previous color:old record/new record/SelfIgnite: 20 400 []
candies after selfignite [[3, 0]]
recording possible save clue [[3, 0]]
[{0: [[3, 0], [[1, 1, 1, 1, 1], 4, 0]]}, {0: [[1, 1, 1, 1, 1], 4, 0]}, {0: [[1, 1, 1, 1, 1], 4, 0]}, {0: [[1, 1, 1, 1, 1], 4, 0]}, {}]