Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #GiocoScopa
- #require file: sum_problem_card.py link: http://pastebin.com/k7zM8L54
- #piccola implementazione del gioco di scopa
- from random import randrange, choice #needed for shuffling and IA
- from sum_problem_card import SumTree #needed for the combination calculations
- verbose = False
- #declaration of the conversions
- nbr2str = ['0',"ASSO"] + [str(n) for n in range(2,8)] + ["FANTE", "DONNA","RE"]
- str2nbr = dict([(nbr, i) for i, nbr in enumerate(nbr2str)])
- suites_list = ["NONE", "CUORI", "QUADRI", "FIORI", "PICCHE"]
- suit2int = dict([(suit, i) for i, suit in enumerate(suites_list)])
- puntitotsq1 = 0
- puntitotsq2 = 0
- class Card(object):
- def __init__(self, number = 0, suit = ""):
- self.number = number
- self.suit = suit
- def __cmp__(self, card):
- if card == None: return -1
- #check the suits
- if self.suit > card.suit : return 1
- if self.suit < card.suit : return -1
- #if they are equal check the numbers
- if self.number > card.number: return 1
- if self.number < card.number: return -1
- #else they're the same card
- return 0
- def __str__(self):
- return nbr2str[self.number] + " di " + self.suit
- class Deck(object):
- def __init__(self):
- self.cards = []
- #compose a 40 card deck
- for suit in suites_list[1:]: # 4 suit
- for n in range(1,11): # 10 numbers ASSO to RE
- self.cards.append(Card(n, suit))
- def shuffle(self):
- for x in range(500):
- #find indices to swap
- i,j = x%len(self.cards), randrange(0, len(self.cards))
- #swap cards
- tmp = self.cards[i]
- self.cards[i], self.cards[j] = self.cards[j], tmp
- def is_empty(self):
- return len(self.cards) == 0
- def take_first(self):
- return self.cards.pop()
- def __str__(self):
- #print the deck card by card
- return "".join( " "*i + str(card)+"\n" for i,card in enumerate(self.cards))
- class Hand(Deck):
- def __init__(self):
- self.cards = []
- def take_card(self, card):
- self.cards.append(card)
- def remove(self, card):
- #remove one card from the card list
- #definendo il __cmp__ method non dovrebbe piu essere un problema
- #passare un istanza card anche e' stata copiata qua e la
- try: self.cards.remove(card)
- except:
- print "card not found:", card
- print self
- def __str__(self):
- s = "".join((" "*i + str(card)+"\n") for i, card in enumerate(self.cards))
- #for i,card in enumerate(self.cards):
- # s+= " "*i + str(card)+"\n"
- return s
- class Player(object):
- def __init__(self, name = "empty"):
- self.type = "base class player"
- self.name = name
- self.hand = Hand()
- def select_card(self):
- pass
- def take_card(self, card):
- self.hand.take_card(card)
- def select_combination(self, maxcomb):
- #is given a number series corresponding to a card combination
- #shall return the integer corresponding to the choosen comb
- pass
- def __str__(self):
- s = str(self.type) +": " + self.name +": \n"
- s += str(self.hand)
- return s
- class Human(Player):
- def __init__(self, name):
- super(Human, self).__init__(name)
- self.type = "human"
- def select_card(self):
- #parse input
- if verbose: print self
- valid_input = False
- card = None
- while not valid_input:
- input = raw_input("which card? ")
- tmp = input.split(' ')
- #the format should be 'ASSO di FIORI'
- if len(tmp) == 3:
- #check if the number is ok
- number = tmp[0]
- nbr_ok = False
- try:
- number = str2nbr[number]
- nbr_ok = True
- except:
- print "not a valid number"
- #check if the suit is ok
- suit = tmp[2]
- suit_ok = False
- if suit in suites_list:
- suit_ok = True
- else:
- print "not a valid suite"
- #if they are ok then instanciate a card
- if nbr_ok and suit_ok:
- card = Card(number,suit)
- if card in self.hand.cards:
- valid_input = True
- self.hand.cards.remove(card)
- if card != None:
- if not valid_input:
- print "you don't have this card", card
- else:
- print "input length has a wrong formatting"
- return card
- def select_combination(self, maxcomb):
- bad_input = True
- while bad_input:
- i = raw_input("pick a combination: ")
- n_ok = False
- try:
- i = int(i)
- n_ok = True
- except:
- print "input not valid"
- if n_ok and i < 0 or i > maxcomb:
- print "input out of range"
- else:
- bad_input = False
- return i
- class IA(Player):
- def __init__(self, name):
- super(IA, self).__init__(name)
- self.type = "CPU"
- def select_card(self):
- if self.hand.is_empty():
- print "error empty hand"
- return None
- else:
- card = choice(self.hand.cards)
- self.hand.remove(card)
- return card
- def select_combination(self, maxcomb):
- return randrange(0, maxcomb)
- class Squadra(object):
- def __init__(self, player1, player2):
- self.players = [player1, player2]
- self.name = player1.name + " " + player2.name
- self.cards = []
- self.score = 0
- self.scopa = 0
- self.last_taken = False
- def take_card(self, card):
- self.cards.append(card)
- def has_player(self, player):
- return player in self.players
- def __str__(self):
- s = self.players[0].name + " " + self.players[1].name
- return s
- # gioco
- class Match:
- def __init__(self, players):
- #take the player array
- self.players = players
- #a central_deck is a hand
- self.central_deck = Hand()
- #build the squads
- self.sq1 = Squadra(self.players[0], self.players[2])
- self.sq2 = Squadra(self.players[1], self.players[3])
- self.squads = [self.sq1, self.sq2]
- #create deck
- d = Deck()
- d.shuffle()
- #fill in the first 4 card
- for i in range(4):
- self.central_deck.take_card(d.take_first())
- #distribute the rest of the cards
- #enclosed in a while loop because the take_first method
- #change dinamically the size
- i = 0
- while not d.is_empty():
- player_index = i%len(self.players)
- self.players[player_index].take_card(d.take_first())
- i+= 1
- def turn(self):
- print "----- Init game----"
- last_player_index = len(self.players)-1
- while not self.players[last_player_index].hand.is_empty():
- if verbose: print "---------- turn begin -----------"
- for i,player in enumerate(self.players):
- if verbose: print "-------", player.name, "plays--------"
- if verbose: print self.central_deck
- card = player.select_card()
- self.analyze(card, player) #if i is even is appended to sq1
- if verbose: print "-------------------------------------"
- if verbose: print "squadra1:",self.sq1.name, "cards:", len(self.sq1.cards), "scopa: ", self.sq1.scopa
- if verbose: print "squadra2:",self.sq2.name, "cards:", len(self.sq2.cards), "scopa: ", self.sq2.scopa
- if self.sq1.last_taken:
- self.sq1.cards += self.central_deck.cards
- else:
- self.sq2.cards += self.central_deck.cards
- if verbose: print "Finished game:"
- if verbose: print "calculating results:"
- return self.calculate_result()
- def analyze(self, card, player):
- if verbose: print "\n\nyou picked:", card
- if self.central_deck.is_empty():
- if verbose: print "appending card to central deck because there are no card on the table"
- self.central_deck.take_card(card)
- else:
- #create the tree with the values of the card
- if verbose: print "-evaluating card ... -"
- s = SumTree(self.central_deck, card.number)
- can_take = s.find_sum(card.number)
- #analyze the combinations
- if len(can_take) == 0:
- #if the player cannot take the card is
- #putted in the central deck
- if verbose: print "0 combination found"
- self.central_deck.take_card(card)
- elif len(can_take) == 1:
- #we have only one option, we take that card
- if verbose: self.print_combinations(can_take)
- self.win_cards(can_take[0], card, player)
- else:
- if verbose: self.print_combinations(can_take)
- count1 = 0
- opt = []
- for option in can_take:
- #costruisce una lista con le lunghezze
- if len(option) == 1:
- count1 += 1
- opt.append(option)
- if count1 == 1:
- #deve prendere quella carta
- if verbose: print "sebbene ci siano altre opzioni"
- if verbose: print "puoi prendere solo: ", opt[0][0]
- self.win_cards(opt[0], card, player)
- elif(count1 > 1):
- self.display_combination(opt, card, player)
- else:
- self.display_combination(can_take, card, player)
- def win_cards(self, card_list, original_card, winner):
- win_squad = None
- #find which squad wins
- for squad in self.squads:
- if squad.has_player(winner):
- squad.last_taken = True
- win_squad = squad
- else:
- squad.last_taken = False
- #append the original card to the card list of the squad
- win_squad.take_card(original_card)
- #append all the won cards
- for c in card_list:
- win_squad.take_card(c)
- self.central_deck.remove(c)
- if self.central_deck.is_empty():
- win_squad.scopa += 1
- def display_combination(self, combinations, org_card, winner):
- #map the cards to a integer and a card list
- int2cards = {}
- if verbose: print "which cards do you want to take?"
- maxcomb = 0
- for i, option in enumerate(combinations):
- #build the dictionary
- int2cards[i] = option
- if verbose: print "option",i,":"
- #print the card list
- for card in option:
- if verbose: print " ", card
- maxcomb += 1
- #comb = raw_input("which combination? ")
- comb = winner.select_combination(maxcomb)
- #pass the card list selected to the win card procedure
- #so that can be appended in the right deck
- self.win_cards(int2cards[int(comb)], org_card,winner)
- def calculate_result(self):
- if verbose: print self.sq1
- if verbose: print self.sq2
- #scopa
- scoresq1 = self.sq1.scopa
- scoresq2 = self.sq2.scopa
- #carte
- if len(self.sq1.cards) > 20:
- scoresq1 += 1
- print "sq1 vince le carte", len(self.sq1.cards)
- elif len(self.sq1.cards) < 20:
- scoresq2 += 1
- print "sq2 vince le carte", len(self.sq2.cards)
- else:
- print "carte patta"
- #ori
- oricount = 0
- for card in self.sq1.cards:
- if card.suit == "QUADRI":
- oricount += 1
- if oricount > 5:
- scoresq1 += 1
- print "sq1 vince gli ori", oricount
- elif oricount < 5:
- scoresq2 += 1
- print "sq2 vince gli ori", 10 - oricount
- else:
- print "ori patta"
- #settebello
- sq1settebello = False
- for card in self.sq1.cards:
- if card.number == 7 and card.suit == "QUADRI":
- sq1settebello = True
- if sq1settebello:
- scoresq1 += 1
- print "sq1 vince il settebbello"
- else:
- scoresq1 += 1
- print "sq2 vince il settebbello"
- #primiera
- prim1 = self.calc_primiera(self.sq1)
- prim2 = self.calc_primiera(self.sq2)
- if prim1 > prim2:
- scoresq1 += 1
- print "sq1 vince la primiera con:", prim1," punti mentre sq2:", prim2
- elif prim1 < prim2:
- scoresq2 += 1
- print "sq2 vince la primiera con:", prim2," punti mentre sq1:", prim1
- else:
- print "primiera patta"
- global puntitotsq1
- global puntitotsq2
- puntitotsq1 += scoresq1
- puntitotsq2 += scoresq2
- if scoresq1 > scoresq2:
- if verbose: print "vincono i giocatori: ", self.sq1
- print "sq1 win: ",scoresq1, "lose: ", scoresq2
- print "-------------END GAME-------------"
- return 1
- elif scoresq1 < scoresq2:
- if verbose: print "vincono i giocatori: ", self.sq2
- print "sq2 win: ", scoresq2, "lose: ", scoresq1
- print "-------------END GAME-------------"
- return -1
- else:
- print "patta"
- print "-------------END GAME-------------"
- return 0
- def calc_primiera(self, sq):
- punti = {}
- punti[7] = 21
- punti[6] = 18
- punti[1] = 16
- for x in range(2,6):
- punti[x] = 10 + x
- for x in range(8,11):
- punti[x] = 10
- return sum(punti[card.number] for card in sq.cards)
- def print_combinations(self, combination):
- print "- combination found -"
- for opt in combination:
- for card in opt:
- print " ",card
- print "---------"
- class Analysis(object):
- def __init__(self):
- self.n_sim = 100
- self.n_run = 100
- self.run_list = []
- def run_sim(self):
- patta = 0
- winsq1 = 0
- winsq2 = 0
- global puntitotsq1, puntitotsq2
- puntitotsq1 = 0
- puntitotsq2 = 0
- for i in range(self.n_sim):
- players = [IA("Mauro"), IA("g2"), IA("g3"), IA("g4")]
- m = Match(players)
- res = m.turn()
- if res == 0: patta += 1
- if res == 1: winsq1 += 1
- if res == -1: winsq2 += 1
- return (patta, winsq1, winsq2, puntitotsq1, puntitotsq2)
- def run_stats(self):
- for stat in range(self.n_run):
- self.run_list.append(self.run_sim())
- def print_stats(self):
- print "patta sq1win sq2win totpuntisq1 totpuntisq2"
- for run in self.run_list:
- for n in run:
- print n,
- print
- a = Analysis()
- a.run_stats()
- a.print_stats()
- # players = [Human("Me"), IA("g2"), IA("g3"), IA("g4")]
- # m = Match(players)
- # m.turn()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement