Skip to content

Instantly share code, notes, and snippets.

@felipecruz
Created April 23, 2014 03:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save felipecruz/11201721 to your computer and use it in GitHub Desktop.
Save felipecruz/11201721 to your computer and use it in GitHub Desktop.
#coding: utf-8
import ctypes
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from Crypto.Random import random
libc = ctypes.CDLL("libc.dylib")
libc.srand.argtypes = [ctypes.c_int]
libc.srand.restype = None
libc.rand.argtypes = []
libc.rand.restype = ctypes.c_int
def crand(limit):
return (libc.rand() % limit) + 1
ROCK = 1
PAPER = 2
SCISSORS = 3
DRAW = (0, 0)
FIRST_WIN = (1, -1)
SECOND_WIN = (-1, 1)
RESULTS = {
(ROCK, ROCK): DRAW,
(PAPER, PAPER): DRAW,
(SCISSORS, SCISSORS): DRAW,
(ROCK, PAPER): SECOND_WIN,
(PAPER, ROCK): FIRST_WIN,
(ROCK, SCISSORS): FIRST_WIN,
(SCISSORS, ROCK): SECOND_WIN,
(PAPER, SCISSORS): SECOND_WIN,
(SCISSORS, PAPER): FIRST_WIN
}
class Player:
def play(self):
pass
def receive(self, result):
pass
def new_game(self, games):
pass
class RandomPlayer(Player):
@property
def name(self):
return "Random"
def play(self):
from random import randint
return randint(1, 3)
class CRandomPlayer(Player):
@property
def name(self):
return "CRand"
def play(self):
return crand(3)
class PyCryptoRandomPlayer(Player):
@property
def name(self):
return "PyCryptoRandomPlayer"
def play(self):
return random.choice([1, 2, 3])
class CountRandomPlayer(Player):
def __init__(self):
self.count = {ROCK: 0, SCISSORS: 0, PAPER: 0}
def new_game(self, games):
self._max = (games / 3)
@property
def name(self):
return "CountRandom"
def play(self):
from random import randint
choice = randint(1, 3)
if self.count[choice] > self._max:
next_choice = randint(1, 3)
while next_choice == choice:
next_choice = randint(1, 3)
choice = next_choice
self.count[choice] += 1
return choice
class Roshambo:
def __init__(self, players):
self.players = players
self.wins = [0] * len(players)
self.total = 0
def play(self, p1, p2):
try:
return RESULTS[(p1, p2)]
except KeyError:
raise Exception("Jogo inválido")
def run(self, games):
for i, p1 in enumerate(self.players):
for j, p2 in enumerate(self.players):
if p1 == p2:
continue
p1.new_game(games)
p2.new_game(games)
for k in range(games):
self.total+=1
p1_play = p1.play()
p2_play = p2.play()
result = self.play(p1_play, p2_play)
p1.receive(p2_play)
p2.receive(p1_play)
self.wins[i] += result[0]
self.wins[j] += result[1]
return self.wins
def main():
prand = RandomPlayer()
pcount = CountRandomPlayer()
pcrand = CRandomPlayer()
pcryptorand = PyCryptoRandomPlayer()
players = [prand, pcount, pcrand, pcryptorand]
all_wins = [[0], [0], [0], [0]]
x = list(range(1001))
for i in range(1000):
roshambo = Roshambo(players)
wins = roshambo.run(1000)
print("Total games: {}".format(roshambo.total))
for i, player in enumerate(players):
all_wins[i].append(all_wins[0][::-1][0] + wins[i])
print("{}: {}".format(player.name, wins[i]))
print(all_wins)
print(x)
plt.plot(x, all_wins[0], label="Random")
plt.plot(x, all_wins[1], label="CountRandom")
plt.plot(x, all_wins[2], label="CRandom")
plt.plot(x, all_wins[3], label="PyCryptoRandom")
plt.show()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment