今天学习edx上的计算机思维导论和python基础,week4,problem set4,做到今天,a部分刚做完,分享下自己做的代码,如下。
1 # The 6.00 Word Game 2 3 import random 4 import string 5 6 VOWELS = 'aeiou' 7 CONSONANTS = 'bcdfghjklmnpqrstvwxyz' 8 HAND_SIZE = 7 9 10 SCRABBLE_LETTER_VALUES = { 11 'a': 1, 'b': 3, 'c': 3, 'd': 2, 'e': 1, 'f': 4, 'g': 2, 'h': 4, 'i': 1, 'j': 8, 'k': 5, 'l': 1, 'm': 3, 'n': 1, 'o': 1, 'p': 3, 'q': 10, 'r': 1, 's': 1, 't': 1, 'u': 1, 'v': 4, 'w': 4, 'x': 8, 'y': 4, 'z': 10 12 } 13 14 # ----------------------------------- 15 # Helper code 16 # (you don't need to understand this helper code) 17 18 WORDLIST_FILENAME = "words.txt" 19 20 def loadWords(): 21 """ 22 Returns a list of valid words. Words are strings of lowercase letters. 23 24 Depending on the size of the word list, this function may 25 take a while to finish. 26 """ 27 print("Loading word list from file...") 28 # inFile: file 29 inFile = open(WORDLIST_FILENAME, 'r') 30 # wordList: list of strings 31 wordList = [] 32 for line in inFile: 33 wordList.append(line.strip().lower()) 34 print(" ", len(wordList), "words loaded.") 35 return wordList 36 37 def getFrequencyDict(sequence): 38 """ 39 Returns a dictionary where the keys are elements of the sequence 40 and the values are integer counts, for the number of times that 41 an element is repeated in the sequence. 42 43 sequence: string or list 44 return: dictionary 45 """ 46 # freqs: dictionary (element_type -> int) 47 freq = {} 48 for x in sequence: 49 freq[x] = freq.get(x,0) + 1 50 return freq 51 52 53 # (end of helper code) 54 # ----------------------------------- 55 56 # 57 # Problem #1: Scoring a word 58 # 59 def getWordScore(word, n): 60 ''' 61 Returns the score for a word. Assumes the word is a valid word. 62 63 The score for a word is the sum of the points for letters in the 64 word, multiplied by the length of the word, PLUS 50 points if all n 65 letters are used on the first turn. 66 67 Letters are scored as in Scrabble; A is worth 1, B is worth 3, C is 68 worth 3, D is worth 2, E is worth 1, and so on (see SCRABBLE_LETTER_VALUES) 69 70 word: string (lowercase letters) 71 n: integer (HAND_SIZE; i.e., hand size required for additional points) 72 returns: int >= 0 73 ''' 74 score_sum=0 75 for i in word: 76 score_sum=score_sum+SCRABBLE_LETTER_VALUES[i] 77 word_score=score_sum*len(word) 78 if n==len(word): 79 return word_score+50 80 else: 81 return word_score 82 83 84 # 85 # Problem #2: Make sure you understand how this function works and what it does! 86 # 87 def displayHand(hand): 88 """ 89 Displays the letters currently in the hand. 90 91 For example: 92 displayHand({'a':1, 'x':2, 'l':3, 'e':1}) 93 Should print out something like: 94 a x x l l l e 95 The order of the letters is unimportant. 96 97 hand: dictionary (string -> int) 98 """ 99 for letter in hand.keys(): 100 for j in range(hand[letter]): 101 print(letter,end=" ") # print all on the same line 102 print() # print an empty line 103 104 # 105 # Problem #2: Make sure you understand how this function works and what it does! 106 # 107 def dealHand(n): 108 """ 109 Returns a random hand containing n lowercase letters. 110 At least n/3 the letters in the hand should be VOWELS. 111 112 Hands are represented as dictionaries. The keys are 113 letters and the values are the number of times the 114 particular letter is repeated in that hand. 115 116 n: int >= 0 117 returns: dictionary (string -> int) 118 """ 119 hand={} 120 numVowels = n // 3 121 122 for i in range(numVowels): 123 x = VOWELS[random.randrange(0,len(VOWELS))] 124 hand[x] = hand.get(x, 0) + 1 125 126 for i in range(numVowels, n): 127 x = CONSONANTS[random.randrange(0,len(CONSONANTS))] 128 hand[x] = hand.get(x, 0) + 1 129 130 return hand 131 132 # 133 # Problem #2: Update a hand by removing letters 134 # 135 def updateHand(hand, word): 136 """ 137 Assumes that 'hand' has all the letters in word. 138 In other words, this assumes that however many times 139 a letter appears in 'word', 'hand' has at least as 140 many of that letter in it. 141 142 Updates the hand: uses up the letters in the given word 143 and returns the new hand, without those letters in it. 144 145 Has no side effects: does not modify hand. 146 147 word: string 148 hand: dictionary (string -> int) 149 returns: dictionary (string -> int) 150 """ 151 hand_2=hand.copy() 152 for i in hand_2.keys(): 153 hand_2[i]=hand_2[i]-word.count(i) 154 return hand_2 155 156 157 158 159 # 160 # Problem #3: Test word validity 161 # 162 def isValidWord(word, hand, wordList): 163 """ 164 Returns True if word is in the wordList and is entirely 165 composed of letters in the hand. Otherwise, returns False. 166 167 Does not mutate hand or wordList. 168 169 word: string 170 hand: dictionary (string -> int) 171 wordList: list of lowercase strings 172 """ 173 hand_2=hand.copy() 174 num=0 175 for i in word: 176 hand_2[i]=hand_2.get(i,0)-1 177 if hand_2[i]>=0: 178 num+=1 179 if word in wordList and num==len(word): 180 return True 181 else: 182 return False 183 184 185 186 187 188 # 189 # Problem #4: Playing a hand 190 # 191 192 def calculateHandlen(hand): 193 """ 194 Returns the length (number of letters) in the current hand. 195 196 hand: dictionary (string-> int) 197 returns: integer 198 """ 199 num=0 200 for i in hand.keys(): 201 num+=hand[i] 202 return num 203 204 205 206 def playHand(hand, wordList, n): 207 """ 208 Allows the user to play the given hand, as follows: 209 210 * The hand is displayed. 211 * The user may input a word or a single period (the string ".") 212 to indicate they're done playing 213 * Invalid words are rejected, and a message is displayed asking 214 the user to choose another word until they enter a valid word or "." 215 * When a valid word is entered, it uses up letters from the hand. 216 * After every valid word: the score for that word is displayed, 217 the remaining letters in the hand are displayed, and the user 218 is asked to input another word. 219 * The sum of the word scores is displayed when the hand finishes. 220 * The hand finishes when there are no more unused letters or the user 221 inputs a "." 222 223 hand: dictionary (string -> int) 224 wordList: list of lowercase strings 225 n: integer (HAND_SIZE; i.e., hand size required for additional points) 226 227 """ 228 total_score=0 229 # Keep track of the total score 230 while calculateHandlen(hand): 231 # As long as there are still letters left in the hand: 232 print('current hand:',hand) 233 # Display the hand 234 word=input('Enter a word or "."to finish:') 235 # Ask user for input 236 if word=='.': 237 # If the input is a single period: 238 print('Goodbye! Total score: ', total_score) 239 break 240 # End the game (break out of the loop) 241 else: 242 # Otherwise (the input is not a single period): 243 if not isValidWord(word,hand,wordList): 244 # If the word is not valid: 245 print('Invalid word, please try again.') 246 # Reject invalid word (print a message followed by a blank line) 247 else: 248 # Otherwise (the word is valid): 249 total_score+=getWordScore(word,n) 250 print('%s earned %d points.Total:%d points'%(word,getWordScore(word,n),total_score)) 251 print('') 252 # Tell the user how many points the word earned, and the updated total score, in one line followed by a blank line 253 hand=updateHand(hand,word) 254 # Update the hand 255 256 else: 257 print('Run out of letters. Total score: ',total_score) 258 # Game is over (user entered a '.' or ran out of letters), so tell user the total score 259 260 261 # 262 # Problem #5: Playing a game 263 # 264 265 def playGame(wordList): 266 """ 267 Allow the user to play an arbitrary number of hands. 268 269 1) Asks the user to input 'n' or 'r' or 'e'. 270 * If the user inputs 'n', let the user play a new (random) hand. 271 * If the user inputs 'r', let the user play the last hand again. 272 * If the user inputs 'e', exit the game. 273 * If the user inputs anything else, tell them their input was invalid. 274 275 2) When done playing the hand, repeat from step 1 276 """ 277 hand={} 278 while True: 279 tips=input('Enter n to deal a new hand, r to replay the last hand, or e to end game:') 280 if tips=='n': 281 hand=dealHand(HAND_SIZE) 282 playHand(hand,wordList,HAND_SIZE) 283 elif tips=='r': 284 if hand=={}: 285 print('You have not played a hand yet. Please play a new hand first!') 286 else: 287 playHand(hand, wordList, HAND_SIZE) 288 elif tips=='e': 289 print('') 290 break 291 else: 292 print('Invalid command.') 293 294 295 296 297 # 298 # Build data structures used for entire session and play game 299 # 300 if __name__ == '__main__': 301 wordList = loadWords() 302 playGame(wordList)