Skip to content

Commit 6ff8a30

Browse files
committed
Initial commit
1 parent c121b2a commit 6ff8a30

File tree

6 files changed

+326
-0
lines changed

6 files changed

+326
-0
lines changed

Rock Paper Scissors/.replit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
language = "python3"
2+
run = "python main.py"

Rock Paper Scissors/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
### Assignment
2+
3+
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.
4+
5+
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").
6+
7+
A player function will receive an empty string as an argument for the first game in a match since there is no previous play.
8+
9+
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.
10+
11+
*Hint: To defeat all four opponents, your program may need to have multiple strategies that change depending on the plays of the opponent.*
12+
13+
### Development
14+
15+
Do not modify `RPS_game.py`. Write all your code in `RPS.py`. For development, you can use `main.py` to test your code.
16+
17+
`main.py` imports the game function and bots from `RPS_game.py`.
18+
19+
To test your code, play a game with the `play` function. The `play` function takes four arguments:
20+
- two players to play against each other (the players are actually functions)
21+
- the number of games to play in the match
22+
- an optional argument to see a log of each game. Set it to `True` to see these messages.
23+
24+
```py
25+
play(player1, player2, num_games[, verbose])
26+
```
27+
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:
28+
```py
29+
play(player, quincy, 1000, verbose=True)
30+
```
31+
32+
Click the "run" button and `main.py` will run.
33+
34+
### Testing
35+
36+
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.
37+
38+
### Submitting
39+
40+
Copy your project's URL and submit it to freeCodeCamp.

Rock Paper Scissors/RPS.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# 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.
2+
3+
my_history = []
4+
init_play = prev_play = 'S'
5+
opponent_list = [False, False, False, False]
6+
ideal_response = {'P' : 'R', 'R' : 'S', 'S' : 'P'}
7+
opponent_quincy_counter = - 1
8+
play_order = [{
9+
"RR" : 0,
10+
"RP" : 0,
11+
"RS" : 0,
12+
"PR" : 0,
13+
"PP" : 0,
14+
"PS" : 0,
15+
"SR" : 0,
16+
"SP" : 0,
17+
"SS" : 0,
18+
}]
19+
20+
def player(prev_opponent_play, opponent_history = []):
21+
global my_history, prev_play, opponent_list, ideal_response, opponent_quincy_counter, play_order
22+
opponent_history.append(prev_opponent_play)
23+
my_history.append(prev_play)
24+
25+
# quincy
26+
if(len(set(opponent_list)) == 1 and opponent_history[-5:] == ['R', 'P', 'P', 'S', 'R']):
27+
opponent_list[0] = True
28+
29+
if(opponent_list[0]):
30+
if(len(opponent_history) % 1000 == 0):
31+
opponent_list = [False, False, False, False]
32+
opponent_history.clear()
33+
34+
opponent_quincy_list = ['P', 'S', 'S', 'R', 'P']
35+
opponent_quincy_counter = (opponent_quincy_counter + 1) % 5
36+
return opponent_quincy_list[opponent_quincy_counter]
37+
38+
# abbey
39+
if(len(set(opponent_list)) == 1 and opponent_history[-5:] == ['P', 'P', 'R', 'R', 'R']):
40+
opponent_list[1] = True
41+
42+
if(opponent_list[1]):
43+
last_two = ''.join(my_history[-2:])
44+
if(len(last_two) == 2):
45+
play_order[0][last_two] += 1
46+
potential_plays = [
47+
prev_play + 'R',
48+
prev_play + 'P',
49+
prev_play + 'S',
50+
]
51+
sub_order = {
52+
k : play_order[0][k]
53+
for k in potential_plays if k in play_order[0]
54+
}
55+
prediction = max(sub_order, key = sub_order.get)[-1:]
56+
if(len(opponent_history) % 1000 == 0):
57+
opponent_list = [False, False, False, False]
58+
opponent_history.clear()
59+
play_order = [{
60+
"RR" : 0,
61+
"RP" : 0,
62+
"RS" : 0,
63+
"PR" : 0,
64+
"PP" : 0,
65+
"PS" : 0,
66+
"SR" : 0,
67+
"SP" : 0,
68+
"SS" : 0,
69+
}]
70+
71+
prev_play = ideal_response[prediction]
72+
return prev_play
73+
74+
# kris
75+
if(len(set(opponent_list)) == 1 and opponent_history[-5:] == ['P', 'R', 'R', 'R', 'R']):
76+
opponent_list[2] = True
77+
78+
if(opponent_list[2]):
79+
if(len(opponent_history) % 1000 == 0):
80+
opponent_history.clear()
81+
opponent_list = [False, False, False, False]
82+
83+
prev_play = ideal_response[prev_play]
84+
return prev_play
85+
86+
# mrugesh
87+
if(len(set(opponent_list)) == 1 and opponent_history[-5:] == ['R', 'R', 'R', 'R', 'R']):
88+
opponent_list[3] = True
89+
90+
if(opponent_list[3]):
91+
last_ten = my_history[-10:]
92+
most_frequent = max(set(last_ten), key = last_ten.count)
93+
if(len(opponent_history) == 1000):
94+
opponent_list = [False, False, False, False]
95+
opponent_history.clear()
96+
97+
prev_play = ideal_response[most_frequent]
98+
return prev_play
99+
100+
prev_play = init_play
101+
return prev_play

Rock Paper Scissors/RPS_game.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# DO NOT MODIFY THIS FILE
2+
3+
import random
4+
5+
6+
def play(player1, player2, num_games, verbose=False):
7+
p1_prev_play = ""
8+
p2_prev_play = ""
9+
results = {"p1": 0, "p2": 0, "tie": 0}
10+
11+
for _ in range(num_games):
12+
p1_play = player1(p2_prev_play)
13+
p2_play = player2(p1_prev_play)
14+
15+
if p1_play == p2_play:
16+
results["tie"] += 1
17+
winner = "Tie."
18+
elif (p1_play == "P" and p2_play == "R") or (
19+
p1_play == "R" and p2_play == "S") or (p1_play == "S"
20+
and p2_play == "P"):
21+
results["p1"] += 1
22+
winner = "Player 1 wins."
23+
elif p2_play == "P" and p1_play == "R" or p2_play == "R" and p1_play == "S" or p2_play == "S" and p1_play == "P":
24+
results["p2"] += 1
25+
winner = "Player 2 wins."
26+
27+
if verbose:
28+
print("Player 1:", p1_play, "| Player 2:", p2_play)
29+
print(winner)
30+
print()
31+
32+
p1_prev_play = p1_play
33+
p2_prev_play = p2_play
34+
35+
games_won = results['p2'] + results['p1']
36+
37+
if games_won == 0:
38+
win_rate = 0
39+
else:
40+
win_rate = results['p1'] / games_won * 100
41+
42+
print("Final results:", results)
43+
print(f"Player 1 win rate: {win_rate}%")
44+
45+
return (win_rate)
46+
47+
48+
def quincy(prev_play, counter=[0]):
49+
50+
counter[0] += 1
51+
choices = ["R", "R", "P", "P", "S"]
52+
return choices[counter[0] % len(choices)]
53+
54+
55+
def mrugesh(prev_opponent_play, opponent_history=[]):
56+
opponent_history.append(prev_opponent_play)
57+
last_ten = opponent_history[-10:]
58+
most_frequent = max(set(last_ten), key=last_ten.count)
59+
60+
if most_frequent == '':
61+
most_frequent = "S"
62+
63+
ideal_response = {'P': 'S', 'R': 'P', 'S': 'R'}
64+
return ideal_response[most_frequent]
65+
66+
67+
def kris(prev_opponent_play):
68+
if prev_opponent_play == '':
69+
prev_opponent_play = "R"
70+
ideal_response = {'P': 'S', 'R': 'P', 'S': 'R'}
71+
return ideal_response[prev_opponent_play]
72+
73+
74+
def abbey(prev_opponent_play,
75+
opponent_history=[],
76+
play_order=[{
77+
"RR": 0,
78+
"RP": 0,
79+
"RS": 0,
80+
"PR": 0,
81+
"PP": 0,
82+
"PS": 0,
83+
"SR": 0,
84+
"SP": 0,
85+
"SS": 0,
86+
}]):
87+
88+
if not prev_opponent_play:
89+
prev_opponent_play = 'R'
90+
opponent_history.append(prev_opponent_play)
91+
92+
last_two = "".join(opponent_history[-2:])
93+
if len(last_two) == 2:
94+
play_order[0][last_two] += 1
95+
96+
potential_plays = [
97+
prev_opponent_play + "R",
98+
prev_opponent_play + "P",
99+
prev_opponent_play + "S",
100+
]
101+
102+
sub_order = {
103+
k: play_order[0][k]
104+
for k in potential_plays if k in play_order[0]
105+
}
106+
107+
prediction = max(sub_order, key=sub_order.get)[-1:]
108+
109+
ideal_response = {'P': 'S', 'R': 'P', 'S': 'R'}
110+
return ideal_response[prediction]
111+
112+
113+
def human(prev_opponent_play):
114+
play = ""
115+
while play not in ['R', 'P', 'S']:
116+
play = input("[R]ock, [P]aper, [S]cissors? ")
117+
print(play)
118+
return play
119+
120+
121+
def random_player(prev_opponent_play):
122+
return random.choice(['R', 'P', 'S'])

Rock Paper Scissors/main.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This entrypoint file to be used in development. Start by reading README.md
2+
from RPS_game import play, mrugesh, abbey, quincy, kris, human, random_player
3+
from RPS import player
4+
from unittest import main
5+
6+
#play(player, quincy, 1000)
7+
#play(player, abbey, 1000)
8+
#play(player, kris, 1000)
9+
#play(player, mrugesh, 1000)
10+
11+
12+
13+
14+
# Uncomment line below to play interactively against a bot:
15+
# play(human, abbey, 20, verbose=True)
16+
17+
# Uncomment line below to play against a bot that plays randomly:
18+
# play(human, random_player, 1000)
19+
20+
21+
22+
# Uncomment line below to run unit tests automatically
23+
main(module='test_module', exit=False)

Rock Paper Scissors/test_module.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import unittest
2+
from RPS_game import play, mrugesh, abbey, quincy, kris
3+
from RPS import player
4+
5+
6+
class UnitTests(unittest.TestCase):
7+
print()
8+
9+
def test_player_vs_quincy(self):
10+
print("Testing game against quincy...")
11+
actual = play(player, quincy, 1000) >= 60
12+
self.assertTrue(
13+
actual,
14+
'Expected player to defeat quincy at least 60% of the time.')
15+
16+
def test_player_vs_abbey(self):
17+
print("Testing game against abbey...")
18+
actual = play(player, abbey, 1000) >= 60
19+
self.assertTrue(
20+
actual,
21+
'Expected player to defeat abbey at least 60% of the time.')
22+
23+
def test_player_vs_kris(self):
24+
print("Testing game against kris...")
25+
actual = play(player, kris, 1000) >= 60
26+
self.assertTrue(
27+
actual, 'Expected player to defeat kris at least 60% of the time.')
28+
29+
def test_player_vs_mrugesh(self):
30+
print("Testing game against mrugesh...")
31+
actual = play(player, mrugesh, 1000) >= 60
32+
self.assertTrue(
33+
actual,
34+
'Expected player to defeat mrugesh at least 60% of the time.')
35+
36+
37+
if __name__ == "__main__":
38+
unittest.main()

0 commit comments

Comments
 (0)