Home > Mobile >  Game abstraction in Python
Game abstraction in Python

Time:12-24

I did a senior python backend engineer interview. The result was not pretty. Their engineer said I'm having clumsy implementation all over the places. I did an upgrade afterwards but still have one confuses me. It's a paper-rock-scissors game. They would like me to change my original implementation about game rules of the game to better abstraction.

My original implementation is:

def _outcome(self, player_move, ai_move):
    """Determine the outcome of current round.

    Paper beats (wraps) rock.
    Rock beats (blunts) scissors.
    Scissors beats (cuts) paper.

    Parameters
    ----------
    player_move : MoveChoice
        Player's move for current round.

    ai_move : MoveChoice
        AI's move for current round.

    Returns
    -------
    outcome : Outcome
        Outcome of the current round.
    """
    if player_move == 1 and ai_move == 2 or \
        player_move == 2 and ai_move == 3 or \
        player_move == 3 and ai_move == 1:
        return self.computer.name
    elif player_move == 1 and ai_move == 3 or \
        player_move == 2 and ai_move == 1 or \
        player_move == 3 and ai_move == 2:
        return self.player.name
    else:
        return 'Draw'

with a mapping:

MOVE_CHOICE = {
    1: 'rock',
    2: 'paper',
    3: 'scissors',
}

I have role.Player and role.Computer class seperately. Their words is:

  • Use of strings (player name or “draw”) to represent the outcome of a round
  • No abstraction of the game rules, just a couple of big Boolean expression testing all combinations 1 by 1

Their suggestions are:

  • Modelling moves (rock, paper, scissors) as an Enum
  • Modelling round outcomes (win, lose, draw) as an Enum
  • Modelling the games rules as either a function that takes 2 moves and returns an outcome, or as a dict mapping a move to a list of move over which it wins

So far I created Enum Moves and Outcome:

class MoveChoice(Enum):
    ROCK = auto()
    PAPER = auto()
    SCISSORS = auto()


class Outcome(Enum):
    WIN = auto()
    LOSE = auto()
    DRAW = auto()

But having trouble abstract the game rules like they asked. Someone help me out please. Thank you.

CodePudding user response:

Based on the code you've shown and the recommendations they gave you, I would do something like this:

from enum import Enum, auto

class MoveChoice(Enum):
    ROCK = auto()
    PAPER = auto()
    SCISSORS = auto()

class Outcome(Enum):
    WIN = auto()
    LOSE = auto()
    DRAW = auto()

WIN_MAPPING = {
    MoveChoice.ROCK: MoveChoice.SCISSORS,
    MoveChoice.SCISSORS: MoveChoice.PAPER,
    MoveChoice.PAPER: MoveChoice.ROCK,
}

def outcome(player_move, ai_move):
    if player_move == ai_move:
        return Outcome.DRAW
    elif WIN_MAPPING[player_move] == ai_move:
        return Outcome.WIN
    else:
        return Outcome.LOSE

Note that I've changed your method to a function. This isn't a recommendation on overall program structure, it's just to present the logic as a more self-contained example.

  • Related