#! /usr/bin/env python3 import sys # for system function, like exit() import random # for generating random numbers ### global variables for storing player's status player_funds = 0 # no money player_furs = [ 0, 0, 0, 0 ] # no furs ### Constants FUR_MINK = 0 FUR_BEAVER = 1 FUR_ERMINE = 2 FUR_FOX = 3 MAX_FURS = 190 FUR_NAMES = [ "MINK", "BEAVER", "ERMINE", "FOX" ] FORT_MONTREAL = 1 FORT_QUEBEC = 2 FORT_NEWYORK = 3 FORT_NAMES = [ "HOCHELAGA (MONTREAL)", "STADACONA (QUEBEC)", "NEW YORK" ] def printAtColumn( column:int, words:str ): """ Print the words at the specified column """ spaces = ' ' * column # make a fat string of spaces print( spaces + words ) def showIntroduction(): """ Show the player the introductory message """ print( "YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN " ) print( "1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET" ) print( "SUPPLIES FOR THE NEXT YEAR. YOU HAVE A CHOICE OF THREE" ) print( "FORTS AT WHICH YOU MAY TRADE. THE COST OF SUPPLIES" ) print( "AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND" ) print( "ON THE FORT THAT YOU CHOOSE." ) print( "" ) def getFortChoice(): """ Show the player the choices of Fort, get their input, if the input is a valid choice (1,2,3) return it, otherwise keep prompting the user. """ result = 0 while ( result == 0 ): print( "" ) print( "YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2," ) print( "OR FORT 3. FORT 1 IS FORT HOCHELAGA (MONTREAL)" ) print( "AND IS UNDER THE PROTECTION OF THE FRENCH ARMY." ) print( "FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE" ) print( "PROTECTION OF THE FRENCH ARMY. HOWEVER, YOU MUST" ) print( "MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS." ) print( "FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL." ) print( "YOU MUST CROSS THROUGH IROQUOIS LAND." ) print( "ANSWER 1, 2, OR 3." ) player_choice = input( ">> " ) # get input from the player # try to convert the player's string input into an integer try: result = int( player_choice ) # string to integer except: # Whatever the player typed, it could not be interpreted as a number pass return result def showFortComment( which_fort ): """ Print the description for the fort """ print( "" ) if ( which_fort == FORT_MONTREAL ): print( "YOU HAVE CHOSEN THE EASIEST ROUTE. HOWEVER, THE FORT" ) print( "IS FAR FROM ANY SEAPORT. THE VALUE" ) print( "YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST" ) print( "OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK." ) elif ( which_fort == FORT_QUEBEC ): print( "YOU HAVE CHOSEN A HARD ROUTE. IT IS, IN COMPARSION," ) print( "HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN" ) print( "THE ROUTE TO NEW YORK. YOU WILL RECEIVE AN AVERAGE VALUE" ) print( "FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE." ) elif ( which_fort == FORT_NEWYORK ): print( "YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE. AT" ) print( "FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE" ) print( "FOR YOUR FURS. THE COST OF YOUR SUPPLIES" ) print( "WILL BE LOWER THAN AT ALL THE OTHER FORTS." ) else: print( "Internal error #1, fort " + str( which_fort ) + " does not exist" ) sys.exit( 1 ) # you have a bug print( "" ) def getYesOrNo(): """ Prompt the player to enter 'YES' or 'NO'. Keep prompting until valid input is entered. Accept various spellings by only checking the first letter of input. Return a single letter 'Y' or 'N' """ result = 0 while ( result not in ( 'Y', 'N' ) ): print( "ANSWER YES OR NO" ) player_choice = input( ">> " ) player_choice = player_choice.strip().upper() # trim spaces, make upper-case if ( player_choice.startswith( 'Y' ) ): result = 'Y' elif ( player_choice.startswith( 'N' ) ): result = 'N' return result def getFursPurchase(): """ Prompt the player for how many of each fur type they want. Accept numeric inputs, re-prompting on incorrect input values """ results = [] print( "YOUR " + str( MAX_FURS ) + " FURS ARE DISTRIBUTED AMONG THE FOLLOWING" ) print( "KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX." ) print( "" ) for i in ( range( len( FUR_NAMES ) ) ): print( "HOW MANY " + FUR_NAMES[i] + " DO YOU HAVE" ) count_str = input( ">> " ) try: count = int( count_str ) results.append( count ) except: # invalid input, prompt again by re-looping i -= 1 return results ### ### MAIN ### if ( __name__ == '__main__' ): printAtColumn( 31, "FUR TRADER" ) printAtColumn( 15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" ) printAtColumn( 15, "(Ported to Python Oct 2012 krt@krt.com.au)" ) print( "\n\n\n" ) game_state = 'starting' fox_price = None # sometimes this takes the "last" price (probably this was a bug) while ( True ): if ( game_state == 'starting' ): showIntroduction() player_funds = 600 # Initial player start money player_furs = [ 0, 0, 0, 0 ] # Player fur inventory print( "DO YOU WISH TO TRADE FURS?" ) should_trade = getYesOrNo() if ( should_trade == 'N' ): sys.exit( 0 ) # STOP game_state = 'trading' elif ( game_state == 'trading' ): print( "" ) print( "YOU HAVE $ %1.2f IN SAVINGS" % ( player_funds ) ) print( "AND " + str( MAX_FURS ) + " FURS TO BEGIN THE EXPEDITION" ) player_furs = getFursPurchase() if ( sum( player_furs ) > MAX_FURS ): print( "" ) print( "YOU MAY NOT HAVE THAT MANY FURS." ) print( "DO NOT TRY TO CHEAT. I CAN ADD." ) print( "YOU MUST START AGAIN." ) game_state = 'starting' # T/N: Wow, harsh. else: game_state = 'choosing fort' elif ( game_state == 'choosing fort' ): which_fort = getFortChoice() showFortComment( which_fort ) print( "DO YOU WANT TO TRADE AT ANOTHER FORT?" ) change_fort = getYesOrNo() if ( change_fort == 'N' ): game_state = 'travelling' elif ( game_state == 'travelling' ): print( "" ) if ( which_fort == FORT_MONTREAL ): mink_price = int( ( 0.2 * random.random() + 0.70 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.7)*10^2+.5)/10^2 ermine_price = int( ( 0.2 * random.random() + 0.65 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.65)*10^2+.5)/10^2 beaver_price = int( ( 0.2 * random.random() + 0.75 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.75)*10^2+.5)/10^2 fox_price = int( ( 0.2 * random.random() + 0.80 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.8)*10^2+.5)/10^2 print( "SUPPLIES AT FORT HOCHELAGA COST $150.00." ) print( "YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00." ) player_funds -= 160 elif ( which_fort == FORT_QUEBEC ): mink_price = int( ( 0.30 * random.random() + 0.85 ) * 100 + 0.5 ) / 100 #INT((.3*RND(1)+.85)*10^2+.5)/10^2 ermine_price = int( ( 0.15 * random.random() + 0.80 ) * 100 + 0.5 ) / 100 #INT((.15*RND(1)+.8)*10^2+.5)/10^2 beaver_price = int( ( 0.20 * random.random() + 0.90 ) * 100 + 0.5 ) / 100 #INT((.2*RND(1)+.9)*10^2+.5)/10^2 fox_price = int( ( 0.25 * random.random() + 1.10 ) * 100 + 0.5 ) / 100 #INT((.25*RND(1)+1.1)*10^2+.5)/10^2 event_picker = int( 10 * random.random() ) + 1 if ( event_picker <= 2 ): print( "YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS" ) print( "THE PORTAGE. YOU HAD TO LEAVE THE PELTS, BUT FOUND" ) print( "THEM STOLEN WHEN YOU RETURNED." ) player_furs[ FUR_BEAVER ] = 0 elif ( event_picker <= 6 ): print( "YOU ARRIVED SAFELY AT FORT STADACONA." ) elif ( event_picker <= 8 ): print( "YOUR CANOE UPSET IN THE LACHINE RAPIDS. YOU" ) print( "LOST ALL YOUR FURS." ) player_furs = [ 0, 0, 0, 0 ] elif ( event_picker <= 10 ): print( "YOUR FOX PELTS WERE NOT CURED PROPERLY." ) print( "NO ONE WILL BUY THEM." ) player_furs[ FUR_FOX ] = 0 else: print( "Internal Error #3, Out-of-bounds event_picker" + str( event_picker ) ) sys.exit( 1 ) # you have a bug print( "" ) print( "SUPPLIES AT FORT STADACONA COST $125.00." ) print( "YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00." ) player_funds -= 140 elif ( which_fort == FORT_NEWYORK ): mink_price = int( ( 0.15 * random.random() + 1.05 ) * 100 + 0.5 ) / 100 #INT((.15*RND(1)+1.05)*10^2+.5)/10^2 ermine_price = int( ( 0.15 * random.random() + 0.95 ) * 100 + 0.5 ) / 100 #INT((.15*RND(1)+.95)*10^2+.5)/10^2 beaver_price = int( ( 0.25 * random.random() + 1.00 ) * 100 + 0.5 ) / 100 #INT((.25*RND(1)+1.00)*10^2+.5)/10^2 if ( fox_price == None ): # Original Bug? There is no Fox price generated for New York, it will use any previous "D1" price # So if there was no previous value, make one up fox_price = int( ( 0.25 * random.random() + 1.05 ) * 100 + 0.5 ) / 100 # not in orginal code event_picker = int( 10 * random.random() ) + 1 if ( event_picker <= 2 ): print( "YOU WERE ATTACKED BY A PARTY OF IROQUOIS." ) print( "ALL PEOPLE IN YOUR TRADING GROUP WERE" ) print( "KILLED. THIS ENDS THE GAME." ) sys.exit( 0 ) elif ( event_picker <= 6 ): print( "YOU WERE LUCKY. YOU ARRIVED SAFELY" ) print( "AT FORT NEW YORK." ) elif ( event_picker <= 8 ): print( "YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY." ) print( "HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND." ) player_furs = [ 0, 0, 0, 0 ] elif ( event_picker <= 10 ): mink_price /= 2 fox_price /= 2 print( "YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP." ) print( "YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS." ) else: print( "Internal Error #4, Out-of-bounds event_picker" + str( event_picker ) ) sys.exit( 1 ) # you have a bug print( "" ) print( "SUPPLIES AT NEW YORK COST $85.00." ) print( "YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00." ) player_funds -= 105 else: print( "Internal error #2, fort " + str( which_fort ) + " does not exist" ) sys.exit( 1 ) # you have a bug # Calculate sales beaver_value = beaver_price * player_furs[ FUR_BEAVER ] fox_value = fox_price * player_furs[ FUR_FOX ] ermine_value = ermine_price * player_furs[ FUR_ERMINE ] mink_value = mink_price * player_furs[ FUR_MINK ] print( "" ) print( "YOUR BEAVER SOLD FOR $%6.2f" % ( beaver_value ) ) print( "YOUR FOX SOLD FOR $%6.2f" % ( fox_value ) ) print( "YOUR ERMINE SOLD FOR $%6.2f" % ( ermine_value ) ) print( "YOUR MINK SOLD FOR $%6.2f" % ( mink_value ) ) player_funds += beaver_value + fox_value + ermine_value + mink_value print( "" ) print( "YOU NOW HAVE $ %1.2f INCLUDING YOUR PREVIOUS SAVINGS" % ( player_funds ) ) print( "" ) print( "DO YOU WANT TO TRADE FURS NEXT YEAR?" ) should_trade = getYesOrNo() if ( should_trade == 'N' ): sys.exit( 0 ) # STOP else: game_state = 'trading'