Advertisement
Guest User

Ship Captain Crew

a guest
Mar 23rd, 2014
509
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Ship Captain Crew
  2. #
  3.  
  4.  
  5.  
  6. import sys
  7. import random
  8.  
  9. # True: Will print unicode dice instead of numbers
  10. # False: Print numbers instead of unicode dice.
  11. use_unicode_dice = False
  12.  
  13. # compatible user input regardless of version.
  14. if sys.version_info[0] == 3:
  15.     raw_input = input
  16.     use_unicode_dice = True
  17.  
  18. # These are unicode representations of dice given their side.
  19. # FACE:               1        2        3        4        5        6
  20. unicode_faces = [None,"\u2680","\u2681","\u2682","\u2683","\u2684","\u2685"]
  21.  
  22. #-------------------------------------------------------------------------------
  23. def get_unicode_dice(dice):
  24.     """
  25.    dice = list of numbers [1-6]
  26.    
  27.    Expect:
  28.        Given provided dice, return the values in unicode.
  29.    
  30.    Return:
  31.        List of unicode characters representing dice values.
  32.    """
  33.     faces = [int(die) for die in dice]
  34.     return [unicode_faces[i] for i in faces]
  35.  
  36. #-------------------------------------------------------------------------------
  37. def print_dice(dice):
  38.     """
  39.    dice = list of numbers [1-6]
  40.    
  41.    Expect:
  42.        prints each die out in single line separated by 2 spaces.
  43.        If use_unicode = True, then prints the unicode. Otherwise,
  44.        print the numerical values.
  45.        
  46.    Return:
  47.        None
  48.    """
  49.     faces = [str(die) for die in dice]
  50.    
  51.     if use_unicode_dice:
  52.         faces = get_unicode_dice(dice)
  53.        
  54.     print('  '.join(faces))
  55.  
  56. #-------------------------------------------------------------------------------
  57. def print_scoreboard(players):
  58.     """
  59.    players = list of player objects
  60.    
  61.    Expect:
  62.        prints the score for all players received in alphabetical order by
  63.        descending score. These results are padded with dots to allow for
  64.        uniform output.
  65.        
  66.    Return:
  67.        None
  68.    """
  69.     names_sorted = sorted(players, key=lambda n: n.name)
  70.     scores_sorted = sorted(names_sorted, key=lambda s: s.score, reverse=True)
  71.    
  72.     text = []
  73.     #           "   _____________________________________________________________ "
  74.     text.append("                      YE PLUNDERED BOOTY!")
  75.    
  76.     for i, s in enumerate(scores_sorted):
  77.         text.append("%d. %s%d" % ((i+1), s.name.ljust(30, '.'), s.score))
  78.        
  79.     print_scroll(text)
  80.    
  81. #===============================================================================
  82. # I honestly do not know why I'm keeping this around. Since python duck-typed,
  83. # it's not like I need it to group the states or anything. I suppose the biggest
  84. # strength it has right now is future extensions that *might* happen.
  85. class State(object):
  86.    
  87.     #---------------------------------------------------------------------------
  88.     def status(self):
  89.         print("You see %s" % self.name)
  90.  
  91. #===============================================================================
  92. # This is our initial state of voyage. We roll 6 dice and attempt to transition
  93. # into other states based on the roll. The only direct transition available is
  94. # into Ship. No score here.
  95. class Deserted(State):
  96.     def __init__(self, voyage):
  97.         self.voyage = voyage
  98.         self.total  = 0
  99.         self.name   = "deserted waters"
  100.    
  101.     #---------------------------------------------------------------------------
  102.     def roll_dice(self):
  103.         dice = get_roll("5d6")
  104.         return dice
  105.    
  106.     #---------------------------------------------------------------------------
  107.     def update(self, dice):
  108.         print_dice(dice)
  109.         if 6 in dice:
  110.             print("6 found!")
  111.             dice.remove(6)
  112.             self.voyage.state = self.voyage.ship
  113.             self.voyage.state.update(dice)
  114.  
  115. #===============================================================================
  116. # This state of voyage is achieved after we have been in Deserted state. In this
  117. # state, we roll 4 dice and can possibly modify state to Captain. No score here.
  118. class Ship(State):
  119.     def __init__(self, voyage):
  120.         self.voyage = voyage
  121.         self.total  = 0
  122.         self.name   = "a ship"
  123.    
  124.     #---------------------------------------------------------------------------
  125.     def roll_dice(self):
  126.         dice = get_roll("4d6")
  127.         return dice
  128.    
  129.     #---------------------------------------------------------------------------
  130.     def update(self, dice):
  131.         print_dice(dice)
  132.         if 5 in dice:
  133.             print("5 found!")
  134.             dice.remove(5)
  135.             self.voyage.state = self.voyage.captain
  136.             self.voyage.state.update(dice)
  137.    
  138. #===============================================================================
  139. # This state of voyage is achieved after we have been in Ship state. In this
  140. # state, we roll 3 dice and can possibly modify state to Crew. No score here.
  141. class Captain(State):
  142.     def __init__(self, voyage):
  143.         self.voyage = voyage
  144.         self.total  = 0
  145.         self.name   = "a ship, and a captain"
  146.    
  147.     #---------------------------------------------------------------------------
  148.     def roll_dice(self):
  149.         dice = get_roll("3d6")
  150.         return dice
  151.    
  152.     #---------------------------------------------------------------------------
  153.     def update(self, dice):
  154.         print_dice(dice)
  155.         if 4 in dice:
  156.             print("4 found!")
  157.             dice.remove(4)
  158.             self.voyage.state = self.voyage.crew
  159.             self.voyage.state.update(dice)
  160.            
  161. #===============================================================================
  162. # This state of voyage is achieved after we have been in Captain state. In this
  163. # state, we roll only 2 dice and we apply total from these dice.
  164. class Crew(State):
  165.     def __init__(self, voyage):
  166.         self.voyage = voyage
  167.         self.total  = 0
  168.         self.name   = "a ship, and a captain, and a crew"
  169.    
  170.     #---------------------------------------------------------------------------
  171.     def roll_dice(self):
  172.         dice = get_roll("2d6")
  173.         return dice
  174.    
  175.     #---------------------------------------------------------------------------
  176.     def update(self, dice):
  177.         print_dice(dice)
  178.         self.total = sum(dice)
  179.         print("Your score is: %d" % self.total)
  180.    
  181. #===============================================================================
  182. # This represents a full turn cycle for a player. This is the top level of our
  183. # state machine. The following states are entered:
  184. #  - Deserted = Before Ship
  185. #  - Ship     = After Deserted -- Before Captain
  186. #  - Captain  = After Ship -- Before Crew
  187. #  - Crew     = After Captain -- End State (scoring mechanics)
  188. class Voyage(object):
  189.    
  190.     def __init__(self):
  191.         self.deserted = Deserted(self)
  192.         self.ship     = Ship(self)
  193.         self.captain  = Captain(self)
  194.         self.crew     = Crew(self)
  195.        
  196.         self.state    = self.deserted
  197.        
  198.         # The number of rolls permitted apparently is unchangable.
  199.         # TODO: modify to list as words [First, Second, Third]
  200.         self.turns    = 3
  201.    
  202.     #---------------------------------------------------------------------------
  203.     # It might make more sense to pass the player into this so we don't have
  204.     # to return the total and instead increment it right here.
  205.     # TODO: pass in player instead.
  206.     def play2(self):
  207.         print("="*40)
  208.         for turn in range(self.turns):
  209.             dice = self.state.roll_dice()
  210.             self.state.update(dice)
  211.             self.state.status()
  212.             if self.state == self.crew:
  213.                 choice = raw_input("Keep score? [Y/N]: ")
  214.                 if choice.lower() in ['y','yes']:
  215.                     print("you keep %d points" % self.state.total)
  216.                     break
  217.             print("That was turn %d" % turn)
  218.         return self.state.total
  219.        
  220.     def play(self, player):
  221.         print("="*40)
  222.         print("%s is scouting" % player.name)
  223.         for turn in range(self.turns):
  224.             dice = self.state.roll_dice()
  225.             self.state.update(dice)
  226.             self.state.status()
  227.             if self.state == self.crew:
  228.                 choice = raw_input("Keep score? [Y/N]: ")
  229.                 if choice.lower() in ['y','yes']:
  230.                     print("you keep %d points" % self.state.total)
  231.                     break
  232.             print("That was turn %d" % turn)
  233.            
  234.         player.score += self.state.total
  235.  
  236. #===============================================================================
  237. # While thin, the player object does make sense because we keep track of a
  238. # score specific to a player.
  239. class Player(object):
  240.     def __init__(self, name):
  241.         self.name = name
  242.         self.score = 0
  243.    
  244.     #---------------------------------------------------------------------------
  245.     def set_sail(self):
  246.         v = Voyage()
  247.         v.play(self)
  248.         #self.score += v.play()
  249.    
  250.     #---------------------------------------------------------------------------
  251.     def status(self):
  252.         print("%s has %d points." % (self.name, self.score))
  253. #===============================================================================
  254.  
  255. #-------------------------------------------------------------------------------
  256. def get_roll(asking):
  257.     """
  258.    We receive a string formated as xdy
  259.    x = quantity of dice
  260.    y = sides of dice
  261.    d = separator
  262.    """
  263.     quantity, sides = asking.lower().split('d')
  264.     dice = [random.randint(1, int(sides)) for i in range(int(quantity))]
  265.     return dice
  266.  
  267. #-------------------------------------------------------------------------------
  268. def get_roster():
  269.     names = raw_input("Enter players separated by comma: ")
  270.     return tuple(names.strip().split(','))
  271.  
  272. #-------------------------------------------------------------------------------
  273. def print_scroll(text):
  274.     print("   _____________________________________________________________ ")
  275.     print("o=(_____________________________________________________________)=o")
  276.    
  277.     for line in text:
  278.         print("   | %s|" % (line.ljust(58)))
  279.        
  280.     print("   |___________________________________________________________|")
  281.     print("o=(_____________________________________________________________)=o")
  282.  
  283. #-------------------------------------------------------------------------------
  284. def show_instructions():
  285.     instructions = [
  286.         "            ----=== SHIP CAPTAIN CREW ===----",
  287.         "The Voyage:",
  288.         "A voyage consists of 3 rolls of the dice. Depending on ",
  289.         "what you have acquired, you may be rolling 5, 4, 3, or ",
  290.         "2 dice. To acquire your needed provisions, you must roll",
  291.         "the numbers in correct order.",
  292.         "",
  293.         "Ship    = 6 from 5 dice",
  294.         "Captain = 5 from 4 dice but only with ship",
  295.         "Crew    = 4 from 3 dice but only with ship and captain",
  296.         "",
  297.         "A single roll may yield multiple provisions but they",
  298.         "cannot be out of order. For example, if the roll is:",
  299.         "                  5  4  3  2  1",
  300.         "you still do not have a ship because no six came up.",
  301.         "Without a ship, there's no captain. Without a captain",
  302.         "there's no crew. Without crew, there's no plunder!",
  303.         "",
  304.         "Scoring:",
  305.         "Once you have a ship, a captain, and a crew, the other",
  306.         "two dice are added together to give you your spoils. If",
  307.         "you do not like what you've gathered, you may roll again",
  308.         "if you have rolls to spare.",
  309.         "",
  310.         "Winning:",
  311.         "The player with the highest score after all voyages have",
  312.         "been played through is the winner.",
  313.         "",
  314.         "Savvy?",
  315.     ]
  316.    
  317.     print_scroll(instructions)
  318.  
  319. #-------------------------------------------------------------------------------
  320. def pre_game():
  321.     """
  322.    We find out whether or not the players need instruction on the game.
  323.    If so, print the instructions. If not, return out.
  324.    If a valid choice is entered, assume instruction is needed.
  325.    """
  326.     print("Har mate! So, ye want to amass vast treasures? Might ye be")
  327.     print("wanting to know how? Or are you salty enough?")
  328.     print("1. Teach me!")
  329.     print("2. Back off dog! I know what I'm doing!")
  330.     choice = raw_input("Choose ye fate: ")
  331.    
  332.     if choice not in ['2']:
  333.         show_instructions()
  334.         raw_input("[press enter when ready to play]")
  335.        
  336.     voyages = raw_input("Ahoy! And how many trips ye be takin'?")
  337.     try:
  338.         return int(voyages)
  339.     except:
  340.         return 5
  341.  
  342. #-------------------------------------------------------------------------------        
  343. def main():
  344.     voyages = pre_game()
  345.    
  346.     names = get_roster()
  347.     players = [Player(name) for name in names]
  348.     print_scoreboard(players)
  349.    
  350.     for voyage in range(voyages):
  351.         print("............VOYAGE %d/%d................" % (voyage+1,voyages))
  352.         for player in players:
  353.             player.set_sail()
  354.             player.status()
  355.             raw_input("waiting...")
  356.  
  357.         print_scoreboard(players)
  358.        
  359.     # Don't currently have a winner code. You just use your eyes when playing.
  360.     # TODO: Add winner code...
  361.  
  362. #-------------------------------------------------------------------------------
  363. if __name__ == '__main__':
  364.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement