#!/usr/bin/python3
import pygame
from pygame.locals import *
import random
import copy
import sys
import os
from time import time
#from time import sleep

dups = []
nodups = []
temp = []
pass_cards = []
meld_source = [] #temp list of cards in hand
meld_build = [] #cards for meld display
#meld_cards = []

yes = 1
no = 0
## init screen and pygame
pygame.init()
screen = pygame.display.set_mode((0,0),pygame.FULLSCREEN)
pygame.display.set_caption('Pinochle')
#screen = pygame.display.set_mode((1280, 720))
font1 = pygame.font.SysFont(None, 30)                               
font2 = pygame.font.SysFont(None, 38)
font3 = pygame.font.SysFont(None, 80) 

arrow = ( "xX                      ",
          "X.X                     ",
          "X..X                    ",
          "X...X                   ",
          "X....X                  ",
          "X.....X                 ",
          "X......X                ",
          "X.......X               ",
          "X........X              ",
          "X.........X             ",
          "X..........X            ",
          "X...........X           ",
          "X............X          ",
          "X.............X         ",
          "X..............X        ",
          "X...............X       ",
          "X................X      ",
          "X.................X     ",
          "X..................X    ",
          "X..........XXXXXXXXXX   ",
          "XXXXXXXX....X           ",
          "        X....X          ",
          "         X....X         ",
          "          XXXXXX        ")

hotspot = None
for y in range(len(arrow)):
    for x in range(len(arrow[y])):
        if arrow[y][x] in ['x', ',', 'O']:
            hotspot = x,y
            break
s2 = []
for line in arrow:
    s2.append(line.replace('x', 'X').replace(',', '.').replace('O','o'))
cursor, mask = pygame.cursors.compile(s2, 'X', '.', 'o')
size = len(arrow[0]), len(arrow)
pygame.mouse.set_cursor(size, hotspot, cursor, mask)

try:
   if sys.frozen or sys.importers:
      ipath = os.path.dirname(sys.executable)
except AttributeError:
   ipath = os.path.dirname(os.path.realpath(__file__))
os.chdir(ipath)

random.seed(time())

#from data import *
#### control
hand_lp = 0 #one hand play of 12 cards
trick_lp = 0 #play 4 cards per trick
deal_posn = 0 #0=south 1=west 2=north 3=east
quit_game = 0

### bid data
bid_posn = 1 #0=south 1=west  (left of dealer)
pass_count = 0 #bidding done if = 4
high_bid = 0 #current/last bid
high_bid_player = 0
last_bid = [1,1,1,1] #clubs,diamonds,hearts,spades set non-zero 0=pass
max_bid = [0,0,0,0] #max for clubs,diamonds,hearts,spades
trumps = [0,0,0,0] #selected trumps by info()
melds = [0,0,0,0] #meld calclations by info()

#### cardpass data #####################
weights = [] # weight, card
Trump = 0

#### play data
score_ns = 0 # North/South score
score_ew = 0 # East/West score
meld_ns = 0
meld_ew = 0
shoot_moon = 0 #0=no 1=yes
last_card_played = [] #[card,player,trick_lp]
trick = [] #card's played for one trick , max of 4 entries
p0_card = [] #[card,player,trick_lp]
p1_card = []
p2_card = []
p3_card = []
top_card = [] #card taking trick so far [cards index,player,trick_lp]
clubs_played = [0,0,0,0,0,0] #cards played so far
diamonds_played = [0,0,0,0,0,0] #count of 9,jack,queen,kings,tens,aces played
hearts_played = [0,0,0,0,0,0]
spades_played = [0,0,0,0,0,0]
ns_tricks = [] #list of index's for cards taken
ew_tricks = []
#data set by suit_play
my_suit_cnt = 0 #number of cards in suit
my_suit_max = 0  #highest card index in suit
out_suit_cnt = 0 # number of cards out and not in hand
out_suit_max = 0 #highest card index out in suit
ns_pointers = 0 #points taken, set by update_hand
ew_pointers = 0 #points taken, set by update_hand
old_score_ns = 0
old_score_ew = 0

#### info data
clubranks = []  #0=9 1=jack 2=queen 3=king 4=ten 5=ace
diamondranks = []
heartranks = []
spaderanks = []
svalue = [] #sum of ranks by suit clubs,diamonds,hearts,spades
scount = [] #count of cards in each suit
runs = [] #suit list
runh = [] #suits with 4 out of 5 run cards
aces = 0 #count 0,1,2 of aces around
aceh = 0 #count 0,1,2 of 3ace holes
kings = 0
kingh = 0
queens = 0
queenh = 0
jacks = 0
jackh = 0
marriage_points = 0 #marriage points, 4 per if trump
marriages_per_suit = []  #clubs,diamonds,hearts,spades
total_aces = 0
pino = 0   #number of pinochles
pinoh = 0  #number of pinochle holes
half_pinos = 0 #1 if jack  3 if spade

trump_sel = 0 #this hands trump choice
trump_nines = 0 #
trump_aces = 0
meld_sel = 0 # this hands meld

#### constants
south = 0
west = 1
north = 2
east = 3
club = 0
diamond = 1
heart = 2
spade = 3
nine = 0
jack = 1
queen = 2
king = 3
ten = 4
ace = 5

black = (0,0,0)
white = (255,255,255)
gray = (192,192,192)
red = (255, 0, 0)
blue = (0,0,255)
yellow = (255,255,0)

#### 

c9 = pygame.image.load('image/c9.png') # 0 index
cj = pygame.image.load('image/cj.png') # 1
cq = pygame.image.load('image/cq.png') # 2
ck = pygame.image.load('image/ck.png') # 3
c10 = pygame.image.load('image/c10.png')#4
ca = pygame.image.load('image/ca.png') # 5
d9 = pygame.image.load('image/d9.png') # 6
dj = pygame.image.load('image/dj.png') # 7
dq = pygame.image.load('image/dq.png') # 8
dk = pygame.image.load('image/dk.png') # 9
d10 = pygame.image.load('image/d10.png')#10
da = pygame.image.load('image/da.png') # 11
h9 = pygame.image.load('image/h9.png') # 12
hj = pygame.image.load('image/hj.png') # 13
hq = pygame.image.load('image/hq.png') # 14
hk = pygame.image.load('image/hk.png') # 15
h10 = pygame.image.load('image/h10.png')#16
ha = pygame.image.load('image/ha.png') # 17
s9 = pygame.image.load('image/s9.png') # 18
sj = pygame.image.load('image/sj.png') # 19
sq = pygame.image.load('image/sq.png') # 20
sk = pygame.image.load('image/sk.png') # 21
s10 = pygame.image.load('image/s10.png')#22
sa = pygame.image.load('image/sa.png') # 23
back = pygame.image.load("image/back.png")

cards = [c9,cj,cq,ck,c10,ca,\
         d9,dj,dq,dk,d10,da,\
         h9,hj,hq,hk,h10,ha,\
         s9,sj,sq,sk,s10,sa]
### card information
# "deck" is used to shuffle cards
#          0   1   2   3   4     5     6     7     8     9    10    11
deck = [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23]

south_hand = [] # card index'x
west_hand =  []
north_hand = []
east_hand =  []

htext1 = "Game is American version of single deck, four player pinochle"
htext2 = "Programmed by Jeff Owens  linuxasm@gmail.com"
htext3 = "Rules can be found on web at pinochle wiki"
htext4 = "GNU GENERAL PUBLIC LICENSE, Version 3, 29 June 2007"
htext5 = "Mouse click on any button or card, space bar = continue"


#input is us(player),card [card,player,posn]
#output is 0 for our team card   1 for opponent card
def team(player,card):
    if player == south or player == north:
        if card[1] == south or card[1] == north:
            return(0)
    if player == west or player == east:
        if card[1] == west or card[1] == east:
            return(0)
    return(1)

#check card index for legality using, top_card,trick, assume play_south called "info"
def legal_card(card):
    have_trump = 0
    have_led_suit = 0
    if len(trick) == 0:
        return(yes)
    for cardx in south_hand:
        if suit(cardx) == Trump:
            have_trump = 1
    if suit(card) == suit(trick[0]):
        return(yes)
    for cardx in south_hand:
        if suit(cardx) == suit(trick[0]):
            have_led_suit = 1
    if have_led_suit == 1 and suit(card) != suit(trick[0]):
        return(no)
    if have_trump == 1 and suit(card) != Trump:
        return(no)
    else:
        return(yes)

#### menus and decode ###############
#setup up variables screen and font before calling
def msg(txt,color1,color2,rfont,xx,yy):
    #font = pygame.font.SysFont(None, size)
    text = rfont.render(txt, True, color1, color2)
    textrect = text.get_rect()
    textrect.bottomleft = (xx, yy)
    if txt != "":
        screen.blit(text, textrect)
    return textrect

#button returns button # 1-5                                                  
def menu(title,button1,button2,button3,button4,button5):
    pygame.draw.line(screen,blue,(0,720),(1500,720),60) #clear button area
    pygame.draw.line(screen,blue,(470,331),(900,331),56) #clear title line
    box1 = msg( button1, red, white, font2, 2*17, 720)
    box2 = msg( button2, red, white, font2, 15*17, 720)
    box3 = msg( button3, red, white, font2, 29*17, 720)
    box4 = msg( button4, red, white, font2, 43*17, 720)
    box5 = msg( button5, red,white,font2,57*17,720)
    msg( title, white, blue, font3, 400, 360)
    show_status()
    pygame.display.update()
    looping = 1
    while looping != 0:
        pygame.display.update()
        for event in pygame.event.get():                                    
            if event.type == pygame.QUIT:
                sys.exit(0)  #return(5,0,0) #quit
            elif event.type == pygame.KEYDOWN:
                if event.key == K_SPACE:
                    return(1,0,0)
            elif event.type == pygame.KEYDOWN:
                if event.key == K_SPACE:
                    return(1,0,0)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # Set the x, y postions of the mouse click           
                x,  y  =  event.pos
                if  box1.collidepoint(x,  y):
                    return(1,x,y)
                elif box2.collidepoint(x, y):
                    return(2,x,y)
                elif box3.collidepoint(x, y):
                    return(3,x,y)
                elif box4.collidepoint(x, y):
                    return(4,x,y)
                elif box5.collidepoint(x, y):
                    sys.exit(0) #return(5,x,y)
                else:
                    return(0,x,y)
    
def show_results():
    display_hand(south_hand,300,500)
    display_hand(west_hand,0,342)
    display_hand(north_hand,300,0)
    display_hand(east_hand,1000,378)

#card selection menu, hand is displayed, fill pass_cards, do operation
# actions... quit,move card to pass_cards, remove card from weidhts, display sel
def select_menu(txt,flag):
    global pass_cards
    screen.fill(blue)
    if flag == 0:
        card1_locx = 300
        card1_locy = 350
    else:
        card1_locx = 400
        card1_locy = 362
    card2_locx = 400
    card2_locy = 350
    card3_locx = 500
    card3_locy = 350
    card4_locx = 600
    card4_locy = 350
    display_hand(south_hand,300,500)
    show_status()
    #display cards in weight list
    posn = 0 #display posn
    for card in pass_cards:
        if posn == 0:
            screen.blit(cards[card],(card1_locx,card1_locy))
        elif posn == 1:
            screen.blit(cards[card],(card2_locx,card2_locy))
        elif posn == 2:
            screen.blit(cards[card],(card3_locx,card3_locy))
        elif posn == 3:
            screen.blit(cards[card],(card4_locx,card4_locy))
        posn = posn + 1
    msg( txt, white, blue, font3, 350, 300)
    if len(pass_cards) == 4:
        box2 = msg( "submit", red, white, font2, 15*17, 720)
    box5 = msg( "quit game", red,white,font2,57*17,720)
    looping = 1
    while looping != 0:
        pygame.display.update()
        for event in pygame.event.get():                                    
            if event.type == pygame.QUIT:
                sys.exit(0)  #return(5) #quit
            elif event.type == pygame.KEYDOWN:
                if event.key == K_SPACE and len(pass_cards) == 4:
                    pygame.draw.line(screen,blue,(0,720),(1500,720),60) #clear button area
                    looping = 0
                    return(2)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # Set the x, y postions of the mouse click           
                x,  y  =  event.pos
                if box5.collidepoint(x, y):
                    looping = 0
                    sys.exit(0) #return(5)
                if len(pass_cards) == 4:
                    if  box2.collidepoint(x,  y):
                        pygame.draw.line(screen,blue,(0,720),(1500,720),60) #clear button area
                        looping = 0
                        return(2)
                if y < 500:
                    #click on pass card?
                    if card4_locx < x:
                        if len(pass_cards) == 4:
                            card = pass_cards[3]
                            pass_cards.pop(3)
                            south_hand.append(card)
                            return(0)
                    if card3_locx < x:
                        if len(pass_cards) > 2:
                            card = pass_cards[2]
                            pass_cards.pop(2)
                            south_hand.append(card)
                            return(0)
                    if card2_locx < x:
                        if len(pass_cards) > 1:
                            card = pass_cards[1]
                            pass_cards.pop(1)
                            south_hand.append(card)
                            return(0)
                    if card1_locx < x:
                        if len(pass_cards) > 0:
                            card = pass_cards[0]
                            pass_cards.pop(0)
                            south_hand.append(card)
                            return(0)
                #select card 
                elif x >= card1_locx and len(pass_cards) < 4:
                    index = (x - card1_locx)/20
                    if index >= len(south_hand):
                        continue
                    else:
                        card = south_hand[int(index)]
                        pass_cards.append(card)
                        south_hand.remove(card)
                        looping = 0
                        return(0)


def show_status():
    pygame.draw.line(screen,blue,(0,94),(240,94),210) #clear status area
    x = 0
    y = 0
    if Trump != 9:
        y = y + 24
        if high_bid_player == 0:
            msg("high bid "+str(high_bid)+" by south", white,blue, font1,x,y)
        elif high_bid_player == 1:
            msg("high bid "+str(high_bid)+" by west ", white,blue, font1,x,y)
        elif high_bid_player == 2:
            msg("high bid "+str(high_bid)+" by north", white,blue, font1,x,y)
        elif high_bid_player == 3:
            msg("high bid "+str(high_bid)+" by east ", white,blue, font1,x,y)
    #show trump
    if Trump != 9:
        y = y + 24
        if Trump == 0:
            msg("trump is clubs",white,blue,font1,x,y)
        elif Trump == 1:
            msg("trump is diamonds",white,blue,font1,x,y)
        elif Trump == 2:
            msg("trump is hearts",white,blue,font1,x,y)
        elif Trump == 3:
            msg("trump is spades",white,blue,font1,x,y)
        #show meld
        if brief_status_display == no:
            y = y + 24
            msg("north/south meld="+str(melds[0]+melds[2]),white,blue,font1,x,y)
            y = y + 24
            msg("east/west meld="+str(melds[1]+melds[3]),white,blue,font1,x,y)
            #show shoot the moon
            if shoot_moon == 1:
                y = y + 24
                msg("Moon Shoot !!",white,red,font1,x,y)
            #points needed by declarer
            y = y + 24
            if high_bid_player == 0 or high_bid_player == 2:
                points_needed = high_bid - meld_ns
                if points_needed < 1:
                    points_needed = 1
                msg("counters needed = "+str(points_needed),white,blue,font1,x,y)
            else:
                points_needed = high_bid - meld_ew
                if points_needed < 1:
                    points_needed = 1
                msg("counters needed = "+str(points_needed),white,blue,font1,x,y)
        #show current score
    y = y + 24
    msg("north/south score="+str(score_ns),white,blue,font1,x,y)
    y = y + 24
    msg("east/west score="+str(score_ew),white,blue,font1,x,y)


# display hand 
def display_hand(hand,x,y):
    for card in hand:
        screen.blit(cards[card],(x,y))
        x = x + 20
 

def suit(card):
    return(int(card/6))

def rank(card):
    return(card % 6)

def build_ranks(player,hand):
    global clubranks,diamondranks,heartranks,spaderanks
    global total_aces,svalue,scount
    clubranks = []
    diamondranks = []
    heartranks = []
    spaderanks = []
    for card in hand:
        if suit(card) == club: #clubs
            clubranks.append(rank(card))
        elif suit(card) == diamond:
            diamondranks.append(rank(card))
        elif suit(card) == heart:
            heartranks.append(rank(card))
        elif suit(card) == spade:
            spaderanks.append(rank(card))
        svalue[suit(card)] = svalue[suit(card)] + rank(card)
        scount[suit(card)] = scount[suit(card)] + 1
        if rank(card) == 5:
            total_aces = total_aces + 1
## deal
    
def deal():
    global south_hand,west_hand,north_hand,east_hand
    south_hand = deck[0:12]
    west_hand = deck[12:24]
    north_hand = deck[24:36]
    east_hand = deck[36:48]
    south_hand.sort()
    west_hand.sort()
    north_hand.sort()
    east_hand.sort()    

## bid
def remove_dups(xs):
    """ Return a new list in which all adjacent
        duplicates from xs have been removed.
    """
    global dups,nodups
    nodups = []
    dups = []
    most_recent_elem = None
    for e in xs:
        if e != most_recent_elem:
            nodups.append(e)
            most_recent_elem = e
        else:
            dups.append(e)    

def run_check(x):
    match = 0
    if 1 in x:
        match = match + 1
    if 2 in x:
        match = match + 1
    if 3 in x:
        match = match + 1
    if 4 in x:
        match = match + 1
    if 5 in x:
        match = match + 1
    return match

#check for j,q,k,ace around in clubranks,diamondranks,heartranks,spaderanks
#output - dups & nodups have suits that matched
def around(rank):
    global nodups, dups
    nodups = []
    dups = []
    count = 0
    for x in clubranks:
        if x == rank and count == 0:
            nodups.append(0)
            count = count + 1
        else:
            if x == rank and count == 1:
                dups.append(0)
    count = 0    
    for x in diamondranks:
        if x == rank and count == 0:
            nodups.append(1)
            count = count + 1
        else:
            if x == rank and count == 1:
                dups.append(1)
    count = 0
    for x in heartranks:
        if x == rank and count == 0:
            nodups.append(2)
            count = 1
        else:
            if x == rank and count == 1:
                dups.append(2)
    count = 0
    for x in spaderanks:
        if x == rank and count == 0:
            nodups.append(3)
            count = 1
        else:
            if x == rank and count ==1:
                dups.append(3)

def info(player,hand):
    global clubranks,diamondranks,heartranks,spaderanks
    global svalue,scount
    global runs,runh,aces,aceh,kings,kingh,queens,queenh,jacks,jackh
    global marriage_points,total_aces,meld_sel,trump_sel,trump_aces
    global marriages_per_suit
    global pino,pinoh,half_pino
    global trump_nines,max_bid,trumps,melds,last_bid
    clubranks = []
    diamondranks = []
    heartranks = []
    spaderanks = []
    svalue = [0,0,0,0] #clear suit value sum
    scount = [0,0,0,0] #clear suit card count
    runs = [] #suit list
    runh = [] #suits with 4 out of 5 run cards
    aces = 0 #count 0,1,2 of aces around
    aceh = 0 #count 0,1,2 of 3ace holes
    kings = 0
    kingh = 0
    queens = 0
    queenh = 0
    jacks = 0
    jackh = 0
    marriage_points = 0
    marriages_per_suit = []
    total_aces = 0
    pino = 0
    pinoh = 0
    half_pino = 0 # 1=diamonds 3=spades
    max_bid[player] = 0
    trump_sel = 0 #this hands trump choice
    trump_nines = 0 #
    trump_aces = 0
    meld_sel = 0 # this hands meld
#build rank list by suit & total value by suit  &  card count by suit
    build_ranks(player,hand)
#look for runs and partial runs
    for suitx in [club,diamond,heart,spade]:
        if suitx == club:
            ranks = clubranks[:]
        elif suitx == diamond:
            ranks = diamondranks[:]
        elif suitx == heart:
            ranks = heartranks[:]
        elif suitx == spade:
            ranks = spaderanks[:]
        remove_dups(ranks)
        nodup_match = run_check(nodups)
        dup_match = run_check(dups)
        if nodup_match == 5 and (Trump == 9 or Trump == suitx):
            runs.append(suitx)
        if nodup_match == 4 and (Trump == 9 or Trump == suitx):
            runh.append(suitx)
        if dup_match == 5 and (Trump == 9 or Trump == suitx):
            runs.append(suitx)
        if dup_match == 4 and (Trump == 9 or Trump == suitx):
            runh.append(suitx)
#select trump
    if Trump != 9:
        trump_sel = Trump #trump already set
    else:
        #select trump for this hand
        loop = 0
        while loop == 0:
            if len(runs) == 2:
                if svalue[runs[0]] >= svalue[runs[1]]:
                    trump_sel = runs[0]
                    break
                else:
                    trump_sel = runs[1]
                    break
            elif len(runs) == 1:
                trump_sel = runs[0]
                break
            elif len(runh) == 1:
                trump_sel = runh[0]
                break
#look for longest suit in scount
            else:
                trump_sel = max(scount)  # trial trump
                temp = []
                count = 0
                for x in scount:
                    if x == trump_sel:
                        temp.append(count)
                    count = count + 1
                if len(temp) == 1:
                    trump_sel = temp[0]
                    break
                if svalue[temp[0]] > svalue[temp[1]]:
                    trump_sel = temp[0]
                    break
                else:
                    trump_sel = temp[1]
                    break
        trumps[player] = trump_sel
#check for arounds and around holes
    for cardx in [jack,queen,king,ace]:
        around(cardx)
        if cardx == jack:
            if len(nodups) == 4:
                jacks = 1
            if len(dups) == 4:
                jacks = 2
            if len(nodups) == 3:
                jackh = 1
            if len(dups) == 3:
                jackh = 1
        if cardx == queen:
            if len(nodups) == 4:
                queens = 1
            if len(dups) == 4:
                queens = 2
            if len(dups) == 3:
                queenh = 1
            if len(nodups) == 3:
                queenh = 1
        if cardx == king:
            if len(nodups) == 4:
                kings = 1
            if len(dups) == 4:
                kings = 2
            if len(nodups) == 3:
                kingh = 1
            if len(dups) == 3:
                kingh = 1
        if cardx == ace:
            if len(nodups) == 4:
                aces = 1
            if len(dups) == 4:
                aces = 2
            if len(nodups) == 3:
                aceh = 1
            if len(dups) == 3:
                aceh = 1
#count trump nines and aces
    if trump_sel == 0:
        temp = clubranks[:]
    elif trump_sel == 1:
        temp = diamondranks[:]
    elif trump_sel == 2:
        temp = heartranks[:]
    else:
        temp = spaderanks[:]
        
    for card in temp:
        if card == 0:
            trump_nines = trump_nines + 1
        elif card == 5:
            trump_aces = trump_aces + 1
#get pinochle info
    dj = 0
    sq = 0
    for card in diamondranks:
        if card == 1:
            dj = dj + 1
    for card in spaderanks:
        if card == 2:
            sq = sq + 1
    if dj > 0 and sq > 0:
        pino = 1
        sq = sq -1
        dj = dj -1
    if dj > 0 and sq > 0:
        pino = 2
        sq =0
        dj = 0
    while dj > 0:
        pinoh = pinoh +1
        dj = dj -1
    while sq > 0:
        pinoh = pinoh + 1
        sq = sq -1
    if dj == 1:
        half_pino = 1
    elif sq == 1:
        half_pino = 3
# get value of marriages
    qq = 0 #count queens
    kk = 0 #count kings
    mcount = 0
    for card in clubranks:
        if card == 2:
            qq = qq + 1
        elif card == 3:
            kk = kk + 1
    while kk > 0 and qq > 0:
        mcount = mcount + 1
        kk = kk -1
        qq = qq -1
    marriages_per_suit.append(mcount)
    if trump_sel == 0:
        mcount = mcount * 2
    marriage_points = mcount * 2

    qq = 0 #count queens
    kk = 0 #count kings
    mcount = 0
    for card in diamondranks:
        if card == 2:
            qq = qq + 1
        elif card == 3:
            kk = kk + 1
    while kk > 0 and qq > 0:
        mcount = mcount + 1
        kk = kk -1
        qq = qq -1
    marriages_per_suit.append(mcount)
    if trump_sel == 1:
        mcount = mcount * 2
    marriage_points = marriage_points + mcount * 2

    qq = 0 #count queens
    kk = 0 #count kings
    mcount = 0
    for card in heartranks:
        if card == 2:
            qq = qq + 1
        elif card == 3:
            kk = kk + 1
    while kk > 0 and qq > 0:
        mcount = mcount + 1
        kk = kk -1
        qq = qq -1
    marriages_per_suit.append(mcount)
    if trump_sel == 2:
        mcount = mcount * 2
    marriage_points = marriage_points + mcount * 2
        
    qq = 0 #count queens
    kk = 0 #count kings
    mcount = 0
    for card in spaderanks:
        if card == 2:
            qq = qq + 1
        elif card == 3:
            kk = kk + 1
    while kk > 0 and qq > 0:
        mcount = mcount + 1
        kk = kk -1
        qq = qq -1
    marriages_per_suit.append(mcount)
    if trump_sel == 3:
        mcount = mcount * 2
    marriage_points = marriage_points + mcount * 2
 
#compute meld for this hand
    meld_sel = 0
    if len(runs) == 2:
        meld_sel = meld_sel + 146 #kludge, marriages counted seperatly
    elif len(runs) == 1:
        meld_sel = meld_sel + 11
    if aces == 2:
        meld_sel = meld_sel + 100
    elif aces == 1:
        meld_sel = meld_sel + 10
    if kings == 2:
        meld_sel = meld_sel + 80
    elif kings == 1:
        meld_sel = meld_sel + 8
    if queens == 2:
        meld_sel = meld_sel + 60
    elif queens == 1:
        meld_sel = meld_sel + 6
    if jacks == 2:
        meld_sel = meld_sel + 40
    elif jacks == 1:
        meld_sel = meld_sel + 4
    if pino == 2:
        meld_sel = meld_sel + 30
    elif pino == 1:
        meld_sel = meld_sel + 4
    meld_sel = meld_sel + marriage_points + trump_nines
    melds[player] = meld_sel

#max bid = meld + holes + trumplength + total aces + trump aces
    
    max_bid[player] = meld_sel  # init max_bid

    if len(runs)  == 0 and len(runh) > 0:
        max_bid[player] = max_bid[player] + 15
    if aceh > 0:
        max_bid[player] = max_bid[player] + 10
#    if kingh > 0:
#        max_bid[player] = max_bid[player] + 4
#    if queenh > 0:
#        max_bid[player] = max_bid[player] + 6
#    if jackh > 0:
#        max_bid[player] = max_bid[player] + 2
    if pinoh > 0:
        max_bid[player] = max_bid[player] + 2
        if pino == 1:
            max_bid[player] = max_bid[player] + 5
    max_bid[player] = max_bid[player] + total_aces * 2
    max_bid[player] = max_bid[player] + trump_aces *4
    max_bid[player] = max_bid[player] + scount[trump_sel] #length of trump suit
    if max_bid[player] > 40:
        max_bid[player] = max_bid[player] - 1
    if max_bid[player] < 25:
        max_bid[player] = max_bid[player] + 1


#get bid, do not set pass state in max_bid[player]
def bid(player,hand):
    global high_bid,high_bid_player,last_bid
    info(player,hand)
    msg("bidding", white, blue, font3, 400, 360)
    pygame.time.delay(500)
    if player != 0:
        # not south
        if max_bid[player] > high_bid:
            high_bid = high_bid +1
            high_bid_player = player
            last_bid[player] = high_bid  #update current bid
            if player == 0:
                msg("bid="+str(last_bid[player])+" ",yellow,black,font2,480,690)
                pygame.display.update()
                pygame.time.delay(1000) #sleep(1)
                msg("bid="+str(last_bid[player])+" ",white,blue,font2,480,690)
            elif player == 1:
                msg("bid="+str(last_bid[player])+" ",yellow,black,font2,20,372)
                pygame.display.update()
                pygame.time.delay(1000) #sleep(1)
                msg("bid="+str(last_bid[player])+" ",white,blue,font2,20,372)
            elif player == 2:
                msg("bid="+str(last_bid[player])+" ",yellow,black,font2,480,80)
                pygame.display.update()
                pygame.time.delay(1000) #sleep(1)
                msg("bid="+str(last_bid[player])+" ",white,blue,font2,480,80)
            elif player == 3:
                msg("bid="+str(last_bid[player])+" ",yellow,black,font2,1150,372)
                pygame.display.update()
                pygame.time.delay(1000) #sleep(1)
                msg("bid="+str(last_bid[player])+" ",white,blue,font2,1150,372)
        else: #pass 
            last_bid[player] = 0  #pass
            if player == 0:
                msg("bid=pass",white,blue,font2,480,690)
            elif player == 1:
                msg("bid=pass",white,blue,font2,20,372)
            elif player == 2:
                msg("bid=pass",white,blue,font2,480,80)
            elif player == 3:
                msg("bid=pass",white,blue,font2,1150,372)
    else:  #special handling for south
        last_bid[player] = high_bid + 1
        while True:
            show_players()
            msg("bid="+str(last_bid[player])+" ",white,blue,font2,480,690)
            but = menu("bidding"," pass","increase bid","decrease_bid","submit bid","quit game")
            if but[0] == 1:
                last_bid[player] = 0 #pass
                msg("bid=pass",white,blue,font2,480,690)
                pygame.draw.line(screen,blue,(0,720),(1500,720),60) #clear button area
                break
            elif but[0] == 2:
                last_bid[player] = last_bid[player] + 1
            elif but[0] == 3:
                if last_bid[player] > high_bid:
                    last_bid[player] = last_bid[player] - 1
            elif but[0] == 4:
                high_bid_player = 0
                break
            #else:
                #break
        if last_bid[player] > high_bid:
            high_bid = last_bid[player]
            high_bid_player = player

def show_bid_winner(player):
    if player == south:
        menu("South Won Bid","continue","","","","quit game")
    if player == west:
        menu("West Won Bid","continue","","","","quit game")
#    if player == north:
#        menu("North Won Bid","continue","","","","quit game")
    if player == east:
        menu("East Won Bid","continue","","","","quit game")

def trump_selection():
    global trump_sel,Trump
#    msg("Trump Select",white,blue,font3,500,400)
    if high_bid_player == 0: #did south take bid
        while True:
            but = menu("Trump Select","clubs","diamonds","hearts","spades","quit game")
            if but[0] == 0:
                index = int((but[1] - 300)/20)
                if index >= len(south_hand):
                    continue
                else:
                    if index >= len(south_hand):
                        continue
                    trump_sel = suit(south_hand[index])
                    if trump_sel == 0:
                        trump_name = "clubs"
                    elif trump_sel == 1:
                        trump_name = "diamonds"
                    elif trump_sel == 2:
                        trump_name = "hearts"
                    else:
                        trump_name = "spades"
                    but = menu("Trump="+trump_name,"accept","reject","","","quit_game")
                    if but[0] == 1:
                        break
                    else:
                        continue
            else:    
                trump_sel = but[0] -1
                break
    else:
        screen.fill(blue)
        if high_bid_player == south:
            return
        if high_bid_player == west:
            hand = west_hand[:]
        elif high_bid_player == north:
            hand = north_hand[:]
        else:
            hand = east_hand[:]
        info(high_bid_player,hand)
        if high_bid_player == 1:
            trump_sel = trumps[high_bid_player]
            msg("west won bid",white,blue,font3,500,400)
        elif high_bid_player == 2:
            trump_sel = trumps[high_bid_player]
#            msg("north won bid",white,blue,font3,500,400)
        elif high_bid_player == 3:
            trump_sel = trumps[high_bid_player]
            msg("east won bid",white,blue,font3,500,400)
        display_hand(south_hand,300,500)
    Trump = trump_sel
    show_status()


#compute Pass weight for one card, use data from info()
def weight_comp(trump,rank,suit):
    weight = 0
    if suit == trump and rank > 0:
        weight = 10
    elif suit == trump and rank == 0:
        weight = 7
    elif rank == 5 and aces == 4:
        weight = 10
    elif rank == 5 and aces < 4:
        weight = 8
    #check for partial pinochles
    elif trump == 3 and rank == 1:
        weight = 3
    elif trump == 1 and rank == 2:
        weight = 3
    #check for queens,kings,jacks around
    elif rank == 3 and kings > 0:
        weight = 2
    elif rank == 2 and queens > 0:
        weight = 3
    elif rank == 1 and jacks > 0:
        weight = 2
    #check for marriages
    elif rank == 2 and marriages_per_suit[suit] > 0:
        weight = 1
    elif rank == 3 and marriages_per_suit[suit] > 0:
        weight = 1   
    return(weight)

# build pass weights in pass_weights, array of  weight,suit,rank
def card_weights(player,trump,hand):
    global weights
    info(player,hand)
    weights = []
    for card in hand:
        weight = weight_comp(trump,rank(card),suit(card))
        weights.append([weight,card])
    weights.sort()
    #put single non trump aces before dual aces
    i = 0
    for item in weights:
        if item[1] != Trump:
            if rank(item[1]) == rank(weights[i+1][1]) and rank(weights[i+2][1]) == 5:
                x = weights[i+2]
                weights[i+2] = weights[i+1]
                weights[i+1] = x
        i = i + 1
        if i > 4:
            break

#pass one card 
def pass_it(card,To,From):
    From.remove(card)
    To.append(card)

#pass cards in pass_cards list to north
def pass_to_north():
    loop_count = 0
    while loop_count < 4:
        card = pass_cards.pop()
        north_hand.append(card)
        loop_count = loop_count + 1

#partner declared trump, pass trump and high cards
def card_pass(from_player,From,to_player,To):
    global weights
    card_weights(from_player,Trump,From) #pass trump and player data
    pass_cnt = 4
    while pass_cnt != 0:
        card = weights.pop()
        pass_it(card[1],To,From)
        pass_cnt = pass_cnt - 1
    

# pass back worst cards
def cards_back(from_player,From,to_player,To):
    card_weights(from_player,Trump,From) #pass trump and player data
    weights.reverse()
    pass_cnt = 4
    while pass_cnt != 0:
        card = weights.pop()
        pass_it(card[1],To,From)
        pass_cnt = pass_cnt - 1

def cards_back_sel(from_player,From,to_player,To): #always south to north, south won bid
    global pass_cards
    #select cards path
    pass_cards = []  #clear select card storage
    while True:
        but = select_menu("North passed, pass back",0)
        if but == 2:
            break
    #move cards from weight to north
    pass_to_north()

def card_pass_sel(from_player,From,to_player,To):  #always south to north, north won bid
    global pass_cards
    #select cards path
    pass_cards = []  #clear select card storage
    while True:
        if Trump == 0:
            tt = "clubs"
        elif Trump == 1:
            tt = "diamnds"
        elif Trump == 2:
            tt = "hearts"
        elif Trump == 3:
            tt = "spades"
        but = select_menu("North Won,Pass 4,Trump="+tt,0)
        if but == 2:
            break
    #move cards from weight to north
    pass_to_north()
            

def exchange_cards():
    global south_hand,west_hand,north_hand,east_hand
    if high_bid_player == south:  #south took bid
        card_pass(north,north_hand,south,south_hand)
        south_hand.sort()
        cards_back_sel(south,south_hand,north,north_hand)
    elif high_bid_player == west: #west won bid
        card_pass(east,east_hand,west,west_hand)
        cards_back(west,west_hand,east,east_hand)
    elif high_bid_player == north: #north won bid
        card_pass_sel(south,south_hand,north,north_hand)
        cards_back(north,north_hand,south,south_hand)
    elif high_bid_player == east: #east won bid
        card_pass(west,west_hand,east,east_hand)
        cards_back(east,east_hand,west,west_hand)
    south_hand.sort()
    west_hand.sort()
    north_hand.sort()
    east_hand.sort()

#display meld
def meld(player,hand,x,y):
    global meld_build,meld_source
    meld_build = []
    meld_source = hand[:]
    info(player,hand)
    #move 9's of trump
    if trump_nines > 0:
        meld_move([Trump*6],0) #move 9, don't force   
    #move runs
    if len(runs) > 0:
        meld_move([Trump*6+1,Trump*6+2,Trump*6+3,Trump*6+4,Trump*6+5],0)
    #move aces around
    if aces > 0:
        meld_move([5,11,17,23],0)
    #move kings around
    if kings > 0:
        meld_move([3,9,15,21],0)
    #move queens around
    if queens > 0:
        meld_move([2,8,14,20],0)
    #move jacks around
    if jacks > 0:
        meld_move([1,7,13,19],0)
    #move marriages
    index = 0
    for cnt in marriages_per_suit:
        if cnt > 0:
            meld_move([2+6*index,3+6*index],0)
        index = index + 1
    #move pinochles
    if pino > 0:
        meld_move([7,20],0)
    #force double ninies of trump
    if trump_nines == 2:
        meld_move([Trump*6],1)
    #force runs
    if len(runs) == 2:
        meld_move([Trump*6+1,Trump*6+2,Trump*6+3,Trump*6+4,Trump*6+5],1)
    #force double aces
    if aces == 2:
        meld_move([5,11,17,23],1)
    #force double kings
    if kings == 2:
        meld_move([3,9,15,21],1)
    #force double queens
    if queens == 2:
        meld_move([2,8,14,20],1)
    #force double jacks
    if jacks == 2:
        meld_move([1,7,13,19],1)
    #force double marriages
    index = 0
    for cnt in marriages_per_suit:
        if cnt == 2:
            meld_move([2+6*index,3+6*index],1)
        index = index + 1
    #force double pinochles
    if pino == 2:
        meld_move([7,20],1)
    meld_display(x,y)
    msg("meld = "+str(meld_sel), white,blue, font1,x,y)

#display cards in meld_build
def meld_display(x,y): #display cards in weight array
    for card in meld_build:
        screen.blit(cards[card],(x,y))
        x = x +20

#move meld card to meld_build if found on meld_source and not at meld_build
#before calling first time, initialize meld_source to hand, meld_build to []
def meld_move(meld_inputs,force):
    global meld_source,meld_build
    for card in meld_inputs:
        if card in meld_source:
            if card not in meld_build or force == 1:
                meld_build.append(card)
                meld_source.remove(card)

#update data for current card taking trick
# input=last_card_played,px_card  output=top_card, card display
#output - update hand for west,north,east
def update_card(player,trick_lp):
    global top_card,p0_card,p1_card,p2_card,p3_card
    global north,south,east,west,trick
    global clubs_played,diamonds_played,hearts_played,spades_played
#    card = last_card_played
    #append index to trick list
    trick.append(last_card_played[0])
    #set top_card_played
    if trick_lp == 0:
        top_card = last_card_played[:]
    else:
        if suit(top_card[0]) == Trump:
            if suit(last_card_played[0]) == Trump:
                if rank(last_card_played[0]) > rank(top_card[0]):
                    top_card = last_card_played[:]
        #top card is not trump
        else:
            if suit(top_card[0]) == suit(last_card_played[0]):
                if rank(last_card_played[0]) > rank(top_card[0]):
                    top_card = last_card_played[:]
            else:
                if suit(last_card_played[0]) == Trump:
                    top_card = last_card_played[:]
    #store px_card and display card played, remove card from hand
    if last_card_played[1] == south: #south
        x=400
        y=362
    elif last_card_played[1] == west: #west
        x=120
        y=300
        west_hand.remove(last_card_played[0])
    elif last_card_played[1] == north: #north
        x=400
        y=80
        north_hand.remove(last_card_played[0])
    else: #east
        x=900
        y=300
        east_hand.remove(last_card_played[0])
    if trick_lp == 0:
        p0_card = last_card_played[:]
        screen.blit(cards[p0_card[0]],(x,y))
    elif trick_lp == 1:
        p1_card = last_card_played[:]
        screen.blit(cards[p1_card[0]],(x,y))
    elif trick_lp == 2:
        p2_card = last_card_played[:]
        screen.blit(cards[p2_card[0]],(x,y))
    elif trick_lp == 3:
        p3_card = last_card_played[:]
        screen.blit(cards[p3_card[0]],(x,y))
    #update cards played history clubs_played,diamonds_played,etc.
    suitx = suit(last_card_played[0]) #suit of last card played
    rankx = rank(last_card_played[0])
    if suitx == club: #club played
        clubs_played[rankx] = clubs_played[rankx] + 1
    if suitx == diamond: #club played
        diamonds_played[rankx] = diamonds_played[rankx] + 1
    if suitx == heart: #club played
        hearts_played[rankx] = hearts_played[rankx] + 1
    if suitx == spade: #club played
        spades_played[rankx] = spades_played[rankx] + 1

# set play_posn to player taking trick
def update_trick():
    global trick_lp,play_posn,ns_tricks,ew_tricks
    play_posn = top_card[1]
    #store cards taken
    if top_card[1] == south or top_card[1] == north: #south or north took trick
        ns_tricks.extend(trick)
    else:
        ew_tricks.extend(trick)
    #display trick winner
    if top_card[1] == south: #south
        notice = "South Takes"
    elif top_card[1] == west: #west
        notice = "West Takes"
    elif top_card[1] == north: #nouth
        notice = "North Takes"
    elif top_card[1] == east: #east
        notice = "East Takes"
#    screen.fill(blue)
    display_hand(south_hand,300,500)
    menu(notice,"continue","","","","quit game")

#check if bid made, update score, display results
def update_hand():
    global score_ns,score_ew
    global ns_pointers,ew_pointers,old_score_ns,old_score_ew
    #count points taken by each team
    ns_pointers = 0
    ew_pointers = 0
    old_score_ns = score_ns
    old_score_ew = score_ew
    for card in ns_tricks:
        if rank(card) > 2:
            ns_pointers = ns_pointers + 1
    for card in ew_tricks:
        if rank(card) > 2:
            ew_pointers = ew_pointers + 1
    #add extra point for last trick taken
    if top_card[1] == north or top_card[1] == south:
        ns_pointers = ns_pointers + 1
    else:
        ew_pointers = ew_pointers + 1
    #check if bid was made
    if high_bid_player == south or high_bid_player == north:
        if shoot_moon != 0:
            if ns_pointers == 25:
                score_ns = score_ns + meld_ns + 50
                report = "North/South hit moon"
            else:
                score_ns = score_ns - 50
                report = "North/South is Set"
        else:
            if high_bid <= (meld_ns + ns_pointers): #did ns make bid
                score_ns = score_ns + meld_ns + ns_pointers
                report = "North/South Made Bid"
            else:
                score_ns = score_ns - high_bid
                report = "North/South Went Set"
        #if east/west took a trick, update score
        if ew_pointers > 0:
            score_ew = score_ew + meld_ew + ew_pointers
    if high_bid_player == west or high_bid_player == east:
        if shoot_moon != 0:
            if ew_pointers == 25:
                score_ew = score_ew + meld_ew + 50
                report = "East/West hit moon"
            else:
                score_ew = score_ew - 50
                report = "East/West is Set"
        else:
            if high_bid <= (meld_ew + ew_pointers): #did ew make bid
                score_ew = score_ew + meld_ew + ew_pointers
                report = "East/West Made Bid"
            else:
                score_ew = score_ew - high_bid
                report = "East/West Went Set"
        #if North/South took a trick, update score
        if ns_pointers > 0:
            score_ns = score_ns + meld_ns + ns_pointers
    return(report)

#suit analysis - inpput(hand,suit)
#output - database - my_suit_cnt my_suit_max out_suit_cnt out_suit_max
#         my_suit_max & out_suit_max 
def suit_info(hand,suitx,player,trick_lp):
    global my_suit_cnt,my_suit_max,out_suit_max,out_suit_cnt
    my_suit_cnt = 0
    my_suit_max = 0
    for card in hand:
        if suit(card) == suitx:
            my_suit_cnt = my_suit_cnt + 1
            if card > my_suit_max:
                my_suit_max = card
    #compute out_suit_cnt and out_suit_max
    if suitx == club:
        out_suit = clubs_played[:]
    elif suitx == diamond:
        out_suit = diamonds_played[:]
    elif suitx == heart:
        out_suit = hearts_played[:]
    elif suitx == spade:
        out_suit = spades_played[:]
    out_suit_cnt = 0
    out_lp = 0
    out_suit_max = 0
    for cnt012 in out_suit:
        out_suit_cnt = out_suit_cnt + cnt012
        if cnt012 < 2:
            out_suit_max = suitx*6 + out_lp
        out_lp = out_lp + 1
    out_suit_cnt = 12 - out_suit_cnt - my_suit_cnt #cards out and not in our hand

#south play one card, posn=0(south) trick_cnt=0-3
# output last_card_played [index,suit,rank,player,trick_lp], quit_game set
def play_south(player,trick_cnt):
    global last_card_played
    sel_cardx = 400
    sel_cardy = 362
    sel_card = []  #index,suit,rank,player
    handx = 300
    handy = 500
    msg( "play", white, blue, font3, 470, 360)
    show_status()
    while True:
        box5 = msg( "quit game", red,white,font2,57*17,720)
        if len(sel_card) > 0:
            box2 = msg( "     submit     ", red, white, font2, 15*17, 720)
        else:
            box2 = msg( "click on card",white,blue, font2, 15*17, 720)
        pygame.draw.line(screen,blue,(300,550),(1000,550),160)
        display_hand(south_hand,300,500)
        pygame.display.update()
        for event in pygame.event.get():                                    
            if event.type == pygame.QUIT:
                sys.exit(0) #return(5) #quit
            elif event.type == pygame.KEYDOWN:
                if event.key == K_SPACE and len(sel_card) > 0:
                    last_card_played = sel_card[:]
                    return(0)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x,  y  =  event.pos
                if box5.collidepoint(x, y):
                    sys.exit(0) #return(5)
                elif len(sel_card) == 0 and x >= handx and y > handy:
                    index = int(x - handx)/20
                    if index < 0:
                        index = 0
                    if index >= len(south_hand):
                        index = len(south_hand) -1
                    else:
                        card = south_hand[int(index)]
                        if legal_card(card) == no:
                            continue
                        sel_card = [card,player,trick_cnt]
                        screen.blit(cards[sel_card[0]],(sel_cardx,sel_cardy))
                        south_hand.remove(card)
                        continue
                elif len(sel_card) > 0:
                    if box2.collidepoint(x,y):
                        last_card_played = sel_card[:]
                        return(0)
                if y < 500 and len(sel_card) > 0:
                    card = sel_card[0] #get index of already selected card
                    south_hand.append(card)
                    last_card_played = sel_card[:]
                    south_hand.sort()
                    sel_card = []
                    pygame.draw.line(screen,blue,(350,450),(800,450),177)

#return point card as [index,player,trick_lp]
def get_counter(player,posn,hand):
    for card in hand:
        if rank(card) == 3: #return kings first
            return(card,player,posn)
    #no non-counter found, return non aces
    for card in hand:
        if rank(card) == 4: #return tens next
            return(card,player,posn)
    for card in hand:
        return(card,player,posn)

#return non-point card as: [index,suit,rank,play,trick_lp]
def get_non_counter(player,posn,hand):
    for card in hand:
        if rank(card) < 3 and suit(card) != Trump:
            return(card,player,posn)
        #no non-counter found, return non aces
    for card in hand:
        if rank(card) < 5 and suit(card) != Trump:
            return(card,player,posn)
    for card in hand:
        return(card,player,posn)

#trump was led, set last_card_played to [index,player,trick_lp]
def play_trump(player,posn,hand):
    global last_card_played
    trump_cards = get_suit(Trump,hand)
    if len(trump_cards) == 0: #no trump
        if team(player,top_card) == 0: #our team taking
            last_card_played = get_counter(player,posn,hand)
        else:
            last_card_played = get_non_counter(player,posn,hand)
    #we have trump and trump played, check if we have higher trump
    elif max(trump_cards) > top_card[0]: #have highest trump
        card = max(trump_cards)
        last_card_played = [card,player,posn]
    else: #we have lower trump
        card = min(trump_cards) #get index
        last_card_played = [card,player,posn]

#retrun [card,player,posn]  
def suit_counter(suit_cards,player,posn):
    for card in suit_cards:
        if rank(card) == king:
            return([card,player,posn])
        elif rank(card) == ten:
            return([card,player,posn])
        if rank(card) == nine:
            return([card,player,posn])
        elif rank(card) == jack:
            return([card,player,posn])
        else:
            return([card,player,posn])


#non trump was led and not trumped so far, set last_card_played [index,suit,rank,player,trick_lp]    
def play_suit(player,posn,hand):
    global last_card_played
    suit_cards = get_suit(suit(p0_card[0]),hand)
    if len(suit_cards) == 0: #cards in suit?
        trump_cards = get_suit(Trump,hand)
        if len(trump_cards) > 0: #have trump
            trumpx = len(trump_cards) - 1
            card = trump_cards[trumpx] #get index
            last_card_played = [card,player,posn]
        else: # no trump
            if player == north or player == south:
                if suit(top_card[0]) == south or suit(top_card[0]) == north: #ns taking trick
                    last_card_played = get_counter(player,posn,hand)
                else:
                    last_card_played = get_non_counter(player,posn,hand)
            else:
                if suit(top_card[0]) == east or suit(top_card[0]) == west: #ew taking trick
                    last_card_played = get_counter(player,posn,hand)
                else:
                    last_card_played = get_non_counter(player,posn,hand)
    #check if we can beat top_card, compare ranks
    elif max(suit_cards) > top_card[0]: #have highest
        card = max(suit_cards)
        last_card_played = [card,player,posn]
    else: # have low cards in suit
        if player == north or player == south:
            if suit(top_card[0]) == south or suit(top_card[0]) == north: #ns taking trick
                last_card_played = suit_counter(suit_cards,player,posn)
            else:
                last_card_played = [min(suit_cards),player,posn]
        else:
            if suit(top_card[0]) == east or suit(top_card[0]) == west: #ew taking trick
                last_card_played = suit_counter(suit_cards,player,posn)
            else:
                last_card_played = [min(suit_cards),player,posn]

def get_suit(suitx,hand):
    suit_build = []
    for card in hand:
        if suit(card) == suitx:
            suit_build.append(card)
    return suit_build

#suit was led and trumped, set last_card_played [index,player,trick_lp]
def play_hybrid(player,posn,hand):
    global last_card_played
    suit_cards = get_suit(suit(p0_card[0]),hand)
    trump_cards = get_suit(Trump,hand)
    if len(suit_cards) != 0: #have cards in suit?
        if player == south or player == north:
            if top_card[1] == south or top_card[1] == north: #ns taking trick
                if len(suit_cards) == 1:
                    last_card_played = [suit_cards[0],player,posn]
                else:
                    last_card_played = [suit_cards[1],player,posn]
            else:
                last_card_played = get_non_counter(player,posn,hand)
        else: #we are east or west
            if top_card[1] == east or top_card[1] == west:
                if len(suit_cards) == 1:
                    last_card_played = [suit_cards[0],player,posn]
                else:
                    last_card_played = [suit_cards[1],player,posn]
            else: #we are east/west and not taking trick
                last_card_played = get_non_counter(player,posn,hand)
    #we don't have suit, do we have trump?
    elif len(trump_cards) == 0: #no trump
        if player == north or player == south:
            if suit(top_card[0]) == south or suit(top_card[0]) == north: #ns taking trick
                last_card_played = get_counter(player,posn,hand)
            else:
                last_card_played = get_non_counter(player,posn,hand)
        else: #we are east or west, check who is taking trick
            if suit(top_card[0]) == west or suit(top_card[0]) == east: #ns taking trick
                last_card_played = get_counter(player,posn,hand)
            else:
                last_card_played = get_non_counter(player,posn,hand)
    #check if we have higher trump, compare ranks
    elif max(trump_cards) > top_card[0]: #have higher trump
        trump_max = max(trump_cards)
        last_card_played = [trump_max,player,posn]
    #we have lower trump, play non counter if possible
    else: #play low trump
        card = trump_cards[0]
        last_card_played = [card,player,posn]

#we took last trick, led card, we are not declarer 
#output = last_card_played [index,player,trick_cnt] and px_card
def p0_play(player,trick_cnt,hand): #trick_cnt = 0
    global last_card_played
    for suitx in [club,diamond,heart,spade]:
        suit_info(hand,suitx,player,trick_cnt) #check suits
        if rank(my_suit_max) == ace: #ace
            if rank(out_suit_max) == ace: #is ace out
                last_card_played = [my_suit_max,player,trick_cnt]
                return
#no aces, play high card
    for suitx in [club,diamond,heart,spade]:
        if suitx == Trump:
            continue
        else:
            suit_info(hand,suitx,player,trick_cnt)
            if my_suit_cnt != 0 and out_suit_cnt != 0:
                if my_suit_max >= out_suit_max:
                    last_card_played = [my_suit_max,player,trick_cnt]
                    return
            elif my_suit_cnt != 0 and out_suit_cnt == 0:
                last_card_played = [my_suit_max,player,trick_cnt]
    #no high cards to play, pick low card
    last_card_played = get_non_counter(player,trick_lp,hand)
    return

#one card played so far, we are not declarer
#output = last_card_played [index,player,trick_cnt] and px_card
def p1_play(player,trick_cnt,hand): #trick_cnt = 1
    global last_card_played
    if suit(p0_card[0]) == Trump:
        play_trump(player,trick_cnt,hand)
    elif suit(top_card[0]) == Trump:
        play_hybrid(player,trick_cnt,hand)
    else:
        play_suit(player,trick_cnt,hand)

#two cards played so far, we are not declarer
#output = last_card_played [index,suit,rank,player,trick_cnt] and px_card
def p2_play(player,trick_cnt,hand): #trick_cnt = 2
    global last_card_played
    if suit(p0_card[0]) == Trump:
        play_trump(player,trick_cnt,hand)
    elif suit(top_card[0]) == Trump:
        play_hybrid(player,trick_cnt,hand)
    else:
        play_suit(player,trick_cnt,hand)

#play final card of trick, we are not declarer
#output = last_card_played [index,suit,rank,player,trick_cnt] and px_card
def p3_play(player,trick_cnt,hand): #trick_cnt = 3
    global last_card_played
    if suit(p0_card[0]) == Trump:
        play_trump(player,trick_cnt,hand)
    elif suit(top_card[0]) == Trump:
        play_hybrid(player,trick_cnt,hand)
    else:
        play_suit(player,trick_cnt,hand)

#we are declarer, play led card of trick
#output = last_card_played [index,suit,rank,player,trick_cnt] and px_card
def p0_declarer(player,trick_cnt,hand): #trick_cnt = 0
    global last_card_played
    suit_info(hand,Trump,player,trick_cnt)
    if out_suit_cnt == 0: #are all trump pulled?
        #trump pulled play high cards
        for suitx in [club,diamond,heart,spade]:
            if suitx == Trump:
                continue
            else:
                suit_info(hand,suitx,player,trick_cnt)
                if my_suit_max >= out_suit_max and my_suit_cnt > 0:
                    last_card_played = [my_suit_max,player,trick_lp]
                    return
        #no high cards to play, pick low card
        last_card_played = get_non_counter(player,trick_lp,hand)
        return
    #trump are still out, check if we can pull them
    if my_suit_max >= out_suit_max: #check if we have high trump
        last_card_played = [my_suit_max,player,trick_lp]
        return
    else: #play aces and high cards
        #trump are till out, check for single aces
        for suitx in [club,diamond,heart,spade]:
            suit_info(hand,suitx,player,trick_cnt)
            if rank(my_suit_max) == ace:
                if rank(out_suit_max) == ace:
                    last_card_played = [my_suit_max,player,trick_lp]
                    return
        for suitx in [club,diamond,heart,spade]:
            if suitx == Trump:
                continue
            else:
                suit_info(hand,suitx,player,trick_cnt)
                if rank(my_suit_max) == ace: #ace
                    last_card_played = [my_suit_max,player,trick_lp]
                    return
        for suitx in [club,diamond,heart,spade]:
            if suitx == Trump:
                continue
            else:
                suit_info(hand,suitx,player,trick_cnt)
                if my_suit_cnt == 0 or out_suit_cnt == 0:
                    continue
                if my_suit_max >= out_suit_max:
                    last_card_played = [my_suit_max,player,trick_lp]
                    return
        last_card_played = get_non_counter(player,trick_cnt,hand)
        return

#we are dec;arer. someone else took trick, play second card
#output = last_card_played [index,player,trick_cnt] and px_card
def p1_declarer(player,trick_cnt,hand): #trick_cnt = 1
    global last_card_played
    if suit(p0_card[0]) == Trump:
        play_trump(player,trick_cnt,hand)
    elif suit(top_card[0]) != Trump:
        play_suit(player,trick_cnt,hand)
    else:
        play_hybrid(player,trick_cnt,hand)

#we are declarer, someone else took trick, play third card position
#output = last_card_played [index,suit,rank,player,trick_cnt] and px_card
def p2_declarer(player,trick_cnt,hand): #trick_cnt = 2
    global last_card_played
    if suit(p0_card[0]) == Trump:
        play_trump(player,trick_cnt,hand)
    elif suit(top_card[0]) != Trump:
        play_suit(player,trick_cnt,hand)
    else:
        play_hybrid(player,trick_cnt,hand)

#we are declarer, someone else took trick, play last card of trick
#output = last_card_played [index,suit,rank,player,trick_cnt] and px_card
def p3_declarer(player,trick_cnt,hand): #trick_cnt = 3
    global last_card_played
    if suit(p0_card[0]) == Trump:
        play_trump(player,trick_cnt,hand)
    elif suit(top_card[0]) != Trump:
        play_suit(player,trick_cnt,hand)
    else:
        play_hybrid(player,trick_cnt,hand)


#called from main loop to play one card  
def play_card(player,trick_cnt):
    if player == 0:
        hand = south_hand
    if player == 1:
        hand = west_hand
    elif player == 2:
        hand = north_hand
    elif player == 3:
        hand = east_hand
    if player == 0:
            play_south(player,trick_cnt)
    elif player == high_bid_player:
        if trick_cnt == 0:
            p0_declarer(player,trick_cnt,hand)
        elif trick_cnt == 1:
            p1_declarer(player,trick_cnt,hand)
        elif trick_cnt == 2:
            p2_declarer(player,trick_cnt,hand)
        elif trick_cnt == 3:
            p3_declarer(player,trick_cnt,hand)
    else:
        if trick_cnt == 0:
            p0_play(player,trick_cnt,hand)
        elif trick_cnt == 1:
            p1_play(player,trick_cnt,hand)
        elif trick_cnt == 2:
            p2_play(player,trick_cnt,hand)
        elif trick_cnt == 3:
            p3_play(player,trick_cnt,hand)

def shuffle_deck():
    global deck
    random.shuffle(deck)


def show_players():
    msg("south",white,blue,font3,480,670)
    msg("west",white,blue,font3,10,342)
    msg("north",white,blue,font3,480,50)
    msg("east",white,blue,font3,1150,342)

def show_score():
    screen.fill(blue)
    south_x_column = 396
    mid_x_column = 550
    west_x_column = 750
    row = 405
    #show line 1
    msg("NORTH/SOUTH",white,blue,font2,south_x_column,row)
    msg("EAST/WEST",white,blue,font2,west_x_column,row)
    row = row + 20
    #show line 2 - bid
    if high_bid_player == south or high_bid_player == north:
        msg(str(high_bid), white,blue, font1,south_x_column,row)
    msg("bid",white,blue,font1,mid_x_column,row)
    if high_bid_player == east or high_bid_player == west:
        msg(str(high_bid), white,blue, font1,west_x_column,row)
    row = row + 20
    #show line 3 meld
    ns_meld = melds[0] + melds[2]
    ew_meld = melds[1] + melds[3]
    msg(str(ns_meld),white,blue,font1,south_x_column,row)
    msg("meld",white,blue,font1,mid_x_column,row)
    msg(str(ew_meld),white,blue,font1,west_x_column,row)
    row = row + 20
    #points needed (bid - meld)
    if high_bid_player == south or high_bid_player == north:
        if (high_bid - ns_meld) > 0:
            msg(str(high_bid - ns_meld), yellow,blue, font1,south_x_column,row)
        else:
            msg("1", yellow,blue, font1,south_x_column,row)
    msg("counters needed",yellow,blue,font1,mid_x_column,row)
    if high_bid_player == west or high_bid_player == east:
        if (high_bid - ew_meld) > 0:
            msg(str(high_bid - ew_meld), yellow,blue, font1,west_x_column,row)
        else:
            msg("1", yellow,blue, font1,west_x_column,row)
    row = row + 20
    #points taken
    msg(str(ns_pointers),white,blue,font1,south_x_column,row)
    msg("counters taken",white,blue,font1,mid_x_column,row)
    msg(str(ew_pointers),white,blue,font1,west_x_column,row)
    row = row + 20
    #shoot the moon
    if (high_bid_player == south or high_bid_player == north) and shoot_moon == 1:
        if ns_pointers == 25:
            msg("25", white,blue, font1,south_x_column,row)
        else:
            msg("-50",white,blue,font1,south_x_column,row)
    else:
        msg("0",white,blue,font1,south_x_column,row)
    msg("shooting",white,blue,font1,mid_x_column,row)
    if (high_bid_player == west or high_bid_player == east) and shoot_moon == 1:
        if ew_pointers == 25:
            msg("25", white,blue, font1,west_x_column,row)
        else:
            msg("-50",white,blue,font1,west_x_column,row)
    else:
        msg("0",white,blue,font1,west_x_column,row)
    row = row + 20
    #net hand results, meld + tricks
    msg(str(ns_meld + ns_pointers),white,blue,font1,south_x_column,row)
    msg("meld+counters",white,blue,font1,mid_x_column,row)
    msg(str(ew_meld + ew_pointers),white,blue,font1,west_x_column,row)
    row = row + 20
    #old score
    msg(str(old_score_ns),white,blue,font1,south_x_column,row)
    msg("old score",white,blue,font1,mid_x_column,row)
    msg(str(old_score_ew),white,blue,font1,west_x_column,row)
    row = row + 20
    #new score
    msg(str(score_ns),white,blue,font1,south_x_column,row)
    msg("new score",white,blue,font1,mid_x_column,row)
    msg(str(score_ew),white,blue,font1,west_x_column,row)
    row = row + 20
    but = menu("Scoring","continue","","","","quit game")
    return(but)

def shoot_moon_check():
    global shoot_moon
    trump_tens = 0
    looser = 0
    if high_bid_player == south:
        return
    if high_bid_player == west:
        hand = west_hand[:]
    elif high_bid_player == north:
        hand = north_hand[:]
    else:
        hand = east_hand[:]
    info(high_bid_player,hand)
    if trump_aces != 2:
        return
    if scount[Trump] < 5:
        return #not enough trumps
    for card in hand:
        if suit(card) == Trump:
            if rank(card) == 4:
                trump_tens = trump_tens + 1
        elif rank(card) < 4:
            looser = looser + 1
    if trump_tens < 1:
        return
    if looser > 0:
        return
    shoot_moon = 1

####### main loop starts here ##########
game_lp = 1
title1 = "Pinochle"
button1 = "start game"
while game_lp > 0:
    screen.fill(blue)
    #quit_game = 0
    Trump = 9                                            
    if game_lp == 1:
        show_players()
        while True:
            but = menu(title1,button1,"","about","using","quit game")
            screen.fill(blue)
            if but[0] == 3:
                msg(htext4, white, blue, font1, 20,600)
                msg(htext1, white, blue, font1, 20,620)
                msg(htext2, white, blue, font1, 20,640)
                continue
            if but[0] == 4:
                msg(htext5, white, blue, font1, 20,600)
                msg(htext3, white, blue, font1, 20,620)
                continue
            if but[0] == 1:
                break
    score_ew = 0
    score_ns = 0
    screen.fill(blue)
    hand_lp = 1
    while hand_lp > 0:
        msg("shuffling", white, blue, font3, 400, 360)
        pygame.display.update()
        pygame.time.delay(1000) #sleep(1)
        pygame.display.update()
        shuffle_deck()
        msg("dealing   ", white, blue, font3, 400, 360)
        pygame.display.update()
        pygame.time.delay(500) #sleep(0.5)
        pygame.display.update()
        pygame.time.delay(1000) #sleep(1)
        deal()  #0=south_hand
        display_hand(south_hand,300,500)
        high_bid_player = deal_posn #default dealer bids 25
        high_bid = 25 #starting bid
        Trump = 9 #initialize trump to not defined
        brief_status_display = yes
        pass_count = 0
        shoot_moon = 0
        last_bid = [1,1,1,1] #0=passed
        max_bid = [0,0,0,0]
        meld_ns = 0
        meld_ew = 0
        melds = [0,0,0,0]
        #bid starting at dealers left
        while pass_count < 3:
            if bid_posn == 0:
                hand = south_hand
            elif bid_posn == 1:
                hand = west_hand
            elif bid_posn == 2:
                hand = north_hand
            elif bid_posn == 3:
                hand = east_hand
            if last_bid[bid_posn] != 0: #current bid for hand
                bid(bid_posn,hand)
#                sleep(0.4)
                pygame.display.update()
                if last_bid[bid_posn] == 0: #check if pass
                    pass_count = pass_count + 1
            bid_posn = (bid_posn + 1) % 4
        show_bid_winner(high_bid_player)
        #select trump
        trump_selection()
        #pass cards
        screen.fill(blue)
#        msg( "Pass cards", white, blue, font3, 500, 400)
        exchange_cards()
        display_hand(south_hand,300,500)
        #show meld
        brief_status_display = no
#        show_results() # temp for testing
#        menu(1,"temp","continue","","","","quit game")
        screen.fill(blue)
        meld(south,south_hand,300,500)    
        meld(west,west_hand,20,342)        
        meld(north,north_hand,300,20)        
        meld(east,east_hand,1000,378)
        meld_ns = melds[south] + melds[north]
        meld_ew = melds[east] + melds[west]
        if high_bid_player == south:
            display_hand(south_hand,300,500)
            but = menu("meld","continue","","","shoot moon","quit game")
        else:
            but = menu("meld","continue","","","","quit game")
        if but[0] == 4:
            shoot_moon = 1
        shoot_moon_check()
        #clear the play data
        clubs_played = [0,0,0,0,0,0] #count per rank
        diamonds_played = [0,0,0,0,0,0]
        hearts_played = [0,0,0,0,0,0]
        spades_played = [0,0,0,0,0,0]
        ns_tricks = [] #list of index's for tricks taken
        ew_tricks = []
        #high bidder now starts play
        #hand_lp = 0
        play_posn = high_bid_player
        trick12_lp = 0
        while trick12_lp < 12: #play 12 tricks
            screen.fill(blue)
            last_card_played = [] #index,suit,rank,player,trick_lp
            trick = [] #index,player,trick_lp
            p0 = [] #lead+0 [index,suit,rank,player,lp]
            p1 = []
            p2 = []
            p3 = []
            top_card = [] #index,player,trick_lp
            #start playing at high_bidder
            trick_lp = 0
            while trick_lp < 4:
                play_card(play_posn,trick_lp)
                pygame.display.update()
                if play_posn != 0:
                    pygame.time.delay(400) #sleep(0.4)
                update_card(play_posn,trick_lp)
                play_posn = (play_posn + 1) % 4
                trick_lp = trick_lp + 1
            #trick loop end, 4 cards played
            update_trick() #also set play_posn to trick winner 
            trick12_lp = trick12_lp + 1
        #trick12 loop end
        # show play screen with status
        report = update_hand()
        deal_posn = (deal_posn + 1) % 4
        bid_posn = (deal_posn + 1) % 4
        #show score display
        but = show_score()
        #refill card lists for last hand
        deal()
        screen.fill(blue)
        show_results()
        but = menu(report,"continue","","","","quit game")
        screen.fill(blue)
        #if game is won, stop loop
        if score_ns >= 250 or score_ew >= 250:
            if score_ns >= 250:
                title1 = "North/South won game"
                break
            elif score_ew >= 250:
                title1 = "West/East won game"
                break
        #while hand_lp > 0 (play hands till score reaches 250)
    button1 = "new game"
    #while game_lp > 0
