Presentation laddar. Vänta.

Presentation laddar. Vänta.

2D1311 Programmeringsteknik med PBL Föreläsning 5 Skolan för Datavetenskap och kommunikation.

Liknande presentationer


En presentation över ämnet: "2D1311 Programmeringsteknik med PBL Föreläsning 5 Skolan för Datavetenskap och kommunikation."— Presentationens avskrift:

1 2D1311 Programmeringsteknik med PBL Föreläsning 5 Skolan för Datavetenskap och kommunikation

2 Kapitel 9 Mer om objekt: –Rita objekt –Arv –Polymorfism –Moduler –BlackJack-exempel

3 Spelkort Klassen Card representerar ett spelkort Klassens attribut är rank (valör), suit (färg) och is_face_up (uppvänt) Metoderna är __init__ (konstruktorn), __str__ (kortet som sträng), flip (vänder) 4 4

4 class Card(object): """ Ett spelkort. """ RANKS = ["ess", "2", "3", "4", "5", "6", "7", "8", "9", "10", "knekt", "dam", "kung"] SUITS = ["Klöver", "Ruter", "Hjärter", "Spader"] def __init__(self, rank, suit, face_up = True): self.rank = rank self.suit = suit self.is_face_up = face_up def __str__(self): if self.is_face_up: rep = self.suit + " " + self.rank else: rep = "XX" return rep def flip(self): self.is_face_up = not self.is_face_up

5 Rita upp ett objekt Card-objekt: rank suit is_face_up "4" "Hjärter" True

6 Korthand Klassen Hand representerar en korthand Klassens attribut är cards (en lista med kort). Metoderna är __init__,__str__,clear (tömmer), add (lägger till ett kort), give (ger bort ett kort till en annan korthand)

7 class Hand(object) def __init__(self): self.cards = [] def __str__(self): if self.cards: rep = "" for card in self.cards: rep += str(card) + "\t" else: rep = " " return rep def clear(self): self.cards = [] def add(self, card): self.cards.append(card) def give(self, card, other_hand): self.cards.remove(card) other_hand.add(card)

8 Rita Hand-objekt rank suit is_face_up "4" "Hjärter" True rank suit is_face_up "7" "Spader" True rank suit is_face_up "8" "Hjärter" True rank suit is_face_up "9" "Spader" True 0 1 2 3 cards lista med Card-objekt

9 Arv Arv låter oss återanvända klasser! Vi vill ha en klass Deck som representerar en hel kortlek. Vi skriver class Deck(Hand) Klassen Deck ärver då alla attribut ( cards ) och metoder (__str__, clear, add, give ) från Hand. Vi definierar också tre nya metoder i klassen Deck: populate (skapar ny lek), shuffle (blandar), deal (delar ut).

10 class Deck(Hand): """ En kortlek. """ def populate(self): for suit in Card.SUITS: for rank in Card.RANKS: self.add(Card(rank, suit)) def shuffle(self): import random random.shuffle(self.cards) def deal(self, hands, per_hand = 1): for rounds in range(per_hand): for hand in hands: if self.cards: top_card = self.cards[0] self.give(top_card, hand) else: print "Slut på kort!"

11 Polymorfism Kommer av grekiskans  (många) och  (form) Innebär att samma funktion kan anropas med olika typer av indata, t ex len("bläckfisk") antal tecken i strängen len((1,2,3,4,5,6,7,8)) antal tal i tuppeln len(["blöt","god"]) antal element i listan Och att vi kan skriva metoder med samma namn och funktion som kan anropas av objekt från olika klasser, t ex metoden __str__ i Card och Deck.

12 Moduler Att dela upp programmet i moduler gör det mer lätthanterligt. Och enklare att hitta fel i! Modulerna kan dessutom återanvändas...

13 Hur gör man en egen modul? Som ett vanligt Python-program utan main Exempel: Modulen games innehåller klassen Player (med attributen name och score samt metoden __str__ ) och funktionerna ask_yes_no samt ask_number.

14 class Player(object): """ Representerar en spelare. """ def __init__(self, name, score = 0): self.name = name self.score = score def __str__(self): rep = self.name + ":\t" + str(self.score) return rep name "Linda" score 710

15 def ask_yes_no(question): """ Ställer en ja/nej-fråga. """ response = None while response not in ("j", "n"): response = raw_input(question).lower() return response def ask_number(question, low, high): """ Läs in ett värde inom intervallet. """ response = None while response not in range(low, high): response = int(raw_input(question)) return response if __name__ == "__main__": print "Du körde denna modul direkt, " print "utan att importera den." raw_input("\n\nTryck Enter för att avsluta.")

16 Spelregler för Blackjack I kortspelet Blackjack (även kallat tjugoett) är målet att summan av kortens valörer ska komma så nära 21 som möjligt. Kortsumman får inte överstiga 21 – då blir man tjock (och förlorar). Ess kan räknas som 1 eller 11. Knekt, Dam och Kung är alla värda 10. Alla spelare startar med två kort och kan välja att ta fler. Given måste ta fler upp till sjutton.

17 Klasser i Blackjack-programmet KlassÄrver frånBeskrivning BJ_Cardcards.Card Som Card men med attributet value tillagt. BJ_Deckcards.Deck En lista med BJ_Card-objekt. BJ_Handcards.Hand Som Hand men med attributen total och name tillagda. BJ_PlayerBJ_Hand En blackjack-spelare. BJ_DealerBJ_Hand Given (som ger ut korten). BJ_Gameobject Själva spelet! Har attributen deck, dealer och players.

18 Klassdiagram cards.Cardcards.Handcards.DeckBJ_Game BJ_Card BJ_Hand BJ_Deck BJ_PlayerBJ_Dealer

19 Algoritm, del 1 Ge två kort till varje spelare och given. Låt varje spelare: –få ett kort till, så länge den vill ha ett kort till och inte blivit tjock Om alla spelare blivit tjocka: –visa givens två kort Annars: –låt given få ett kort till, så länge den har mindre än sjutton (och inte blivit tjock)

20 Algoritm, del 2 Om given blivit tjock: –så vinner alla kvarvarande spelare Annars: –Gå igenom varje kvarvarande spelare: spelare som ligger högre än given vinner, spelare som ligger lägre förlorar, övriga får oavgjort.

21 # Blackjack ur Dawson kapitel 9 # Modifierad av Linda 20 februari 2006 import cards, games class BJ_Card(cards.Card): """ A Blackjack Card. """ ACE_VALUE = 1 def get_value(self): if self.is_face_up: value = BJ_Card.RANKS.index(self.rank) + 1 if value > 10: value = 10 else: value = None return value value = property(get_value) class BJ_Deck(cards.Deck): """ A Blackjack Deck. """ def populate(self): for suit in BJ_Card.SUITS: for rank in BJ_Card.RANKS: self.cards.append(BJ_Card(rank, suit)) class BJ_Hand(cards.Hand): """ A Blackjack Hand. """ def __init__(self, name): super(BJ_Hand, self).__init__() self.name = name def __str__(self): rep = self.name + ":\t" + super(BJ_Hand, self).__str__() if self.total: rep += "(" + str(self.total) + ")" return rep def get_total(self): # if a card in the hand has value of None, then total is None for card in self.cards: if not card.value: return None # add up card values, treat each Ace as 1 total = 0 for card in self.cards: total += card.value # determine if hand contains an Ace contains_ace = False for card in self.cards: if card.value == BJ_Card.ACE_VALUE: contains_ace = True # if hand contains Ace and total is low enough, treat Ace as 11 if contains_ace and total <= 11: # add only 10 since we've already added 1 for the Ace total += 10 return total total = property(get_total) def is_busted(self): return self.total > 21 class BJ_Player(BJ_Hand): """ A Blackjack Player. """ def is_hitting(self): response = games.ask_yes_no("\n" + self.name + ", vill du ha ett kort? (J/N): ") return response == "j" def bust(self): print self.name, "blir tjock." self.lose() def lose(self): print self.name, "förlorar." def win(self): print self.name, "vinner." def push(self): print "Det det blev oavgjort." class BJ_Dealer(BJ_Hand): """ A Blackjack Dealer. """ def is_hitting(self): return self.total < 17 def bust(self): print self.name, "blir tjock." def flip_first_card(self): first_card = self.cards[0] first_card.flip() class BJ_Game(object): """ A Blackjack Game. """ def __init__(self, names): self.players = [] for name in names: player = BJ_Player(name) self.players.append(player) self.dealer = BJ_Dealer("Given") self.deck = BJ_Deck() self.deck.populate() self.deck.shuffle() def get_still_playing(self): remaining = [] for player in self.players: if not player.is_busted(): remaining.append(player) return remaining # list of players still playing (not busted) this round still_playing = property(get_still_playing) def __additional_cards(self, player): while not player.is_busted() and player.is_hitting(): self.deck.deal([player]) print player if player.is_busted(): player.bust() def play(self): # deal initial 2 cards to everyone self.deck.deal(self.players + [self.dealer], per_hand = 2) self.dealer.flip_first_card() # hide dealer's first card for player in self.players: print player print self.dealer # deal additional cards to players for player in self.players: self.__additional_cards(player) self.dealer.flip_first_card() # reveal dealer's first if not self.still_playing: # since all players have busted, just show the dealer's hand print self.dealer else: # deal additional cards to dealer print self.dealer self.__additional_cards(self.dealer) if self.dealer.is_busted(): # everyone still playing wins for player in self.still_playing: player.win() else: # compare each player still playing to dealer for player in self.still_playing: if player.total > self.dealer.total: player.win() elif player.total < self.dealer.total: player.lose() else: player.push() # remove everyone's cards for player in self.players: player.clear() self.dealer.clear() def main(): print "\t\tVälkommen till Blackjack!\n" names = [] number = games.ask_number("Hur många spelare? (1 - 7): ", low = 1, high = 8) for i in range(number): name = raw_input("Mata in spelarens namn: ") names.append(name) print game = BJ_Game(names) again = None while again != "n": game.play() again = games.ask_yes_no("\nVill du spela igen? ") main() raw_input("\nTryck Enter för att avsluta.")

22 # Cards Module # Basic classes for a game with playing cards # Michael Dawson 4/18/03 class Card(object): """ A playing card. """ RANKS = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] SUITS = ["c", "d", "h", "s"] def __init__(self, rank, suit, face_up = True): self.rank = rank self.suit = suit self.is_face_up = face_up def __str__(self): if self.is_face_up: rep = self.rank + self.suit else: rep = "XX" return rep def flip(self): self.is_face_up = not self.is_face_up class Hand(object): """ A hand of playing cards. """ def __init__(self): self.cards = [] def __str__(self): if self.cards: rep = "" for card in self.cards: rep += str(card) + "\t" else: rep = " " return rep def clear(self): self.cards = [] def add(self, card): self.cards.append(card) def give(self, card, other_hand): self.cards.remove(card) other_hand.add(card) class Deck(Hand): """ A deck of playing cards. """ def populate(self): for suit in Card.SUITS: for rank in Card.RANKS: self.add(Card(rank, suit)) def shuffle(self): import random random.shuffle(self.cards) def deal(self, hands, per_hand = 1): for rounds in range(per_hand): for hand in hands: if self.cards: top_card = self.cards[0] self.give(top_card, hand) else: print "Can't continue deal. Out of cards!" if __name__ == "__main__": print "This is a module with classes for playing cards." raw_input("\n\nPress the enter key to exit.")

23 # Games # Demonstrates module creation # Michael Dawson 4/10/03 class Player(object): """ A player for a game. """ def __init__(self, name, score = 0): self.name = name self.score = score def __str__(self): rep = self.name + ":\t" + str(self.score) return rep def ask_yes_no(question): """Ask a yes or no question.""" response = None while response not in ("y", "n"): response = raw_input(question).lower() return response def ask_number(question, low, high): """Ask for a number within a range.""" response = None while response not in range(low, high): response = int(raw_input(question)) return response if __name__ == "__main__": print "You ran this module directly (and did not 'import' it)." raw_input("\n\nPress the enter key to exit.")


Ladda ner ppt "2D1311 Programmeringsteknik med PBL Föreläsning 5 Skolan för Datavetenskap och kommunikation."

Liknande presentationer


Google-annonser