Advertisement
Guest User

Ship Captain Crew

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