import json
import random
from ws4py.client.threadedclient import WebSocketClient
import numpy as np


def empty(list_of_card):
    flag=1
    for i in list_of_card:
        if i:
            flag=0
    return flag


class Action(object):

    def __init__(self, action, card_type, rank):
        self.action = action
        self.card_type = card_type
        self.rank = rank


class Board(object):
    # client对象中生成，一直存在，随着轮数update
    # allcard=[[0, '1'],[0, '2'],[0, '3'],[0, '4'],[0, '5'],[0, '6'],[0, '7'],[0, '8'],[0, '9'],[0, '10'],[0, 'J'],[0, 'Q'],[0, 'K'],[0, 'A'],[0, 'JOKER'],
    # [1, '1'],[1, '2'],[1, '3'],[1, '4'],[1, '5'],[1, '6'],[1, '7'],[1, '8'],[1, '9'],[1, '10'],[1, 'J'],[1, 'Q'],[1, 'K'],[1, 'A'],[1, 'JOKER'],
    # [2, '1'],[2, '2'],[2, '3'],[2, '4'],[2, '5'],[2, '6'],[2, '7'],[2, '8'],[2, '9'],[2, '10'],[2, 'J'],[2, 'Q'],[2, 'K'],[2, 'A'],[0, 'JOKER'],
    # [3, '1'],[3, '2'],[3, '3'],[3, '4'],[3, '5'],[3, '6'],[3, '7'],[3, '8'],[3, '9'],[3, '10'],[3, 'J'],[3, 'Q'],[3, 'K'],[3, 'A'],[1, 'JOKER']]

    allcard=[[0, '3'], [2, '3'], [0, '5'], [1, '5'], [3, '6'], [0, '6'], [2, '7'], [1, '7'], [0, '7'], [1, '8'], [2, '8'], [2, '9'], [0, '9'], [1, '9'], [1, '10'], [1, '10'], [0, '10'], [3, '10'], [2, 'J'], [0, 'Q'], [1, 'K'], [2, 'A'], [1, 'A'], [0, 'A'], [2, '2'], [3, '2'], [0, 'JOKER'],[1, '3'], [1, '3'], [3, '3'], [3, '4'], [2, '4'], [1, '4'], [0, '5'], [0, '6'], [2, '7'], [1, '7'], [3, '7'], [1, '8'], [3, '8'], [2, '9'], [3, '9'], [0, '10'], [0, 'J'], [1, 'J'], [2, 'Q'], [0, 'Q'], [3, 'Q'], [3, 'K'], [1, 'K'], [2, 'A'], [0, '2'], [0, 'JOKER'], [1, 'JOKER'],[3, '3'], [1, '4'], [2, '4'], [0, '4'], [3, '4'], [1, '5'], [1, '6'], [0, '7'], [3, '7'], [2, '8'], [3, '8'], [0, '8'], [3, '9'], [1, '9'], [2, '10'], [2, '10'], [3, 'J'], [1, 'J'], [1, 'Q'], [2, 'Q'], [3, 'Q'], [2, 'K'], [2, 'K'], [3, 'A'], [3, 'A'], [1, '2'], [1, '2'],[2, '3'], [0, '3'], [0, '4'], [2, '5'], [3, '5'], [2, '5'], [3, '5'], [3, '6'], [2, '6'], [2, '6'], [1, '6'], [0, '8'], [0, '9'], [3, '10'], [0, 'J'], [3, 'J'], [2, 'J'], [1, 'Q'], [0, 'K'], [3, 'K'], [0, 'K'], [1, 'A'], [0, 'A'], [0, '2'], [3, '2'], [2, '2'], [1, 'JOKER']]

    def __init__(self):
        self.flag=0
        self.theplayerindex=0
        self.key_card=[]
        self.content=[]
        self.hand_cards=[]
        self.index=''
        self.public=[]
        self.current_player=0
        self.current_stage=0
        self.self_rank=0
        self.opponent_rank=0
        self.current_rank=0
        self.action_list=[]
        self.action_performed={}
        self.current_times=0
        self.training_times=0
        self.winners=[]
        self.player0=np.zeros((4,15))
        self.player1=np.zeros((4,15))
        self.player2=np.zeros((4,15))
        self.opponentcards=np.full((5,16),2.0)
        self.boardcards=np.zeros((4,15))
        self.playcard=[[],[],[],[]]
        self.knowplaycard=[]
        self.unknowplaycard=[]
        self.unknowplaycardarr=np.zeros((5,16))
        self.weight=np.zeros((10,15))
        self.cardWeight={'A': 14, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8,
            '9': 9, '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'JOKER': 16,
             'PASS': 10000000,
            'Straight': 10, 'TripsPair': 10, 'ThreeWithTwo': 11, 'ThreePair': 10, 'Trips': 13,
            'Pair': 14, 'Single': 15,'Bomb':12,'StraightFlush':100000,'back':1 ,'tribute':1}
        self.cardWeight0={'A': 14, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8,
            '9': 9, '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'JOKER': 16, 'PASS': 7000000,
            'Straight': 10, 'TripsPair': 10, 'ThreeWithTwo': 10, 'ThreePair': 10, 'Trips': 85,
            'Pair': 685, 'Single': 5485,'Bomb':43885,'StraightFlush':351085,'back':1 ,'tribute':1}
        self.mycardWeight0={
        "Single":{'2':15, '3':14, '4':13,'5':12, '6':11, "7":10, "8":9, "9":8, "10":7, "J":6, "Q":5, "K":4, "A":3, "JOKER":1},
        "Pair":{'2':30,'3': 29, '4':28, '5':27, '6':26,'7': 25,'8': 24, '9':23, '10':22, 'J':21, "Q":20, "K":19, "A":18, "JOKER":16},
        "Trips":{'2':45, '3':44,"4": 43, "5":42, "6":41, '7':40,"8": 39,"9":38, "10":37, "J":36, "Q":35, "K":34, "A":33.0,"JOKER": 31.0},
        "ThreePair":{'2':60, "3":59, "4":58, "5":57, "6":56, "7":55, "8":54, "9":53, "10":52, "J":51, "Q":50,"K":49,"A":48,"JOKER": 46},
        "ThreeWithTwo":{"2":75,'3': 74,"4":73,"5":72, "6":71, "7":70, "8":69, "9":68, "10":67, "J":66, "Q":65, "K":64,"A":63, "JOKER":61},
        "TripsPair":{'2':90, "3":89, "4":88, "5":87, "6":86, "7":85, "8":84, "9":83, "10":82, "J":81, "Q":80, "K":79,"A":78,"JOKER":76},
        "Straight":{"2":108, "3":106, "4":104, "5":102, "6":100, "7":99, "8":98,"9": 97, "10":96, "J":95, "Q":94, "K":93,"A":92,"JOKER": 91},
        "StraightFlush":{'2':7.4, "3":8.4, "4":9.4, "5":10.4, "6":11.2, "7":12.2, "8":13.2, "9":14.2, "10":15.2,"J": 16.2, "Q":17.2,"K":18.2,"A":18.7, "JOKER":19.2},
        "Bomb":{"2":45.28, "3":45.26, "4":45.24, "5":45.22, "6":45.2, "7":45.18, "8":45.16, "9":45.14, "10":45.12,"J": 45.1, "Q":45.08, "K":45.06,"A":45.04,"JOKER":45.02},
        'back':{'2':15, '3':14, '4':13,'5':12, '6':11, "7":10, "8":9,"9":8, "10":7, "J":6, "Q":5, "K":4, "A":3, "JOKER":1},
        'tribute':{'2':15, '3':14, '4':13,'5':12, '6':11, "7":10, "8":9,"9":8, "10":7, "J":6, "Q":5, "K":4, "A":3, "JOKER":1},
        "PASS":{"PASS":0.0001}
    }
    #{'2':0.98, "3":0.96, "4":0.94, "5":0.92, "6":0.9, "7":0.88, "8":0.86, "9":0.84, "10":0.82,"J": 0.8, "Q":0.78,"K":0.76,"A":0.74, "JOKER":0.7},
        self.mycardWeight={
        "Single":{'2':15, '3':14, '4':13,'5':12, '6':11, "7":10, "8":9, "9":8, "10":7, "J":6, "Q":5, "K":4, "A":3, "JOKER":1},
        "Pair":{'2':30,'3': 29, '4':28, '5':27, '6':26,'7': 25,'8': 24, '9':23, '10':22, 'J':21, "Q":20, "K":19, "A":18, "JOKER":16},
        "Trips":{'2':45, '3':44,"4": 43, "5":42, "6":41, '7':40,"8": 39,"9":38, "10":37, "J":36, "Q":35, "K":34, "A":33.0,"JOKER": 31.0},
        "ThreePair":{'2':60, "3":59, "4":58, "5":57, "6":56, "7":55, "8":54, "9":53, "10":52, "J":51, "Q":50,"K":49,"A":48,"JOKER": 46},
        "ThreeWithTwo":{"2":75,'3': 74,"4":73,"5":72, "6":71, "7":70, "8":69, "9":68, "10":67, "J":66, "Q":65, "K":64,"A":63, "JOKER":61},
        "TripsPair":{'2':90, "3":89, "4":88, "5":87, "6":86, "7":85, "8":84, "9":83, "10":82, "J":81, "Q":80, "K":79,"A":78,"JOKER":76},
        "Straight":{"2":108, "3":106, "4":104, "5":102, "6":100, "7":99, "8":98,"9": 97, "10":96, "J":95, "Q":94, "K":93,"A":92,"JOKER": 91},
        "StraightFlush":{'2':0.98, "3":0.96, "4":0.94, "5":0.92, "6":0.9, "7":0.88, "8":0.86, "9":0.84, "10":0.82,"J": 0.8, "Q":0.78,"K":0.76,"A":0.74, "JOKER":0.7},
        "Bomb":{"2":45.28, "3":45.26, "4":45.24, "5":45.22, "6":45.2, "7":45.18, "8":45.16, "9":45.14, "10":45.12,"J": 45.1, "Q":45.08, "K":45.06,"A":45.04,"JOKER":45.02},
        'back':{'2':15, '3':14, '4':13,'5':12, '6':11, "7":10, "8":9,"9":8, "10":7, "J":6, "Q":5, "K":4, "A":3, "JOKER":1},
        'tribute':{'2':15, '3':14, '4':13,'5':12, '6':11, "7":10, "8":9,"9":8, "10":7, "J":6, "Q":5, "K":4, "A":3, "JOKER":1},
        "PASS":{"PASS":0.0001}
    }
        self.mycardWeight2={
        "Single":{'2':4.0, '3':3.4, '4':3.2,'5':3.0, '6':2.8, "7":2.6, "8":2.4, "9":2.2, "10":2.0, "J":1.8, "Q":1.6, "K":1.4, "A":1.2, "JOKER":1.0},
        "Pair":{'2':7.2,'3': 6.6, '4':6.4, '5':6.2, '6':6.0,'7': 5.8,'8': 5.6, '9':5.4, '10':5.2, 'J':5.0, "Q":4.8, "K":4.6, "A":4.4, "JOKER":4.2},
        "Trips":{'2':10.4, '3':9.8,"4": 9.6, "5":9.4, "6":9.2, '7':9.0,"8": 8.8,"9" :8.6, "10":8.4, "J":8.2, "Q":8.0, "K":7.8, "A":7.6,"JOKER": 7.4},
        "Bomb":{'2':10.54, '3':10.53,"4": 10.52, "5":10.51, "6":10.50, '7':10.49,"8": 10.48,"9" :10.47, "10":10.46, "J":10.45, "Q":10.44, "K":10.43, "A":10.42,"JOKER": 10.41},
        "StraightFlush":{'2':13.2, "3":13.0, "4":12.8, "5":12.6, "6":12.4, "7":12.2, "8":12.0, "9":11.8, "10":11.6,"J": 11.4, "Q":11.2,"K":11.0,"A":10.8, "JOKER":10.6},
        "ThreePair":{'2':15.8, "3":15.6, "4":15.4, "5":15.2, "6":15.0, "7":14.8, "8":14.6, "9":14.4, "10":14.2, "J":14.0, "Q":13.8,"K":13.6,"A":13.4,"JOKER": 13.2},
        "ThreeWithTwo":{'2':15.8, "3":15.6, "4":15.4, "5":15.2, "6":15.0, "7":14.8, "8":14.6, "9":14.4, "10":14.2, "J":14.0, "Q":13.8,"K":13.6,"A":13.4,"JOKER": 13.2},
        "TripsPair":{'2':15.8, "3":15.6, "4":15.4, "5":15.2, "6":15.0, "7":14.8, "8":14.6, "9":14.4, "10":14.2, "J":14.0, "Q":13.8,"K":13.6,"A":13.4,"JOKER": 13.2},
        "Straight":{'2':15.8, "3":15.6, "4":15.4, "5":15.2, "6":15.0, "7":14.8, "8":14.6, "9":14.4, "10":14.2, "J":14.0, "Q":13.8,"K":13.6,"A":13.4,"JOKER": 13.2},
        'back':{'2':4.0, '3':3.4, '4':3.2,'5':3.0, '6':2.8, "7":2.6, "8":2.4, "9":2.2, "10":2.0, "J":1.8, "Q":1.6, "K":1.4, "A":1.2, "JOKER":1.0},
        'tribute':{'2':4.0, '3':3.4, '4':3.2,'5':3.0, '6':2.8, "7":2.6, "8":2.4, "9":2.2, "10":2.0, "J":1.8, "Q":1.6, "K":1.4, "A":1.2, "JOKER":1.0},
        "PASS":{"PASS":0.0001,"JOKER":0.4001}
        }
    
        self.mycardWeight2={
        "Single":{'2':4.0, '3':3.4, '4':3.2,'5':3.0, '6':2.8, "7":2.6, "8":2.4, "9":2.2, "10":2.0, "J":1.8, "Q":1.6, "K":1.4, "A":1.2, "JOKER":1.0},
        "Pair":{'2':7.2,'3': 6.6, '4':6.4, '5':6.2, '6':6.0,'7': 5.8,'8': 5.6, '9':5.4, '10':5.2, 'J':5.0, "Q":4.8, "K":4.6, "A":4.4, "JOKER":4.2},
        "Trips":{'2':10.4, '3':9.8,"4": 9.6, "5":9.4, "6":9.2, '7':9.0,"8": 8.8,"9" :8.6, "10":8.4, "J":8.2, "Q":8.0, "K":7.8, "A":7.6,"JOKER": 7.4},
        "Bomb":{'2':10.54, '3':10.53,"4": 10.52, "5":10.51, "6":10.50, '7':10.49,"8": 10.48,"9" :10.47, "10":10.46, "J":10.45, "Q":10.44, "K":10.43, "A":10.42,"JOKER": 10.41},
        "StraightFlush":{'2':0.98, "3":0.96, "4":0.94, "5":0.92, "6":0.9, "7":0.88, "8":0.86, "9":0.84, "10":0.82,"J": 0.8, "Q":0.78,"K":0.76,"A":0.74, "JOKER":0.7},
        "ThreePair":{'2':15.8, "3":15.6, "4":15.4, "5":15.2, "6":15.0, "7":14.8, "8":14.6, "9":14.4, "10":14.2, "J":14.0, "Q":13.8,"K":13.6,"A":13.4,"JOKER": 13.2},
        "ThreeWithTwo":{'2':15.8, "3":15.6, "4":15.4, "5":15.2, "6":15.0, "7":14.8, "8":14.6, "9":14.4, "10":14.2, "J":14.0, "Q":13.8,"K":13.6,"A":13.4,"JOKER": 13.2},
        "TripsPair":{'2':15.8, "3":15.6, "4":15.4, "5":15.2, "6":15.0, "7":14.8, "8":14.6, "9":14.4, "10":14.2, "J":14.0, "Q":13.8,"K":13.6,"A":13.4,"JOKER": 13.2},
        "Straight":{'2':15.8, "3":15.6, "4":15.4, "5":15.2, "6":15.0, "7":14.8, "8":14.6, "9":14.4, "10":14.2, "J":14.0, "Q":13.8,"K":13.6,"A":13.4,"JOKER": 13.2},
        'back':{'2':4.0, '3':3.4, '4':3.2,'5':3.0, '6':2.8, "7":2.6, "8":2.4, "9":2.2, "10":2.0, "J":1.8, "Q":1.6, "K":1.4, "A":1.2, "JOKER":1.0},
        'tribute':{'2':4.0, '3':3.4, '4':3.2,'5':3.0, '6':2.8, "7":2.6, "8":2.4, "9":2.2, "10":2.0, "J":1.8, "Q":1.6, "K":1.4, "A":1.2, "JOKER":1.0},
        "PASS":{"PASS":0.0001,"JOKER":0.4001}
        }
        #make the current cards that I need to compete

    def initial(self,content):
        self.flag=0
        #print("the process of init board")
        self.key_card=content['current_rank']
        self.current_rank=content['current_rank']
        self.content=content
        self.hand_cards=content['hand_cards']
        self.index=content['index']
        self.public=content['public']
        self.current_player=content['current_player']
        self.current_stage==content['current_stage']
        self.self_rank=content['self_rank']
        #print('opponent_rank')
        self.opponent_rank=content['opponent_rank']
        #print('action_list')
        self.action_list=content['action_list']
        self.action_performed=content['action_performed']
        #print('current_performed')
        self.current_times=content['current_times']
        self.training_times=content['training_times']
        self.winners=[]
        self.player0=np.zeros((4,15))
        self.player1=np.zeros((4,15))
        self.player2=np.zeros((4,15))
        self.opponentcards=np.full((5,16),2.0)
        self.boardcards=np.zeros((4,15))
        #if content['type']==1:
        #self.playcard=[[],[],[],[]]
        #self.knowplaycard=[]
        if content['public'][0]['rest']==27 and content['public'][1]['rest']==27 and content['public'][2]['rest']==27 and content['public'][3]['rest']==27 and content['current_player']==0:
            self.unknowplaycardarr=np.zeros((5,16))
        self.unknowplaycard=[]
        self.weight=np.zeros((10,15))
        self.cards=[]
    def updateBoard(self,content,message):
        #开局计算对手池
        #print('update board')
        if content['type']==1:
            if content['action_performed']['type']=='PASS':
                self.playcard[content['current_player']]=[]
            else:
                self.playcard[content['current_player']]=content['action_performed']['action']
                for i in range(4):
                    if i != content['current_player']:
                        self.playcard[i]=[]
            #print('playcard')
            #print(self.playcard)
            #print(content['current_player'],"____________python____",content['action_performed']['action'])
        elif content['type']==2 and content['current_stage']==2:
            self.flag=1
            for i in range(4):
                if i != self.theplayerindex:
                    if self.playcard[i]:
                        self.flag=0
        if content['public'][0]['rest']==27 and content['public'][1]['rest']==27 and content['public'][2]['rest']==27 and content['public'][3]['rest']==27:
            self.opponentcards=np.full((5,16),2.0)
            self.opponentcards[0,:]=np.full((16),8.0)
            self.opponentcards[1:5,0]=np.full((4),30.0)
            self.opponentcards[0,0]=0
            self.opponentcards=self.opponentcards-message.mycards
            self.boardcards=np.zeros((4,15))
            self.player0=np.zeros((4,15))
            self.player1=np.zeros((4,15))
            self.player2=np.zeros((4,15))
            self.knowplaycard=[]
        #print(1111)
        if content['type']==1 and content['action_performed']['type']!="PASS" and content['action_performed']['action']:
            c=content['action_performed']['action']
            #print('action_perform......action',c)
            #self.knowplaycard+=c
            for i in c:
                #print("the element in action..........",i)
                self.knowplaycard.append(i)
        #print("get_unknowcard")
        #对手池,全部牌-出了的牌-自己的手牌
        for i in Board.allcard:
            if i in self.knowplaycard or i in self.hand_cards:
                pass
            else:
                self.unknowplaycard.append(i)
        for [i,j] in self.unknowplaycard:
            if j=='JOKER':
                self.unknowplaycardarr[i+1,message.card_dict[str(i)+j]+1]+=1
                self.unknowplaycardarr[0,message.card_dict[str(i)+j]+1]+=1
                self.unknowplaycardarr[i+1,0]+=1
            else:
                self.unknowplaycardarr[i+1,message.card_dict[j]+1]+=1
                self.unknowplaycardarr[0,message.card_dict[j]+1]+=1
                self.unknowplaycardarr[i+1,0]+=1

        '''
        if content['public'][0]['rest']==27 and content['public'][1]['rest']==27 and content['public'][2]['rest']==27 and content['public'][3]['rest']==27:
            if content['type']==2:
                doc=open('mycard.csv','w')
                print(message.mycards,doc)
                doc.close()
                doc=open('unknowcard','w')
                print(self.unknowplaycardarr,doc)
                doc.close()
        '''
        #更新通知消息下我需要对抗的牌型、对手池、board牌型
        #出牌阶段
        #print('Get the players cards outputed'
    def updateWeight(self,message):
        minn=100
        maxx=-1
        cnt=0
        minn_my=100
        maxx_my=-1
        cnt_my=0
        print(1111111)
        for i in range(16):
            if self.unknowplaycardarr[0][i]>=3:
                cnt+=1
                if minn > i:
                    minn=i
                if maxx < i:
                    maxx=i
        print(2222222)
        for i in range(16):
            if message.mycards[0,i]>=3:
                cnt_my+=1
                if minn_my > i:
                    minn=i
                if maxx > i:
                    maxx = i
        if cnt and cnt_my:
            if minn > maxx_my:
                self.cardWeight['Trips']+=1
            elif maxx < minn_my:
                self.cardWeight['Trips']-=1
        minn=100
        maxx=-1
        cnt=0
        minn_my=100
        maxx_my=-1
        cnt_my=0
        for i in range(16):
            if self.unknowplaycardarr[0][i]>=2:
                cnt+=1
                if minn > i:
                    minn=i
                if maxx < i:
                    maxx=i
        for i in range(16):
            if message.mycards[0,i]>=2:
                cnt_my+=1
                if minn_my > i:
                    minn=i
                if maxx > i:
                    maxx = i
        if cnt and cnt_my:
            if minn > maxx_my:
                self.cardWeight['Pair']+=1
            elif maxx < minn_my:
                self.cardWeight['Pair']-=1
        pass
    def cooperate(self):
        if board.public[board.index]['rest'] < board.public[(board.index+2)%4]['rest']*2:
            return True 
        else:
            return False

class Message:
    SuitNum=4
    RankNum=15
    #根据手牌列表初始化手牌对象得到——出完某种牌型后的手牌的value
    def __init__(self,hand_cards,key_card,weight):
        #print('hand_cards init the cardmessage')
        self.rankNum=['A','K','Q','J','10','9','8','7','6','5','4','3','2']
        self.card_dict={'1JOKER':14,'0JOKER':13,'A':12,'K':11,'Q':10,'J':9,'10':8,'9':7,'8':6,'7':5,'6':4,'5':3,'4':2,'3':1,'2':0}
        self.weight=weight
        self.key_card=key_card
        self.hand_cards=hand_cards
        self.mycards=np.zeros((5,16))
        self.card_mark=np.zeros((16))
        self.BombNum=0
        self.StraightNum=0
        self.StraightFlushNum=0
        self.TripsPairNum=0
        self.ThreeWithTwoNum=0
        self.ThreePairNum=0
        self.TripsNum=0
        self.PairNum=0
        self.SingleNum=0
        self.card_dict[key_card]=12
        for i in self.rankNum:
            if i != self.key_card:
                self.card_dict[i]-=1
            else:
                break
        self.value_dict={v:k for k,v in self.card_dict.items()}
        for [i,j] in hand_cards:
            if j=='JOKER':
                self.mycards[i+1,self.card_dict[str(i)+j]+1]+=1
                self.mycards[0,self.card_dict[str(i)+j]+1]+=1
                self.mycards[i+1,0]+=1
            else:
                self.mycards[i+1,self.card_dict[j]+1]+=1
                self.mycards[0,self.card_dict[j]+1]+=1
                self.mycards[i+1,0]+=1

    def value(self):
        pass
    def GetValue(self):
        #print('get_number_of_Bomb')
        for i in range(Message.RankNum):
            if self.mycards[0,i+1]>=4:
                self.BombNum+=1
            self.card_mark[i+1]=min(self.card_mark[i+1]+4,self.mycards[0,i+1])
        #print('get_number_of_straight')
        for i in range(Message.RankNum-4):
            minn=0
            for j in range(5):
                minn=min(minn,self.mycards[0,i+j+1])
            self.StraightNum+=minn
            self.card_mark[i+1]=min(self.card_mark[i+1]+minn,self.mycards[0,i+1])
        #print('get_number_of_straightFlush')
        for i in range(Message.SuitNum):
            for j in range(Message.RankNum-4):
                minn=0
                for k in range(5):
                    minn=min(minn,self.mycards[i+1,j+k+1])
                self.StraightFlushNum+=minn
                self.card_mark[j+1]=min(self.card_mark[j+1]+minn,self.mycards[i+1,j+1])
        #print('get_number_of_tripspair')
        for i in range(Message.RankNum-1):
            minn=0
            flag=1
            for j in range(2):
                if self.mycards[0,i+j+1]<3:
                    flag=0
                    break
            if flag:
                self.TripsPairNum+=1
                self.card_mark[i+1]=min(self.card_mark[i+1]+3,self.mycards[0,i+1])
        #print('get_number_of_threePairnum')
        for i in range(Message.RankNum-2):
            minn=0
            flag=1
            for j in range(3):
                if self.mycards[0,i+j+1]<2:
                    flag=0
                    break
            if flag:
                self.ThreePairNum+=1
                self.card_mark[i+1]=min(self.card_mark[i+1]+3,self.mycards[0,i+1])
        #print('get_single_pair')
        for i in range(Message.RankNum):
            a=self.mycards[0,i+1]-self.card_mark[i+1]
            if a==2:
                self.PairNum+=1
            elif a==1:
                self.SingleNum+=1
        return self.BombNum*8+self.StraightFlushNum*9+self.StraightNum*10+self.TripsPairNum*7+self.ThreePairNum*6+self.TripsNum*5+self.PairNum*2+self.SingleNum*1

#cardMes,包含手牌列表，手牌矩阵
#board，包含信息，1类信息所有
class Policy:
    def __init__(self):
        pass
        #print('init_policy')
        
    def Tribute1(self,cardmes,board):
        #card_type = random.choice(list(cardmes.action_list.keys()))
        #print("Choose type ", card_type)
        #rank = random.choice(list(cardmes.action_list[card_type].keys()))
        #action = random.choice(list(cardmes.action_list[card_type][rank]))
        #print("Choose action:", action)
        print('tribute')
        #action_list=board.action_list['Single']
        #orted_action_list=sorted(action_list.items(),key=lambda action_list:action_list[0])
        #card_type='Single'
        #rank=sorted_action_list[0][1]
        action=sorted_action_list[card_type][rank][0]
        card_type = random.choice(list(board.action_list.keys()))
        print("Choose type ", card_type)
        rank = random.choice(list(board.action_list[card_type].keys()))
        action = random.choice(list(board.action_list[card_type][rank]))
        print("Choose action:", action)
        act=Action(action,card_type,rank)
        return act
    def BackTribute2(self,cardmes,board):
        card_type = random.choice(list(board.action_list.keys()))
        print("Choose type ", card_type)
        rank = random.choice(list(board.action_list[card_type].keys()))
        action = random.choice(list(board.action_list[card_type][rank]))
        print("Choose action:", action)
        act=Action(action,card_type,rank)
        return act

    def BackTribute1(self,cardmes,board):
        #card_type = random.choice(list(cardmes.action_list.keys()))
        #print("Choose type ", card_type)
        #rank = random.choice(list(cardmes.action_list[card_type].keys()))
        #action = random.choice(list(cardmes.action_list[card_type][rank]))
        #print("Choose action:", action)
        action=[]
        flag=0
        print('backtribute')
        for i in range(11):
            if i and cardmes.mycards[0,i]==1:
                for j in range(5):
                    if j and cardmes.mycards[j,i]==1:
                        flag=1
                        rank=str(cardmes.value_dict[i-1])
                        card_type='Single'
                        action=[j-1,rank]
                        act=Action(action,card_type,rank)
                        break
        
        if flag==0:
            for i in range(10):
                if i and cardmes.mycards[0,i]:
                    for j in range(5):
                        if j and cardmes.mycards[j,i]:
                            flag=1
                            rank=str(cardmes.value_dict[i-1])
                            card_type='Single'
                            action=[j-1,rank]
                            act=Action(action,card_type,rank)
                            break
        #card_type = random.choice(list(board.action_list.keys()))
        print("Choose type ", card_type)
        #rank = random.choice(list(board.action_list[card_type].keys()))
        #action = random.choice(list(board.action_list[card_type][rank]))
        print("Choose action:", action)
        #act=Action(action,card_type,rank)
        return act
    def OutPutCard1(self,cardmes,board):
        #print('outputcard')
        #搜索可行动作状态空间，寻找出牌后value最小的情况，记录返回Action对象
        maxx=-0x3f3f3f
        minn=0x3f3f3f
        selecOutCard=[]
        print('board_playcard')
        print(board.playcard)
        #多余一个合法动作不选pass
        #被动出牌
        if empty(board.playcard) == 0:
            print('passive outputcard')
            if len(board.action_list)>1:
                for dic1 in board.action_list:
                    for dic2 in board.action_list[dic1]:
                        for list1 in board.action_list[dic1][dic2]:
                            if dic1 != 'PASS':
                                c=[]
                                #print(list1)
                                for i in cardmes.hand_cards:
                                    if i in list1:
                                        pass
                                    else:
                                        c.append(i)
                                newcardmes=Message(c,board.key_card,board.weight)
                                #print('get_remain_value')
                                newvalue=newcardmes.GetValue()
                                print('output the list1 remainedcard value is ',newvalue)
                                print(list1)
                                #print('get_value_end')
                                if newvalue < minn:
                                    minn=newvalue
                                    selecOutCard=list1
                                    card_type=dic1
                                    action=selecOutCard
                                    rank=dic2
            #只有一种牌型包括pass
            else:
                #print('the not best')
                if list(board.action_list.keys())[0]=="PASS":
                    card_type='PASS'
                    action=[[0,'PASS']]
                    rank='PASS'
                else:
                    for dic1 in board.action_list:
                        for dic2 in board.action_list[dic1]:
                            for list1 in board.action_list[dic1][dic2]:                       
                                c=[]
                                #print(list1)
                                for i in cardmes.hand_cards:
                                    if i in list1:
                                        pass
                                    else:
                                        c.append(i)
                                newcardmes=Message(c,board.key_card,board.weight)
                                #print('get_remain_value')
                                newvalue=newcardmes.GetValue()
                                print('output the list1 remainedcard value is ',newvalue)
                                print(list1)
                                #print('get_value_end')
                                if newvalue < minn:
                                    minn=newvalue
                                    selecOutCard=list1
                                    card_type=dic1
                                    action=selecOutCard
                                    rank=dic2
        #主动出牌
        else:
            print('positive outputcard')
            if len(board.action_list)>1:
                for dic1 in board.action_list:
                    for dic2 in board.action_list[dic1]:
                        for list1 in board.action_list[dic1][dic2]:
                            if dic1!='PASS':
                                newcardmes=Message(list1,board.key_card,board.weight)
                                #print('get_remain_value')
                                newvalue=newcardmes.GetValue()
                                print('output the list1 value is ',newvalue)
                                print(list1)
                                #print('get_value_end')
                                if newvalue >= maxx:
                                    maxx=newvalue
                                    selecOutCard=list1
                                    card_type=dic1
                                    action=selecOutCard
                                    rank=dic2
            else:
                if list(board.action_list.keys())[0]=="PASS":
                    card_type='PASS'
                    action=[[0,'PASS']]
                    rank='PASS'

                else:
                    for dic1 in board.action_list:
                        for dic2 in board.action_list[dic1]:
                            for list1 in board.action_list[dic1][dic2]:                       
                                newcardmes=Message(list1,board.key_card,board.weight)
                                #print('get_remain_value')
                                newvalue=newcardmes.GetValue()
                                #print('output the list1 value is ',newvalue)
                                #print(list1)
                                #print('get_value_end')
                                if newvalue >= maxx:
                                    maxx=newvalue
                                    selecOutCard=list1
                                    card_type=dic1
                                    action=selecOutCard
                                    rank=dic2
        #print('action',action)
        #print('card_type',card_type)
        act=Action(action,card_type,rank)
        return act
    
    def OutPutCard(self,cardmes,board):
        minn=10000000000
        _card_type='PASS'
        _rank='PASS'
        _action=[[0,'PASS']]
        #if (board.current_player+board.index) %2!=0 and board.cooperate() or board.current_player==board.index:
        if (board.current_player+board.index) %2!=0 and board.cooperate() or board.current_player==board.index:
            for card_type in list(board.action_list.keys()):
                for rank in list(board.action_list[card_type].keys()):
                    for action in list(board.action_list[card_type][rank]):
                        score1=board.cardWeight[rank]
                        score2=board.cardWeight[card_type]
                        if rank == board.current_rank:
                            score1=15
                        score=score1*score2
                        if minn > score:
                            minn = score
                            _card_type=card_type
                            _rank=rank
                            _action=action
        act=Action(_action,_card_type,_rank)
        if _card_type!='PASS':
            board.playcard[board.index]=_action
            for i in range(4):
                if i != board.index:
                    board.playcard[i]=[]
            board.knowplaycard+=_action
        return act
    def OutPutCard1(self,cardmes,board):
        maxx=-10000000000
        _card_type='PASS'
        _rank='PASS'
        _action=[[0,'PASS']]
        for card_type in list(board.action_list.keys()):
            for rank in list(board.action_list[card_type].keys()):
                for action in list(board.action_list[card_type][rank]):
                    score=board.mycardWeight[card_type][rank]
                    if rank == board.current_rank:
                        score=board.mycardWeight[card_type]['JOKER']+0.1
                    if maxx < score:
                        maxx = score
                        _card_type=card_type
                        _rank=rank
                        _action=action
        act=Action(_action,_card_type,_rank)
        if _card_type!='PASS':
            board.playcard[board.index]=_action
        for i in range(4):
                    if i != board.index:
                        board.playcard[i]=[]
        return act
class ExampleClient(WebSocketClient):
    def __init__(self, url):
        super().__init__(url)
        self.name = "Agent1"
        self.board=Board()
    def opened(self):
        pass
        # self.send(json.dumps({"name": self.name}))w

    def closed(self, code, reason=None):
        print("Closed down", code, reason)

    def received_message(self, message):
        content = json.loads(str(message))
        #print(content['type'])
        '''
        if content['type']==0:
            doc=open('state.csv','w')
            print(content['winners'],doc)
            doc.close()
            pass

        '''
        if "action_list" in content:
            #print("initial the board")
            #only initial the board when 
            self.board.initial(content)
            #print("update the board")
            #print('the cardmessage')
            print(content['type'],content['current_player'])
            cardmes=Message(self.board.hand_cards,self.board.key_card,self.board.weight)
            policy=Policy()
            #print('updateBoard')
            self.board.updateBoard(content,cardmes)
            print("mycards")
            print(cardmes.hand_cards)
            print('board_playcard')
            print(self.board.playcard)
            if self.board.current_stage==2:
                if empty(self.board.playcard) == 0:
                    print('passive outputcard')
                else:
                    print('positive outputcard')
            #print('updateWeight')
            self.board.updateWeight(cardmes)
            #print("policy")
            if content['action_list']:
                act=policy.OutPutCard(cardmes,self.board)
                print(act.action)
                self.send(json.dumps({"action": act.action, "type": act.card_type, "rank": act.rank}))
                '''
                if content['current_stage']==2:
                    #print('choose 2')
                    act=policy.OutPutCard(cardmes,self.board)
                elif content['current_stage']==5:
                    #print('choose 5')
                    act=policy.Tribute(cardmes,self.board)
                elif content['current_stage']==6:
                    #print('choose 6')
                    act=policy.BackTribute(cardmes,self.board)
                self.send(json.dumps({"action": act.action, "type": act.card_type, "rank": act.rank}))
                '''
            

            #print("action_list")
            #print(content['action_list'])
            print('KnowPlayCard')
            print(self.board.knowplaycard)
            print('unknowplaycard')
            print(self.board.unknowplaycard)
            
if __name__ == '__main__':
    try:
        ws = ExampleClient('ws://192.168.1.124:23456/game/csy1')
        ws.connect()
        ws.run_forever()
    except KeyboardInterrupt:
        print('fail',ws.fail)
        print('success',ws.success)
        ws.close()




