Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
127
Task/Pig-the-dice-game-Player/Python/pig-the-dice-game-player.py
Normal file
127
Task/Pig-the-dice-game-Player/Python/pig-the-dice-game-player.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
'''
|
||||
See: http://en.wikipedia.org/wiki/Pig_(dice)
|
||||
|
||||
This program scores, throws the dice, and plays for an N player game of Pig.
|
||||
|
||||
'''
|
||||
|
||||
from random import randint
|
||||
from collections import namedtuple
|
||||
import random
|
||||
from pprint import pprint as pp
|
||||
from collections import Counter
|
||||
|
||||
|
||||
playercount = 2
|
||||
maxscore = 100
|
||||
maxgames = 100000
|
||||
|
||||
|
||||
Game = namedtuple('Game', 'players, maxscore, rounds')
|
||||
Round = namedtuple('Round', 'who, start, scores, safe')
|
||||
|
||||
|
||||
class Player():
|
||||
def __init__(self, player_index):
|
||||
self.player_index = player_index
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%i)' % (self.__class__.__name__, self.player_index)
|
||||
|
||||
def __call__(self, safescore, scores, game):
|
||||
'Returns boolean True to roll again'
|
||||
pass
|
||||
|
||||
class RandPlay(Player):
|
||||
def __call__(self, safe, scores, game):
|
||||
'Returns random boolean choice of whether to roll again'
|
||||
return bool(random.randint(0, 1))
|
||||
|
||||
class RollTo20(Player):
|
||||
def __call__(self, safe, scores, game):
|
||||
'Roll again if this rounds score < 20'
|
||||
return (((sum(scores) + safe[self.player_index]) < maxscore) # Haven't won yet
|
||||
and(sum(scores) < 20)) # Not at 20 this round
|
||||
|
||||
class Desparat(Player):
|
||||
def __call__(self, safe, scores, game):
|
||||
'Roll again if this rounds score < 20 or someone is within 20 of winning'
|
||||
return (((sum(scores) + safe[self.player_index]) < maxscore) # Haven't won yet
|
||||
and( (sum(scores) < 20) # Not at 20 this round
|
||||
or max(safe) >= (maxscore - 20))) # Someone's close
|
||||
|
||||
|
||||
def game__str__(self):
|
||||
'Pretty printer for Game class'
|
||||
return ("Game(players=%r, maxscore=%i,\n rounds=[\n %s\n ])"
|
||||
% (self.players, self.maxscore,
|
||||
',\n '.join(repr(round) for round in self.rounds)))
|
||||
Game.__str__ = game__str__
|
||||
|
||||
|
||||
def winningorder(players, safescores):
|
||||
'Return (players in winning order, their scores)'
|
||||
return tuple(zip(*sorted(zip(players, safescores),
|
||||
key=lambda x: x[1], reverse=True)))
|
||||
|
||||
def playpig(game):
|
||||
'''
|
||||
Plays the game of pig returning the players in winning order
|
||||
and their scores whilst updating argument game with the details of play.
|
||||
'''
|
||||
players, maxscore, rounds = game
|
||||
playercount = len(players)
|
||||
safescore = [0] * playercount # Safe scores for each player
|
||||
player = 0 # Who plays this round
|
||||
scores=[] # Individual scores this round
|
||||
|
||||
while max(safescore) < maxscore:
|
||||
startscore = safescore[player]
|
||||
rolling = players[player](safescore, scores, game)
|
||||
if rolling:
|
||||
rolled = randint(1, 6)
|
||||
scores.append(rolled)
|
||||
if rolled == 1:
|
||||
# Bust!
|
||||
round = Round(who=players[player],
|
||||
start=startscore,
|
||||
scores=scores,
|
||||
safe=safescore[player])
|
||||
rounds.append(round)
|
||||
scores, player = [], (player + 1) % playercount
|
||||
else:
|
||||
# Stick
|
||||
safescore[player] += sum(scores)
|
||||
round = Round(who=players[player],
|
||||
start=startscore,
|
||||
scores=scores,
|
||||
safe=safescore[player])
|
||||
rounds.append(round)
|
||||
if safescore[player] >= maxscore:
|
||||
break
|
||||
scores, player = [], (player + 1) % playercount
|
||||
|
||||
# return players in winning order and all scores
|
||||
return winningorder(players, safescore)
|
||||
|
||||
if __name__ == '__main__':
|
||||
game = Game(players=tuple(RandPlay(i) for i in range(playercount)),
|
||||
maxscore=20,
|
||||
rounds=[])
|
||||
print('ONE GAME')
|
||||
print('Winning order: %r; Respective scores: %r\n' % playpig(game))
|
||||
print(game)
|
||||
game = Game(players=tuple(RandPlay(i) for i in range(playercount)),
|
||||
maxscore=maxscore,
|
||||
rounds=[])
|
||||
algos = (RollTo20, RandPlay, Desparat)
|
||||
print('\n\nMULTIPLE STATISTICS using %r\n for %i GAMES'
|
||||
% (', '.join(p.__name__ for p in algos), maxgames,))
|
||||
winners = Counter(repr(playpig(game._replace(players=tuple(random.choice(algos)(i)
|
||||
for i in range(playercount)),
|
||||
rounds=[]))[0])
|
||||
for i in range(maxgames))
|
||||
print(' Players(position) winning on left; occurrences on right:\n %s'
|
||||
% ',\n '.join(str(w) for w in winners.most_common()))
|
||||
Loading…
Add table
Add a link
Reference in a new issue