Advertisement
Pella86

Gioco Scopa Python

Apr 15th, 2012
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.77 KB | None | 0 0
  1. #GiocoScopa
  2. #require file: sum_problem_card.py link: http://pastebin.com/k7zM8L54
  3.  
  4. #piccola implementazione del gioco di scopa
  5.  
  6. from random import randrange, choice  #needed for shuffling and IA
  7. from sum_problem_card import SumTree  #needed for the combination calculations
  8.  
  9. verbose = False
  10.  
  11. #declaration of the conversions
  12. nbr2str = ['0',"ASSO"] + [str(n) for n in range(2,8)] + ["FANTE", "DONNA","RE"]
  13. str2nbr = dict([(nbr, i) for i, nbr in enumerate(nbr2str)])
  14.  
  15. suites_list = ["NONE", "CUORI", "QUADRI", "FIORI", "PICCHE"]
  16. suit2int = dict([(suit, i) for i, suit in enumerate(suites_list)])
  17.  
  18. puntitotsq1 = 0
  19. puntitotsq2 = 0
  20.  
  21.  
  22.  
  23.  
  24. class Card(object):
  25.     def __init__(self, number = 0, suit = ""):
  26.         self.number = number
  27.         self.suit = suit
  28.    
  29.     def __cmp__(self, card):
  30.         if card == None: return -1
  31.         #check the suits
  32.         if self.suit > card.suit : return  1
  33.         if self.suit < card.suit : return -1
  34.         #if they are equal check the numbers
  35.         if self.number > card.number: return  1
  36.         if self.number < card.number: return -1
  37.         #else they're the same card
  38.         return 0
  39.        
  40.     def __str__(self):
  41.         return nbr2str[self.number] + " di " + self.suit
  42.        
  43.  
  44.  
  45. class Deck(object):
  46.     def __init__(self):
  47.         self.cards = []
  48.         #compose a 40 card deck
  49.         for suit in suites_list[1:]: # 4 suit
  50.             for n in range(1,11):    # 10 numbers ASSO to RE
  51.                 self.cards.append(Card(n, suit))
  52.    
  53.     def shuffle(self):
  54.         for x in range(500):
  55.             #find indices to swap
  56.             i,j = x%len(self.cards), randrange(0, len(self.cards))
  57.             #swap cards
  58.             tmp = self.cards[i]
  59.             self.cards[i], self.cards[j] = self.cards[j], tmp
  60.            
  61.     def is_empty(self):
  62.         return len(self.cards) == 0
  63.    
  64.     def take_first(self):
  65.         return self.cards.pop()
  66.    
  67.     def __str__(self):
  68.         #print the deck card by card
  69.         return "".join( " "*i + str(card)+"\n" for i,card in enumerate(self.cards))
  70.  
  71.  
  72. class Hand(Deck):
  73.     def __init__(self):
  74.         self.cards = []
  75.    
  76.     def take_card(self, card):
  77.         self.cards.append(card)
  78.    
  79.     def remove(self, card):
  80.         #remove one card from the card list
  81.         #definendo il __cmp__ method non dovrebbe piu essere un problema
  82.         #passare un istanza card anche e' stata copiata qua e la
  83.         try: self.cards.remove(card)
  84.         except:
  85.             print "card not found:", card
  86.             print self
  87.        
  88.     def __str__(self):
  89.        
  90.         s = "".join((" "*i + str(card)+"\n") for i, card in enumerate(self.cards))
  91.         #for i,card in enumerate(self.cards):
  92.         #   s+= " "*i + str(card)+"\n"
  93.         return s
  94.  
  95. class Player(object):
  96.     def __init__(self, name = "empty"):
  97.         self.type = "base class player"
  98.         self.name = name
  99.         self.hand = Hand()
  100.    
  101.     def select_card(self):
  102.         pass
  103.    
  104.     def take_card(self, card):
  105.         self.hand.take_card(card)
  106.    
  107.  
  108.     def select_combination(self, maxcomb):
  109.         #is given a number series corresponding to a card combination
  110.         #shall return the integer corresponding to the choosen comb
  111.         pass
  112.    
  113.     def __str__(self):
  114.         s = str(self.type) +": " + self.name +": \n"
  115.         s += str(self.hand)
  116.         return s
  117.  
  118. class Human(Player):
  119.     def __init__(self, name):
  120.         super(Human, self).__init__(name)
  121.         self.type = "human"
  122.    
  123.     def select_card(self):
  124.         #parse input
  125.         if verbose: print self
  126.        
  127.         valid_input = False
  128.         card = None
  129.        
  130.         while not valid_input: 
  131.             input = raw_input("which card?   ")
  132.             tmp = input.split(' ')
  133.             #the format should be 'ASSO di FIORI'
  134.             if len(tmp) == 3:
  135.                 #check if the number is ok
  136.                 number = tmp[0]
  137.                 nbr_ok = False
  138.                 try:
  139.                     number = str2nbr[number]
  140.                     nbr_ok = True
  141.                 except:
  142.                     print "not a valid number"
  143.                
  144.                 #check if the suit is ok
  145.                 suit = tmp[2]
  146.                 suit_ok = False
  147.                 if suit in suites_list:
  148.                     suit_ok = True
  149.                 else:
  150.                     print "not a valid suite"
  151.                
  152.                 #if they are ok then instanciate a card
  153.                 if nbr_ok and suit_ok:
  154.                     card = Card(number,suit)
  155.                
  156.                 if card in self.hand.cards:
  157.                         valid_input = True
  158.                         self.hand.cards.remove(card)
  159.                
  160.                 if card != None:
  161.                     if not valid_input:
  162.                         print "you don't have this card", card
  163.             else:
  164.                 print "input length has a wrong formatting"
  165.         return card
  166.    
  167.     def select_combination(self, maxcomb):
  168.         bad_input = True
  169.         while bad_input:
  170.             i = raw_input("pick a combination: ")
  171.             n_ok = False
  172.             try:
  173.                 i = int(i)
  174.                 n_ok = True
  175.             except:
  176.                 print "input not valid"
  177.            
  178.             if n_ok and i < 0 or i > maxcomb:
  179.                 print "input out of range"
  180.             else:
  181.                 bad_input = False
  182.         return i
  183.        
  184.  
  185. class IA(Player):
  186.     def __init__(self, name):
  187.         super(IA, self).__init__(name)
  188.         self.type = "CPU"
  189.    
  190.     def select_card(self):
  191.         if self.hand.is_empty():
  192.             print "error empty hand"
  193.             return None
  194.         else:
  195.             card = choice(self.hand.cards)
  196.             self.hand.remove(card)
  197.             return card
  198.    
  199.     def select_combination(self, maxcomb):
  200.         return randrange(0, maxcomb)
  201.  
  202. class Squadra(object):
  203.     def __init__(self, player1, player2):
  204.         self.players = [player1, player2]
  205.         self.name = player1.name + " " + player2.name
  206.         self.cards = []
  207.         self.score = 0
  208.         self.scopa = 0
  209.         self.last_taken = False
  210.    
  211.     def take_card(self, card):
  212.         self.cards.append(card)
  213.    
  214.     def has_player(self, player):
  215.         return player in self.players
  216.    
  217.     def __str__(self):
  218.         s = self.players[0].name + " " + self.players[1].name
  219.         return s
  220. # gioco
  221.  
  222. class Match:
  223.     def __init__(self, players):
  224.         #take the player array
  225.         self.players = players
  226.        
  227.         #a central_deck is a hand
  228.         self.central_deck = Hand()
  229.        
  230.         #build the squads
  231.         self.sq1 = Squadra(self.players[0], self.players[2])
  232.         self.sq2 = Squadra(self.players[1], self.players[3])
  233.         self.squads = [self.sq1, self.sq2]
  234.        
  235.         #create deck
  236.         d = Deck()
  237.         d.shuffle()
  238.        
  239.        
  240.         #fill in the first 4 card
  241.         for i in range(4):
  242.             self.central_deck.take_card(d.take_first())
  243.        
  244.         #distribute the rest of the cards
  245.         #enclosed in a while loop because the take_first method
  246.         #change dinamically the size
  247.         i = 0
  248.         while not d.is_empty():
  249.             player_index = i%len(self.players)
  250.             self.players[player_index].take_card(d.take_first())
  251.             i+= 1
  252.        
  253.    
  254.     def turn(self):
  255.         print "----- Init game----"
  256.         last_player_index = len(self.players)-1
  257.         while not self.players[last_player_index].hand.is_empty():
  258.             if verbose: print "---------- turn begin -----------"
  259.             for i,player in enumerate(self.players):
  260.                 if verbose: print "-------", player.name, "plays--------"
  261.                 if verbose: print self.central_deck
  262.                 card = player.select_card()
  263.                 self.analyze(card, player) #if i is even is appended to sq1
  264.                 if verbose: print "-------------------------------------"
  265.                 if verbose: print "squadra1:",self.sq1.name, "cards:", len(self.sq1.cards), "scopa: ", self.sq1.scopa
  266.                 if verbose: print "squadra2:",self.sq2.name, "cards:", len(self.sq2.cards), "scopa: ", self.sq2.scopa
  267.        
  268.         if self.sq1.last_taken:
  269.             self.sq1.cards += self.central_deck.cards
  270.         else:
  271.             self.sq2.cards += self.central_deck.cards
  272.         if verbose: print "Finished game:"
  273.         if verbose: print "calculating results:"
  274.         return self.calculate_result()
  275.          
  276.     def analyze(self, card, player):
  277.         if verbose: print "\n\nyou picked:", card
  278.         if self.central_deck.is_empty():
  279.             if verbose: print "appending card to central deck because there are no card on the table"
  280.             self.central_deck.take_card(card)
  281.         else:
  282.             #create the tree with the values of the card
  283.             if verbose: print "-evaluating card ... -"
  284.             s = SumTree(self.central_deck, card.number)
  285.             can_take = s.find_sum(card.number)
  286.            
  287.             #analyze the combinations
  288.             if len(can_take) == 0:
  289.                 #if the player cannot take the card is
  290.                 #putted in the central deck
  291.                 if verbose: print "0 combination found"
  292.                 self.central_deck.take_card(card)
  293.             elif len(can_take) == 1:
  294.                 #we have only one option, we take that card
  295.                 if verbose: self.print_combinations(can_take)
  296.                 self.win_cards(can_take[0], card, player)
  297.             else:
  298.                 if verbose: self.print_combinations(can_take)
  299.                 count1 = 0
  300.                 opt = []
  301.                 for option in can_take:
  302.                     #costruisce una lista con le lunghezze
  303.                     if len(option) == 1:
  304.                         count1 += 1
  305.                         opt.append(option)
  306.                 if count1 == 1:
  307.                     #deve prendere quella carta
  308.                     if verbose: print "sebbene ci siano altre opzioni"
  309.                     if verbose: print "puoi prendere solo: ", opt[0][0]
  310.                     self.win_cards(opt[0], card, player)
  311.                 elif(count1 > 1):
  312.                     self.display_combination(opt, card, player)
  313.                 else:
  314.                     self.display_combination(can_take, card, player)
  315.            
  316.    
  317.     def win_cards(self, card_list, original_card, winner):
  318.         win_squad = None
  319.         #find which squad wins
  320.         for squad in self.squads:
  321.             if squad.has_player(winner):
  322.                 squad.last_taken = True
  323.                 win_squad = squad
  324.             else:
  325.                 squad.last_taken = False
  326.        
  327.         #append the original card to the card list of the squad
  328.         win_squad.take_card(original_card)
  329.         #append all the won cards
  330.         for c in card_list:
  331.             win_squad.take_card(c)
  332.             self.central_deck.remove(c)
  333.        
  334.         if self.central_deck.is_empty():
  335.             win_squad.scopa += 1
  336.            
  337.  
  338.     def display_combination(self, combinations, org_card, winner):
  339.         #map the cards to a integer and a card list
  340.         int2cards = {}
  341.         if verbose: print "which cards do you want to take?"
  342.        
  343.         maxcomb = 0
  344.         for i, option in enumerate(combinations):
  345.             #build the dictionary
  346.             int2cards[i] = option
  347.             if verbose: print "option",i,":"
  348.             #print the card list
  349.             for card in option:
  350.                 if verbose: print "  ", card
  351.             maxcomb += 1
  352.         #comb = raw_input("which combination? ")
  353.         comb = winner.select_combination(maxcomb)
  354.         #pass the card list selected to the win card procedure
  355.         #so that can be appended in the right deck
  356.         self.win_cards(int2cards[int(comb)], org_card,winner)
  357.  
  358.        
  359.     def calculate_result(self):    
  360.         if verbose: print self.sq1
  361.         if verbose: print self.sq2
  362.         #scopa
  363.         scoresq1 = self.sq1.scopa
  364.         scoresq2 = self.sq2.scopa
  365.        
  366.         #carte
  367.         if len(self.sq1.cards) > 20:
  368.             scoresq1 += 1
  369.             print "sq1 vince le carte", len(self.sq1.cards)
  370.         elif len(self.sq1.cards) < 20:
  371.             scoresq2 += 1
  372.             print "sq2 vince le carte", len(self.sq2.cards)
  373.         else:
  374.             print "carte patta"
  375.        
  376.         #ori
  377.         oricount = 0
  378.         for card in self.sq1.cards:
  379.             if card.suit == "QUADRI":
  380.                 oricount += 1
  381.        
  382.         if oricount > 5:
  383.             scoresq1 += 1
  384.             print "sq1 vince gli ori", oricount
  385.         elif oricount < 5:
  386.             scoresq2 += 1
  387.             print "sq2 vince gli ori", 10 - oricount   
  388.         else:
  389.             print "ori patta"
  390.        
  391.         #settebello
  392.         sq1settebello = False
  393.         for card in self.sq1.cards:
  394.             if card.number == 7 and card.suit == "QUADRI":
  395.                 sq1settebello = True
  396.        
  397.         if sq1settebello:
  398.             scoresq1 += 1
  399.             print "sq1 vince il settebbello"
  400.         else:
  401.             scoresq1 += 1
  402.             print "sq2 vince il settebbello"
  403.            
  404.         #primiera
  405.         prim1 = self.calc_primiera(self.sq1)
  406.         prim2 = self.calc_primiera(self.sq2)
  407.         if prim1 > prim2:
  408.             scoresq1 += 1
  409.             print "sq1 vince la primiera con:", prim1," punti mentre sq2:", prim2
  410.         elif prim1 < prim2:
  411.             scoresq2 += 1
  412.             print "sq2 vince la primiera con:", prim2," punti mentre sq1:", prim1
  413.         else:
  414.             print "primiera patta"
  415.        
  416.         global puntitotsq1
  417.         global puntitotsq2
  418.         puntitotsq1 += scoresq1
  419.         puntitotsq2 += scoresq2
  420.        
  421.         if scoresq1 > scoresq2:
  422.             if verbose: print "vincono i giocatori: ", self.sq1
  423.             print "sq1 win: ",scoresq1, "lose: ", scoresq2
  424.             print "-------------END GAME-------------"
  425.             return 1
  426.         elif scoresq1 < scoresq2:
  427.             if verbose: print "vincono i giocatori: ", self.sq2
  428.             print "sq2 win: ", scoresq2, "lose: ", scoresq1
  429.             print "-------------END GAME-------------"
  430.             return -1
  431.         else:
  432.             print "patta"
  433.             print "-------------END GAME-------------"
  434.             return 0
  435.    
  436.     def calc_primiera(self, sq):
  437.         punti = {}
  438.         punti[7] = 21
  439.         punti[6] = 18
  440.         punti[1] = 16
  441.        
  442.         for x in range(2,6):
  443.             punti[x] = 10 + x
  444.         for x in range(8,11):
  445.             punti[x] = 10
  446.         return sum(punti[card.number] for card in sq.cards)
  447.        
  448.     def print_combinations(self, combination):
  449.         print "- combination found -"
  450.         for opt in combination:
  451.             for card in opt:
  452.                 print "  ",card
  453.             print "---------"
  454.        
  455.            
  456.              
  457.  
  458. class Analysis(object):
  459.     def __init__(self):
  460.         self.n_sim = 100
  461.         self.n_run = 100
  462.         self.run_list = []
  463.  
  464.    
  465.     def run_sim(self):
  466.         patta = 0
  467.         winsq1 = 0
  468.         winsq2 = 0
  469.         global puntitotsq1, puntitotsq2
  470.         puntitotsq1 = 0
  471.         puntitotsq2 = 0
  472.         for i in range(self.n_sim):
  473.             players =  [IA("Mauro"), IA("g2"), IA("g3"), IA("g4")]
  474.             m = Match(players)
  475.             res = m.turn()
  476.             if res ==  0: patta += 1
  477.             if res ==  1: winsq1   += 1
  478.             if res == -1: winsq2   += 1
  479.        
  480.         return (patta, winsq1, winsq2, puntitotsq1, puntitotsq2)
  481.    
  482.     def run_stats(self):
  483.         for stat in range(self.n_run):
  484.             self.run_list.append(self.run_sim())
  485.    
  486.     def print_stats(self):
  487.         print "patta sq1win sq2win totpuntisq1 totpuntisq2"
  488.         for run in self.run_list:
  489.             for n in run:
  490.                 print n,
  491.             print
  492.  
  493. a = Analysis()
  494. a.run_stats()
  495. a.print_stats()
  496.  
  497.  
  498. #   players =  [Human("Me"), IA("g2"), IA("g3"), IA("g4")]
  499. #   m = Match(players)
  500. #   m.turn()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement