تمرين- إضافة سلوك إلى اللعبة

مكتمل

الآن بعد أن أضفت الطبقات والبيانات إلى الصخور الخاصة بك، والورقة، والمقص، حان الوقت لإضافة الجزء الأخير، وهو السلوك. سوف تضيف سلوكًا في شكل أساليب. عليك إضافة أساليب إلى الفئات الخاصة بك، والنتيجة النهائية ستكون لعبة من الصخور والورق والمقص.

تنفيذ السلوك

لقد تم تعليمك أنه لبناء برنامج بأسلوب برمجة موجة للعناصر (OOP)، تقوم أولاً بالنمذجة، ثم البرمجة. أنتجت النمذجة ناتج جدول يمثل العناصر والبيانات والسلوك الذي يبدو أن برنامجك يتكون منه. نعرض الجدول ذاته مرة أخرى.

المرحلة الفاعل سلوك بيانات
الإدخال المشارك يختار الرمز رمز محفوظ في شكل خيار على المشارك (اختيار)
قيد المعالجة جولة اللعبة مقارنة الخيارات في مقابل قواعد اللعبة النتيجة فُحصت
قيد المعالجة جولة اللعبة نقاط الجوائز بناءً على قيمة النتائج النقاط المضافة إلى الفائز المشارك (نقطة)
قيد المعالجة اللعبة التحقق من إجابة المتابعة الإجابة صحيحة، تابع، قم بإنهاء آخر
الإخراج اللعبة جولة جديدة من اللعبة، أو الدرجة في نهاية اللعبة

في هذه المرة، ستركز على العمود Behavior وتعبئته بالطرق التي ستتم إضافتها إلى فئاتك. بالإضافة إلى ذلك، ستقوم بإضافة التعليمات البرمجية إلى تلك الطرق بحيث تعمل بالطريقة التي ينبغي العمل بها.

ها هي التعليمة البرمجية حتى الآن. دعونا نوسّع ذلك في الخطوات التالية:

  1. يجب أن يكون لديك ملف rock-paper-scissor.py. إذا لم يكن الأمر كذلك، فاتبع الخطوات التالية:

  2. إنشاء الملف rock-paper-scissor وفتح المحرر:

    touch rock-paper-scissor.py
    code .
    

    وأضف التعليمات البرمجية التالية:

    class Participant:
        def __init__(self):
            self.points = 0
            self.choice = ""
    
    class GameRound:
    
    class Game:
        def __init__(self):
            self.endGame = False
            self.participant = Participant()
            self.secondParticipant = Participant()
    

ابدأ اللعبة

ينطوي الجزء الأول من اللعبة على إعدادها، وهو ما يعني إنشاء مثيل للعبة ذاتها، وأخذ اللعبة إلى نقطة ينتظر عندها المشاركون لاتخاذ إجراء.

  1. استبدل محتوى rock-paper-scissor.py بالتعليمات البرمجية هذه واحفظ الملف:

    class Participant:
        def __init__(self, name):
            self.name = name
            self.points = 0
            self.choice = ""
        def choose(self):
            self.choice = input("{name}, select rock, paper or scissor: ".format(name= self.name))
            print("{name} selects {choice}".format(name=self.name, choice = self.choice))
    
    class GameRound:
        def __init__(self, p1, p2):
            p1.choose()
            p2.choose()
        def compareChoices(self):
            print("implement")
        def awardPoints(self):
            print("implement")
    
    class Game:
        def __init__(self):
            self.endGame = False
            self.participant = Participant("Spock")
            self.secondParticipant = Participant("Kirk")
        def start(self):
            game_round = GameRound(self.participant, self.secondParticipant)
    
        def checkEndCondition(self):
            print("implement")
        def determineWinner(self):
            print("implement")
    
    game = Game()
    game.start()
    

    لقد أضفت الأساليب من الجدول الخاص بك إلى كل عنصر. يمكن التعبير عن التغييرات التي أجريتها باستخدام جدول بحيث تكون من الأسهل رؤية السلوك الذي أدى إلى الوسيلة التي تتم إضافتها.

    سلوك الطريقة الفاعل
    يختار الرمز اختر() المشارك
    مقارنة الخيارات مقارنة الخيارات() جولة اللعبة
    نقاط الجوائز نقاط الجوائز() جولة اللعبة
    التحقق من إجابة المتابعة التحقق من حالة النهاية() اللعبة
    نتيجة نهاية اللعبة تحديد الفائز() اللعبة

    يتوافق معظم السلوك في الجدول السابق مع الأساليب التي تحمل أسماء مشابهة. الاستثناء هو نتيجة نهاية الائتمان، الذي يصبح determineWinner(). السبب هو أنه جزء نهاية لعبة، فيُستحسن إذا كنت تستطيع التحقق من الفائز وطباعة تلك المعلومات. الأمر متروك لكم إذا كنت تريد تسمية هذا الأسلوب اسمًا آخر.

  2. تشغيل التعليمات البرمجية عن طريق استدعاء python3:

    python3 rock-paper-scissor.py
    

    ينتج البرنامج إخراج على النحو التالي:

    Spock, select rock, paper or scissor:
    

    يعني هذا الإخراج أن البرنامج ينتظرك لكي تتخذ إجراء.

  3. تأكد من عمل البرنامج من خلال تحديد rock ثم تحديد وأدخل. حدد paper، وحدد وأدخل مرة أخرى:

    تشبه مخرجاتك هذا النص:

    Spock, select rock, paper or scissor: rock
    Spock selects rock
    Kirk, select rock, paper or scissor: paper
    Kirk selects paper
    

إشعار

يمكنك إيجاد الحل لهذا التمرين على بدء اللعبة - التعليمات البرمجية للحل.

تطبيق القواعد

من خلال وصف المشكلة، تقرأ أن بعض الخيارات تتفوق على خيارات أخرى. على سبيل المثال، الصخرة تهزم المقص، والمقص يهزم الورق، وما إلى ذلك. من المغري كتابة التعليمات البرمجية التي تبدو على النحو التالي:

if choice1 == "rock" and choice2 == "scissor":
    return 1
elif choice1 == "paper" and choice2 == "scissor":
    return -1
else:
    # something else

# and so on

يؤدي ذلك إلى وجود كمية كبيرة من التعليمات البرمجية المكتوبة ويصبح غير عملي إلى حدٍّ ما. ماذا لو احتاجت اللعبة إلى توسيع مجموعة قواعدها، ما قد يجعل التعليمات البرمجية أكثر صعوبة في الحفاظ عليها؟

لحسن الحظ، توجد طريقة أفضل. النهج الأفضل هو التفكير في القواعد على أنها مصفوفة. تتمثل فكرة استخدام المصفوفة في التعبير عن المجموعة التي تفوز على أخرى. تحصل خطوة الفوز على 1، ويحصل التعادل على 0، وتحصل حركة الخسارة على -1. المصفوفة التالية هي للصخرة والورق والمقص:

الاختيار الصخر الورق المقص
الصخر 0 -1 1
الورق 1 0 -1
المقص -1 1 0

يمكنك تطبيق الجدول السابق في بايثون باستخدام صفيف متعدد الأبعاد على النحو التالي:

rules = [
    [0, -1, 1],
    [1, 0, -1],
    [-1, 1, 0]
]

rules[0][1] # Rock vs Paper = -1, Paper wins over Rock
  1. حدد موقع الفئة Participant وأضف الأسلوب toNumericalChoice():

        def toNumericalChoice(self):
            switcher = {
                "rock": 0,
                "paper": 1,
                "scissor": 2
            }
            return switcher[self.choice]
    

    يعمل الأسلوب السابق على تحويل إدخال سلسلة سطر الأوامر إلى عدد صحيح. يُسهّل ذلك من تحديد الفائز في الجولات.

    تلميح

    تأكد من وضع المؤشر لتحديد مسافة بادئة للتعليمات البرمجية بشكل صحيح.

  2. حدد موقع الفئة GameRound، وبادر بتحديث الأسلوب compareChoices():

        def compareChoices(self, p1, p2):
            return self.rules[p1.toNumericalChoice()][p2.toNumericalChoice()]
    

    تمكنك التعليمات البرمجية من مقارنة خيارين وتحديد الفائز.

  3. في الفئة ذاتها، أضف الأسلوب getResultAsString():

        def getResultAsString(self, result):
            res = {
                0: "draw",
                1: "win",
                -1: "loss"
            }       
            return res[result]
    

    يساعد هذا الأسلوب في تحديد النتيجة وطباعة نص سهل الفهم على الشاشة.

  4. لا نزال في الفئة ذاتها، استبدال محتويات __init__() بهذه التعليمة البرمجية:

        def __init__(self, p1, p2):
            self.rules = [
                [0, -1, 1],
                [1, 0, -1],
                [-1, 1, 0]
            ]
    
            p1.choose()
            p2.choose()
            result = self.compareChoices(p1,p2)
            print("Round resulted in a {result}".format(result = self.getResultAsString(result) ))
    

    تعرض التعليمات البرمجية السابقة الحقل rules، الذي يحتوي على تنفيذ قواعد الصخور والورق والمقص. إضافةً إلى ما سبق، self.compareChoices()يقارن الاستدعاء بين الخيارين. وأخيرًا، يوجد صف يطبع النتائج الملائمة للقارئ على الشاشة.

