
Hi, Habrozhiteli! You have probably heard about the book by Michael Dawson (Michael Dawson), in which he teaches the Python programming language in the same way, that is, through the programming of simple games. Learn by creating your own entertainment programs.
Despite the entertaining nature of the examples, quite a serious programming technique is demonstrated. The following is an excerpt from the chapter Object-Oriented Programming. Blackjack Game »
Introduction to the game "Black Jack"
The project, which we will work on developing in this chapter, is a simplified version of the Blackjack card game. The gameplay goes like this: participants receive cards with which certain numerical values ​​are associated - points, and each participant seeks to score 21 points, but not more. The number of points corresponding to the card with the number is equal to its face value; Jack, Queen and King go for 10 points, and an ace - for 1 or 11 (depending on how profitable it is for the player).
A computer deals cards and plays against several players, from one to seven. At the beginning of each round, the computer transfers to each of the participants, including himself, two cards. Players can see each other’s cards, and even the current sum of points on each hand is automatically calculated. However, of the two cards that the dealer has passed to himself, one for the time being lies face down.
')
Then each player in turn is given the opportunity to draw additional cards. The player can take them from the mixed deck as long as he pleases and until the sum of points on his hands exceeds 21. If exceeded, which is called brute force, the participant loses. If everyone went over, the computer displays its second card and starts a new round. If one or more participants remain in the game, the round is not over yet. The dealer opens his second card and, as a general rule, Blackjack draws additional cards for himself until the sum of his points is 17 or more. If the dealer, in our case, the computer, does a bust, then all the participants remaining in the game win. If not, then the sum of points of each of the participants is compared with the points that the computer has dialed. Scored more points (person or computer) wins. With the same amount of points, a draw is declared between the computer and one or several participants.
The game process is shown in fig. 9.1.

Sending and receiving messages
An object-oriented program is a kind of ecological system in which objects are living organisms. In order to maintain biocenosis in order, its inhabitants must interact; the same happens in the PLO. The program cannot be useful if the objects in it do not interact in any successfully specified way. In terms of OOP, this interaction is called message sending. In practice, objects just call each other's methods. Although not entirely polite, it is, in any case, better than if objects had to directly access each other’s attributes.
Acquaintance with the program "Death of an Alien"
The program depicts a situation from a computer game in which a player shoots an alien aggressor. Everything literally happens: the player shoots, and the newcomer dies (but, however, he manages to say a few pompous words at the end). This is implemented by sending a message from one object to another. The result of the program is shown in Fig. 9.2.

Technically speaking, the program creates a hero - an instance of the Player class and an invader - an instance of the Alien class. When the hero object's blast () method is called with the invader argument, this object calls the invader object's die () method. In other words, when a hero shoots an alien, it means that the “hero” object sends a message to the “alien” object demanding to die. This message exchange is shown in Fig. 9.3.

The code for this program can be found on the helper site (courseptr.com/downloads) in the folder Chapter 9. The file is called alien_blaster.py:
# # class Player(object): """ -. """ def blast(self, enemy): print(" .\n") enemy.die() class Alien(object): """ - -. """ def die(self): print(" , : ', . . \n" \ " … , … \n" \ ", .'") # print("\t\t \n") hero = Player() invader = Alien() hero.blast(invader) input("\n\n Enter, .")
Posting a message
Before one object can send a message to another, you need two objects! So many of them were created in the main part of my program: first, an object of the Player class, with which the hero variable binds, and then an object of the Alien class, with which the variable invader is associated.
The interesting thing happens in the line of code that follows these two. Using the hero.blast (invader) command, I call the hero's blast () method and pass the invader object as an argument to it. After examining the blast () declaration, you can see that this method takes an argument in the parameter enemy. Therefore, when blast () is called, its internal enemy variable refers to an object of the Alien class. After displaying the text, the blast () method with the command of enemy.die () calls the die () method of the Alien object. Thus, essentially, an instance of the Player class sends a message to the instance of the Alien class that its die () method calls.
Receive a message
The invader object receives the message from the hero object in a natural way: the die () method is called and the visitor dies, saying a heart-breaking gravestone to himself.
Combination of objects
Usually in life, complex things are built from simpler ones. Thus, a racing car can be considered as a single object, which, however, is made up of other, simpler objects: body, engine, wheels, etc. Sometimes there is an important particular case: objects representing sets of other objects. Such, for example, a zoo, which can be represented as a set of animals. These types of relationships are also possible between software objects in OOP. For example, nothing prevents to write the class Drag_Racer, representing a racing car; objects of this class will have an attribute of the engine, referring to the object Race_Engine (engine). You can write the class Zoo, representing the zoo, the objects of which will have the attribute animals - a list of animals (objects of the class Animal). The combination of objects, as in these examples, allows you to build complex objects from simple ones.
Acquaintance with the program "Maps"
In the “Cards” program, objects represent individual playing cards that can be used for any of the games from “Blackjack” to “Fool” (depending on what your tastes and monetary assets are). Further, in the same program, the “hand” object (Hand) is constructed, representing a set of cards of one player; this is nothing more than a list of map objects. The result of the program is shown in Fig. 9.4.

I will parse the code in small portions, but you can also see the entire program on the assistant site (
www.courseptr.com/downloads ) in the folder Chapter 9. The file is called playing_cards.py.
Creating a Card Class
First of all, in this program I create a class Card, whose objects will represent playing cards.
# # class Card(object): """ . """ RANKS = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] SUITS = ["c", "d", "h", "s"] def __init__(self, rank, suit): self.rank = rank self.suit = suit def __str__(self): rep = self.rank + self.suit return rep
Each Card object has a rank attribute, the value of which is the dignity of the map. The attribute of the class RANKS contains all possible values: an ace (“A”), cards with values ​​from 2 to 10, a jack (“J”), a queen (“Q”) and a king (“K”). Each card also has a suit attribute representing the card suit. All its possible values ​​are contained in the class attribute SUITS: “c” (clubs) - clubs, “d” (diamonds) - diamonds, “h” (hearts) - hearts, and finally, “s” (spades) - peaks.
For example, an object with a rank value of “A” and a suit value of “d” represents a diamonds ace. The values ​​of these two attributes, connected in a single line, are returned for printing to the special method __str __ ().
Hand class creation
The next thing I have to do in the program is to create a class Hand, instances of which will represent sets of map objects:
class Hand(object): """ '': . """ def __init__(self): self.cards = [] def __str__(self): if self.cards: rep = "" for card in self.cards: rep += str(card) + " " 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)
A new object of the class Hand appears the attribute cards, which is a list of cards. Thus, the attribute of a single object is a list that can contain any number of other objects.
The special method __str __ () returns the entire "hand" in one line. The method sequentially takes all objects of the Card class and connects their string representations. If the Hand object contains no cards, then the string <empty> will be returned.
The clear () method clears the list of cards: the attribute “hands” of cards is equated to an empty list. The add () method adds an object to the cards list. The give () method removes an object from the list of cards belonging to this “hand” and adds the same object to the card set of another object of class Hand (its add () method is called for this). In other words, the first Hand object sends a message to the second Hand object: add this Card object to the cards attribute.
Use of map objects
In the main part of the program, I create and display five objects of the Card class:
# card1 = Card(rank = "A", suit = "c") print(" -:") print(card1) card2 = Card(rank = "2", suit = "c") card3 = Card(rank = "3", suit = "c") card4 = Card(rank = "4", suit = "c") card5 = Card(rank = "5", suit = "c") print("\n :") print(card2) print(card3) print(card4) print(card5)
For the first of the created instances of the Card class, the rank attribute is “A” and the suit attribute is “c” (ace of clubs). On the screen, this object is displayed as Ac; other cards are similar.
Combination of map objects in the Hand object
Now I will create an instance of the class Hand, bind it to the variable my_hand and display information about it on the screen:
my_hand = Hand() print("\n , :") print(my_hand)
Since the cards attribute of this object is still equal to the empty list, <empty> will be printed on the screen.
I’ll add five Card class objects to my_hand and bring the object to the screen again:
my_hand.add(card1) my_hand.add(card2) my_hand.add(card3) my_hand.add(card4) my_hand.add(card5) print("\n , :") print(my_hand)
The text Ac 2c 3c 4c 5c appears on the screen.
And now I will create another instance of the Hand class called your_hand. Having applied the give () method to my_hand, I transfer two cards from “my hand” to “your hand” and then I will display the contents of both “hands” on the screen:
your_hand = Hand() my_hand.give(card1, your_hand) my_hand.give(card2, your_hand) print("\n .") print(" :") print(your_hand) print(" :") print(my_hand)
As you would expect, your_hand is of the form Ac 2c, and my_hand is 3c 4c 5c.
At the end of the program, I will call the clear () method of the my_hand object and print it on the screen again:
my_hand.clear() print("\n , :") print(my_hand) input("\n\n Enter, .")
Naturally displayed <empty>.
Creating new classes using inheritance
One of the key ideas of OOP is inheritance. Thanks to him, you can base the newly created class on the existing one, and the new class will automatically receive (inherit) all the methods and attributes of the old one. It is as if the entire amount of work that went into creating the original class did not have to be paid!
Extending a class through inheritance
Inheritance is especially useful when the programmer wants to create a more narrow and specialized version of the finished class. As you already know, the inheriting class acquires all the methods and attributes of the parent. But after all, nothing prevents you from adding your own methods and attributes to extend the functionality of the objects of this new class.
Imagine, for example, that your class Drag_Racer sets an object — a racing car with the stop () and go () methods. It is possible on the basis of it to create a new class, describing a special type of racing cars with the function of cleaning the windshield (insects will fight all the time at speeds up to 400 km / h). This new class will automatically inherit the stop () and go () methods from the Drag_Racer class. So you just have to declare just one new method for cleaning the windshield, and the class will be ready.
»More information about the book can be found on
the publisher's website.»
Table of Contents»
ExcerptFor Habrozhiteley 25% discount coupon -
Python