Ten Thousand: a dice game for multiple players

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite
1












A fun little game for as many players as you have friends. This is my first Python project so any advice on how to improve is welcome and appreciated. I'm not concerned with the clunky interface as I'd like to use it for a touch screen device. Have fun playing!



msg = '''
Welcome to 10,000
The Game!
Game objective:
The objective of the game is to have the highest score.
Actually, it's to have fun!
It might take a minute to get used to playing, just relax,
take a few practice runs, and challenge some friends!
To score:
Pick 1's and 5's from the dice you've thrown.
1's are worth 100 points. 5's are worth 50 points.
You may also select any three or four of a kind.
Three of a kind scores the number on the die x 100.
Four of a kind scores double a three of a kind of the same number.
Three ones are worth 1000 points, four ones are worth 2000 points.
Choose any combination of the above. We'll call 'em 'keepers'.
Look carefully on your first roll! The following are worth a lot of
points!:
A Straight 1-6 (chosen in any order) is worth 1500 points.
A Full House (three pairs) is worth 1500 points.
[I'm really proud of the code for these^^ check it out!!]
Six of a kind scores 5000 points!!!
And you get to roll all six dice again!
To play:
For each turn you will start with six dice.
Your dice will appear in [brackets].
It's just old school. You'll be fine. Hang in there.
You must choose at least one keeper from each throw to continue your turn.
To choose a keeper, use the reference number (0-5) located above it.
WTF? Yeah, I know. You'll get used to it and it'll be fun. Trust me.
Enter the reference number and hit Enter.
Repeat until you have all the keepers you want selected.
Then, hit Enter again to submit your selections to scoring.
If all six dice are kept, in one or more turns, all six may be thrown again.
To get on the board you must have a turn worth 500 or more points.
If you would like to stop rolling and keep your score for the
turn, press k and Enter.
If you wish, press Enter and the remaining die will now be thrown again.
You will choose your keepers and whether to throw again in the
same way until...
Your turn ends because you keep your score or your roll has no keepers.
The game continues until one player's score is over 10,000.
The other players will then have one turn to better that player's score.*
The winner is the player with the highest total score!*
*[Not currently functional. I'm working on making sure the winner
actually does have the high score, any advice there, or on anything,
would be greatly appreciated!]
THANK YOU FOR PLAYING !!
Created by:
Paul Kutrich'''

import random
import collections

class Game:
def __init__(self, player_list, round_score = 0):
self.round_score = round_score
self.player_list = player_list

#sets number of players and player names.
def set_player(self, player_list = ):
players = int(input("Enter number of players:""n",))
x = 0
while x < players:
name = input("Enter your name:""n",)
self.name = name
self.name = Player(name)
player_list.append(self.name)
x += 1
return player_list

#checks for full house and returns score.
def full_house(self, choice):
pair_count = 0
score = 0
for i in range(0,3):
try:
if choice[0] == choice[1]:
pair_count += 1
del(choice[1], choice[0])
continue
if choice[0] == choice[2]:
pair_count += 1
del(choice[2], choice[0])
continue
if choice[0] == choice[3]:
pair_count += 1
del(choice[3], choice[0])
continue
if choice[0] == choice[4]:
pair_count += 1
del(choice[4], choice[0])
continue
if choice[0] == choice[5]:
pair_count += 1
del(choice[5], choice[0])
except IndexError:
pass
if pair_count == 3:
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
return score

#checks for straight and returns score.
def straight(self, choice):
score = 0
if len([(x,y) for x in choice for y in choice if x == y]) == 6:
score += 1500
print("You got a Straight!!n")
return score

#scores choices from Player.pick().
def keep_score(self, choice):
score = 0
if len(choice) == 6:
score += self.full_house(choice)
score += self.straight(choice)
return score
else:
valuedict = 1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000


try:
counts = collections.Counter(choice)
score = sum(valuedict[die][count] for die,count
in counts.items())
if score == 0:
print("No keepersnThat's a bummern")
return 0
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
return score

#sets winning score, updates total scores,
#switches between players until winning score met.
#this is essentially the game script.
def take_turns(self, player_list):
self.player_list = Game.set_player(Game, )
scores_list = [self.name.total_score for self.name in self.player_list
if self.name.total_score >= 10000]
while len(scores_list) == 0:
for x in range(0,len(self.player_list)):
self.player_list[x].turn(self.player_list[x].name)
scores_list = [self.name.total_score for self.name
in self.player_list if self.name.total_score >= 10000]
for x in range(0,len(self.player_list)):
print("n",self.player_list[x].name,"'s total score is"
,self.player_list[x].total_score,"n")
winner_list = [self.name for self.name in self.player_list
if self.name.total_score >=10000]
if len(winner_list) > 0:
winner_list.sort(key=lambda Player: self.name.total_score)
print("The winner is",winner_list[-1].name,"!! With a score of:"
,winner_list[-1].total_score,"n")
else:
print("The winner is",winner_list[0].name,"wins!! With a score of:"
,winner_list[0].total_score,"n")
return False

class Player(Game):
def __init__(self, name, total_score = 0):
self.total_score = total_score
self.name = name

#rolls six dice and puts rolls into a list. Returns list of dice.
def throw(self, throw_count):
dice = 5
list =
i = 0
while i <= dice - len(throw_count):
i +=1
list.append(random.randint(1,6))
return list

#takes user input to choose dice by index. Returns list of choices.
def pick(self, list):
choice_list =
choose =
choice =
i = 0
while i <= len(list):
i += 1
try:
choose = int(input('''
Choose which die to keep by position 0-5
Type choice, then enter, repeat for all choices.
Press enter when finished
''',))
if choose >= len(list):
print("Choice not availablenGo ahead and try again.n")
else:
choice_list.append(choose)
except ValueError:
Idx = choice_list
choice = [list[i] for i in Idx]
if choice == None:
choice =
return choice

#one player turn.
def turn(self, player):
round_score = 0
list = self.throw()
print("n",player,", your dice in n 0 1 2 3 4 5n",list,"n")
throw_list =
throw_list.append(list)
choice = self.pick(throw_list[0])
print("Here are your choices",choice,"n")
score = self.keep_score(choice)
print("Your score for this throw is:",score,"n")
if score == 0:
round_score = 0
return round_score
else:
round_score += score
keepers_list =
keepers_list += choice
if len(keepers_list) == 6:
print("Six keepers! Roll 'em again!n")
keepers_list =
throw_list =
throw_count = -1
else:
throw_count = 0
again = input("Roll again or keep?nEnter = roll, K = keepn",)
if again is r"k":
self.total_score += round_score
if self.total_score < 500:
round_score = 0
print("Must score 500 to get on the board.n")
print("Your score this turn:",round_score,"n")
False
self.total_score = 0
return round_score
else:
print("Your score this turn:",round_score,"n")
print("Your total_score", self.total_score,"n")
False
return round_score
elif again != "q":
while True:
for i in range(0,4):
throw_count += 1
list = self.throw(keepers_list)
print("n",player,", your dice in n 0 1 2 3 4 5n"
,list,"n")
throw_list.append(list)
choice = self.pick(throw_list[throw_count])
print("Here are your choices:",choice,"n")
score = self.keep_score(choice)
print("Your score this throw is:",score,"n")
if score == 0:
round_score = 0
False
return round_score
else:
round_score += score
print("Turn score:",round_score,"n")
keepers_list += choice
if len(keepers_list) ==6:
print("Six keepers! Roll 'em again!n")
keepers_list =
throw_list =
throw_count = -1
again = (input(
'''
Roll again or keep?
Enter = roll K = keep''',))
if again == r"k":
self.total_score += round_score
if self.total_score < 500:
print("Must score 500 to get on the board. n")
print("Your score this turn:",round_score,"n")
False
self.total_score = 0
round_score = 0
return round_score
else:
print("Your score this turn:",round_score,"n")
print("Your total_score", self.total_score,"n")
False
return round_score
False
return round_score

def main():
while True:
Game.take_turns(Game, )

print(msg)
main()






share|improve this question

















  • 3




    Is this a duplicate of your previous question?
    – Peilonrayz
    Jan 14 at 20:11










  • I always thought that a full house was 3+2 instead of 2+2+2
    – Mathias Ettinger
    Jan 15 at 12:35










  • @MathiasEttinger It is in poker. This however doesn't seem to be poker.
    – Peilonrayz
    Jan 15 at 15:03










  • It really should be called something other than a full house. But it's traditionally called that, at least in these parts.
    – Paul K
    Jan 15 at 21:12










  • Huh. Not three pairs?
    – David K
    Jan 16 at 1:15
















up vote
5
down vote

favorite
1












A fun little game for as many players as you have friends. This is my first Python project so any advice on how to improve is welcome and appreciated. I'm not concerned with the clunky interface as I'd like to use it for a touch screen device. Have fun playing!



msg = '''
Welcome to 10,000
The Game!
Game objective:
The objective of the game is to have the highest score.
Actually, it's to have fun!
It might take a minute to get used to playing, just relax,
take a few practice runs, and challenge some friends!
To score:
Pick 1's and 5's from the dice you've thrown.
1's are worth 100 points. 5's are worth 50 points.
You may also select any three or four of a kind.
Three of a kind scores the number on the die x 100.
Four of a kind scores double a three of a kind of the same number.
Three ones are worth 1000 points, four ones are worth 2000 points.
Choose any combination of the above. We'll call 'em 'keepers'.
Look carefully on your first roll! The following are worth a lot of
points!:
A Straight 1-6 (chosen in any order) is worth 1500 points.
A Full House (three pairs) is worth 1500 points.
[I'm really proud of the code for these^^ check it out!!]
Six of a kind scores 5000 points!!!
And you get to roll all six dice again!
To play:
For each turn you will start with six dice.
Your dice will appear in [brackets].
It's just old school. You'll be fine. Hang in there.
You must choose at least one keeper from each throw to continue your turn.
To choose a keeper, use the reference number (0-5) located above it.
WTF? Yeah, I know. You'll get used to it and it'll be fun. Trust me.
Enter the reference number and hit Enter.
Repeat until you have all the keepers you want selected.
Then, hit Enter again to submit your selections to scoring.
If all six dice are kept, in one or more turns, all six may be thrown again.
To get on the board you must have a turn worth 500 or more points.
If you would like to stop rolling and keep your score for the
turn, press k and Enter.
If you wish, press Enter and the remaining die will now be thrown again.
You will choose your keepers and whether to throw again in the
same way until...
Your turn ends because you keep your score or your roll has no keepers.
The game continues until one player's score is over 10,000.
The other players will then have one turn to better that player's score.*
The winner is the player with the highest total score!*
*[Not currently functional. I'm working on making sure the winner
actually does have the high score, any advice there, or on anything,
would be greatly appreciated!]
THANK YOU FOR PLAYING !!
Created by:
Paul Kutrich'''

import random
import collections

class Game:
def __init__(self, player_list, round_score = 0):
self.round_score = round_score
self.player_list = player_list

#sets number of players and player names.
def set_player(self, player_list = ):
players = int(input("Enter number of players:""n",))
x = 0
while x < players:
name = input("Enter your name:""n",)
self.name = name
self.name = Player(name)
player_list.append(self.name)
x += 1
return player_list

#checks for full house and returns score.
def full_house(self, choice):
pair_count = 0
score = 0
for i in range(0,3):
try:
if choice[0] == choice[1]:
pair_count += 1
del(choice[1], choice[0])
continue
if choice[0] == choice[2]:
pair_count += 1
del(choice[2], choice[0])
continue
if choice[0] == choice[3]:
pair_count += 1
del(choice[3], choice[0])
continue
if choice[0] == choice[4]:
pair_count += 1
del(choice[4], choice[0])
continue
if choice[0] == choice[5]:
pair_count += 1
del(choice[5], choice[0])
except IndexError:
pass
if pair_count == 3:
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
return score

#checks for straight and returns score.
def straight(self, choice):
score = 0
if len([(x,y) for x in choice for y in choice if x == y]) == 6:
score += 1500
print("You got a Straight!!n")
return score

#scores choices from Player.pick().
def keep_score(self, choice):
score = 0
if len(choice) == 6:
score += self.full_house(choice)
score += self.straight(choice)
return score
else:
valuedict = 1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000


try:
counts = collections.Counter(choice)
score = sum(valuedict[die][count] for die,count
in counts.items())
if score == 0:
print("No keepersnThat's a bummern")
return 0
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
return score

#sets winning score, updates total scores,
#switches between players until winning score met.
#this is essentially the game script.
def take_turns(self, player_list):
self.player_list = Game.set_player(Game, )
scores_list = [self.name.total_score for self.name in self.player_list
if self.name.total_score >= 10000]
while len(scores_list) == 0:
for x in range(0,len(self.player_list)):
self.player_list[x].turn(self.player_list[x].name)
scores_list = [self.name.total_score for self.name
in self.player_list if self.name.total_score >= 10000]
for x in range(0,len(self.player_list)):
print("n",self.player_list[x].name,"'s total score is"
,self.player_list[x].total_score,"n")
winner_list = [self.name for self.name in self.player_list
if self.name.total_score >=10000]
if len(winner_list) > 0:
winner_list.sort(key=lambda Player: self.name.total_score)
print("The winner is",winner_list[-1].name,"!! With a score of:"
,winner_list[-1].total_score,"n")
else:
print("The winner is",winner_list[0].name,"wins!! With a score of:"
,winner_list[0].total_score,"n")
return False

class Player(Game):
def __init__(self, name, total_score = 0):
self.total_score = total_score
self.name = name

#rolls six dice and puts rolls into a list. Returns list of dice.
def throw(self, throw_count):
dice = 5
list =
i = 0
while i <= dice - len(throw_count):
i +=1
list.append(random.randint(1,6))
return list

#takes user input to choose dice by index. Returns list of choices.
def pick(self, list):
choice_list =
choose =
choice =
i = 0
while i <= len(list):
i += 1
try:
choose = int(input('''
Choose which die to keep by position 0-5
Type choice, then enter, repeat for all choices.
Press enter when finished
''',))
if choose >= len(list):
print("Choice not availablenGo ahead and try again.n")
else:
choice_list.append(choose)
except ValueError:
Idx = choice_list
choice = [list[i] for i in Idx]
if choice == None:
choice =
return choice

#one player turn.
def turn(self, player):
round_score = 0
list = self.throw()
print("n",player,", your dice in n 0 1 2 3 4 5n",list,"n")
throw_list =
throw_list.append(list)
choice = self.pick(throw_list[0])
print("Here are your choices",choice,"n")
score = self.keep_score(choice)
print("Your score for this throw is:",score,"n")
if score == 0:
round_score = 0
return round_score
else:
round_score += score
keepers_list =
keepers_list += choice
if len(keepers_list) == 6:
print("Six keepers! Roll 'em again!n")
keepers_list =
throw_list =
throw_count = -1
else:
throw_count = 0
again = input("Roll again or keep?nEnter = roll, K = keepn",)
if again is r"k":
self.total_score += round_score
if self.total_score < 500:
round_score = 0
print("Must score 500 to get on the board.n")
print("Your score this turn:",round_score,"n")
False
self.total_score = 0
return round_score
else:
print("Your score this turn:",round_score,"n")
print("Your total_score", self.total_score,"n")
False
return round_score
elif again != "q":
while True:
for i in range(0,4):
throw_count += 1
list = self.throw(keepers_list)
print("n",player,", your dice in n 0 1 2 3 4 5n"
,list,"n")
throw_list.append(list)
choice = self.pick(throw_list[throw_count])
print("Here are your choices:",choice,"n")
score = self.keep_score(choice)
print("Your score this throw is:",score,"n")
if score == 0:
round_score = 0
False
return round_score
else:
round_score += score
print("Turn score:",round_score,"n")
keepers_list += choice
if len(keepers_list) ==6:
print("Six keepers! Roll 'em again!n")
keepers_list =
throw_list =
throw_count = -1
again = (input(
'''
Roll again or keep?
Enter = roll K = keep''',))
if again == r"k":
self.total_score += round_score
if self.total_score < 500:
print("Must score 500 to get on the board. n")
print("Your score this turn:",round_score,"n")
False
self.total_score = 0
round_score = 0
return round_score
else:
print("Your score this turn:",round_score,"n")
print("Your total_score", self.total_score,"n")
False
return round_score
False
return round_score

def main():
while True:
Game.take_turns(Game, )

print(msg)
main()






share|improve this question

















  • 3




    Is this a duplicate of your previous question?
    – Peilonrayz
    Jan 14 at 20:11










  • I always thought that a full house was 3+2 instead of 2+2+2
    – Mathias Ettinger
    Jan 15 at 12:35










  • @MathiasEttinger It is in poker. This however doesn't seem to be poker.
    – Peilonrayz
    Jan 15 at 15:03










  • It really should be called something other than a full house. But it's traditionally called that, at least in these parts.
    – Paul K
    Jan 15 at 21:12










  • Huh. Not three pairs?
    – David K
    Jan 16 at 1:15












up vote
5
down vote

favorite
1









up vote
5
down vote

favorite
1






1





A fun little game for as many players as you have friends. This is my first Python project so any advice on how to improve is welcome and appreciated. I'm not concerned with the clunky interface as I'd like to use it for a touch screen device. Have fun playing!



msg = '''
Welcome to 10,000
The Game!
Game objective:
The objective of the game is to have the highest score.
Actually, it's to have fun!
It might take a minute to get used to playing, just relax,
take a few practice runs, and challenge some friends!
To score:
Pick 1's and 5's from the dice you've thrown.
1's are worth 100 points. 5's are worth 50 points.
You may also select any three or four of a kind.
Three of a kind scores the number on the die x 100.
Four of a kind scores double a three of a kind of the same number.
Three ones are worth 1000 points, four ones are worth 2000 points.
Choose any combination of the above. We'll call 'em 'keepers'.
Look carefully on your first roll! The following are worth a lot of
points!:
A Straight 1-6 (chosen in any order) is worth 1500 points.
A Full House (three pairs) is worth 1500 points.
[I'm really proud of the code for these^^ check it out!!]
Six of a kind scores 5000 points!!!
And you get to roll all six dice again!
To play:
For each turn you will start with six dice.
Your dice will appear in [brackets].
It's just old school. You'll be fine. Hang in there.
You must choose at least one keeper from each throw to continue your turn.
To choose a keeper, use the reference number (0-5) located above it.
WTF? Yeah, I know. You'll get used to it and it'll be fun. Trust me.
Enter the reference number and hit Enter.
Repeat until you have all the keepers you want selected.
Then, hit Enter again to submit your selections to scoring.
If all six dice are kept, in one or more turns, all six may be thrown again.
To get on the board you must have a turn worth 500 or more points.
If you would like to stop rolling and keep your score for the
turn, press k and Enter.
If you wish, press Enter and the remaining die will now be thrown again.
You will choose your keepers and whether to throw again in the
same way until...
Your turn ends because you keep your score or your roll has no keepers.
The game continues until one player's score is over 10,000.
The other players will then have one turn to better that player's score.*
The winner is the player with the highest total score!*
*[Not currently functional. I'm working on making sure the winner
actually does have the high score, any advice there, or on anything,
would be greatly appreciated!]
THANK YOU FOR PLAYING !!
Created by:
Paul Kutrich'''

import random
import collections

class Game:
def __init__(self, player_list, round_score = 0):
self.round_score = round_score
self.player_list = player_list

#sets number of players and player names.
def set_player(self, player_list = ):
players = int(input("Enter number of players:""n",))
x = 0
while x < players:
name = input("Enter your name:""n",)
self.name = name
self.name = Player(name)
player_list.append(self.name)
x += 1
return player_list

#checks for full house and returns score.
def full_house(self, choice):
pair_count = 0
score = 0
for i in range(0,3):
try:
if choice[0] == choice[1]:
pair_count += 1
del(choice[1], choice[0])
continue
if choice[0] == choice[2]:
pair_count += 1
del(choice[2], choice[0])
continue
if choice[0] == choice[3]:
pair_count += 1
del(choice[3], choice[0])
continue
if choice[0] == choice[4]:
pair_count += 1
del(choice[4], choice[0])
continue
if choice[0] == choice[5]:
pair_count += 1
del(choice[5], choice[0])
except IndexError:
pass
if pair_count == 3:
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
return score

#checks for straight and returns score.
def straight(self, choice):
score = 0
if len([(x,y) for x in choice for y in choice if x == y]) == 6:
score += 1500
print("You got a Straight!!n")
return score

#scores choices from Player.pick().
def keep_score(self, choice):
score = 0
if len(choice) == 6:
score += self.full_house(choice)
score += self.straight(choice)
return score
else:
valuedict = 1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000


try:
counts = collections.Counter(choice)
score = sum(valuedict[die][count] for die,count
in counts.items())
if score == 0:
print("No keepersnThat's a bummern")
return 0
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
return score

#sets winning score, updates total scores,
#switches between players until winning score met.
#this is essentially the game script.
def take_turns(self, player_list):
self.player_list = Game.set_player(Game, )
scores_list = [self.name.total_score for self.name in self.player_list
if self.name.total_score >= 10000]
while len(scores_list) == 0:
for x in range(0,len(self.player_list)):
self.player_list[x].turn(self.player_list[x].name)
scores_list = [self.name.total_score for self.name
in self.player_list if self.name.total_score >= 10000]
for x in range(0,len(self.player_list)):
print("n",self.player_list[x].name,"'s total score is"
,self.player_list[x].total_score,"n")
winner_list = [self.name for self.name in self.player_list
if self.name.total_score >=10000]
if len(winner_list) > 0:
winner_list.sort(key=lambda Player: self.name.total_score)
print("The winner is",winner_list[-1].name,"!! With a score of:"
,winner_list[-1].total_score,"n")
else:
print("The winner is",winner_list[0].name,"wins!! With a score of:"
,winner_list[0].total_score,"n")
return False

class Player(Game):
def __init__(self, name, total_score = 0):
self.total_score = total_score
self.name = name

#rolls six dice and puts rolls into a list. Returns list of dice.
def throw(self, throw_count):
dice = 5
list =
i = 0
while i <= dice - len(throw_count):
i +=1
list.append(random.randint(1,6))
return list

#takes user input to choose dice by index. Returns list of choices.
def pick(self, list):
choice_list =
choose =
choice =
i = 0
while i <= len(list):
i += 1
try:
choose = int(input('''
Choose which die to keep by position 0-5
Type choice, then enter, repeat for all choices.
Press enter when finished
''',))
if choose >= len(list):
print("Choice not availablenGo ahead and try again.n")
else:
choice_list.append(choose)
except ValueError:
Idx = choice_list
choice = [list[i] for i in Idx]
if choice == None:
choice =
return choice

#one player turn.
def turn(self, player):
round_score = 0
list = self.throw()
print("n",player,", your dice in n 0 1 2 3 4 5n",list,"n")
throw_list =
throw_list.append(list)
choice = self.pick(throw_list[0])
print("Here are your choices",choice,"n")
score = self.keep_score(choice)
print("Your score for this throw is:",score,"n")
if score == 0:
round_score = 0
return round_score
else:
round_score += score
keepers_list =
keepers_list += choice
if len(keepers_list) == 6:
print("Six keepers! Roll 'em again!n")
keepers_list =
throw_list =
throw_count = -1
else:
throw_count = 0
again = input("Roll again or keep?nEnter = roll, K = keepn",)
if again is r"k":
self.total_score += round_score
if self.total_score < 500:
round_score = 0
print("Must score 500 to get on the board.n")
print("Your score this turn:",round_score,"n")
False
self.total_score = 0
return round_score
else:
print("Your score this turn:",round_score,"n")
print("Your total_score", self.total_score,"n")
False
return round_score
elif again != "q":
while True:
for i in range(0,4):
throw_count += 1
list = self.throw(keepers_list)
print("n",player,", your dice in n 0 1 2 3 4 5n"
,list,"n")
throw_list.append(list)
choice = self.pick(throw_list[throw_count])
print("Here are your choices:",choice,"n")
score = self.keep_score(choice)
print("Your score this throw is:",score,"n")
if score == 0:
round_score = 0
False
return round_score
else:
round_score += score
print("Turn score:",round_score,"n")
keepers_list += choice
if len(keepers_list) ==6:
print("Six keepers! Roll 'em again!n")
keepers_list =
throw_list =
throw_count = -1
again = (input(
'''
Roll again or keep?
Enter = roll K = keep''',))
if again == r"k":
self.total_score += round_score
if self.total_score < 500:
print("Must score 500 to get on the board. n")
print("Your score this turn:",round_score,"n")
False
self.total_score = 0
round_score = 0
return round_score
else:
print("Your score this turn:",round_score,"n")
print("Your total_score", self.total_score,"n")
False
return round_score
False
return round_score

def main():
while True:
Game.take_turns(Game, )

print(msg)
main()






share|improve this question













A fun little game for as many players as you have friends. This is my first Python project so any advice on how to improve is welcome and appreciated. I'm not concerned with the clunky interface as I'd like to use it for a touch screen device. Have fun playing!



msg = '''
Welcome to 10,000
The Game!
Game objective:
The objective of the game is to have the highest score.
Actually, it's to have fun!
It might take a minute to get used to playing, just relax,
take a few practice runs, and challenge some friends!
To score:
Pick 1's and 5's from the dice you've thrown.
1's are worth 100 points. 5's are worth 50 points.
You may also select any three or four of a kind.
Three of a kind scores the number on the die x 100.
Four of a kind scores double a three of a kind of the same number.
Three ones are worth 1000 points, four ones are worth 2000 points.
Choose any combination of the above. We'll call 'em 'keepers'.
Look carefully on your first roll! The following are worth a lot of
points!:
A Straight 1-6 (chosen in any order) is worth 1500 points.
A Full House (three pairs) is worth 1500 points.
[I'm really proud of the code for these^^ check it out!!]
Six of a kind scores 5000 points!!!
And you get to roll all six dice again!
To play:
For each turn you will start with six dice.
Your dice will appear in [brackets].
It's just old school. You'll be fine. Hang in there.
You must choose at least one keeper from each throw to continue your turn.
To choose a keeper, use the reference number (0-5) located above it.
WTF? Yeah, I know. You'll get used to it and it'll be fun. Trust me.
Enter the reference number and hit Enter.
Repeat until you have all the keepers you want selected.
Then, hit Enter again to submit your selections to scoring.
If all six dice are kept, in one or more turns, all six may be thrown again.
To get on the board you must have a turn worth 500 or more points.
If you would like to stop rolling and keep your score for the
turn, press k and Enter.
If you wish, press Enter and the remaining die will now be thrown again.
You will choose your keepers and whether to throw again in the
same way until...
Your turn ends because you keep your score or your roll has no keepers.
The game continues until one player's score is over 10,000.
The other players will then have one turn to better that player's score.*
The winner is the player with the highest total score!*
*[Not currently functional. I'm working on making sure the winner
actually does have the high score, any advice there, or on anything,
would be greatly appreciated!]
THANK YOU FOR PLAYING !!
Created by:
Paul Kutrich'''

import random
import collections

class Game:
def __init__(self, player_list, round_score = 0):
self.round_score = round_score
self.player_list = player_list

#sets number of players and player names.
def set_player(self, player_list = ):
players = int(input("Enter number of players:""n",))
x = 0
while x < players:
name = input("Enter your name:""n",)
self.name = name
self.name = Player(name)
player_list.append(self.name)
x += 1
return player_list

#checks for full house and returns score.
def full_house(self, choice):
pair_count = 0
score = 0
for i in range(0,3):
try:
if choice[0] == choice[1]:
pair_count += 1
del(choice[1], choice[0])
continue
if choice[0] == choice[2]:
pair_count += 1
del(choice[2], choice[0])
continue
if choice[0] == choice[3]:
pair_count += 1
del(choice[3], choice[0])
continue
if choice[0] == choice[4]:
pair_count += 1
del(choice[4], choice[0])
continue
if choice[0] == choice[5]:
pair_count += 1
del(choice[5], choice[0])
except IndexError:
pass
if pair_count == 3:
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
return score

#checks for straight and returns score.
def straight(self, choice):
score = 0
if len([(x,y) for x in choice for y in choice if x == y]) == 6:
score += 1500
print("You got a Straight!!n")
return score

#scores choices from Player.pick().
def keep_score(self, choice):
score = 0
if len(choice) == 6:
score += self.full_house(choice)
score += self.straight(choice)
return score
else:
valuedict = 1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000


try:
counts = collections.Counter(choice)
score = sum(valuedict[die][count] for die,count
in counts.items())
if score == 0:
print("No keepersnThat's a bummern")
return 0
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
return score

#sets winning score, updates total scores,
#switches between players until winning score met.
#this is essentially the game script.
def take_turns(self, player_list):
self.player_list = Game.set_player(Game, )
scores_list = [self.name.total_score for self.name in self.player_list
if self.name.total_score >= 10000]
while len(scores_list) == 0:
for x in range(0,len(self.player_list)):
self.player_list[x].turn(self.player_list[x].name)
scores_list = [self.name.total_score for self.name
in self.player_list if self.name.total_score >= 10000]
for x in range(0,len(self.player_list)):
print("n",self.player_list[x].name,"'s total score is"
,self.player_list[x].total_score,"n")
winner_list = [self.name for self.name in self.player_list
if self.name.total_score >=10000]
if len(winner_list) > 0:
winner_list.sort(key=lambda Player: self.name.total_score)
print("The winner is",winner_list[-1].name,"!! With a score of:"
,winner_list[-1].total_score,"n")
else:
print("The winner is",winner_list[0].name,"wins!! With a score of:"
,winner_list[0].total_score,"n")
return False

class Player(Game):
def __init__(self, name, total_score = 0):
self.total_score = total_score
self.name = name

#rolls six dice and puts rolls into a list. Returns list of dice.
def throw(self, throw_count):
dice = 5
list =
i = 0
while i <= dice - len(throw_count):
i +=1
list.append(random.randint(1,6))
return list

#takes user input to choose dice by index. Returns list of choices.
def pick(self, list):
choice_list =
choose =
choice =
i = 0
while i <= len(list):
i += 1
try:
choose = int(input('''
Choose which die to keep by position 0-5
Type choice, then enter, repeat for all choices.
Press enter when finished
''',))
if choose >= len(list):
print("Choice not availablenGo ahead and try again.n")
else:
choice_list.append(choose)
except ValueError:
Idx = choice_list
choice = [list[i] for i in Idx]
if choice == None:
choice =
return choice

#one player turn.
def turn(self, player):
round_score = 0
list = self.throw()
print("n",player,", your dice in n 0 1 2 3 4 5n",list,"n")
throw_list =
throw_list.append(list)
choice = self.pick(throw_list[0])
print("Here are your choices",choice,"n")
score = self.keep_score(choice)
print("Your score for this throw is:",score,"n")
if score == 0:
round_score = 0
return round_score
else:
round_score += score
keepers_list =
keepers_list += choice
if len(keepers_list) == 6:
print("Six keepers! Roll 'em again!n")
keepers_list =
throw_list =
throw_count = -1
else:
throw_count = 0
again = input("Roll again or keep?nEnter = roll, K = keepn",)
if again is r"k":
self.total_score += round_score
if self.total_score < 500:
round_score = 0
print("Must score 500 to get on the board.n")
print("Your score this turn:",round_score,"n")
False
self.total_score = 0
return round_score
else:
print("Your score this turn:",round_score,"n")
print("Your total_score", self.total_score,"n")
False
return round_score
elif again != "q":
while True:
for i in range(0,4):
throw_count += 1
list = self.throw(keepers_list)
print("n",player,", your dice in n 0 1 2 3 4 5n"
,list,"n")
throw_list.append(list)
choice = self.pick(throw_list[throw_count])
print("Here are your choices:",choice,"n")
score = self.keep_score(choice)
print("Your score this throw is:",score,"n")
if score == 0:
round_score = 0
False
return round_score
else:
round_score += score
print("Turn score:",round_score,"n")
keepers_list += choice
if len(keepers_list) ==6:
print("Six keepers! Roll 'em again!n")
keepers_list =
throw_list =
throw_count = -1
again = (input(
'''
Roll again or keep?
Enter = roll K = keep''',))
if again == r"k":
self.total_score += round_score
if self.total_score < 500:
print("Must score 500 to get on the board. n")
print("Your score this turn:",round_score,"n")
False
self.total_score = 0
round_score = 0
return round_score
else:
print("Your score this turn:",round_score,"n")
print("Your total_score", self.total_score,"n")
False
return round_score
False
return round_score

def main():
while True:
Game.take_turns(Game, )

print(msg)
main()








share|improve this question












share|improve this question




share|improve this question








edited Jan 16 at 0:42









Jamal♦

30.1k11114225




30.1k11114225









asked Jan 14 at 19:05









Paul K

1198




1198







  • 3




    Is this a duplicate of your previous question?
    – Peilonrayz
    Jan 14 at 20:11










  • I always thought that a full house was 3+2 instead of 2+2+2
    – Mathias Ettinger
    Jan 15 at 12:35










  • @MathiasEttinger It is in poker. This however doesn't seem to be poker.
    – Peilonrayz
    Jan 15 at 15:03










  • It really should be called something other than a full house. But it's traditionally called that, at least in these parts.
    – Paul K
    Jan 15 at 21:12










  • Huh. Not three pairs?
    – David K
    Jan 16 at 1:15












  • 3




    Is this a duplicate of your previous question?
    – Peilonrayz
    Jan 14 at 20:11










  • I always thought that a full house was 3+2 instead of 2+2+2
    – Mathias Ettinger
    Jan 15 at 12:35










  • @MathiasEttinger It is in poker. This however doesn't seem to be poker.
    – Peilonrayz
    Jan 15 at 15:03










  • It really should be called something other than a full house. But it's traditionally called that, at least in these parts.
    – Paul K
    Jan 15 at 21:12










  • Huh. Not three pairs?
    – David K
    Jan 16 at 1:15







3




3




Is this a duplicate of your previous question?
– Peilonrayz
Jan 14 at 20:11




Is this a duplicate of your previous question?
– Peilonrayz
Jan 14 at 20:11












I always thought that a full house was 3+2 instead of 2+2+2
– Mathias Ettinger
Jan 15 at 12:35




I always thought that a full house was 3+2 instead of 2+2+2
– Mathias Ettinger
Jan 15 at 12:35












@MathiasEttinger It is in poker. This however doesn't seem to be poker.
– Peilonrayz
Jan 15 at 15:03




@MathiasEttinger It is in poker. This however doesn't seem to be poker.
– Peilonrayz
Jan 15 at 15:03












It really should be called something other than a full house. But it's traditionally called that, at least in these parts.
– Paul K
Jan 15 at 21:12




It really should be called something other than a full house. But it's traditionally called that, at least in these parts.
– Paul K
Jan 15 at 21:12












Huh. Not three pairs?
– David K
Jan 16 at 1:15




Huh. Not three pairs?
– David K
Jan 16 at 1:15










1 Answer
1






active

oldest

votes

















up vote
3
down vote













  • You should move most of the functions out of the classes. Leaving as little as possible in each class.

  • You should have Player not inherit from Game. As a Player is not a child of Game.

  • You should change throw to take an amount to throw. And make it a simple comprehension.

  • You should make a select_range function that generates none to $N$ numbers, in the range zero to $N$. This is to help simplify pick.

  • You should change pick to only select choices, by iterating over select_range.

  • I'd change input_players to make, and store Player objects.


  • is_full_house should sort the choices, and check if the pairs are the same.


  • is_straight should sort and check that the choices are 1 to 6.


  • score can be simplified if you move valuedict out of the function.


  • You can drastically simplify take_turn, by merging all the loops into one.



    I also removed some other aspects, that seemed unneeded. Which overcomplicate the core of the function.




  • In take_turns you can reduce the while loop if you use any, rather than using a list comprehension.



    You can also use max, rather than sorting the list. Which can allow you to merge all your ifs together.



I don't fully get how you start the Game, and so I've left that out. But below is how I'd change the code:



import random
import collections

valuedict =
1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000




def throw(amount):
return [
random.randint(Game._DICE_MIN, Game._DICE_MAX)
for _ in range(amount)
]


def select_range(stop):
for _ in range(stop):
try:
while True:
choice = int(input())
if 0 <= choice < stop:
break
yield choice
except ValueError:
break


def pick(choices):
return [
choices[choice]
for choice in set(select_range(len(choices)))
]


def input_players():
players = int(input("Enter number of players:""n",))
player_list =
for _ in range(players):
name = input("Enter your name:""n",)
player_list.append(Player(name))
return player_list


def is_full_house(choices):
return len(choices) == 6 and all(a == b for a, b in zip(*[iter(sorted(choices))]*2))


def is_straight(choices):
return sorted(choices) == list(range(1, 7))


def score(choices):
score = 0
if len(choices) == 6:
if is_full_house(choices):
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
if is_straight(choices):
score += 1500
print("You got a Straight!!n")
else:
counts = collections.Counter(choice)
try:
score = sum(valuedict[die][count] for die, count
in counts.items())
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
else:
if score == 0:
print("No keepersnThat's a bummern")
return score


class Player:
def __init__(self, name):
self.name = name
self.score = 0

def take_turn(self):
total_score = 0
choices =
while True:
choices += throw(Game._DICE_MAX - len(choices))
print("nself.name, you rolledn 0 1 2 3 4 5n choices n")
choices = pick(choices)
print("Here are your choices choicesn")
score = score(choices)
if score == 0:
return 0

total_score += score
print("Your score this throw is: scoren")
if len(choices) == 6:
print("Six keepers! Roll 'em again!n")

again = input("Roll again or keep?nEnter = roll, K = keepn")
if again in "qk":
break
self.score += total_score


class Game:
_DICE_MIN = 1
_DICE_MAX = 6

def __init__(self, player_list, round_score=0):
self.round_score = round_score
self.player_list = player_list

@staticmethod
def take_turns(players):
while not any(player.score >= 10000 for player in players):
for player in players:
player.take_turn()
for player in players:
print("nplayer.name's score is player.score'")

winner = max(players, lambda player: player.score)
print("The winner is winner.name!! With a score of: winner.scoren")





share|improve this answer





















  • Thank you! I'm going to implement a lot of this! There are some tools here I wasn't aware of and simplifications I didn't think to try. I really appreciate you taking the time to answer!
    – Paul K
    Jan 16 at 19:54










  • Could you further explain your reasoning for moving functions out of classes and for Player not inheriting from Game. My understanding is that encapsulating is generally better. I have written a computer player (a very dumb one) that also inherits from Game and that seems useful.
    – Paul K
    Jan 17 at 19:30










  • @PaulK I find inheritance easier to understand if you think it's like taxonomic rank. A Felis silvestris catus (domestic cat) is a subclass of Felis silvestris (wildcat). This is as domestic cats have everything a wild cat does, but it changes some aspects - it's domesticated. However a person isn't a game, or a slightly changed one. Finally I moved the functions out of the class as name is easier to use than class.name. And means you don't have to wrap them all in static_methods.
    – Peilonrayz
    Jan 17 at 20:14










  • Ah, Okay. I was thinking along the lines of; a game has players. I see your point.
    – Paul K
    Jan 17 at 20:26






  • 1




    @PaulK that is actually a good point to lead towards is a vs has a relationships. Inheritance creates is a relationships (e. g. John is a Person, so John inherits from Person). Even where inheritance makes sense (with Player and Game it does not), has a relationships are often prefered, which is called composition (e. g. Game has Players, for example a list of them).
    – Raimund Krämer
    Jan 19 at 11:12










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185103%2ften-thousand-a-dice-game-for-multiple-players%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
3
down vote













  • You should move most of the functions out of the classes. Leaving as little as possible in each class.

  • You should have Player not inherit from Game. As a Player is not a child of Game.

  • You should change throw to take an amount to throw. And make it a simple comprehension.

  • You should make a select_range function that generates none to $N$ numbers, in the range zero to $N$. This is to help simplify pick.

  • You should change pick to only select choices, by iterating over select_range.

  • I'd change input_players to make, and store Player objects.


  • is_full_house should sort the choices, and check if the pairs are the same.


  • is_straight should sort and check that the choices are 1 to 6.


  • score can be simplified if you move valuedict out of the function.


  • You can drastically simplify take_turn, by merging all the loops into one.



    I also removed some other aspects, that seemed unneeded. Which overcomplicate the core of the function.




  • In take_turns you can reduce the while loop if you use any, rather than using a list comprehension.



    You can also use max, rather than sorting the list. Which can allow you to merge all your ifs together.



I don't fully get how you start the Game, and so I've left that out. But below is how I'd change the code:



import random
import collections

valuedict =
1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000




def throw(amount):
return [
random.randint(Game._DICE_MIN, Game._DICE_MAX)
for _ in range(amount)
]


def select_range(stop):
for _ in range(stop):
try:
while True:
choice = int(input())
if 0 <= choice < stop:
break
yield choice
except ValueError:
break


def pick(choices):
return [
choices[choice]
for choice in set(select_range(len(choices)))
]


def input_players():
players = int(input("Enter number of players:""n",))
player_list =
for _ in range(players):
name = input("Enter your name:""n",)
player_list.append(Player(name))
return player_list


def is_full_house(choices):
return len(choices) == 6 and all(a == b for a, b in zip(*[iter(sorted(choices))]*2))


def is_straight(choices):
return sorted(choices) == list(range(1, 7))


def score(choices):
score = 0
if len(choices) == 6:
if is_full_house(choices):
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
if is_straight(choices):
score += 1500
print("You got a Straight!!n")
else:
counts = collections.Counter(choice)
try:
score = sum(valuedict[die][count] for die, count
in counts.items())
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
else:
if score == 0:
print("No keepersnThat's a bummern")
return score


class Player:
def __init__(self, name):
self.name = name
self.score = 0

def take_turn(self):
total_score = 0
choices =
while True:
choices += throw(Game._DICE_MAX - len(choices))
print("nself.name, you rolledn 0 1 2 3 4 5n choices n")
choices = pick(choices)
print("Here are your choices choicesn")
score = score(choices)
if score == 0:
return 0

total_score += score
print("Your score this throw is: scoren")
if len(choices) == 6:
print("Six keepers! Roll 'em again!n")

again = input("Roll again or keep?nEnter = roll, K = keepn")
if again in "qk":
break
self.score += total_score


class Game:
_DICE_MIN = 1
_DICE_MAX = 6

def __init__(self, player_list, round_score=0):
self.round_score = round_score
self.player_list = player_list

@staticmethod
def take_turns(players):
while not any(player.score >= 10000 for player in players):
for player in players:
player.take_turn()
for player in players:
print("nplayer.name's score is player.score'")

winner = max(players, lambda player: player.score)
print("The winner is winner.name!! With a score of: winner.scoren")





share|improve this answer





















  • Thank you! I'm going to implement a lot of this! There are some tools here I wasn't aware of and simplifications I didn't think to try. I really appreciate you taking the time to answer!
    – Paul K
    Jan 16 at 19:54










  • Could you further explain your reasoning for moving functions out of classes and for Player not inheriting from Game. My understanding is that encapsulating is generally better. I have written a computer player (a very dumb one) that also inherits from Game and that seems useful.
    – Paul K
    Jan 17 at 19:30










  • @PaulK I find inheritance easier to understand if you think it's like taxonomic rank. A Felis silvestris catus (domestic cat) is a subclass of Felis silvestris (wildcat). This is as domestic cats have everything a wild cat does, but it changes some aspects - it's domesticated. However a person isn't a game, or a slightly changed one. Finally I moved the functions out of the class as name is easier to use than class.name. And means you don't have to wrap them all in static_methods.
    – Peilonrayz
    Jan 17 at 20:14










  • Ah, Okay. I was thinking along the lines of; a game has players. I see your point.
    – Paul K
    Jan 17 at 20:26






  • 1




    @PaulK that is actually a good point to lead towards is a vs has a relationships. Inheritance creates is a relationships (e. g. John is a Person, so John inherits from Person). Even where inheritance makes sense (with Player and Game it does not), has a relationships are often prefered, which is called composition (e. g. Game has Players, for example a list of them).
    – Raimund Krämer
    Jan 19 at 11:12














up vote
3
down vote













  • You should move most of the functions out of the classes. Leaving as little as possible in each class.

  • You should have Player not inherit from Game. As a Player is not a child of Game.

  • You should change throw to take an amount to throw. And make it a simple comprehension.

  • You should make a select_range function that generates none to $N$ numbers, in the range zero to $N$. This is to help simplify pick.

  • You should change pick to only select choices, by iterating over select_range.

  • I'd change input_players to make, and store Player objects.


  • is_full_house should sort the choices, and check if the pairs are the same.


  • is_straight should sort and check that the choices are 1 to 6.


  • score can be simplified if you move valuedict out of the function.


  • You can drastically simplify take_turn, by merging all the loops into one.



    I also removed some other aspects, that seemed unneeded. Which overcomplicate the core of the function.




  • In take_turns you can reduce the while loop if you use any, rather than using a list comprehension.



    You can also use max, rather than sorting the list. Which can allow you to merge all your ifs together.



I don't fully get how you start the Game, and so I've left that out. But below is how I'd change the code:



import random
import collections

valuedict =
1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000




def throw(amount):
return [
random.randint(Game._DICE_MIN, Game._DICE_MAX)
for _ in range(amount)
]


def select_range(stop):
for _ in range(stop):
try:
while True:
choice = int(input())
if 0 <= choice < stop:
break
yield choice
except ValueError:
break


def pick(choices):
return [
choices[choice]
for choice in set(select_range(len(choices)))
]


def input_players():
players = int(input("Enter number of players:""n",))
player_list =
for _ in range(players):
name = input("Enter your name:""n",)
player_list.append(Player(name))
return player_list


def is_full_house(choices):
return len(choices) == 6 and all(a == b for a, b in zip(*[iter(sorted(choices))]*2))


def is_straight(choices):
return sorted(choices) == list(range(1, 7))


def score(choices):
score = 0
if len(choices) == 6:
if is_full_house(choices):
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
if is_straight(choices):
score += 1500
print("You got a Straight!!n")
else:
counts = collections.Counter(choice)
try:
score = sum(valuedict[die][count] for die, count
in counts.items())
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
else:
if score == 0:
print("No keepersnThat's a bummern")
return score


class Player:
def __init__(self, name):
self.name = name
self.score = 0

def take_turn(self):
total_score = 0
choices =
while True:
choices += throw(Game._DICE_MAX - len(choices))
print("nself.name, you rolledn 0 1 2 3 4 5n choices n")
choices = pick(choices)
print("Here are your choices choicesn")
score = score(choices)
if score == 0:
return 0

total_score += score
print("Your score this throw is: scoren")
if len(choices) == 6:
print("Six keepers! Roll 'em again!n")

again = input("Roll again or keep?nEnter = roll, K = keepn")
if again in "qk":
break
self.score += total_score


class Game:
_DICE_MIN = 1
_DICE_MAX = 6

def __init__(self, player_list, round_score=0):
self.round_score = round_score
self.player_list = player_list

@staticmethod
def take_turns(players):
while not any(player.score >= 10000 for player in players):
for player in players:
player.take_turn()
for player in players:
print("nplayer.name's score is player.score'")

winner = max(players, lambda player: player.score)
print("The winner is winner.name!! With a score of: winner.scoren")





share|improve this answer





















  • Thank you! I'm going to implement a lot of this! There are some tools here I wasn't aware of and simplifications I didn't think to try. I really appreciate you taking the time to answer!
    – Paul K
    Jan 16 at 19:54










  • Could you further explain your reasoning for moving functions out of classes and for Player not inheriting from Game. My understanding is that encapsulating is generally better. I have written a computer player (a very dumb one) that also inherits from Game and that seems useful.
    – Paul K
    Jan 17 at 19:30










  • @PaulK I find inheritance easier to understand if you think it's like taxonomic rank. A Felis silvestris catus (domestic cat) is a subclass of Felis silvestris (wildcat). This is as domestic cats have everything a wild cat does, but it changes some aspects - it's domesticated. However a person isn't a game, or a slightly changed one. Finally I moved the functions out of the class as name is easier to use than class.name. And means you don't have to wrap them all in static_methods.
    – Peilonrayz
    Jan 17 at 20:14










  • Ah, Okay. I was thinking along the lines of; a game has players. I see your point.
    – Paul K
    Jan 17 at 20:26






  • 1




    @PaulK that is actually a good point to lead towards is a vs has a relationships. Inheritance creates is a relationships (e. g. John is a Person, so John inherits from Person). Even where inheritance makes sense (with Player and Game it does not), has a relationships are often prefered, which is called composition (e. g. Game has Players, for example a list of them).
    – Raimund Krämer
    Jan 19 at 11:12












up vote
3
down vote










up vote
3
down vote









  • You should move most of the functions out of the classes. Leaving as little as possible in each class.

  • You should have Player not inherit from Game. As a Player is not a child of Game.

  • You should change throw to take an amount to throw. And make it a simple comprehension.

  • You should make a select_range function that generates none to $N$ numbers, in the range zero to $N$. This is to help simplify pick.

  • You should change pick to only select choices, by iterating over select_range.

  • I'd change input_players to make, and store Player objects.


  • is_full_house should sort the choices, and check if the pairs are the same.


  • is_straight should sort and check that the choices are 1 to 6.


  • score can be simplified if you move valuedict out of the function.


  • You can drastically simplify take_turn, by merging all the loops into one.



    I also removed some other aspects, that seemed unneeded. Which overcomplicate the core of the function.




  • In take_turns you can reduce the while loop if you use any, rather than using a list comprehension.



    You can also use max, rather than sorting the list. Which can allow you to merge all your ifs together.



I don't fully get how you start the Game, and so I've left that out. But below is how I'd change the code:



import random
import collections

valuedict =
1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000




def throw(amount):
return [
random.randint(Game._DICE_MIN, Game._DICE_MAX)
for _ in range(amount)
]


def select_range(stop):
for _ in range(stop):
try:
while True:
choice = int(input())
if 0 <= choice < stop:
break
yield choice
except ValueError:
break


def pick(choices):
return [
choices[choice]
for choice in set(select_range(len(choices)))
]


def input_players():
players = int(input("Enter number of players:""n",))
player_list =
for _ in range(players):
name = input("Enter your name:""n",)
player_list.append(Player(name))
return player_list


def is_full_house(choices):
return len(choices) == 6 and all(a == b for a, b in zip(*[iter(sorted(choices))]*2))


def is_straight(choices):
return sorted(choices) == list(range(1, 7))


def score(choices):
score = 0
if len(choices) == 6:
if is_full_house(choices):
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
if is_straight(choices):
score += 1500
print("You got a Straight!!n")
else:
counts = collections.Counter(choice)
try:
score = sum(valuedict[die][count] for die, count
in counts.items())
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
else:
if score == 0:
print("No keepersnThat's a bummern")
return score


class Player:
def __init__(self, name):
self.name = name
self.score = 0

def take_turn(self):
total_score = 0
choices =
while True:
choices += throw(Game._DICE_MAX - len(choices))
print("nself.name, you rolledn 0 1 2 3 4 5n choices n")
choices = pick(choices)
print("Here are your choices choicesn")
score = score(choices)
if score == 0:
return 0

total_score += score
print("Your score this throw is: scoren")
if len(choices) == 6:
print("Six keepers! Roll 'em again!n")

again = input("Roll again or keep?nEnter = roll, K = keepn")
if again in "qk":
break
self.score += total_score


class Game:
_DICE_MIN = 1
_DICE_MAX = 6

def __init__(self, player_list, round_score=0):
self.round_score = round_score
self.player_list = player_list

@staticmethod
def take_turns(players):
while not any(player.score >= 10000 for player in players):
for player in players:
player.take_turn()
for player in players:
print("nplayer.name's score is player.score'")

winner = max(players, lambda player: player.score)
print("The winner is winner.name!! With a score of: winner.scoren")





share|improve this answer













  • You should move most of the functions out of the classes. Leaving as little as possible in each class.

  • You should have Player not inherit from Game. As a Player is not a child of Game.

  • You should change throw to take an amount to throw. And make it a simple comprehension.

  • You should make a select_range function that generates none to $N$ numbers, in the range zero to $N$. This is to help simplify pick.

  • You should change pick to only select choices, by iterating over select_range.

  • I'd change input_players to make, and store Player objects.


  • is_full_house should sort the choices, and check if the pairs are the same.


  • is_straight should sort and check that the choices are 1 to 6.


  • score can be simplified if you move valuedict out of the function.


  • You can drastically simplify take_turn, by merging all the loops into one.



    I also removed some other aspects, that seemed unneeded. Which overcomplicate the core of the function.




  • In take_turns you can reduce the while loop if you use any, rather than using a list comprehension.



    You can also use max, rather than sorting the list. Which can allow you to merge all your ifs together.



I don't fully get how you start the Game, and so I've left that out. But below is how I'd change the code:



import random
import collections

valuedict =
1:
1: 100,
2: 200,
3: 1000,
4: 2000,
6: 5000
,
2:
3: 200,
4: 400,
6: 5000
,
3:
3: 300,
4: 600,
6: 5000
,
4:
3: 400,
4: 800,
6: 5000
,
5:
1: 50,
2: 100,
3: 500,
4: 1000,
6: 5000
,
6:
3: 600,
4: 1200,
6: 5000




def throw(amount):
return [
random.randint(Game._DICE_MIN, Game._DICE_MAX)
for _ in range(amount)
]


def select_range(stop):
for _ in range(stop):
try:
while True:
choice = int(input())
if 0 <= choice < stop:
break
yield choice
except ValueError:
break


def pick(choices):
return [
choices[choice]
for choice in set(select_range(len(choices)))
]


def input_players():
players = int(input("Enter number of players:""n",))
player_list =
for _ in range(players):
name = input("Enter your name:""n",)
player_list.append(Player(name))
return player_list


def is_full_house(choices):
return len(choices) == 6 and all(a == b for a, b in zip(*[iter(sorted(choices))]*2))


def is_straight(choices):
return sorted(choices) == list(range(1, 7))


def score(choices):
score = 0
if len(choices) == 6:
if is_full_house(choices):
score += 1500
print("You got a Full House!!nSix keepers! Roll 'em again!n")
if is_straight(choices):
score += 1500
print("You got a Straight!!n")
else:
counts = collections.Counter(choice)
try:
score = sum(valuedict[die][count] for die, count
in counts.items())
except KeyError:
print("One of your choices was not a keeper.")
print("Try not cheating next time.nn")
else:
if score == 0:
print("No keepersnThat's a bummern")
return score


class Player:
def __init__(self, name):
self.name = name
self.score = 0

def take_turn(self):
total_score = 0
choices =
while True:
choices += throw(Game._DICE_MAX - len(choices))
print("nself.name, you rolledn 0 1 2 3 4 5n choices n")
choices = pick(choices)
print("Here are your choices choicesn")
score = score(choices)
if score == 0:
return 0

total_score += score
print("Your score this throw is: scoren")
if len(choices) == 6:
print("Six keepers! Roll 'em again!n")

again = input("Roll again or keep?nEnter = roll, K = keepn")
if again in "qk":
break
self.score += total_score


class Game:
_DICE_MIN = 1
_DICE_MAX = 6

def __init__(self, player_list, round_score=0):
self.round_score = round_score
self.player_list = player_list

@staticmethod
def take_turns(players):
while not any(player.score >= 10000 for player in players):
for player in players:
player.take_turn()
for player in players:
print("nplayer.name's score is player.score'")

winner = max(players, lambda player: player.score)
print("The winner is winner.name!! With a score of: winner.scoren")






share|improve this answer













share|improve this answer



share|improve this answer











answered Jan 16 at 0:39









Peilonrayz

24.4k336102




24.4k336102











  • Thank you! I'm going to implement a lot of this! There are some tools here I wasn't aware of and simplifications I didn't think to try. I really appreciate you taking the time to answer!
    – Paul K
    Jan 16 at 19:54










  • Could you further explain your reasoning for moving functions out of classes and for Player not inheriting from Game. My understanding is that encapsulating is generally better. I have written a computer player (a very dumb one) that also inherits from Game and that seems useful.
    – Paul K
    Jan 17 at 19:30










  • @PaulK I find inheritance easier to understand if you think it's like taxonomic rank. A Felis silvestris catus (domestic cat) is a subclass of Felis silvestris (wildcat). This is as domestic cats have everything a wild cat does, but it changes some aspects - it's domesticated. However a person isn't a game, or a slightly changed one. Finally I moved the functions out of the class as name is easier to use than class.name. And means you don't have to wrap them all in static_methods.
    – Peilonrayz
    Jan 17 at 20:14










  • Ah, Okay. I was thinking along the lines of; a game has players. I see your point.
    – Paul K
    Jan 17 at 20:26






  • 1




    @PaulK that is actually a good point to lead towards is a vs has a relationships. Inheritance creates is a relationships (e. g. John is a Person, so John inherits from Person). Even where inheritance makes sense (with Player and Game it does not), has a relationships are often prefered, which is called composition (e. g. Game has Players, for example a list of them).
    – Raimund Krämer
    Jan 19 at 11:12
















  • Thank you! I'm going to implement a lot of this! There are some tools here I wasn't aware of and simplifications I didn't think to try. I really appreciate you taking the time to answer!
    – Paul K
    Jan 16 at 19:54










  • Could you further explain your reasoning for moving functions out of classes and for Player not inheriting from Game. My understanding is that encapsulating is generally better. I have written a computer player (a very dumb one) that also inherits from Game and that seems useful.
    – Paul K
    Jan 17 at 19:30










  • @PaulK I find inheritance easier to understand if you think it's like taxonomic rank. A Felis silvestris catus (domestic cat) is a subclass of Felis silvestris (wildcat). This is as domestic cats have everything a wild cat does, but it changes some aspects - it's domesticated. However a person isn't a game, or a slightly changed one. Finally I moved the functions out of the class as name is easier to use than class.name. And means you don't have to wrap them all in static_methods.
    – Peilonrayz
    Jan 17 at 20:14










  • Ah, Okay. I was thinking along the lines of; a game has players. I see your point.
    – Paul K
    Jan 17 at 20:26






  • 1




    @PaulK that is actually a good point to lead towards is a vs has a relationships. Inheritance creates is a relationships (e. g. John is a Person, so John inherits from Person). Even where inheritance makes sense (with Player and Game it does not), has a relationships are often prefered, which is called composition (e. g. Game has Players, for example a list of them).
    – Raimund Krämer
    Jan 19 at 11:12















Thank you! I'm going to implement a lot of this! There are some tools here I wasn't aware of and simplifications I didn't think to try. I really appreciate you taking the time to answer!
– Paul K
Jan 16 at 19:54




Thank you! I'm going to implement a lot of this! There are some tools here I wasn't aware of and simplifications I didn't think to try. I really appreciate you taking the time to answer!
– Paul K
Jan 16 at 19:54












Could you further explain your reasoning for moving functions out of classes and for Player not inheriting from Game. My understanding is that encapsulating is generally better. I have written a computer player (a very dumb one) that also inherits from Game and that seems useful.
– Paul K
Jan 17 at 19:30




Could you further explain your reasoning for moving functions out of classes and for Player not inheriting from Game. My understanding is that encapsulating is generally better. I have written a computer player (a very dumb one) that also inherits from Game and that seems useful.
– Paul K
Jan 17 at 19:30












@PaulK I find inheritance easier to understand if you think it's like taxonomic rank. A Felis silvestris catus (domestic cat) is a subclass of Felis silvestris (wildcat). This is as domestic cats have everything a wild cat does, but it changes some aspects - it's domesticated. However a person isn't a game, or a slightly changed one. Finally I moved the functions out of the class as name is easier to use than class.name. And means you don't have to wrap them all in static_methods.
– Peilonrayz
Jan 17 at 20:14




@PaulK I find inheritance easier to understand if you think it's like taxonomic rank. A Felis silvestris catus (domestic cat) is a subclass of Felis silvestris (wildcat). This is as domestic cats have everything a wild cat does, but it changes some aspects - it's domesticated. However a person isn't a game, or a slightly changed one. Finally I moved the functions out of the class as name is easier to use than class.name. And means you don't have to wrap them all in static_methods.
– Peilonrayz
Jan 17 at 20:14












Ah, Okay. I was thinking along the lines of; a game has players. I see your point.
– Paul K
Jan 17 at 20:26




Ah, Okay. I was thinking along the lines of; a game has players. I see your point.
– Paul K
Jan 17 at 20:26




1




1




@PaulK that is actually a good point to lead towards is a vs has a relationships. Inheritance creates is a relationships (e. g. John is a Person, so John inherits from Person). Even where inheritance makes sense (with Player and Game it does not), has a relationships are often prefered, which is called composition (e. g. Game has Players, for example a list of them).
– Raimund Krämer
Jan 19 at 11:12




@PaulK that is actually a good point to lead towards is a vs has a relationships. Inheritance creates is a relationships (e. g. John is a Person, so John inherits from Person). Even where inheritance makes sense (with Player and Game it does not), has a relationships are often prefered, which is called composition (e. g. Game has Players, for example a list of them).
– Raimund Krämer
Jan 19 at 11:12












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185103%2ften-thousand-a-dice-game-for-multiple-players%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Chat program with C++ and SFML

Function to Return a JSON Like Objects Using VBA Collections and Arrays

Will my employers contract hold up in court?