예제 #1
0
def analyze(hand, turncard):
    """
    """
    log.trace("Analyzing hand for %s: %s" % (hand.seat['name'], hand.card_tags))
    discard = None
    bid_analysis = [BidAnalysis(hand.cards, s, turncard) for s in SUITS]
    # penalty/reward for ordering trump into dealer hand (note, this should be
    # pushed into BidAnalysis, one way or another!)
    turn_idx = turncard.suit['idx']
    if hand.pos in (0, 2):
        penalty = turncard.efflevel[turn_idx]
        bid_analysis[turn_idx].hand_score -= penalty
    elif hand.pos == 1:
        reward = turncard.efflevel[turn_idx] // 2
        bid_analysis[turn_idx].hand_score += reward

    # fix up dealer hand based on turncard
    if hand.pos == 3:
        suit_idx = turncard.suit['idx']
        # note that the following may actually return the turncard, e.g. if it
        # would be the lowest trump (or perhaps some wacky other reason)
        discard = _bestdiscard(bid_analysis[suit_idx], turncard)
        newcards = hand.cards.copy()
        newcards.append(turncard)
        newcards.remove(discard)
        log.trace("Reanalyzing dealer hand with turncard (%s) and discard (%s)" %
                  (turncard.tag, discard.tag))
        reanalysis = BidAnalysis(newcards, turncard.suit, turncard, discard)
        bid_analysis[suit_idx] = reanalysis

    return (bid_analysis, discard)
예제 #2
0
    def nonblocking(self):
        s = self.socket()
        try:
            s.setblocking(0)
        except Exception as exc:
            log.error(exc, 'nonblocking(%d) fail', s.fileno())
            return None

        log.trace(0, 'connection nonblocking *%d', self.index)
        return self
예제 #3
0
    def parse_sockaddr(self, sockaddr):
        self.sockaddr = sockaddr
        if isinstance(sockaddr, tuple) or isinstance(sockaddr, list):
            self.text = ':'.join([str(i) for i in sockaddr])
        else:
            self.text = str(sockaddr)

        self.addr_text = self.text
        log.trace(0, 'Addr.parse_sockaddr() result: %s', self.sockaddr)
        return self
예제 #4
0
def create_socket(addr):
    try:
        s = socket.socket(addr.family, addr.socktype, addr.proto)
    except Exception as exc:
        log.error(exc, 'socket.socket(%s) fail', addr.text)
        return None

    log.trace(0, 'socket create: %d(%s) family:%r socktype:%r proto:%r',
              s.fileno(), addr.text, addr.family, addr.socktype, addr.proto)
    return s
예제 #5
0
    def reuse(self):
        s = self.socket()
        try:
            s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        except Exception as exc:
            log.error(exc, 'reuse(%d) fail', s.fileno())
            return None

        log.trace(0, 'connection reuse *%d', self.index)
        return self
예제 #6
0
    def socket(self, s=None):
        if isinstance(s, Addr) or isinstance(s, socket.socket):
            if isinstance(s, Addr):
                s = create_socket(s)
            elif isinstance(s, socket.socket):
                s = s.dup()

            self.close()
            self.sock = s
            log.trace(0, 'connection socket *%d: %d', self.index, s.fileno())

        return self.sock
예제 #7
0
    def keepalive(self, interval=30):
        s = self.socket()
        try:
            # if not is_darwin:
            #     s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, interval)
            s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, interval)
        except Exception as exc:
            log.error(exc, 'keepalive(%d) fail', s.fileno())
            return None

        log.trace(0, 'connection keepalive *%d', self.index)
        return self
예제 #8
0
    def close(self):
        if self.sock:
            log.trace(0, 'connection close *%d: %d', self.index, self.sock.fileno())
            if self.rev.active or self.wev.active:
                del_conn(self, WRITE_EVENT | READ_EVENT)
            self.wev.handler = None
            self.rev.handler = None
            self.wev.buff = ''
            self.rev.buff = ''
            close_socket(self.sock)
            self.sock = None

        return self
예제 #9
0
    def __init__(self):
        self.index = get_sequence()
        log.trace(0, 'connection create *%d', self.index)
        if is_cygwin and self.index > 500:
            exit(0)

        # 防止循环引用,无法释放
        self.wev = Event(weakref.proxy(self))
        self.rev = Event(weakref.proxy(self))

        self.wev.write = True
        self.rev.read = True

        self.sock = None
예제 #10
0
    def __set_addr_info(self, index):
        if not self.addr_infos or index >= len(self.addr_infos):
            return None

        self.info_index = index
        # addr info: (family, socktype, proto, canonname, sockaddr)
        info = self.addr_infos[index]
        log.trace(0, 'text: %s, index: %d, addr info: %r', self.text, index,
                  info)

        self.__set_procotol(info[0], info[1], info[2])
        self.sockaddr = info[4]
        self.__set_addr_text()
        return self
예제 #11
0
    def process(self, msg):
        c = self.conn
        cmd = msg.get(0)
        if cmd != 'heartbeat rsp':
            log.debug(0, '*%d read message: %s', c.index, msg)
        else:
            log.trace(0, '*%d read message: %s', c.index, msg)

        if not self.DO_MAP.has_key(cmd):
            log.error(0, 'invalid command. msg:%s', msg)
            return

        add_timer(self.stimer, HEARTBEAT_INTERVAL)
        add_timer(self.rtimer, HEARTBEAT_TIMEOUT)
        self.DO_MAP[cmd](self, msg)
예제 #12
0
    def process(self, msg):
        c = self.conn
        cmd = msg.get(0)
        if cmd != 'heartbeat req':
            log.debug(0, '*%d read message: %s', c.index, msg)
        else:
            log.trace(0, '*%d read message: %s', c.index, msg)

        if not self.DO_MAP.has_key(cmd):
            log.error(0, 'invalid command. msg:%s', msg)
            return

        if self.register_key:
            add_timer(self.timer, EXPIRE_TIME)
        self.DO_MAP[cmd](self, msg)
예제 #13
0
    def send_msg(self, msg):
        c = self.conn
        if isinstance(msg, str) or isinstance(msg, list) or isinstance(
                msg, Message):
            msg = Message(msg)
        if msg.get(0) != 'heartbeat req':
            log.debug(0, '*%d send message: %s', c.index, msg)
        else:
            log.trace(0, '*%d send message: %s', c.index, msg)

        buff = msg.encode()
        if not buff:
            log.error(0, 'invalid message: %s', msg)
            return
        self.send_bin(buff)
예제 #14
0
def close_socket(s):
    if not isinstance(s, socket.socket):
        log.warn('it is not socket')
        return

    try:
        s.shutdown(socket.SHUT_RDWR)
        log.trace(0, 'socket close: %d', s.fileno())
        return
    except Exception as exc:
        log.error(exc, 'socket.shutdown(%d) fail', s.fileno())
    try:
        s.close()
        return
    except Exception as exc:
        log.error(exc, 'socket.close(%d) fail', s.fileno())
예제 #15
0
    def forward(self, rc, wc):
        add_timer(self.timer, EXPIRE_TIME)
        log.trace(0, 'recv: *%d(%s)    send: *%d(%s)',
                  rc.index, rc.addr.text, wc.index, wc.addr.text)

        buff = rc.rev.buff
        while True:
            r = 0
            if not buff:
                r, buff = rc.recv(4096)
            if r != 0:
                if r == 1:
                    log.debug(0, '*%d(%s) closed', rc.index, rc.addr.text)
                rc.rev.ready = False
                break
            if not buff:
                rc.rev.buff = ''
                add_conn(rc, READ_EVENT)
                del_conn(wc, WRITE_EVENT)
                rc.rev.ready = False
                return

            r, size = wc.send(buff)
            if r != 0:
                if r == 1:
                    log.debug(0, '*%d(%s) closed', wc.index, wc.addr.text)
                wc.wev.ready = False
                break
            if not size:
                rc.rev.buff = buff
                del_conn(rc, READ_EVENT)
                add_conn(wc, WRITE_EVENT)
                wc.wev.ready = False
                return
            buff = buff[size:]

        c0 = self.c0
        c1 = self.c1
        log.info(0, 'bridge break *%d(%s) *%d(%s)', c0.index,
                 c0.addr.text, c1.index, c1.addr.text)
        self.close()
예제 #16
0
    def connect(self, addr):
        s = self.socket()
        if not s:
            s = self.socket(addr)
        if not s:
            return None

        try:
            s.connect(addr.sockaddr)
        except Exception as exc:
            err = exc.errno
            if err != errno.EINPROGRESS:
                log.error(exc, 'connect(%s) fail', addr.text)
                return None

        self.addr = addr

        log.trace(0, 'connection connect *%d: %s', self.index, addr.text)

        self.keepalive()
        return self
예제 #17
0
    def parse_text(self, text, *args):
        self.text = text
        self.sockaddr = None

        arr = text.split(':')
        if len(arr) != 2:
            log.error(0, 'invalid addr text: %s', text)
            return None

        try:
            addr_infos = socket.getaddrinfo(arr[0], arr[1], *args)
        except Exception as exc:
            log.error(exc, 'socket.getaddrinfo(%s) fail', text)
            return None
        if not addr_infos:
            log.error(0, 'socket.getaddrinfo(%s) is empty', text)
            return None

        self.addr_infos = addr_infos
        log.trace(0, 'socket.getaddrinfo(%s): %r', text, addr_infos)

        self.__set_addr_info(0)
        log.trace(0, 'Addr.parse_text(%s): %s', text, self.sockaddr)
        return self
예제 #18
0
 def next_sockaddr(self):
     index = self.info_index + 1
     if not self.__set_addr_info(index):
         return None
     log.trace(0, 'Addr.next_sockaddr(): %s', self.sockaddr)
     return self
예제 #19
0
 def __del__(self):
     self.close()
     log.trace(0, 'connection destroy *%d', self.index)
예제 #20
0
 def log_trace(self):
     """
     """
     log.trace("  with %s as trump:" % (self.trump['tag']))
     log.trace("    cards by suit:    %s" % (self.card_tags_by_suit))
     log.trace("    count by suit:    %s" % (self.suitcount))
     log.trace("    trump score:      %s" % (self.trump_score))
     log.trace("    next score:       %s" % (self.next_score))
     log.trace("    green score:      %s" % (self.green_score))
     log.trace("    purple score:     %s" % (self.purple_score))
     log.trace("    trumps:           %s" % (self.trumps))
     log.trace("    top trump scores: %s" % (self.top_trump_scores))
     log.trace("    aces:             %s" % (self.aces))
     log.trace("    voids:            %s" % (self.voids))
     log.trace("    singletons:       %s" % (self.singletons))
     log.trace("    hand score:       %s" % (self.hand_score))