Learn faster and stay on-track by joining this free class with other self-learners.
Register for MIT OpenCourseWare 6.00 Introduction to Computer Science and Programming now.
|
MIT OpenCourseWare 6.00 Introduction to Computer Science and ProgrammingClass length: 24 weeks. Start anytime. Creator: duallain Status: Established |
Join this class! |
|
Lesson 18: Assignment 1: PS 10Homework Submissions7 totalProbably like this project the least. Never felt confident that I was writing the code correctly. But the program did work in the end. # Backend code for PS10
import random
import string
# Global Constants
VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 30
SCRABBLE_LETTER_VALUES = {
'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
}
HUMAN_SOLO = 0
HUMAN_VS_HUMAN = 1
HUMAN_VS_COMP = 2
WORDLIST_FILENAME = "words.txt"
def getFrequencyDict(sequence):
"""
Given a sequence of letters, convert the sequence to a dictionary of
letters -> frequencies. Used by containsLetters().
returns: dictionary of letters -> frequencies
"""
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
def getWordScore(word):
"""
Computes the score of a word (no bingo bonus is added).
word: The word to score (a string).
returns: score of the word.
"""
score = 0
for ch in word:
score += SCRABBLE_LETTER_VALUES[ch]
if len(word) == HAND_SIZE:
score += 50
return score
#
# Problem 2: Representing a Hand
#
class Hand(object):
def __init__(self, handSize, initialHandDict = None):
"""
Initialize a hand.
handSize: The size of the hand
postcondition: initializes a hand with random set of initial letters.
"""
num_vowels = handSize / 3
if initialHandDict is None:
initialHandDict = {}
for i in range(num_vowels):
x = VOWELS[random.randrange(0,len(VOWELS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
for i in range(num_vowels, handSize):
x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
self.initialSize = handSize
self.handDict = initialHandDict
def update(self, word):
"""
Remove letters in word from this hand.
word: The word (a string) to remove from the hand
postcondition: Letters in word are removed from this hand
"""
freq = getFrequencyDict(word)
newhand = {}
for char in self.handDict:
newhand[char] = self.handDict[char]-freq.get(char,0)
self.handDict = newhand
def containsLetters(self, letters):
"""
Test if this hand contains the characters required to make the input
string (letters)
returns: True if the hand contains the characters to make up letters,
False otherwise
"""
freq = getFrequencyDict(letters)
for letter in letters:
if freq[letter] > self.handDict.get(letter, 0):
return False
return True
def isEmpty(self):
"""
Test if there are any more letters left in this hand.
returns: True if there are no letters remaining, False otherwise.
"""
emptyTest = self.handDict.values()
for i in emptyTest:
if i != 0:
return False
return True
def __eq__(self, other):
"""
Equality test, for testing purposes
returns: True if this Hand contains the same number of each letter as
the other Hand, False otherwise
"""
if self.handDict == other.handDict:
return True
return False
def __str__(self):
"""
Represent this hand as a string
returns: a string representation of this hand
"""
string = ''
for letter in self.handDict.keys():
for j in range(self.handDict[letter]):
string = string + letter + ' '
return string
#
# Problem 3: Representing a Player
#
class Player(object):
"""
General class describing a player.
Stores the player's ID number, hand, and score.
"""
def __init__(self, idNum, hand):
"""
Initialize a player instance.
idNum: integer: 1 for player 1, 2 for player 2. Used in informational
displays in the GUI.
hand: An object of type Hand.
postcondition: This player object is initialized
"""
self.points = 0.
self.idNum = idNum
self.hand = hand
def getHand(self):
"""
Return this player's hand.
returns: the Hand object associated with this player.
"""
return self.hand
def addPoints(self, points):
"""
Add points to this player's total score.
points: the number of points to add to this player's score
postcondition: this player's total score is increased by points
"""
self.points += points
def getPoints(self):
"""
Return this player's total score.
returns: A float specifying this player's score
"""
return self.points
def getIdNum(self):
"""
Return this player's ID number (either 1 for player 1 or
2 for player 2).
returns: An integer specifying this player's ID number.
"""
return self.idNum
def __cmp__(self, other):
"""
Compare players by their scores.
returns: 1 if this player's score is greater than other player's score,
-1 if this player's score is less than other player's score, and 0 if
they're equal.
"""
if self.getPoints() > other.getPoints():
return 1
elif self.getPoints < other.getPoints():
return -1
else: return 0
def __str__(self):
"""
Represent this player as a string
returns: a string representation of this player
"""
return 'Player %d\n\nScore: %.2f\n' % \
(self.getIdNum(), self.getPoints())
#
# Problem 4: Representing a Computer Player
#
class ComputerPlayer(Player):
"""
A computer player class.
Does everything a Player does, but can also pick a word using the
PickBestWord method.
"""
def pickBestWord(self, wordlist):
"""
Pick the best word available to the computer player.
returns: The best word (a string), given the computer player's hand and
the wordlist
"""
ans = False
best = False
wordScore = 0
wordList = wordlist.getList()
currentHand = getFrequencyDict(str(self.getHand()))
for word in wordList:
word_freq = getFrequencyDict(word)
for letter in word_freq:
if letter in currentHand and word_freq[letter] <= currentHand[letter]:
ans = True
continue
else:
ans = False
break
if ans == True:
new_score = getWordScore(word)
if new_score > wordScore:
wordScore = new_score
best_word = word
best = True
if best == True:
return best_word
else: return '.'
def playHand(self, callback, wordlist):
"""
Play a hand completely by passing chosen words to the callback
function.
"""
while callback(self.pickBestWord(wordlist)): pass
class HumanPlayer(Player):
"""
A Human player class.
No methods are needed because everything is taken care of by the GUI.
"""
class Wordlist(object):
"""
A word list.
"""
def __init__(self):
"""
Initializes a Wordlist object.
postcondition: words are read in from a file (WORDLIST_FILENAME, a
global constant) and stored as a list.
"""
inputFile = open(WORDLIST_FILENAME)
try:
self.wordlist = []
for line in inputFile:
self.wordlist.append(line.strip().lower())
finally:
inputFile.close()
def containsWord(self, word):
"""
Test whether this wordlist includes word
word: The word to check (a string)
returns: True if word is in this Wordlist, False if word is not in
Wordlist
"""
return word in self.wordlist
def getList(self):
return self.wordlist
class EndHand(Exception): pass
class Game(object):
"""
Stores the state needed to play a round of the word game.
"""
def __init__(self, mode, wordlist):
"""
Initializes a game.
mode: Can be one of three constant values - HUMAN_SOLO, HUMAN_VS_COMP,
and HUMAN_VS_HUMAN
postcondition: Initializes the players nd their hands.
"""
hand = Hand(HAND_SIZE)
hand2 = Hand(HAND_SIZE, hand.handDict.copy())
if mode == HUMAN_SOLO:
self.players = [HumanPlayer(1, hand)]
elif mode == HUMAN_VS_COMP:
self.players = [HumanPlayer(1, hand),
ComputerPlayer(2, hand2)]
elif mode == HUMAN_VS_HUMAN:
self.players = [HumanPlayer(1, hand),
HumanPlayer(2, hand2)]
self.playerIndex = 0
self.wordlist = wordlist
def getCurrentPlayer(self):
"""
Gets the Player object corresponding to the active player.
returns: The active Player object.
"""
return self.players[self.playerIndex]
def nextPlayer(self):
"""
Changes the game state so that the next player is the active player.
postcondition: playerIndex is incremented
"""
if self.playerIndex + 1 < len(self.players):
self.playerIndex = self.playerIndex + 1
return True
else:
return False
def gameOver(self):
"""
Determines if the game is over
returns: True if the playerIndex >= the number of players, False
otherwise
"""
return self.playerIndex >= len(self.players)
def tryWord(self, word):
if word == '.':
raise EndHand()
player = self.getCurrentPlayer()
hand = player.getHand()
if self.wordlist.containsWord(word) and hand.containsLetters(word):
points = getWordScore(word)
player.addPoints(points)
hand.update(word)
if hand.isEmpty():
raise EndHand()
return points
else:
return None
def getWinner(self):
return max(self.players)
def getNumPlayers(self):
return len(self.players)
def isTie(self):
return len(self.players) > 1 and \
self.players[0].getPoints() == self.players[1].getPoints()
def __str__(self):
"""
Convert this game object to a string
returns: the concatenation of the string representation of the players
"""
string = ''
for player in self.players:
string = string + str(player)
return string
# Backend code for PS10
import random
import string
# Global Constants
VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 30
SCRABBLE_LETTER_VALUES = {
'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
}
HUMAN_SOLO = 0
HUMAN_VS_HUMAN = 1
HUMAN_VS_COMP = 2
WORDLIST_FILENAME = "words.txt"
def getFrequencyDict(sequence):
"""
Given a sequence of letters, convert the sequence to a dictionary of
letters -> frequencies. Used by containsLetters().
returns: dictionary of letters -> frequencies
"""
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
def getWordScore(word):
"""
Computes the score of a word (no bingo bonus is added).
word: The word to score (a string).
returns: score of the word.
"""
score = 0
for ch in word:
score += SCRABBLE_LETTER_VALUES[ch]
if len(word) == HAND_SIZE:
score += 50
return score
#
# Problem 2: Representing a Hand
#
class Hand(object):
def __init__(self, handSize, initialHandDict = None):
"""
Initialize a hand.
handSize: The size of the hand
postcondition: initializes a hand with random set of initial letters.
"""
num_vowels = handSize / 3
if initialHandDict is None:
initialHandDict = {}
for i in range(num_vowels):
x = VOWELS[random.randrange(0,len(VOWELS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
for i in range(num_vowels, handSize):
x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
self.initialSize = handSize
self.handDict = initialHandDict
def update(self, word):
"""
Remove letters in word from this hand.
word: The word (a string) to remove from the hand
postcondition: Letters in word are removed from this hand
"""
for letter in word:
if self.handDict.get(letter,0) > 1:
self.handDict[letter] -= 1
else:
del self.handDict[letter]
def containsLetters(self, letters):
"""
Test if this hand contains the characters required to make the input
string (letters)
returns: True if the hand contains the characters to make up letters,
False otherwise
"""
tempD = self.handDict.copy()
for c in letters:
if tempD.get(c,0) > 0:
tempD[c] -= 1
else:
if tempD.get(c,0) == 0:
return False
return True
def isEmpty(self):
"""
Test if there are any more letters left in this hand.
returns: True if there are no letters remaining, False otherwise.
"""
for c in self.handDict:
if self.handDict.get(c,0) != 0:
return False
return True
def __eq__(self, other):
"""
Equality test, for testing purposes
returns: True if this Hand contains the same number of each letter as
the other Hand, False otherwise
"""
return self.handDict == other.handDict
def __str__(self):
"""
Represent this hand as a string
returns: a string representation of this hand
"""
string = ''
for letter in self.handDict.keys():
for j in range(self.handDict[letter]):
string = string + letter + ' '
return string
#
# Problem 3: Representing a Player
#
class Player(object):
"""
General class describing a player.
Stores the player's ID number, hand, and score.
"""
def __init__(self, idNum, hand):
"""
Initialize a player instance.
idNum: integer: 1 for player 1, 2 for player 2. Used in informational
displays in the GUI.
hand: An object of type Hand.
postcondition: This player object is initialized
"""
self.points = 0.
self.idNum = idNum
self.hand = hand
def getHand(self):
"""
Return this player's hand.
returns: the Hand object associated with this player.
"""
return self.hand
def addPoints(self, points):
"""
Add points to this player's total score.
points: the number of points to add to this player's score
postcondition: this player's total score is increased by points
"""
self.points += points
def getPoints(self):
"""
Return this player's total score.
returns: A float specifying this player's score
"""
return self.points
def getIdNum(self):
"""
Return this player's ID number (either 1 for player 1 or
2 for player 2).
returns: An integer specifying this player's ID number.
"""
return self.idNum
def __cmp__(self, other):
"""
Compare players by their scores.
returns: 1 if this player's score is greater than other player's score,
-1 if this player's score is less than other player's score, and 0 if
they're equal.
"""
if self.getPoints() == other.getPoints():
return 0
if self.getPoints() > other.getPoints():
return 1
else:
return -1
def __str__(self):
"""
Represent this player as a string
returns: a string representation of this player
"""
return 'Player %d\n\nScore: %.2f\n' % \
(self.getIdNum(), self.getPoints())
#
# Problem 4: Representing a Computer Player
#
class ComputerPlayer(Player):
"""
A computer player class.
Does everything a Player does, but can also pick a word using the
PickBestWord method.
"""
def pickBestWord(self, wordlist):
"""
Pick the best word available to the computer player.
returns: The best word (a string), given the computer player's hand and
the wordlist
"""
score = 0
bestword = None
for word in wordlist.getList():
if self.getHand().containsLetters(word):
wordscore = getWordScore(word)
if wordscore > score:
score = wordscore
bestword = word
return bestword
def playHand(self, callback, wordlist):
"""
Play a hand completely by passing chosen words to the callback
function.
"""
while callback(self.pickBestWord(wordlist)): pass
class HumanPlayer(Player):
"""
A Human player class.
No methods are needed because everything is taken care of by the GUI.
"""
class Wordlist(object):
"""
A word list.
"""
def __init__(self):
"""
Initializes a Wordlist object.
postcondition: words are read in from a file (WORDLIST_FILENAME, a
global constant) and stored as a list.
"""
inputFile = open(WORDLIST_FILENAME)
try:
self.wordlist = []
for line in inputFile:
self.wordlist.append(line.strip().lower())
finally:
inputFile.close()
def containsWord(self, word):
"""
Test whether this wordlist includes word
word: The word to check (a string)
returns: True if word is in this Wordlist, False if word is not in
Wordlist
"""
return word in self.wordlist
def getList(self):
return self.wordlist
class EndHand(Exception): pass
class Game(object):
"""
Stores the state needed to play a round of the word game.
"""
def __init__(self, mode, wordlist):
"""
Initializes a game.
mode: Can be one of three constant values - HUMAN_SOLO, HUMAN_VS_COMP,
and HUMAN_VS_HUMAN
postcondition: Initializes the players nd their hands.
"""
hand = Hand(HAND_SIZE)
hand2 = Hand(HAND_SIZE, hand.handDict.copy())
if mode == HUMAN_SOLO:
self.players = [HumanPlayer(1, hand)]
elif mode == HUMAN_VS_COMP:
self.players = [HumanPlayer(1, hand),
ComputerPlayer(2, hand2)]
elif mode == HUMAN_VS_HUMAN:
self.players = [HumanPlayer(1, hand),
HumanPlayer(2, hand2)]
self.playerIndex = 0
self.wordlist = wordlist
def getCurrentPlayer(self):
"""
Gets the Player object corresponding to the active player.
returns: The active Player object.
"""
return self.players[self.playerIndex]
def nextPlayer(self):
"""
Changes the game state so that the next player is the active player.
postcondition: playerIndex is incremented
"""
if self.playerIndex + 1 < len(self.players):
self.playerIndex = self.playerIndex + 1
return True
else:
return False
def gameOver(self):
"""
Determines if the game is over
returns: True if the playerIndex >= the number of players, False
otherwise
"""
return self.playerIndex >= len(self.players)
def tryWord(self, word):
if word == '.':
raise EndHand()
player = self.getCurrentPlayer()
hand = player.getHand()
if self.wordlist.containsWord(word) and hand.containsLetters(word):
points = getWordScore(word)
player.addPoints(points)
hand.update(word)
if hand.isEmpty():
raise EndHand()
return points
else:
return None
def getWinner(self):
return max(self.players)
def getNumPlayers(self):
return len(self.players)
def isTie(self):
return len(self.players) > 1 and \
self.players[0].getPoints() == self.players[1].getPoints()
def __str__(self):
"""
Convert this game object to a string
returns: the concatenation of the string representation of the players
"""
string = ''
for player in self.players:
string = string + str(player)
return string
No comments. Sign up or log in to comment # Backend code for PS10
import random
import string
# Global Constants
VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 30
SCRABBLE_LETTER_VALUES = {
'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
}
HUMAN_SOLO = 0
HUMAN_VS_HUMAN = 1
HUMAN_VS_COMP = 2
WORDLIST_FILENAME = "words.txt"
def getFrequencyDict(sequence):
"""
Given a sequence of letters, convert the sequence to a dictionary of
letters -> frequencies. Used by containsLetters().
returns: dictionary of letters -> frequencies
"""
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
def getWordScore(word):
"""
Computes the score of a word (no bingo bonus is added).
word: The word to score (a string).
returns: score of the word.
"""
score = 0
for ch in word:
score += SCRABBLE_LETTER_VALUES[ch]
if len(word) == HAND_SIZE:
score += 50
return score
#
# Problem 2: Representing a Hand
#
class Hand(object):
def __init__(self, handSize, initialHandDict = None):
"""
Initialize a hand.
handSize: The size of the hand
postcondition: initializes a hand with random set of initial letters.
"""
num_vowels = handSize / 3
if initialHandDict is None:
initialHandDict = {}
for i in range(num_vowels):
x = VOWELS[random.randrange(0,len(VOWELS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
for i in range(num_vowels, handSize):
x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
self.initialSize = handSize
for letter, frequency in initialHandDict.items():
if frequency < 1:
del initialHandDict[letter]
self.handDict = initialHandDict
def update(self, word):
"""
Remove letters in word from this hand.
word: The word (a string) to remove from the hand
postcondition: Letters in word are removed from this hand
"""
for letter, frequency in getFrequencyDict(word).items():
self.handDict[letter] = self.handDict[letter] - frequency
if 0 == self.handDict[letter]:
del self.handDict[letter]
def containsLetters(self, letters):
"""
Test if this hand contains the characters required to make the input
string (letters)
returns: True if the hand contains the characters to make up letters,
False otherwise
"""
for letter, frequency in getFrequencyDict(letters).items():
if self.handDict.get(letter, 0) < frequency:
return False
return True
def isEmpty(self):
"""
Test if there are any more letters left in this hand.
returns: True if there are no letters remaining, False otherwise.
"""
return not len(self.handDict)
def __eq__(self, other):
"""
Equality test, for testing purposes
returns: True if this Hand contains the same number of each letter as
the other Hand, False otherwise
"""
return self.handDict == other.handDict
def __str__(self):
"""
Represent this hand as a string
returns: a string representation of this hand
"""
string = ''
for letter in self.handDict.keys():
for j in range(self.handDict[letter]):
string = string + letter + ' '
return string
#
# Problem 3: Representing a Player
#
class Player(object):
"""
General class describing a player.
Stores the player's ID number, hand, and score.
"""
def __init__(self, idNum, hand):
"""
Initialize a player instance.
idNum: integer: 1 for player 1, 2 for player 2. Used in informational
displays in the GUI.
hand: An object of type Hand.
postcondition: This player object is initialized
"""
self.points = 0.
self.idNum = idNum
self.hand = hand
def getHand(self):
"""
Return this player's hand.
returns: the Hand object associated with this player.
"""
return self.hand
def addPoints(self, points):
"""
Add points to this player's total score.
points: the number of points to add to this player's score
postcondition: this player's total score is increased by points
"""
self.points += points
def getPoints(self):
"""
Return this player's total score.
returns: A float specifying this player's score
"""
return self.points
def getIdNum(self):
"""
Return this player's ID number (either 1 for player 1 or
2 for player 2).
returns: An integer specifying this player's ID number.
"""
return self.idNum
def __cmp__(self, other):
"""
Compare players by their scores.
returns: 1 if this player's score is greater than other player's score,
-1 if this player's score is less than other player's score, and 0 if
they're equal.
"""
return cmp(self.getPoints(), other.getPoints())
def __str__(self):
"""
Represent this player as a string
returns: a string representation of this player
"""
return 'Player %d\n\nScore: %.2f\n' % \
(self.getIdNum(), self.getPoints())
#
# Problem 4: Representing a Computer Player
#
class ComputerPlayer(Player):
"""
A computer player class.
Does everything a Player does, but can also pick a word using the
PickBestWord method.
"""
def pickBestWord(self, wordlist):
"""
Pick the best word available to the computer player.
returns: The best word (a string), given the computer player's hand and
the wordlist
"""
bestScore = 0
bestWord = ''
for word in wordlist.getList():
if self.hand.containsLetters(word):
wordScore = getWordScore(word)
if wordScore > bestScore:
bestScore = wordScore
bestWord = word
return bestWord
def playHand(self, callback, wordlist):
"""
Play a hand completely by passing chosen words to the callback
function.
"""
while callback(self.pickBestWord(wordlist)): pass
class HumanPlayer(Player):
"""
A Human player class.
No methods are needed because everything is taken care of by the GUI.
"""
class Wordlist(object):
"""
A word list.
"""
def __init__(self):
"""
Initializes a Wordlist object.
postcondition: words are read in from a file (WORDLIST_FILENAME, a
global constant) and stored as a list.
"""
inputFile = open(WORDLIST_FILENAME)
try:
self.wordlist = []
for line in inputFile:
self.wordlist.append(line.strip().lower())
finally:
inputFile.close()
def containsWord(self, word):
"""
Test whether this wordlist includes word
word: The word to check (a string)
returns: True if word is in this Wordlist, False if word is not in
Wordlist
"""
return word in self.wordlist
def getList(self):
return self.wordlist
class EndHand(Exception): pass
class Game(object):
"""
Stores the state needed to play a round of the word game.
"""
def __init__(self, mode, wordlist):
"""
Initializes a game.
mode: Can be one of three constant values - HUMAN_SOLO, HUMAN_VS_COMP,
and HUMAN_VS_HUMAN
postcondition: Initializes the players nd their hands.
"""
hand = Hand(HAND_SIZE)
hand2 = Hand(HAND_SIZE, hand.handDict.copy())
if mode == HUMAN_SOLO:
self.players = [HumanPlayer(1, hand)]
elif mode == HUMAN_VS_COMP:
self.players = [HumanPlayer(1, hand),
ComputerPlayer(2, hand2)]
elif mode == HUMAN_VS_HUMAN:
self.players = [HumanPlayer(1, hand),
HumanPlayer(2, hand2)]
self.playerIndex = 0
self.wordlist = wordlist
def getCurrentPlayer(self):
"""
Gets the Player object corresponding to the active player.
returns: The active Player object.
"""
return self.players[self.playerIndex]
def nextPlayer(self):
"""
Changes the game state so that the next player is the active player.
postcondition: playerIndex is incremented
"""
if self.playerIndex + 1 < len(self.players):
self.playerIndex = self.playerIndex + 1
return True
else:
return False
def gameOver(self):
"""
Determines if the game is over
returns: True if the playerIndex >= the number of players, False
otherwise
"""
return self.playerIndex >= len(self.players)
def tryWord(self, word):
if word == '.':
raise EndHand()
player = self.getCurrentPlayer()
hand = player.getHand()
if self.wordlist.containsWord(word) and hand.containsLetters(word):
points = getWordScore(word)
player.addPoints(points)
hand.update(word)
if hand.isEmpty():
raise EndHand()
return points
else:
return None
def getWinner(self):
return max(self.players)
def getNumPlayers(self):
return len(self.players)
def isTie(self):
return len(self.players) > 1 and \
self.players[0].getPoints() == self.players[1].getPoints()
def __str__(self):
"""
Convert this game object to a string
returns: the concatenation of the string representation of the players
"""
string = ''
for player in self.players:
string = string + str(player)
return string
# Test code
import ps10; reload(ps10)
from ps10 import *
def isClose(float1, float2):
"""
Helper function - are two floating point values close?
"""
return abs(float1 - float2) < .01
def testResult(boolean):
"""
Helper function - print 'Test Failed' if boolean is false, 'Test
Succeeded' otherwise.
"""
if boolean:
print 'Test Succeeded'
else:
print 'Test Failed'
def testHand():
"""
Test the hand class. Add your own test cases
"""
h = Hand(8, {'a':3, 'b':2, 'd':3})
expected = {'a': 2, 'b': 1, 'd': 2};
print("\nTesting that handDict %s is changed to %s after h.update('bad')" % (h.handDict, expected))
h.update('bad')
testResult(h.handDict == expected)
print("\nTesting that h.containsLetters('aabdd') returns True and h.isEmpty() returns False with handDict %s" % h.handDict)
testResult(h.containsLetters('aabdd') and not h.isEmpty())
expected = {'a': 1, 'b': 1}
print("\nTesting that handDict %s is changed to %s after h.update('dad')" % (h.handDict, expected))
h.update('dad')
testResult(h.handDict == expected)
print("\nTesting that h.containsLetters('ab') returns True and h.isEmpty() returns False with handDict %s" % h.handDict)
testResult(h.containsLetters('ab') and not h.isEmpty())
expected = {}
print("\nTesting that handDict %s is changed to %s after h.update('ab')" % (h.handDict, expected))
h.update('ab')
testResult(h.handDict == expected)
print("\nTesting that h.isEmpty() returns True with handDict %s" % h.handDict)
testResult(h.isEmpty())
h = Hand(8, {'a':3, 'b':2, 'd':3})
print("\nTesting that h.containsLetters('z') returns False handDict %s" % h.handDict)
testResult(not h.containsLetters('z'))
h = Hand(8, {'a':3, 'b':2, 'd':3})
oh = Hand(8, {'a':3, 'b':2, 'd':3})
print("\nTesting that hand with %s is equal to hand with %s" % (h.handDict, oh.handDict))
testResult(h == oh)
h = Hand(8, {'a':3, 'b':2, 'd':3})
oh = Hand(8, {'d':3, 'b':2, 'a':3, 'c':0})
print("\nTesting that hand with %s is equal to hand with %s" % (h.handDict, oh.handDict))
testResult(h == oh)
h = Hand(8, {'b':3, 'c':2, 'e':3})
oh = Hand(8, {'a':3, 'b':2, 'd':3})
print("\nTesting that hand with %s is not equal to hand with %s" % (h.handDict, oh.handDict))
testResult(h != oh)
def testPlayer():
"""
Test the Player class. Add your own test cases.
"""
hand = Hand(6, {'c':1, 'a':1, 'b':1 ,'d':1, 'o':1, 'e':1})
p = Player(1, hand)
print("\nTesting that p.getHand() returns an instance of Hand")
testResult(type(p.getHand()) == Hand)
print("\nTesting that the Player constructor initializes p.hand to %s, p.points to %0.1f and p.idNum to %d" % (hand, 0., 1))
testResult(p.hand == hand)
testResult(p.points == 0)
testResult(p.idNum == 1)
print("\nTesting that p.getHand() returns p.hand")
testResult(p.getHand() == p.hand)
print("\nTesting that p.getPoints returns p.points")
testResult(p.getPoints() == p.points)
print("\nTesting that p.getIdNum returns p.idNum")
testResult(p.getIdNum() == p.idNum)
print("\nTesting that calling p.addPoints(5.) and p.addPoints(12.) sets the total number of points close to 17")
p.addPoints(5.)
p.addPoints(12.)
testResult(isClose(p.getPoints(), 17))
p1 = Player(1, Hand(1, {'a': 1}))
p2 = Player(2, Hand(1, {'b': 1}))
print("\nTesting that p1 with %0.1f points is equal to p2 with %0.1f points" % (p1.getPoints(), p2.getPoints()))
testResult(p1 == p2)
p1.addPoints(1)
print("\nTesting that p1 with %0.1f points is greater than p2 with %0.1f points" % (p1.getPoints(), p2.getPoints()))
testResult(p1 > p2)
print("\nTesting that p2 with %0.1f points is less than p1 with %0.1f points" % (p2.getPoints(), p1.getPoints()))
testResult(p2 < p1)
def testComputerPlayer():
"""
Test the ComputerPlayer class. Add your own test cases.
"""
wordlist = Wordlist()
p = ComputerPlayer(1, Hand(6, {'c':1, 'a':1, 'b':1 ,'d':1, 'o':1, 'e':1}))
expected = 'abode'
print("Testing that the best word formed with the hand %s is %s and the best score possible is %0.1f" % (p.getHand(), expected, getWordScore(expected)))
bestWord = p.pickBestWord(wordlist)
testResult(bestWord == expected)
testResult(getWordScore(bestWord) == getWordScore(expected))
p = ComputerPlayer(1, Hand(7, {'h': 1, 'a': 2, 'z': 1, 'm': 3, 'o': 1, 'c': 2, 'k': 1}))
expected = 'hammock'
print("\nTesting that the best word formed with the hand %s is %s and the best score possible is %0.1f" % (p.getHand(), expected, getWordScore(expected)))
bestWord = p.pickBestWord(wordlist)
testResult(bestWord == expected)
testResult(getWordScore(bestWord) == getWordScore(expected))
p = ComputerPlayer(1, Hand(1, {'x': 1}))
expected = ''
print("\nTesting that the best word formed with the hand %s is %s and the best score possible is %0.1f" % (p.getHand(), expected, getWordScore(expected)))
bestWord = p.pickBestWord(wordlist)
testResult(bestWord == expected)
testResult(getWordScore(bestWord) == getWordScore(expected))
def testAll():
"""
Run all Tests
"""
print "Uncomment the tests in this file as you complete each problem."
print "PROBLEM 2 -----------------------------------------"
testHand()
print
print 'PROBLEM 3 -----------------------------------------'
testPlayer()
print
print 'PROBLEM 4 -----------------------------------------'
testComputerPlayer()
print
testAll()
No comments. Sign up or log in to comment Passes basic tests in ps10_test.py. Error in GUI game on missing HumanPlayer IdNum. # Backend code for PS10
import random
import string
import itertools
# Global Constants
VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 7
SCRABBLE_LETTER_VALUES = {
'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
}
HUMAN_SOLO = 0
HUMAN_VS_HUMAN = 1
HUMAN_VS_COMP = 2
WORDLIST_FILENAME = "words.txt"
def getFrequencyDict(sequence):
"""
Given a sequence of letters, convert the sequence to a dictionary of
letters -> frequencies. Used by containsLetters().
returns: dictionary of letters -> frequencies
"""
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
def getWordScore(word):
"""
Computes the score of a word (no bingo bonus is added).
word: The word to score (a string).
returns: score of the word.
"""
score = 0
for ch in word:
score += SCRABBLE_LETTER_VALUES[ch]
if len(word) == HAND_SIZE:
score += 50
return score
#
# Problem 2: Representing a Hand
#
class Hand(object):
def __init__(self, handSize, initialHandDict = None):
"""
Initialize a hand.
handSize: The size of the hand
postcondition: initializes a hand with random set of initial letters.
"""
num_vowels = handSize / 3
if initialHandDict is None:
initialHandDict = {}
for i in range(num_vowels):
x = VOWELS[random.randrange(0,len(VOWELS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
for i in range(num_vowels, handSize):
x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
self.initialSize = handSize
self.handDict = initialHandDict
def update(self, word):
"""
Remove letters in word from this hand.
word: The word (a string) to remove from the hand
postcondition: Letters in word are removed from this hand
"""
# TODO
dictWord = getFrequencyDict(word)
for letter in self.handDict:
self.handDict[letter] = max(0, self.handDict[letter] - dictWord.get(letter,0))
def containsLetters(self, letters):
"""
Test if this hand contains the characters required to make the input
string (letters)
returns: True if the hand contains the characters to make up letters,
False otherwise
"""
# if letters include letter not in handDict, or has more than handDict, return False
dictWord = getFrequencyDict(letters)
for char in dictWord:
if self.handDict.get(char, 0) == 0:
return False
elif dictWord[char] > self.handDict[char]:
return False
return True
def isEmpty(self):
"""
Test if there are any more letters left in this hand.
returns: True if there are no letters remaining, False otherwise.
"""
# if there's a non-zero letter in handDict return False
for letter in self.handDict:
if self.handDict[letter] > 0: return False
return True
def __eq__(self, other):
"""
Equality test, for testing purposes
returns: True if this Hand contains the same number of each letter as
the other Hand, False otherwise
"""
# TODO
if cmp(self.handDict, other.handDict) == 0: return True
return False
def __str__(self):
"""
Represent this hand as a string
returns: a string representation of this hand
"""
string = ''
for letter in self.handDict.keys():
for j in range(self.handDict[letter]):
string = string + letter + ' '
return string
#
# Problem 3: Representing a Player
#
class Player(object):
"""
General class describing a player.
Stores the player's ID number, hand, and score.
"""
def __init__(self, IdNum, hand):
"""
Initialize a player instance.
IdNum: integer: 1 for player 1, 2 for player 2. Used in informational
displays in the GUI.
hand: An object of type Hand.
postcondition: This player object is initialized
"""
self.points = 0.
self.IdNum = IdNum
self.hand = hand
def getHand(self):
"""
Return this player's hand.
returns: the Hand object associated with this player.
"""
# TODO
return self.hand
def addPoints(self, points):
"""
Add points to this player's total score.
points: the number of points to add to this player's score
postcondition: this player's total score is increased by points
"""
# TODO
self.points += points
def getPoints(self):
"""
Return this player's total score.
returns: A float specifying this player's score
"""
# TODO
return self.points
def getIdNum(self):
"""
Return this player's ID number (either 1 for player 1 or
2 for player 2).
returns: An integer specifying this player's ID number.
"""
# TODO
return self.IdNum
def __cmp__(self, other):
"""
Compare players by their scores.
returns: 1 if this player's score is greater than other player's score,
-1 if this player's score is less than other player's score, and 0 if
they're equal.
"""
# TODO
return cmp(self.hand, other.hand)
def __str__(self):
"""
Represent this player as a string
returns: a string representation of this player
"""
return 'Player %d\n\nScore: %.2f\n' % \
(self.getIdNum(), self.getPoints())
#
# Problem 4: Representing a Computer Player
#
class ComputerPlayer(Player):
"""
A computer player class.
Does everything a Player does, but can also pick a word using the
PickBestWord method.
"""
def pickBestWord(self, wordlist):
"""
Pick the best word available to the computer player.
returns: The best word (a string), given the computer player's hand and
the wordlist
"""
# TODO
# get string representation of hand
hand = self.getHand()
handChars = str(hand)
handChars = handChars.replace(' ','')
max = 0
bestWord = ''
for i in range(len(handChars)):
# create permutations of letters in hand
for charSet in itertools.permutations(handChars, i):
testWord = ''
for j in range(len(charSet)):
# j is a tuple of permuted characters
testWord += charSet[j]
if wordlist.containsWord(testWord):
wordScore = getWordScore(testWord)
if wordScore > max:
bestWord = testWord
max = wordScore
if max > 0:
self.addPoints(max)
hand.update(bestWord)
return bestWord
else: return '.'
def playHand(self, callback, wordlist):
"""
Play a hand completely by passing chosen words to the callback
function.
"""
while callback(self.pickBestWord(wordlist)):
pass
class HumanPlayer(Player):
"""
A Human player class.
No methods are needed because everything is taken care of by the GUI.
"""
class Wordlist(object):
"""
A word list.
"""
def __init__(self):
"""
Initializes a Wordlist object.
postcondition: words are read in from a file (WORDLIST_FILENAME, a
global constant) and stored as a list.
"""
inputFile = open(WORDLIST_FILENAME)
try:
self.wordlist = []
for line in inputFile:
self.wordlist.append(line.strip().lower())
finally:
inputFile.close()
def containsWord(self, word):
"""
Test whether this wordlist includes word
word: The word to check (a string)
returns: True if word is in this Wordlist, False if word is not in
Wordlist
"""
return word in self.wordlist
def getList(self):
return self.wordlist
class EndHand(Exception): pass
class Game(object):
"""
Stores the state needed to play a round of the word game.
"""
def __init__(self, mode, wordlist):
"""
Initializes a game.
mode: Can be one of three constant values - HUMAN_SOLO, HUMAN_VS_COMP,
and HUMAN_VS_HUMAN
postcondition: Initializes the players nd their hands.
"""
hand = Hand(HAND_SIZE)
hand2 = Hand(HAND_SIZE, hand.handDict.copy())
if mode == HUMAN_SOLO:
self.players = [HumanPlayer(1, hand)]
elif mode == HUMAN_VS_COMP:
self.players = [HumanPlayer(1, hand),
ComputerPlayer(2, hand2)]
elif mode == HUMAN_VS_HUMAN:
self.players = [HumanPlayer(1, hand),
HumanPlayer(2, hand2)]
self.playerIndex = 0
self.wordlist = wordlist
def getCurrentPlayer(self):
"""
Gets the Player object corresponding to the active player.
returns: The active Player object.
"""
return self.players[self.playerIndex]
def nextPlayer(self):
"""
Changes the game state so that the next player is the active player.
postcondition: playerIndex is incremented
"""
if self.playerIndex + 1 < len(self.players):
self.playerIndex = self.playerIndex + 1
return True
else:
return False
def gameOver(self):
"""
Determines if the game is over
returns: True if the playerIndex >= the number of players, False
otherwise
"""
return self.playerIndex >= len(self.players)
def tryWord(self, word):
if word == '.':
raise EndHand()
player = self.getCurrentPlayer()
hand = player.getHand()
if self.wordlist.containsWord(word) and hand.containsLetters(word):
points = getWordScore(word)
player.addPoints(points)
hand.update(word)
if hand.isEmpty():
raise EndHand()
return points
else:
return None
def getWinner(self):
return max(self.players)
def getNumPlayers(self):
return len(self.players)
def isTie(self):
return len(self.players) > 1 and \
self.players[0].getPoints() == self.players[1].getPoints()
def __str__(self):
"""
Convert this game object to a string
returns: the concatenation of the string representation of the players
"""
string = ''
for player in self.players:
string = string + str(player)
return string
No comments. Sign up or log in to comment krqt.kndy@gmail.com # Problem Set 10
# Name: Joe LI
# Time: 3:00
# Backend code for PS10
import random
import string
# Global Constants
VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 30
SCRABBLE_LETTER_VALUES = {
'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
}
HUMAN_SOLO = 0
HUMAN_VS_HUMAN = 1
HUMAN_VS_COMP = 2
WORDLIST_FILENAME = "words.txt"
def getFrequencyDict(sequence):
"""
Given a sequence of letters, convert the sequence to a dictionary of
letters -> frequencies. Used by containsLetters().
returns: dictionary of letters -> frequencies
"""
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
def getWordScore(word):
"""
Computes the score of a word (no bingo bonus is added).
word: The word to score (a string).
returns: score of the word.
"""
score = 0
for ch in word:
score += SCRABBLE_LETTER_VALUES[ch]
if len(word) == HAND_SIZE:
score += 50
return score
#
# Problem 2: Representing a Hand
#
class Hand(object):
def __init__(self, handSize, initialHandDict = None):
"""
Initialize a hand.
handSize: The size of the hand
postcondition: initializes a hand with random set of initial letters.
"""
num_vowels = handSize / 3
if initialHandDict is None:
initialHandDict = {}
for i in range(num_vowels):
x = VOWELS[random.randrange(0,len(VOWELS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
for i in range(num_vowels, handSize):
x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
self.initialSize = handSize
self.handDict = initialHandDict
def update(self, word):
"""
Remove letters in word from this hand.
word: The word (a string) to remove from the hand
postcondition: Letters in word are removed from this hand
"""
for c in word:
if self.handDict.get(c, 0) != 0:
self.handDict[c] -= 1
def containsLetters(self, letters):
"""
Test if this hand contains the characters required to make the input
string (letters)
returns: True if the hand contains the characters to make up letters,
False otherwise
"""
copy = self.handDict.copy()
for c in letters:
try:
copy[c] -= 1
if copy[c] < 0:
return False
except:
return False
return True
def isEmpty(self):
"""
Test if there are any more letters left in this hand.
returns: True if there are no letters remaining, False otherwise.
"""
for c in self.handDict:
if self.handDict.get(c, 0) != 0:
return False
return True
def __eq__(self, other):
"""
Equality test, for testing purposes
returns: True if this Hand contains the same number of each letter as
the other Hand, False otherwise
"""
for c in self.handDict:
if self.handDict[c] != other.handDict.get(c, 0):
return False
for c in other.handDict:
if c not in self.handDict:
return False
return True
def __str__(self):
"""
Represent this hand as a string
returns: a string representation of this hand
"""
string = ''
for letter in self.handDict.keys():
for j in range(self.handDict[letter]):
string = string + letter + ' '
return string
#
# Problem 3: Representing a Player
#
class Player(object):
"""
General class describing a player.
Stores the player's ID number, hand, and score.
"""
def __init__(self, idNum, hand):
"""
Initialize a player instance.
idNum: integer: 1 for player 1, 2 for player 2. Used in informational
displays in the GUI.
hand: An object of type Hand.
postcondition: This player object is initialized
"""
self.points = 0.
self.idNum = idNum
self.hand = hand
def getHand(self):
"""
Return this player's hand.
returns: the Hand object associated with this player.
"""
return self.hand
def addPoints(self, points):
"""
Add points to this player's total score.
points: the number of points to add to this player's score
postcondition: this player's total score is increased by points
"""
self.points += points
def getPoints(self):
"""
Return this player's total score.
returns: A float specifying this player's score
"""
return self.points
def getIdNum(self):
"""
Return this player's ID number (either 1 for player 1 or
2 for player 2).
returns: An integer specifying this player's ID number.
"""
return self.idNum
def __cmp__(self, other):
"""
Compare players by their scores.
returns: 1 if this player's score is greater than other player's score,
-1 if this player's score is less than other player's score, and 0 if
they're equal.
"""
if self.points > other.points:
return 1
elif self.points < other.points:
return -1
else:
return 0
def __str__(self):
"""
Represent this player as a string
returns: a string representation of this player
"""
return 'Player %d\n\nScore: %.2f\n' % \
(self.getIdNum(), self.getPoints())
#
# Problem 4: Representing a Computer Player
#
class ComputerPlayer(Player):
"""
A computer player class.
Does everything a Player does, but can also pick a word using the
PickBestWord method.
"""
def pickBestWord(self, wordlist):
"""
Pick the best word available to the computer player.
returns: The best word (a string), given the computer player's hand and
the wordlist
"""
points = {}
for word in wordlist.wordlist:
value = 0
for letter in word:
value += SCRABBLE_LETTER_VALUES[letter]
points[word] = value
highest = ''
for word in points:
if self.hand.containsLetters(word):
if highest == '' or points[word]>points[highest]:
highest = word
if highest != '':
return highest
return '.' # no word can be spelled with current hand
def playHand(self, callback, wordlist):
"""
Play a hand completely by passing chosen words to the callback
function.
"""
while callback(self.pickBestWord(wordlist)): pass
class HumanPlayer(Player):
"""
A Human player class.
No methods are needed because everything is taken care of by the GUI.
"""
class Wordlist(object):
"""
A word list.
"""
def __init__(self):
"""
Initializes a Wordlist object.
postcondition: words are read in from a file (WORDLIST_FILENAME, a
global constant) and stored as a list.
"""
inputFile = open(WORDLIST_FILENAME)
try:
self.wordlist = []
for line in inputFile:
self.wordlist.append(line.strip().lower())
finally:
inputFile.close()
def containsWord(self, word):
"""
Test whether this wordlist includes word
word: The word to check (a string)
returns: True if word is in this Wordlist, False if word is not in
Wordlist
"""
return word in self.wordlist
def getList(self):
return self.wordlist
class EndHand(Exception): pass
class Game(object):
"""
Stores the state needed to play a round of the word game.
"""
def __init__(self, mode, wordlist):
"""
Initializes a game.
mode: Can be one of three constant values - HUMAN_SOLO, HUMAN_VS_COMP,
and HUMAN_VS_HUMAN
postcondition: Initializes the players nd their hands.
"""
hand = Hand(HAND_SIZE)
hand2 = Hand(HAND_SIZE, hand.handDict.copy())
if mode == HUMAN_SOLO:
self.players = [HumanPlayer(1, hand)]
elif mode == HUMAN_VS_COMP:
self.players = [HumanPlayer(1, hand),
ComputerPlayer(2, hand2)]
elif mode == HUMAN_VS_HUMAN:
self.players = [HumanPlayer(1, hand),
HumanPlayer(2, hand2)]
self.playerIndex = 0
self.wordlist = wordlist
def getCurrentPlayer(self):
"""
Gets the Player object corresponding to the active player.
returns: The active Player object.
"""
return self.players[self.playerIndex]
def nextPlayer(self):
"""
Changes the game state so that the next player is the active player.
postcondition: playerIndex is incremented
"""
if self.playerIndex + 1 < len(self.players):
self.playerIndex = self.playerIndex + 1
return True
else:
return False
def gameOver(self):
"""
Determines if the game is over
returns: True if the playerIndex >= the number of players, False
otherwise
"""
return self.playerIndex >= len(self.players)
def tryWord(self, word):
if word == '.':
raise EndHand()
player = self.getCurrentPlayer()
hand = player.getHand()
if self.wordlist.containsWord(word) and hand.containsLetters(word):
points = getWordScore(word)
player.addPoints(points)
hand.update(word)
if hand.isEmpty():
raise EndHand()
return points
else:
return None
def getWinner(self):
return max(self.players)
def getNumPlayers(self):
return len(self.players)
def isTie(self):
return len(self.players) > 1 and \
self.players[0].getPoints() == self.players[1].getPoints()
def __str__(self):
"""
Convert this game object to a string
returns: the concatenation of the string representation of the players
"""
string = ''
for player in self.players:
string = string + str(player)
return string
No comments. Sign up or log in to comment # Backend code for PS10
import random
import string
# Global Constants
VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 30
SCRABBLE_LETTER_VALUES = {
'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
}
HUMAN_SOLO = 0
HUMAN_VS_HUMAN = 1
HUMAN_VS_COMP = 2
WORDLIST_FILENAME = "words.txt"
def getFrequencyDict(sequence):
"""
Given a sequence of letters, convert the sequence to a dictionary of
letters -> frequencies. Used by containsLetters().
returns: dictionary of letters -> frequencies
"""
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
def getWordScore(word):
"""
Computes the score of a word (no bingo bonus is added).
word: The word to score (a string).
returns: score of the word.
"""
score = 0
for ch in word:
score += SCRABBLE_LETTER_VALUES[ch]
if len(word) == HAND_SIZE:
score += 50
return score
#
# Problem 2: Representing a Hand
#
class Hand(object):
def __init__(self, handSize, initialHandDict = None):
"""
Initialize a hand.
handSize: The size of the hand
postcondition: initializes a hand with random set of initial letters.
"""
num_vowels = handSize / 3
if initialHandDict is None:
initialHandDict = {}
for i in range(num_vowels):
x = VOWELS[random.randrange(0,len(VOWELS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
for i in range(num_vowels, handSize):
x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
self.initialSize = handSize
self.handDict = initialHandDict
def update(self, word):
"""
Remove letters in word from this hand.
word: The word (a string) to remove from the hand
postcondition: Letters in word are removed from this hand
"""
for letter in word:
self.handDict[letter] = self.handDict.get(letter, 0) - 1
if self.handDict[letter] == 0:
del self.handDict[letter]
def containsLetters(self, letters):
"""
Test if this hand contains the characters required to make the input
string (letters)
returns: True if the hand contains the characters to make up letters,
False otherwise
"""
tmpDict = self.handDict.copy()
for letter in letters:
if tmpDict.get(letter, 0) == 0:
return False
else:
tmpDict[letter] = tmpDict.get(letter, 0) - 1
return True
def isEmpty(self):
"""
Test if there are any more letters left in this hand.
returns: True if there are no letters remaining, False otherwise.
"""
if self.handDict:
return False
else:
return True
def __eq__(self, other):
"""
Equality test, for testing purposes
returns: True if this Hand contains the same number of each letter as
the other Hand, False otherwise
"""
if self.handDict.equal(other):
return True
else:
return False
def __str__(self):
"""
Represent this hand as a string
returns: a string representation of this hand
"""
string = ''
for letter in self.handDict.keys():
for j in range(self.handDict[letter]):
string = string + letter + ' '
return string
#
# Problem 3: Representing a Player
#
class Player(object):
"""
General class describing a player.
Stores the player's ID number, hand, and score.
"""
def __init__(self, idNum, hand):
"""
Initialize a player instance.
idNum: integer: 1 for player 1, 2 for player 2. Used in informational
displays in the GUI.
hand: An object of type Hand.
postcondition: This player object is initialized
"""
self.points = 0.
self.idNum = idNum
self.hand = hand
def getHand(self):
"""
Return this player's hand.
returns: the Hand object associated with this player.
"""
return self.hand
def addPoints(self, points):
"""
Add points to this player's total score.
points: the number of points to add to this player's score
postcondition: this player's total score is increased by points
"""
self.points += points
def getPoints(self):
"""
Return this player's total score.
returns: A float specifying this player's score
"""
return self.points
def getIdNum(self):
"""
Return this player's ID number (either 1 for player 1 or
2 for player 2).
returns: An integer specifying this player's ID number.
"""
return self.idNum
def __cmp__(self, other):
"""
Compare players by their scores.
returns: 1 if this player's score is greater than other player's score,
-1 if this player's score is less than other player's score, and 0 if
they're equal.
"""
return cmp(self.points, other.getPoints())
def __str__(self):
"""
Represent this player as a string
returns: a string representation of this player
"""
return 'Player %d\n\nScore: %.2f\n' % \
(self.getIdNum(), self.getPoints())
#
# Problem 4: Representing a Computer Player
#
class ComputerPlayer(Player):
"""
A computer player class.
Does everything a Player does, but can also pick a word using the
PickBestWord method.
"""
def pickBestWord(self, wordlist):
"""
Pick the best word available to the computer player.
returns: The best word (a string), given the computer player's hand and
the wordlist
"""
word = "."
score = 0
best_score = 0
h = self.getHand()
for tmp_word in wordlist.getList():
if h.containsLetters(tmp_word):
score = getWordScore(tmp_word)
if score > best_score:
word = tmp_word
best_score = score
return word
def playHand(self, callback, wordlist):
"""
Play a hand completely by passing chosen words to the callback
function.
"""
while callback(self.pickBestWord(wordlist)): pass
class HumanPlayer(Player):
"""
A Human player class.
No methods are needed because everything is taken care of by the GUI.
"""
class Wordlist(object):
"""
A word list.
"""
def __init__(self):
"""
Initializes a Wordlist object.
postcondition: words are read in from a file (WORDLIST_FILENAME, a
global constant) and stored as a list.
"""
inputFile = open(WORDLIST_FILENAME)
try:
self.wordlist = []
for line in inputFile:
self.wordlist.append(line.strip().lower())
finally:
inputFile.close()
def containsWord(self, word):
"""
Test whether this wordlist includes word
word: The word to check (a string)
returns: True if word is in this Wordlist, False if word is not in
Wordlist
"""
return word in self.wordlist
def getList(self):
return self.wordlist
class EndHand(Exception): pass
class Game(object):
def __init__(self, mode, wordlist):
hand = Hand(HAND_SIZE)
hand2 = Hand(HAND_SIZE, hand.handDict.copy())
if mode == HUMAN_SOLO:
self.players = [HumanPlayer(1, hand)]
elif mode == HUMAN_VS_COMP:
self.players = [HumanPlayer(1, hand),
ComputerPlayer(2, hand2)]
elif mode == HUMAN_VS_HUMAN:
self.players = [HumanPlayer(1, hand),
HumanPlayer(2, hand2)]
self.playerIndex = 0
self.wordlist = wordlist
def getCurrentPlayer(self):
return self.players[self.playerIndex]
def nextPlayer(self):
if self.playerIndex + 1 < len(self.players):
self.playerIndex = self.playerIndex + 1
return True
else:
return False
def gameOver(self):
return self.playerIndex >= len(self.players)
def tryWord(self, word):
if word == '.':
raise EndHand()
player = self.getCurrentPlayer()
hand = player.getHand()
if self.wordlist.containsWord(word) and hand.containsLetters(word):
points = getWordScore(word)
player.addPoints(points)
hand.update(word)
if hand.isEmpty():
raise EndHand()
return points
else:
return None
def getWinner(self):
return max(self.players)
def getNumPlayers(self):
return len(self.players)
def isTie(self):
return len(self.players) > 1 and \
self.players[0].getPoints() == self.players[1].getPoints()
def __str__(self):
string = ''
for player in self.players:
string = string + str(player)
return string
No comments. Sign up or log in to comment # Backend code for PS10
import random
import string
# Global Constants
VOWELS = 'aeiou'
CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HAND_SIZE = 30
SCRABBLE_LETTER_VALUES = {'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}
HUMAN_SOLO = 0
HUMAN_VS_HUMAN = 1
HUMAN_VS_COMP = 2
WORDLIST_FILENAME = "words.txt"
def getFrequencyDict(sequence):
"""
Given a sequence of letters, convert the sequence to a dictionary of
letters -> frequencies. Used by containsLetters().
returns: dictionary of letters -> frequencies
"""
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
def getWordScore(word):
"""
Computes the score of a word (no bingo bonus is added).
word: The word to score (a string).
returns: score of the word.
"""
score = 0
for ch in word:
score += SCRABBLE_LETTER_VALUES[ch]
if len(word) == HAND_SIZE:
score += 50
return score
#
# Problem 2: Representing a Hand
#
class Hand(object):
def __init__(self, handSize, initialHandDict = None):
"""
Initialize a hand.
handSize: The size of the hand
postcondition: initializes a hand with random set of initial letters.
"""
num_vowels = handSize / 3
if initialHandDict is None:
initialHandDict = {}
for i in range(num_vowels):
x = VOWELS[random.randrange(0,len(VOWELS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
for i in range(num_vowels, handSize):
x = CONSONANTS[random.randrange(0,len(CONSONANTS))]
initialHandDict[x] = initialHandDict.get(x, 0) + 1
self.initialSize = handSize
self.handDict = initialHandDict
def update(self, word):
"""
Remove letters in word from this hand.
word: The word (a string) to remove from the hand
postcondition: Letters in word are removed from this hand
"""
for letter in word: # goes through the word
if self.handDict[letter] > 1: # if the number of letters in hand is > 1
self.handDict[letter] = self.handDict.pop(letter) - 1 # the number is reduced by 1
else:
self.handDict.pop(letter) # if less than one, the key:value pair is removed
# pop(key, default = error) removes the key:value pair and displays the value
return self.handDict
def containsLetters(self, letters):
"""
Test if this hand contains the characters required to make the input
string (letters)
returns: True if the hand contains the characters to make up letters,
False otherwise
"""
self.testDict = 0
self.tempDict = self.handDict.copy()
for letter in letters:
if self.tempDict.get(letter, 0) > 0:
self.tempDict[letter] = self.tempDict.pop(letter) - 1
self.testDict += 1
if self.testDict != len(letters):
return False
else:
return True
def isEmpty(self):
"""
Test if there are any more letters left in this hand.
returns: True if there are no letters remaining, False otherwise.
"""
return len(self.handDict) == 0
def __eq__(self, other):
"""
Equality test, for testing purposes
returns: True if this Hand contains the same number of each letter as
the other Hand, False otherwise
"""
return other.handDict == self.handDict
def __str__(self):
"""
Represent this hand as a string
returns: a string representation of this hand
"""
string = ''
for letter in self.handDict.keys():
for j in range(self.handDict[letter]):
string = string + letter + ' '
return string
#
# Problem 3: Representing a Player
#
class Player(object):
"""
General class describing a player.
Stores the player's ID number, hand, and score.
"""
def __init__(self, idNum, hand):
"""
Initialize a player instance.
idNum: integer: 1 for player 1, 2 for player 2. Used in informational
displays in the GUI.
hand: An object of type Hand.
postcondition: This player object is initialized
"""
self.points = 0.
self.idNum = idNum
self.hand = hand
def getHand(self):
"""
Return this player's hand.
returns: the Hand object associated with this player.
"""
return self.hand
def addPoints(self, points):
"""
Add points to this player's total score.
points: the number of points to add to this player's score
postcondition: this player's total score is increased by points
"""
self.points = self.points + points
return self.points
def getPoints(self):
"""
Return this player's total score.
returns: A float specifying this player's score
"""
return self.points
def getIdNum(self):
"""
Return this player's ID number (either 1 for player 1 or
2 for player 2).
returns: An integer specifying this player's ID number.
"""
return self.idNum
def __cmp__(self, other):
"""
Compare players by their scores.
returns: 1 if this player's score is greater than other player's score,
-1 if this player's score is less than other player's score, and 0 if
they're equal.
"""
self.sign = self.getPoints() - other.getPoints()
if self.sign > 0:
return 1
if self.sign < 0:
return -1
else:
return 0
def __str__(self):
"""
Represent this player as a string
returns: a string representation of this player
"""
return 'Player %d\n\nScore: %.2f\n' % \
(self.getIdNum(), self.getPoints())
#
# Problem 4: Representing a Computer Player
#
class ComputerPlayer(Player):
"""
A computer player class.
Does everything a Player does, but can also pick a word using the
PickBestWord method.
"""
def pickBestWord(self, wordlist):
"""
Pick the best word available to the computer player.
returns: The best word (a string), given the computer player's hand and
the wordlist
"""
self.goodwords = []
self.bestword = None
self.bestvalue = 0
for word in wordlist.getList():
if self.hand.containsLetters(word):
self.goodwords.append(word)
for word in self.goodwords:
self.points = getWordScore(word)
if self.points > self.bestvalue:
self.bestvalue = self.points
self.bestword = word
if self.bestword == None:
return '.'
else:
return self.bestword
def playHand(self, callback, wordlist):
"""
Play a hand completely by passing chosen words to the callback
function.
"""
while callback(self.pickBestWord(wordlist)): pass
class HumanPlayer(Player):
"""
A Human player class.
No methods are needed because everything is taken care of by the GUI.
"""
class Wordlist(object):
"""
A word list.
"""
def __init__(self):
"""
Initializes a Wordlist object.
postcondition: words are read in from a file (WORDLIST_FILENAME, a
global constant) and stored as a list.
"""
inputFile = open(WORDLIST_FILENAME)
try:
self.wordlist = []
for line in inputFile:
self.wordlist.append(line.strip().lower())
finally:
inputFile.close()
def containsWord(self, word):
"""
Test whether this wordlist includes word
word: The word to check (a string)
returns: True if word is in this Wordlist, False if word is not in
Wordlist
"""
return word in self.wordlist
def getList(self):
return self.wordlist
class EndHand(Exception): pass
class Game(object):
"""
Stores the state needed to play a round of the word game.
"""
def __init__(self, mode, wordlist):
"""
Initializes a game.
mode: Can be one of three constant values - HUMAN_SOLO, HUMAN_VS_COMP,
and HUMAN_VS_HUMAN
postcondition: Initializes the players nd their hands.
"""
hand = Hand(HAND_SIZE)
hand2 = Hand(HAND_SIZE, hand.handDict.copy())
if mode == HUMAN_SOLO:
self.players = [HumanPlayer(1, hand)]
elif mode == HUMAN_VS_COMP:
self.players = [HumanPlayer(1, hand),
ComputerPlayer(2, hand2)]
elif mode == HUMAN_VS_HUMAN:
self.players = [HumanPlayer(1, hand),
HumanPlayer(2, hand2)]
self.playerIndex = 0
self.wordlist = wordlist
def getCurrentPlayer(self):
"""
Gets the Player object corresponding to the active player.
returns: The active Player object.
"""
return self.players[self.playerIndex]
def nextPlayer(self):
"""
Changes the game state so that the next player is the active player.
postcondition: playerIndex is incremented
"""
if self.playerIndex + 1 < len(self.players):
self.playerIndex = self.playerIndex + 1
return True
else:
return False
def gameOver(self):
"""
Determines if the game is over
returns: True if the playerIndex >= the number of players, False
otherwise
"""
return self.playerIndex >= len(self.players)
def tryWord(self, word):
if word == '.':
raise EndHand()
player = self.getCurrentPlayer()
hand = player.getHand()
if self.wordlist.containsWord(word) and hand.containsLetters(word):
points = getWordScore(word)
player.addPoints(points)
hand.update(word)
if hand.isEmpty():
raise EndHand()
return points
else:
return None
def getWinner(self):
return max(self.players)
def getNumPlayers(self):
return len(self.players)
def isTie(self):
return len(self.players) > 1 and \
self.players[0].getPoints() == self.players[1].getPoints()
def __str__(self):
"""
Convert this game object to a string
returns: the concatenation of the string representation of the players
"""
string = ''
for player in self.players:
string = string + str(player)
return string
No comments. Sign up or log in to comment |
No comments. Sign up or log in to comment