إشعار

يمكنك العثور على حل لهذا التمرين على تنفيذ القواعد - التعليمات البرمجية للحل .

نتيجة اللعبة

يتعلق تحديد نتيجة اللعبة بتعيين نقاط للاعب المناسب بعد انتهاء اللعب. يحصل اللاعب الفائز على نقطة واحدة أو تعادل أو لا يحصل على نقاط في حال الخسارة.

  1. حدد موقع Participant الفئة، وأضف الأسلوب incrementPoint():

        def incrementPoint(self):
            self.points += 1
    

    تلميح

    يُعد إدخال أسلوب لتغيير سمة هو الخطوة الأولى نحو التغليف. حاول تغيير points الحقل إلى __points__ من أجلإخفاء العضو من الخارج للتغليف التدريبي.

  2. حدد موقع GameRound الفئة، ثم أضف التعليمات البرمجية التالية إلى نهاية __init()__ الأسلوب:

            if result > 0:
               p1.incrementPoint()
            elif result < 0:
               p2.incrementPoint()
    

إشعار

يمكنك إيجاد الحل لهذا التمرين على لعبة النقاط - التعليمات البرمجية للحل.

أضف استعلام المتابعة

استعلام المتابعة عبارة عن سؤال في نهاية جولة اللعبة يسأل اللاعب إذا كانوا يريدون المتابعة أم لا. إذا اختار المستخدم عدم المتابعة، فيمكنه إخراج النتائج الحالية والفائز، إن وجد.

  1. حدد موقع الفئة Game، وبادر بتحديث الأسلوب determineWinner():

        def determineWinner(self):
            resultString = "It's a Draw"
            if self.participant.points > self.secondParticipant.points:
                resultString = "Winner is {name}".format(name=self.participant.name)
            elif self.participant.points < self.secondParticipant.points:
                resultString = "Winner is {name}".format(name=self.secondParticipant.name)
            print(resultString)
    
  2. في الفئة ذاتها، بادر بتحديث الأسلوب checkEndCondition():

        def checkEndCondition(self):
            answer = input("Continue game y/n: ")
            if answer == 'y':
                GameRound(self.participant, self.secondParticipant)
                self.checkEndCondition()
            else:
                print("Game ended, {p1name} has {p1points}, and {p2name} has {p2points}".format(p1name = self.participant.name, p1points= self.participant.points, p2name=self.secondParticipant.name, p2points=self.secondParticipant.points))
                self.determineWinner()
                self.endGame = True
    
  3. في الفئة ذاتها، استبدل التعليمات البرمجية start() للأسلوب بتلك التعليمة البرمجية:

        def start(self):
            while not self.endGame:
                GameRound(self.participant, self.secondParticipant)
                self.checkEndCondition()
    
  4. احفظ الملف.

  5. شغّل الأمر python3 rock-paper-scissor.py لاختبار البرنامج:

    python3 rock-paper-scissor.py
    

    حدد rock وpaper كمدخلات، وأدخل n عندما يُطلب منك المتابعة.

    يبدو المُخرج مشابهًا للنص التالي:

    Spock, select rock, paper or scissor: rock
    Spock selects rock
    Kirk, select rock, paper or scissor: paper
    Kirk selects paper
    Round resulted in a loss
    Continue game y/n: n
    Game ended, Spock has 0, and Kirk has 1
    Winner is Kirk
    

إشعار

يمكنك إيجاد الحل لهذا التمرين على استعلام المتابعة - التعليمات البرمجية للحل.

تهانينا، لقد نجحت! كنت قد نفذت نسخة OOP من لعبة الصخور، والورق، والمقص.