OOP, FP and IMP condensed in Rock, Paper and Scissors Rock Paper and Scissors is a pretty basic program.

The reason I wrote this program is because I wanted to see what a small script that used all of the main programming paradigms looked like.

My code contains:


OOP: A Player object.
FP: First class functions : player.intelligence is a function is stored in a variables and I use anonymous lambdas
IMP: The code asks for input freely, asking for input freely in a functional paradigm is not possible, so this is the imperative part.


Tell me if you like it or if you think it is too complex for an easy task and should be simplified.

from collections import namedtuple
import random

RPS = ["rock", "paper", "scissors"]

Player = namedtuple('Player', 'name intelligence')

def rock_paper_scissors(player_1, player_2):
    a, b = player_1.intelligence(), player_2.intelligence()
    print("\n{} chose {}\n{} chose {}\n".format(
        player_1.name, RPS[a-1], player_2.name, RPS[b-1]))
    return "Tie" if a == b else \
      "The winner is " + (player_1.name if (a - b) % 3 == 1 else player_2.name)

def human_intelligence(prompt):
    return RPS.index(input("The Player 1 move: ").lower())+1

def random_ai():
    return random.choice((1,2,3))


Human vs Computer

print(rock_paper_scissors(
    Player("The Human", lambda: human_intelligence("The human's move : ")),
    Player("The Computer", random_ai)
    )
)


Human vs Human

print(rock_paper_scissors(
    Player("The Player 1", lambda: human_intelligence("Player 1 move : ")),
    Player("The Player 2", lambda: human_intelligence("Player 2 move : "))
    )
)


Computer vs Computer

print(rock_paper_scissors(
    Player("The Computer 1", random_ai),
    Player("The Computer 2", random_ai)
    )
)
I'm almost sorry to say, that it feels like you are naming things just because you can name them according to some coding principle. 

Calling a named tuple OOP, is stretching it very thin. Yes, it encapsulates something but it doesn't have any options to do actions on the object, and it's not a very good use of it. Could possibly use OOP if you used inheritance for the human player and the computer player incorporating the choice logic.

But then again, that would ruin your so-called FP approach with lambdas and storing of functions. Which again is stretching it rather thin, as you don't use a functional approach avoiding state handling and mathemical functions on lists.

So in the end it is mostly imperative programming, which most paradigms ends up with at some level deep within. And it's imperative programming with a very slight touch of OOP, and a very slight touch of FP.

As this however is Code Review, lets add some review issues as well:


User interface is almost non-existent – You don't provide the user with any information on what to enter, nor do you have error handling of any sort. Only after studying the code intensely I see that you enter either "rock", "paper" or "scissors", which is looked up, incremented, and finally decremented to be displayed back within rock_paper_scissors(). Slightly confusing...
Not the best of variable names – The names RPS, a and b are not according to style guidelines, nor very descriptive.
Neat version to select winner – Simple in code, although undescribed, version to select the winner
Add vertical spacing to rock_paper_scissors() – Instead of everything jammed together, I would love to have a little vertical space to help me distinguish the statements of this function.


To summarize, your script does implement a function to play rock, paper or scissors, but it is, in my opinion, too condensed and should be expanded upon rather than simplified any more.