Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Ship Captain Crew
- #
- import sys
- import random
- # True: Will print unicode dice instead of numbers
- # False: Print numbers instead of unicode dice.
- use_unicode_dice = False
- # compatible user input regardless of version.
- if sys.version_info[0] == 3:
- raw_input = input
- use_unicode_dice = True
- # These are unicode representations of dice given their side.
- # FACE: 1 2 3 4 5 6
- unicode_faces = [None,"\u2680","\u2681","\u2682","\u2683","\u2684","\u2685"]
- #-------------------------------------------------------------------------------
- def get_unicode_dice(dice):
- """
- dice = list of numbers [1-6]
- Expect:
- Given provided dice, return the values in unicode.
- Return:
- List of unicode characters representing dice values.
- """
- faces = [int(die) for die in dice]
- return [unicode_faces[i] for i in faces]
- #-------------------------------------------------------------------------------
- def print_dice(dice):
- """
- dice = list of numbers [1-6]
- Expect:
- prints each die out in single line separated by 2 spaces.
- If use_unicode = True, then prints the unicode. Otherwise,
- print the numerical values.
- Return:
- None
- """
- faces = [str(die) for die in dice]
- if use_unicode_dice:
- faces = get_unicode_dice(dice)
- print(' '.join(faces))
- #-------------------------------------------------------------------------------
- def print_scoreboard(players):
- """
- players = list of player objects
- Expect:
- prints the score for all players received in alphabetical order by
- descending score. These results are padded with dots to allow for
- uniform output.
- Return:
- None
- """
- names_sorted = sorted(players, key=lambda n: n.name)
- scores_sorted = sorted(names_sorted, key=lambda s: s.score, reverse=True)
- text = []
- # " _____________________________________________________________ "
- text.append(" YE PLUNDERED BOOTY!")
- for i, s in enumerate(scores_sorted):
- text.append("%d. %s%d" % ((i+1), s.name.ljust(30, '.'), s.score))
- print_scroll(text)
- #===============================================================================
- # I honestly do not know why I'm keeping this around. Since python duck-typed,
- # it's not like I need it to group the states or anything. I suppose the biggest
- # strength it has right now is future extensions that *might* happen.
- class State(object):
- #---------------------------------------------------------------------------
- def status(self):
- print("You see %s" % self.name)
- #===============================================================================
- # This is our initial state of voyage. We roll 6 dice and attempt to transition
- # into other states based on the roll. The only direct transition available is
- # into Ship. No score here.
- class Deserted(State):
- def __init__(self, voyage):
- self.voyage = voyage
- self.total = 0
- self.name = "deserted waters"
- #---------------------------------------------------------------------------
- def roll_dice(self):
- dice = get_roll("5d6")
- return dice
- #---------------------------------------------------------------------------
- def update(self, dice):
- print_dice(dice)
- if 6 in dice:
- print("6 found!")
- dice.remove(6)
- self.voyage.state = self.voyage.ship
- self.voyage.state.update(dice)
- #===============================================================================
- # This state of voyage is achieved after we have been in Deserted state. In this
- # state, we roll 4 dice and can possibly modify state to Captain. No score here.
- class Ship(State):
- def __init__(self, voyage):
- self.voyage = voyage
- self.total = 0
- self.name = "a ship"
- #---------------------------------------------------------------------------
- def roll_dice(self):
- dice = get_roll("4d6")
- return dice
- #---------------------------------------------------------------------------
- def update(self, dice):
- print_dice(dice)
- if 5 in dice:
- print("5 found!")
- dice.remove(5)
- self.voyage.state = self.voyage.captain
- self.voyage.state.update(dice)
- #===============================================================================
- # This state of voyage is achieved after we have been in Ship state. In this
- # state, we roll 3 dice and can possibly modify state to Crew. No score here.
- class Captain(State):
- def __init__(self, voyage):
- self.voyage = voyage
- self.total = 0
- self.name = "a ship, and a captain"
- #---------------------------------------------------------------------------
- def roll_dice(self):
- dice = get_roll("3d6")
- return dice
- #---------------------------------------------------------------------------
- def update(self, dice):
- print_dice(dice)
- if 4 in dice:
- print("4 found!")
- dice.remove(4)
- self.voyage.state = self.voyage.crew
- self.voyage.state.update(dice)
- #===============================================================================
- # This state of voyage is achieved after we have been in Captain state. In this
- # state, we roll only 2 dice and we apply total from these dice.
- class Crew(State):
- def __init__(self, voyage):
- self.voyage = voyage
- self.total = 0
- self.name = "a ship, and a captain, and a crew"
- #---------------------------------------------------------------------------
- def roll_dice(self):
- dice = get_roll("2d6")
- return dice
- #---------------------------------------------------------------------------
- def update(self, dice):
- print_dice(dice)
- self.total = sum(dice)
- print("Your score is: %d" % self.total)
- #===============================================================================
- # This represents a full turn cycle for a player. This is the top level of our
- # state machine. The following states are entered:
- # - Deserted = Before Ship
- # - Ship = After Deserted -- Before Captain
- # - Captain = After Ship -- Before Crew
- # - Crew = After Captain -- End State (scoring mechanics)
- class Voyage(object):
- def __init__(self):
- self.deserted = Deserted(self)
- self.ship = Ship(self)
- self.captain = Captain(self)
- self.crew = Crew(self)
- self.state = self.deserted
- # The number of rolls permitted apparently is unchangable.
- # TODO: modify to list as words [First, Second, Third]
- self.turns = 3
- #---------------------------------------------------------------------------
- # It might make more sense to pass the player into this so we don't have
- # to return the total and instead increment it right here.
- # TODO: pass in player instead.
- def play2(self):
- print("="*40)
- for turn in range(self.turns):
- dice = self.state.roll_dice()
- self.state.update(dice)
- self.state.status()
- if self.state == self.crew:
- choice = raw_input("Keep score? [Y/N]: ")
- if choice.lower() in ['y','yes']:
- print("you keep %d points" % self.state.total)
- break
- print("That was turn %d" % turn)
- return self.state.total
- def play(self, player):
- print("="*40)
- print("%s is scouting" % player.name)
- for turn in range(self.turns):
- dice = self.state.roll_dice()
- self.state.update(dice)
- self.state.status()
- if self.state == self.crew:
- choice = raw_input("Keep score? [Y/N]: ")
- if choice.lower() in ['y','yes']:
- print("you keep %d points" % self.state.total)
- break
- print("That was turn %d" % turn)
- player.score += self.state.total
- #===============================================================================
- # While thin, the player object does make sense because we keep track of a
- # score specific to a player.
- class Player(object):
- def __init__(self, name):
- self.name = name
- self.score = 0
- #---------------------------------------------------------------------------
- def set_sail(self):
- v = Voyage()
- v.play(self)
- #self.score += v.play()
- #---------------------------------------------------------------------------
- def status(self):
- print("%s has %d points." % (self.name, self.score))
- #===============================================================================
- #-------------------------------------------------------------------------------
- def get_roll(asking):
- """
- We receive a string formated as xdy
- x = quantity of dice
- y = sides of dice
- d = separator
- """
- quantity, sides = asking.lower().split('d')
- dice = [random.randint(1, int(sides)) for i in range(int(quantity))]
- return dice
- #-------------------------------------------------------------------------------
- def get_roster():
- names = raw_input("Enter players separated by comma: ")
- return tuple(names.strip().split(','))
- #-------------------------------------------------------------------------------
- def print_scroll(text):
- print(" _____________________________________________________________ ")
- print("o=(_____________________________________________________________)=o")
- for line in text:
- print(" | %s|" % (line.ljust(58)))
- print(" |___________________________________________________________|")
- print("o=(_____________________________________________________________)=o")
- #-------------------------------------------------------------------------------
- def show_instructions():
- instructions = [
- " ----=== SHIP CAPTAIN CREW ===----",
- "The Voyage:",
- "A voyage consists of 3 rolls of the dice. Depending on ",
- "what you have acquired, you may be rolling 5, 4, 3, or ",
- "2 dice. To acquire your needed provisions, you must roll",
- "the numbers in correct order.",
- "",
- "Ship = 6 from 5 dice",
- "Captain = 5 from 4 dice but only with ship",
- "Crew = 4 from 3 dice but only with ship and captain",
- "",
- "A single roll may yield multiple provisions but they",
- "cannot be out of order. For example, if the roll is:",
- " 5 4 3 2 1",
- "you still do not have a ship because no six came up.",
- "Without a ship, there's no captain. Without a captain",
- "there's no crew. Without crew, there's no plunder!",
- "",
- "Scoring:",
- "Once you have a ship, a captain, and a crew, the other",
- "two dice are added together to give you your spoils. If",
- "you do not like what you've gathered, you may roll again",
- "if you have rolls to spare.",
- "",
- "Winning:",
- "The player with the highest score after all voyages have",
- "been played through is the winner.",
- "",
- "Savvy?",
- ]
- print_scroll(instructions)
- #-------------------------------------------------------------------------------
- def pre_game():
- """
- We find out whether or not the players need instruction on the game.
- If so, print the instructions. If not, return out.
- If a valid choice is entered, assume instruction is needed.
- """
- print("Har mate! So, ye want to amass vast treasures? Might ye be")
- print("wanting to know how? Or are you salty enough?")
- print("1. Teach me!")
- print("2. Back off dog! I know what I'm doing!")
- choice = raw_input("Choose ye fate: ")
- if choice not in ['2']:
- show_instructions()
- raw_input("[press enter when ready to play]")
- voyages = raw_input("Ahoy! And how many trips ye be takin'?")
- try:
- return int(voyages)
- except:
- return 5
- #-------------------------------------------------------------------------------
- def main():
- voyages = pre_game()
- names = get_roster()
- players = [Player(name) for name in names]
- print_scoreboard(players)
- for voyage in range(voyages):
- print("............VOYAGE %d/%d................" % (voyage+1,voyages))
- for player in players:
- player.set_sail()
- player.status()
- raw_input("waiting...")
- print_scoreboard(players)
- # Don't currently have a winner code. You just use your eyes when playing.
- # TODO: Add winner code...
- #-------------------------------------------------------------------------------
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement