init
This commit is contained in:
commit
f56abf5d40
40
README.md
Normal file
40
README.md
Normal file
@ -0,0 +1,40 @@
|
||||
### Assignment
|
||||
|
||||
For this challenge, you will create a program to play Rock, Paper, Scissors. A program that picks at random will usually win 50% of the time. To pass this challenge your program must play matches against four different bots, winning at least 60% of the games in each match.
|
||||
|
||||
In the file `RPS.py` you are provided with a function called `player`. The function takes an argument that is a string describing the last move of the opponent ("R", "P", or "S"). The function should return a string representing the next move for it to play ("R", "P", or "S").
|
||||
|
||||
A player function will receive an empty string as an argument for the first game in a match since there is no previous play.
|
||||
|
||||
The file `RPS.py` shows an example function that you will need to update. The example function is defined with two arguments (`player(prev_play, opponent_history = [])`). The function is never called with a second argument so that one is completely optional. The reason why the example function contains a second argument (`opponent_history = []`) is because that is the only way to save state between consecutive calls of the `player` function. You only need the `opponent_history` argument if you want to keep track of the opponent_history.
|
||||
|
||||
*Hint: To defeat all four opponents, your program may need to have multiple strategies that change depending on the plays of the opponent.*
|
||||
|
||||
### Development
|
||||
|
||||
Do not modify `RPS_game.py`. Write all your code in `RPS.py`. For development, you can use `main.py` to test your code.
|
||||
|
||||
`main.py` imports the game function and bots from `RPS_game.py`.
|
||||
|
||||
To test your code, play a game with the `play` function. The `play` function takes four arguments:
|
||||
- two players to play against each other (the players are actually functions)
|
||||
- the number of games to play in the match
|
||||
- an optional argument to see a log of each game. Set it to `True` to see these messages.
|
||||
|
||||
```py
|
||||
play(player1, player2, num_games[, verbose])
|
||||
```
|
||||
For example, here is how you would call the function if you want `player` and `quincy` to play 1000 games against each other and you want to see the results of each game:
|
||||
```py
|
||||
play(player, quincy, 1000, verbose=True)
|
||||
```
|
||||
|
||||
Click the "run" button and `main.py` will run.
|
||||
|
||||
### Testing
|
||||
|
||||
The unit tests for this project are in `test_module.py`. We imported the tests from `test_module.py` to `main.py` for your convenience. If you uncomment the last line in `main.py`, the tests will run automatically whenever you hit the "run" button.
|
||||
|
||||
### Submitting
|
||||
|
||||
Copy your project's URL and submit it to freeCodeCamp.
|
10
RPS.py
Normal file
10
RPS.py
Normal file
@ -0,0 +1,10 @@
|
||||
# The example function below keeps track of the opponent's history and plays whatever the opponent played two plays ago. It is not a very good player so you will need to change the code to pass the challenge.
|
||||
|
||||
def player(prev_play, opponent_history=[]):
|
||||
opponent_history.append(prev_play)
|
||||
|
||||
guess = "R"
|
||||
if len(opponent_history) > 2:
|
||||
guess = opponent_history[-2]
|
||||
|
||||
return guess
|
122
RPS_game.py
Normal file
122
RPS_game.py
Normal file
@ -0,0 +1,122 @@
|
||||
# DO NOT MODIFY THIS FILE
|
||||
|
||||
import random
|
||||
|
||||
|
||||
def play(player1, player2, num_games, verbose=False):
|
||||
p1_prev_play = ""
|
||||
p2_prev_play = ""
|
||||
results = {"p1": 0, "p2": 0, "tie": 0}
|
||||
|
||||
for _ in range(num_games):
|
||||
p1_play = player1(p2_prev_play)
|
||||
p2_play = player2(p1_prev_play)
|
||||
|
||||
if p1_play == p2_play:
|
||||
results["tie"] += 1
|
||||
winner = "Tie."
|
||||
elif (p1_play == "P" and p2_play == "R") or (
|
||||
p1_play == "R" and p2_play == "S") or (p1_play == "S"
|
||||
and p2_play == "P"):
|
||||
results["p1"] += 1
|
||||
winner = "Player 1 wins."
|
||||
elif p2_play == "P" and p1_play == "R" or p2_play == "R" and p1_play == "S" or p2_play == "S" and p1_play == "P":
|
||||
results["p2"] += 1
|
||||
winner = "Player 2 wins."
|
||||
|
||||
if verbose:
|
||||
print("Player 1:", p1_play, "| Player 2:", p2_play)
|
||||
print(winner)
|
||||
print()
|
||||
|
||||
p1_prev_play = p1_play
|
||||
p2_prev_play = p2_play
|
||||
|
||||
games_won = results['p2'] + results['p1']
|
||||
|
||||
if games_won == 0:
|
||||
win_rate = 0
|
||||
else:
|
||||
win_rate = results['p1'] / games_won * 100
|
||||
|
||||
print("Final results:", results)
|
||||
print(f"Player 1 win rate: {win_rate}%")
|
||||
|
||||
return (win_rate)
|
||||
|
||||
|
||||
def quincy(prev_play, counter=[0]):
|
||||
|
||||
counter[0] += 1
|
||||
choices = ["R", "R", "P", "P", "S"]
|
||||
return choices[counter[0] % len(choices)]
|
||||
|
||||
|
||||
def mrugesh(prev_opponent_play, opponent_history=[]):
|
||||
opponent_history.append(prev_opponent_play)
|
||||
last_ten = opponent_history[-10:]
|
||||
most_frequent = max(set(last_ten), key=last_ten.count)
|
||||
|
||||
if most_frequent == '':
|
||||
most_frequent = "S"
|
||||
|
||||
ideal_response = {'P': 'S', 'R': 'P', 'S': 'R'}
|
||||
return ideal_response[most_frequent]
|
||||
|
||||
|
||||
def kris(prev_opponent_play):
|
||||
if prev_opponent_play == '':
|
||||
prev_opponent_play = "R"
|
||||
ideal_response = {'P': 'S', 'R': 'P', 'S': 'R'}
|
||||
return ideal_response[prev_opponent_play]
|
||||
|
||||
|
||||
def abbey(prev_opponent_play,
|
||||
opponent_history=[],
|
||||
play_order=[{
|
||||
"RR": 0,
|
||||
"RP": 0,
|
||||
"RS": 0,
|
||||
"PR": 0,
|
||||
"PP": 0,
|
||||
"PS": 0,
|
||||
"SR": 0,
|
||||
"SP": 0,
|
||||
"SS": 0,
|
||||
}]):
|
||||
|
||||
if not prev_opponent_play:
|
||||
prev_opponent_play = 'R'
|
||||
opponent_history.append(prev_opponent_play)
|
||||
|
||||
last_two = "".join(opponent_history[-2:])
|
||||
if len(last_two) == 2:
|
||||
play_order[0][last_two] += 1
|
||||
|
||||
potential_plays = [
|
||||
prev_opponent_play + "R",
|
||||
prev_opponent_play + "P",
|
||||
prev_opponent_play + "S",
|
||||
]
|
||||
|
||||
sub_order = {
|
||||
k: play_order[0][k]
|
||||
for k in potential_plays if k in play_order[0]
|
||||
}
|
||||
|
||||
prediction = max(sub_order, key=sub_order.get)[-1:]
|
||||
|
||||
ideal_response = {'P': 'S', 'R': 'P', 'S': 'R'}
|
||||
return ideal_response[prediction]
|
||||
|
||||
|
||||
def human(prev_opponent_play):
|
||||
play = ""
|
||||
while play not in ['R', 'P', 'S']:
|
||||
play = input("[R]ock, [P]aper, [S]cissors? ")
|
||||
print(play)
|
||||
return play
|
||||
|
||||
|
||||
def random_player(prev_opponent_play):
|
||||
return random.choice(['R', 'P', 'S'])
|
20
main.py
Normal file
20
main.py
Normal file
@ -0,0 +1,20 @@
|
||||
# This entrypoint file to be used in development. Start by reading README.md
|
||||
from RPS_game import play, mrugesh, abbey, quincy, kris, human, random_player
|
||||
from RPS import player
|
||||
from unittest import main
|
||||
|
||||
play(player, quincy, 1000)
|
||||
play(player, abbey, 1000)
|
||||
play(player, kris, 1000)
|
||||
play(player, mrugesh, 1000)
|
||||
|
||||
# Uncomment line below to play interactively against a bot:
|
||||
# play(human, abbey, 20, verbose=True)
|
||||
|
||||
# Uncomment line below to play against a bot that plays randomly:
|
||||
# play(human, random_player, 1000)
|
||||
|
||||
|
||||
|
||||
# Uncomment line below to run unit tests automatically
|
||||
# main(module='test_module', exit=False)
|
38
test_module.py
Normal file
38
test_module.py
Normal file
@ -0,0 +1,38 @@
|
||||
import unittest
|
||||
from RPS_game import play, mrugesh, abbey, quincy, kris
|
||||
from RPS import player
|
||||
|
||||
|
||||
class UnitTests(unittest.TestCase):
|
||||
print()
|
||||
|
||||
def test_player_vs_quincy(self):
|
||||
print("Testing game against quincy...")
|
||||
actual = play(player, quincy, 1000) >= 60
|
||||
self.assertTrue(
|
||||
actual,
|
||||
'Expected player to defeat quincy at least 60% of the time.')
|
||||
|
||||
def test_player_vs_abbey(self):
|
||||
print("Testing game against abbey...")
|
||||
actual = play(player, abbey, 1000) >= 60
|
||||
self.assertTrue(
|
||||
actual,
|
||||
'Expected player to defeat abbey at least 60% of the time.')
|
||||
|
||||
def test_player_vs_kris(self):
|
||||
print("Testing game against kris...")
|
||||
actual = play(player, kris, 1000) >= 60
|
||||
self.assertTrue(
|
||||
actual, 'Expected player to defeat kris at least 60% of the time.')
|
||||
|
||||
def test_player_vs_mrugesh(self):
|
||||
print("Testing game against mrugesh...")
|
||||
actual = play(player, mrugesh, 1000) >= 60
|
||||
self.assertTrue(
|
||||
actual,
|
||||
'Expected player to defeat mrugesh at least 60% of the time.')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Loading…
Reference in New Issue
Block a user