لعبة Rock, Paper, Scissors بشكل مختلف + مشكلة صغيرة (Python)

موضوعات كثيرة على الانترنت تتحدث عم هذه اللعبة لكني لم أجد أحد فعلها بطريقة الClasses
في لغة python
هذه النتيجة حتى الآن في الـ Terminal:

C:\Users\Nasr\Desktop>py starterGame.py

Game start!


------- Round 0 ------- :

Player 1: paper  Player 2: rock


------- Round 1 ------- :

Player 1: scissors  Player 2: scissors


------- Round 2 ------- :

Player 1: scissors  Player 2: rock


****** Game over! ******

يبدو الموضوع جميل… لكن ليس هناك score و من الفائز في اللعبة !
أيضا سأضيف أشياء أخرى مثل لاعب بشري يستطيع أن يتفاعل مع الكمبيوتر

في الكود التالي عرفت كل الـ Classes
وعملت comment لمحاولتي في اظهار الفائز ومرفق ايضا نوع الerror

#!/usr/bin/env python3
"""This program plays a game of Rock, Paper, Scissors between two Players,
and reports both Player's scores each round."""

moves = ['rock', 'paper', 'scissors']

"""The Player class is the parent class for all of the Players
in this game"""

import random

# Player
class Player:
    def move(self):
        return 'rock'

    def learn(self, my_move, their_move):
        pass

    # specifies winning rules
    def beats(one, two):
        return ((one == 'rock' and two == 'scissors') or
                (one == 'scissors' and two == 'paper') or
                (one == 'paper' and two == 'rock'))

# subclass
class RandomPlayer(Player):
    
    def move(self):
        for move in moves:
            move = random.choice(moves)
        return move

# Game
class Game:
    
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2
        self.p1_score = 0
        self.p2_score = 0
        
    def play_round(self):
        move1 = self.p1.move()
        move2 = self.p2.move()
        print(f"Player 1: {move1}  Player 2: {move2}\n")
        self.p1.learn(move1, move2)
        self.p2.learn(move2, move1)

        # هنا المشكلة >> ARRTIBUTE ERROR >> object has
        # no attribute BEATS
        
    #    if beats(move1, move2) == True:
     #       print("Player 1 wins")
      #  elif beats(move2, move1) == True:
       #     print("Player 2 wins")
        #else:
         #   print("Tie round!")
        

    def play_game(self):
        print("\nGame start! \n")
        for round in range(3):
            print(f"\n------- Round {round} ------- : \n")
            self.play_round()
        print("\n****** Game over! ******")


if __name__ == '__main__':
    game = Game(RandomPlayer(), RandomPlayer())
    game.play_game()

4 Likes

قد شيكت على الكود وحاولت أصلحه

import random
"""This program plays a game of Rock, Paper, Scissors between two Players,
and reports both Player's scores each round."""

moves = ['rock', 'paper', 'scissors']

"""The Player class is the parent class for all of the Players
in this game"""



# Player
class Player:
    def move(self):
        return 'rock'

    def learn(self, my_move, their_move):
        pass

    # specifies winning rules
    def beats(self, one, two):
        return ((one == 'rock' and two == 'scissors') or
                (one == 'scissors' and two == 'paper') or
                (one == 'paper' and two == 'rock'))


# subclass
class RandomPlayer(Player):

    def move(self):
        for move in moves:
            move = random.choice(moves)
        return move


# Game
class Game:

    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2
        self.p1_score = 0
        self.p2_score = 0

    def play_round(self):
        move1 = self.p1.move()
        move2 = self.p2.move()
        print(f"Player 1: {move1}  Player 2: {move2}\n")
        self.p1.learn(move1, move2)
        self.p2.learn(move2, move1)

        # هنا المشكلة >> ARRTIBUTE ERROR >> object has
        # no attribute BEATS

        if self.p1.beats(move1, move2) == True:
            print("Player 1 wins")
        elif self.p2.beats(move2, move1) == True:
            print("Player 2 wins")
        else:
            print("Tie round!")

    def play_game(self):
        print("\nGame start! \n")
        for round in range(3):
            print(f"\n------- Round {round} ------- : \n")
            self.play_round()
        print("\n****** Game over! ******")


if __name__ == '__main__':
    game = Game(RandomPlayer(), RandomPlayer())
    game.play_game()

4 Likes

نعم حاولت نفس طريقتك سابقا:

if self.p1.beats(move1, move2) == True:
            print("Player 1 wins")
        elif self.p2.beats(move2, move1) == True:
            print("Player 2 wins")

لكن نسيت اضافة self في دالة beats
الان تعمل بشكل جيد

2 Likes

@Adetech

لقد أضفت 2 subclasses

الأول هو: ReflectPlayer

class ReflectPlayer(Player):

في هذا الsubclass احببت أن يحفظ أخر حركة قام بها الخصم ويلعبها في الround التالية،
بمعنى: لو لعب الخصم مثلا 'rock' فسيلعب الكمبيوتر هاته الحركة في الـround التالي

تخيلت شكلها هكذا:

# subclass ReflectPlayer
class ReflectPlayer(Player):
    def move(self):
        return random.choice(moves)

    def learn(self, my_move, their_move):
        if their_move == 'rock':
            return 'rock'
        elif their_move == 'paper':
            return 'paper'
        elif their_move == 'scissors':
            return 'scissors'

لكن صراحة عندما أختبرها في الterminal لا أجد اختلاف كثير

الثاني هو: CyclePlayer

وهو سيتذكر الحركة التي لعبها سابقا ويلعب حركة مخالفة لها في الراوند التالي
تخيلت الشكل العام هكذا:

class CyclePlayer(Player):
    def move(self):
        for move in moves:
            if self.their_move in moves:
                return(random.choice(moves))

مشكلة إضافية واجهتني بخصوص humanplayer:
جربو في الرابط بالاسفل تشغيل اللعبة مع عدم ادخال الحركة المطلوبة (فقط اضغط Enter)
كما نرى هنا اللعبة تقبل القيمة وهي None! وطبعا أريد التحكم في ذلك:

Game start!
------- Round 0 ------- :

Choose Rock? Paper? scissors?



Invalid Request, try again!

Rock? Paper? Scissors?

Player 1: None  Player 2: rock

Tie round!

يمكننا تجربة الكود النهائي هنا:

3 Likes

من أجل التحكم في اللعبة في حالة ما إذا اللاعب ضغط على Enter بدون إدخال أي قيمة None، قمت بهذه المحاولة وأعتقد أنها نجحت وتلبي الطلب

        if move1 is not None:

            if self.p1.beats(move1, move2) == True:
                print("Player 1 wins")
                self.p1_score += 1
                if self.p2_score > 0:
                    self.p2_score -= 1
                print(f"Player1_score: {self.p1_score}  Player2_score: {self.p2_score}")

            elif self.p2.beats(move2, move1) == True:
                print("                  Player 2 wins")
                self.p2_score += 1
                if self.p1_score > 0:
                    self.p1_score -= 1
                print(f"Player1_score: {self.p1_score}  Player2_score: {self.p2_score}")
            else:
                print("Tie round!")
        else:
            print("Hey!! let's restart the game :-( ")
            self.play_game()

النتيجة النهائية:

#!/usr/bin/env python3
"""This program plays a game of Rock, Paper, Scissors between two Players,
and reports both Player's scores each round."""

moves = ['rock', 'paper', 'scissors']

"""The Player class is the parent class for all of the Players
in this game"""

import random


# ****************** Player Class ****************** #
class Player:
    def move(self):
        return 'rock'

    def learn(self, my_move, their_move):
        self.my_move = my_move
        self.their_move = their_move

    # specifies winning rules
    def beats(self, one, two):
        return ((one == 'rock' and two == 'scissors') or
                (one == 'scissors' and two == 'paper') or
                (one == 'paper' and two == 'rock'))


# +++++++++++  subclasses ++++++++++ #

# subclass RandomPlayer
class RandomPlayer(Player):

    def move(self):
        for move in moves:
            return random.choice(moves)


# subclass HumanPlayer
class HumanPlayer(Player):
    def move(self):
        order = input("Choose Rock? Paper? scissors? \n\n")
        if order.lower() not in moves:
            print("Invalid Request, try again! Rock? Paper? Scissors? \n\n")
        else:
            return order.lower()


# subclass ReflectPlayer
class ReflectPlayer(Player):
    def move(self):
        return random.choice(moves)

    def learn(self, my_move, their_move):
        if their_move == 'rock':
            return 'rock'
        elif their_move == 'paper':
            return 'paper'
        elif their_move == 'scissors':
            return 'scissors'


# subclass CyclePlayer
class CyclePlayer(Player):
    def move(self):
        for move in moves:
            if self.their_move in moves:
                return (random.choice(moves))
    # pass


# ****************** Player Class Complete! ****************** #

# Game
class Game:

    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2
        self.p1_score = 0
        self.p2_score = 0

    def play_round(self):
        move1 = self.p1.move()
        move2 = self.p2.move()
        print(f"Player 1: {move1}  Player 2: {move2}\n")
        self.p1.learn(move1, move2)
        self.p2.learn(move2, move1)

        # هنا المشكلة >> ARRTIBUTE ERROR >> object has
        # no attribute BEATS
        if move1 is not None:

            if self.p1.beats(move1, move2) == True:
                print("Player 1 wins")
                self.p1_score += 1
                if self.p2_score > 0:
                    self.p2_score -= 1
                print(f"Player1_score: {self.p1_score}  Player2_score: {self.p2_score}")

            elif self.p2.beats(move2, move1) == True:
                print("                  Player 2 wins")
                self.p2_score += 1
                if self.p1_score > 0:
                    self.p1_score -= 1
                print(f"Player1_score: {self.p1_score}  Player2_score: {self.p2_score}")
            else:
                print("Tie round!")
        else:
            print("Hey!! let's restart the game :-( ")
            self.play_game()

    def play_game(self):
        print("\nGame start! \n")
        for round in range(3):
            print(f"\n------- Round {round} ------- : \n")
            self.play_round()
        print("\n****** Game over! ******")


if __name__ == '__main__':
    game = Game(HumanPlayer(), ReflectPlayer())
    game.play_game()

2 Likes