|
MIT OpenCourseWare 6.00 Introduction to Computer Science and ProgrammingClass length: 13 weeks. Start anytime. Creator: duallain Status: Under Construction |
|
Assignment 2There is one problem set, but I have split it into two assignments so you can paste your code for the two games separately. Please post your solutions thusly:
POST YOUR SOLUTIONS TO GHOST HERE.The solutions to the 6.00 Wordgame should be posted to lesson 9 HW 1
Homework Submissions (6 total):I wrote Ghost with the same variable-passing work-around I used for global variables in the 6.00 Wordgame. #!/usr/bin/env python
#-*- coding:utf-8 -*-
import random
# -----------------------------------
# Helper code
# (you don't need to understand this helper code)
import string
WORDLIST_FILENAME = "/home/dave/Documents/python/Assignments/ps5/words.txt"
def load_words():
"""
Returns a list of valid words. Words are strings of lowercase letters.
Depending on the size of the word list, this function may
take a while to finish.
"""
print "Loading word list from file..."
# inFile: file
inFile = open(WORDLIST_FILENAME, 'r', 0)
# wordlist: list of strings
word_list = []
for line in inFile:
word_list.append(line.strip().lower())
print " ", len(word_list), "words loaded."
return word_list
def get_frequency_dict(sequence):
"""
Returns a dictionary where the keys are elements of the sequence
and the values are integer counts, for the number of times that
an element is repeated in the sequence.
sequence: string or list
return: dictionary
"""
# freqs: dictionary (element_type -> int)
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
# (end of helper code)
# -----------------------------------
# Load the dictionary of words and point to it with
# the wordlist variable so that it can be accessed from anywhere
# in the program.
# word_list = load_words()
#def generate_letter():
# '''Returns a random, lowercase letter'''
# index = random.randint(0, 25)
# char = string.lowercase[index]
# return char
# returns true if sequence is a valid word longer than 3 characters
def is_valid_word(word, word_list):
"""
Returns True if word is in the word_list and is entirely
composed of letters in the hand. Otherwise, returns False.
Does not mutate hand or word_list. DOES NOT FAIL IF word IS AN
INVALID WORD FRAGMENT.
word: string
hand: dictionary (string -> int)
word_list: list of lowercase strings
"""
if len(word) < 4:
return False
elif word in word_list:
return True
else:
return False
#
# returns true if input is a valid word fragment or word, else returns false. To confirm 'word' is a playable fragment, contrast result with is_valid_word()
def is_valid_fragment(fragment, word_list):
n = len(fragment)
for word in word_list:
if len(word) < n: # if 'word' is smaller than frag, skip
continue
for i in range(0,n):
if word[i] == fragment[i]: # stepwise comparison iterating by index
if i == (n - 1):
return True
else:
i += 1
continue
else:
break
return False
def update_player(player):
if player is 1:
player = 2
else:
player = 1
return player
# tests word sequence. If valid word fragment, returns 1. If invalid word fragment, returns 2. If valid word longer than 3 characters, returns 0.
def word_test(word, word_list):
is_word = is_valid_word(word, word_list)
if is_word:
return 0
else:
frag = is_valid_fragment(word, word_list)
if frag:
return 1
else:
return 2
def new_game(word_list):
newgame = raw_input("Play again? (y/n)\n")
if newgame == 'y':
play_game(word_list)
elif newgame == 'n':
print "Thanks for playing!"
return ""
else:
print newgame, " is not a valid option."
new_game(word_list)
# Effectively plays a round. Accepts user input. converts uppercase to lower case, requests new input if not a valid character. User can input '.' to exit.
def play_char(word_list, word, player):
print "Current word fragment: ", word
print "\nPlayer", player,
char = raw_input("plays letter: ")
if char == '.':
print "Thanks for playing!"
return ''
elif char in string.letters:
char = string.lower(char)
word_temp = word[:] + char
test = word_test(word_temp, word_list)
if test == 2:
print word_temp, " is not a valid word fragment. Please try again.\n"
play_char(word_list, word, player)
elif test == 0:
print word_temp, "is a word."
print "GAME OVER."
new_game(word_list)
elif test == 1:
player = update_player(player)
word = word_temp
play_char(word_list, word, player)
else:
print char, " is not a valid character."
play_char(word_list, word, player)
## initiates computers turn
## def computer_plays():
##
## initiates two player game. Prompts whether player wants to go first.
## def two_players(word_list):
## pass
##
## initiates a single player game
## def single_player(word_list):
## pass
# initiate game.
# ONCE GAME IS BUILT: prompt number of players. If 1, player vs. computer. If 2, human vs. human. After each round, prompt player if they want to play again. Also, insert option to track score later on.
def play_game(word_list):
word = ''
player = 1
print "Welcome to Ghost!"
print "Player 1 goes first. Type '.' to quit round."
play_char(word_list, word, player)
if __name__ == '__main__':
word_list = load_words()
play_game(word_list)
Permalink
# Problem Set 5, Part 2
#########
# GHOST #
#########
# -----------------------------------
# Helper code
# (you don't need to understand this helper code)
import string
WORDLIST_FILENAME = "words.txt"
def load_words():
"""
Returns a list of valid words. Words are strings of lowercase letters.
Depending on the size of the word list, this function may
take a while to finish.
"""
print "Loading word list from file..."
# inFile: file
inFile = open(WORDLIST_FILENAME, 'r', 0)
# wordlist: list of strings
wordlist = []
for line in inFile:
wordlist.append(line.strip().upper())
print " ", len(wordlist), "words loaded."
return wordlist
def get_frequency_dict(sequence):
"""
Returns a dictionary where the keys are elements of the sequence
and the values are integer counts, for the number of times that
an element is repeated in the sequence.
sequence: string or list
return: dictionary
"""
# freqs: dictionary (element_type -> int)
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
# (end of helper code)
# -----------------------------------
def isvalid(wordSoFar, wordlist):
"""
Takes in the word created so far as well as a list of valid words.
Returns, in a tuple:
[0] Whether the game has ended (a word has been or cannot be formed)
[1] An updated word list containing the remaining possible words
"""
numltr = len(wordSoFar)
# Make a list of all possible words that can be formed.
# The word list is updated to include only these words.
newwordlist = [word for word in wordlist if wordSoFar in word[0:numltr]]
# Checks to see if any possible words were found
if len(newwordlist) == 0:
gameover = True
print '\nThere is no word that begins with the letters',\
wordSoFar + '!'
# Checks to see if a word has already been formed
elif wordSoFar in wordlist and numltr > 3:
gameover = True
print '\nYou have formed the word', wordSoFar + '!'
else: gameover = False
return (gameover, newwordlist)
def swapPlayer(p):
"""Switches the player from 1 to 2 or vice versa"""
if p == 1:
p = 2
else: p = 1
return p
def playGhost(p):
"""
This represents a round of the game.
The input is the starting player; the winner is the output.
"""
word = ''
wordlist = masterwordlist
gameover = False
while not gameover:
# This runs until the player enters an acceptable character
while True:
print '\nThe word so far is:', word
ltr = raw_input("It's your turn, Player " + str(p) +\
'. ' + 'Add a letter! ').upper()
# Stops the loop when a letter is entered
if (ltr in string.ascii_letters) and (len(ltr) == 1):
word += ltr
break
# Helpful message if an unacceptable character is entered
print '\nInvalid input. Try again!'
gameover,wordlist = isvalid(word, wordlist)
p = swapPlayer(p)
print 'Player',p,'wins!'
return p
def ghost():
"""
Play the exciting two-player word game Ghost!
Players alternate entering letters to form a word, or more accurately,
to NOT form a word while forming the beginnings of a word.
A player loses if he or she:
(1) Forms a complete word greater than 3 letters long
(2) Creates a fragment which cannot become a word by adding more letters
("QZ", for example)
"""
scores = [0,0]
first = 1 # Player 1 goes first in the first game. It then alternates.
while True:
action = raw_input('\nWelcome to Ghost! Enter "1" to play a round,'+\
'"2" to reset the scores, or "3" to exit. ')
if action is '1':
winrar = playGhost(first)
scores[winrar-1] += 1
print '\nThe overall score is:'
print 'Player 1:',scores[0]
print 'Player 2:',scores[1],'\n'
first = swapPlayer(first)
elif action is '2':
scores = [0,0]
print 'The scores have been reset.'
elif action is '3':
break
else: print '\nInvalid input. How about trying one of the given'+\
'options?'
if __name__ == '__main__':
masterwordlist = load_words()
ghost()
Permalink
No comments. Sign up or log in to comment # Problem Set 5: Ghost
# Name:
# Collaborators:
# Time:
#
import random
# -----------------------------------
# Helper code
# (you don't need to understand this helper code)
import string
WORDLIST_FILENAME = "words.txt"
def load_words():
"""
Returns a list of valid words. Words are strings of lowercase letters.
Depending on the size of the word list, this function may
take a while to finish.
"""
print "Loading word list from file..."
# inFile: file
inFile = open(WORDLIST_FILENAME, 'r', 0)
# wordlist: list of strings
wordlist = []
for line in inFile:
wordlist.append(line.strip().lower())
print " ", len(wordlist), "words loaded."
return wordlist
def get_frequency_dict(sequence):
"""
Returns a dictionary where the keys are elements of the sequence
and the values are integer counts, for the number of times that
an element is repeated in the sequence.
sequence: string or list
return: dictionary
"""
# freqs: dictionary (element_type -> int)
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
# (end of helper code)
# -----------------------------------
# Actually load the dictionary of words and point to it with
# the wordlist variable so that it can be accessed from anywhere
# in the program.
def lost_by_word(word, wordlist):
"""Did player lost the game?"""
if len(word) > 3 and word in wordlist:
return True
return False
def lost_by_no_word(word, wordlist):
for tmp_word in wordlist:
if word in tmp_word[0:len(word)]:
print tmp_word
return False
return True
def test_lost_by_word(wordlist):
succeed = True
word = "eye"
if lost_by_word(word, wordlist):
print "Must return False and got True with word " + word
succeed = False
word = "banana"
if not lost_by_word(word, wordlist):
print "Must return True and got False with word " + word
succeed = False
if succeed:
print "All test passed"
else:
print "Failed"
def test_lost_by_no_word(wordlist):
succeed = True
word = "zar"
if not lost_by_no_word(word, wordlist):
print "Must return True and got False with word " + word
succeed = False
word = "pyn"
if lost_by_no_word(word, wordlist):
print "Must return False and got True with word " + word
succeed = False
if succeed:
print "All test passed"
else:
print "Failed"
def ghost(wordlist):
print "Welcome to Ghost"
print "Player 1 goes first."
game_over = False
fragment = ''
current_player = 1
while not game_over:
print "Current word fragment: '" + fragment + "'"
no_letter = True
while no_letter:
letter = raw_input("Player " + str(current_player) + " says letter: ")
if letter not in string.ascii_letters:
print "A letter please!"
else:
no_letter = False
fragment += letter.lower()
#print fragment
if lost_by_word(fragment, wordlist):
game_over = True
print "Player " + str(current_player) + " loses because '" + fragment + "' is a word!"
if lost_by_no_word(fragment, wordlist):
game_over = True
print "Player " + str(current_player) + " loses no word begins with " + fragment
if current_player == 1:
current_player = 2
else:
current_player = 1
if game_over:
print "Player " + str(current_player) + " wins!"
wordlist = load_words()
ghost(wordlist)
# test_lost_by_word(wordlist)
# test_lost_by_no_word(wordlist)
Permalink
No comments. Sign up or log in to comment This was fun! import random
#---Helper code
import string
WORDLIST_FILENAME = "words.txt"
def load_words():
"""
Returns a list of valid words. Words are strings of lowercase letters.
Depending on the size of the word list, this function may
take a while to finish.
"""
print "Loading word list from file..."
# inFile: file
inFile = open(WORDLIST_FILENAME, 'r', 0)
# wordlist: list of strings
wordlist = []
for line in inFile:
wordlist.append(line.strip().lower())
print " ", len(wordlist), "words loaded."
return wordlist
def get_frequency_dict(sequence):
"""
Returns a dictionary where the keys are elements of the sequence
and the values are integer counts, for the number of times that
an element is repeated in the sequence.
sequence: string or list
return: dictionary
"""
# freqs: dictionary (element_type -> int)
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
#---End of helper code
# Actually load the dictionary of words and point to it with
# the wordlist variable so that it can be accessed from anywhere
# in the program.
wordlist = load_words()
def get_letter(message):
"""
Asks the player for a letter, checks that it is a valid
letter and returns that letter if it is.
message: string
return: string
"""
letter = raw_input(message)
while True:
if letter in string.ascii_letters and len(letter) == 1:
return letter
else:
letter = raw_input("not a valid letter, please try again: ")
def update_stub(stub, letter):
"""
Adds a valid letter to a given stub and returns the new stub.
letter: string
stub: string
"""
new_stub = stub + letter
print "Current word fragment is: %s" % string.upper(new_stub)
return new_stub
def validate_stub(stub, wordlist):
"""
Checks if a given stub is a valid part word, also checking if
it is a full word already returning a code for each result:
0 = not a valid word fragment
1 = a valid fragment
2 = already a complete word longer than 3 characters
stub: string
wordlist: list
"""
def slice_words(stub, wordlist):
"""
Slices each item in the wordlist to the same number of characters
as the stub then returns the unique items in this new list.
stub: string
wordlist: list
"""
length = len(stub)
sliced_list = []
for word in wordlist:
sliced_list.append(word[:length])
return set(sliced_list) # cast the list to a set to remove all dups
if stub in slice_words(stub, wordlist):
if stub in wordlist and len(stub) > 3:
return 2
else:
return 1
else:
return 0
# TODO: write outer loop that will ask to play again or exit
def main_loop():
play_again = 1
while play_again == 1:
inner_loop()
again = string.upper(raw_input("Play again (Y or N)"))
while True:
if again == "Y":
play_again = 1
break
elif again == "N":
play_again = 0
break
else:
again = string.upper(raw_input("Please enter Y or N"))
def inner_loop():
letter = ""
stub = ""
player = 1
game_state = 1
print "Welcome to Ghost!"
print "Player 1 goes first"
while game_state == 1:
letter = get_letter("Player %i's letter: " % player)
stub = update_stub(stub, letter)
if player == 1:
player += 1
elif player == 2:
player -= 1
game_state = validate_stub(stub, wordlist)
game_states = {0: "is not a valid word fragment",
1: "is a valid stub",
2: "is a full word"}
if player == 1:
player += 1
elif player == 2:
player -= 1
print "player %i looses because '%s' %s" % (player, string.upper(stub),
game_states[game_state])
main_loop()
Permalink
No comments. Sign up or log in to comment Word games # Problem Set 5: Ghost
# Name: Joe Li
# Time: 3:30
#
import random
# -----------------------------------
# Helper code
# (you don't need to understand this helper code)
import string
WORDLIST_FILENAME = "words.txt"
def load_words():
"""
Returns a list of valid words. Words are strings of lowercase letters.
Depending on the size of the word list, this function may
take a while to finish.
"""
print "Loading word list from file..."
# inFile: file
inFile = open(WORDLIST_FILENAME, 'r', 0)
# wordlist: list of strings
wordlist = []
for line in inFile:
wordlist.append(line.strip().lower())
print " ", len(wordlist), "words loaded."
return wordlist
def get_frequency_dict(sequence):
"""
Returns a dictionary where the keys are elements of the sequence
and the values are integer counts, for the number of times that
an element is repeated in the sequence.
sequence: string or list
return: dictionary
"""
# freqs: dictionary (element_type -> int)
freq = {}
for x in sequence:
freq[x] = freq.get(x,0) + 1
return freq
# (end of helper code)
# -----------------------------------
# Actually load the dictionary of words and point to it with
# the wordlist variable so that it can be accessed from anywhere
# in the program.
wordlist = load_words()
def ghost(wordlist):
print 'Welcome to Ghost!'
current=''
print 'Player 1 goes first.'
turn=1
player=1
valid=1
# if valid=1, this game continue
while valid==1:
if turn>1:
# the odd turn is player 1's turn, the even trun is player 2's turn
if turn%2==0:
player='2'
else:
player='1'
print 'Player '+player+'\'s turn.'
#this messege should only occur since 2nd turn
else:
#the 1st turn is player 1's turn
player='1'
print 'Current word fragment: '+current
letter=string.lower(raw_input('Player '+player+' says letter: '))
valid=0
passtest=0
# if passtest==0 after the test, means that no word begins with the current word
if letter in string.ascii_letters:
# make sure only one letter entered
current+=letter
for word in wordlist:
# check if there's a word start with the current word
if len(current)<=len(word):
if current==word[:len(current)]:
passtest=1
if passtest==1:
if len(current)>3:
# if len(current)>3, the current word can't be an actual word, else the player lose
if not current in wordlist:
# the current word isn't yet an actual word
valid=1
# game continue
turn+=1
else:
# the current word is an actual word
print 'Player '+player+' loses because \''+current+'\' is a word!'
if player==1:
print 'Player 2 wins!'
else:
print 'Player 1 win!'
else:
# if the len(current)<=3, then it doesn't matter
valid=1
turn+=1
else:
# fail the passtest
print 'Player '+player+' loses because no word begins with \''+current+'\'!'
if player=='1':
print 'Player 2 wins!'
else:
print 'Player 1 win!'
else:
# whatever entered is not a letter
print 'Please enter a letter.'
valid=1
ghost(wordlist)
Permalink
No comments. Sign up or log in to comment #Problem Set 5
#Name: chip
WORDLIST_FILENAME = "words.txt"
def load_words():
inFile = open(WORDLIST_FILENAME, encoding='utf-8')
wordlist = []
for line in inFile:
wordlist.append(line.strip().lower())
return wordlist
word_list = load_words()
def make_turn(player, fragment):
print("Current word fragment:\'",fragment,"\'")
print(player, "turn")
letter = input(player + " says letter: ")
if check_input(letter) != False:
fragment += letter
check_fragment(fragment)
return fragment
def check_input(letter):
if not letter.isalpha() or len(letter) != 1:
return False
return True
def check_fragment(fragment):
fg = fragment.lower().strip()
if fg in word_list and len(fg) > 3:
return fragment + " is a word"
for word in word_list:
indx = word.find(fg)
if indx != -1:
if indx == 0:
return True
return "no words begins with " + fragment;
def play_game():
players = ["Player 1", "Player 2"]
player = 0
fragment = ""
print ("Welcome to Ghost!")
while True:
fragment = make_turn(players[player], fragment)
fragment_check = check_fragment(fragment)
if fragment_check != True:
print("Player", players[player],"loses because",fragment_check)
break
if player + 1 >= len(players):
player = 0
else:
player += 1
print("\n")
play_game()
Permalink
No comments. Sign up or log in to comment |
Comments:
4 months ago
my one 'problem' with this set of code (which I haven't gone through your other code to see if you do the same thing), but some of your comments are too long for a single line.
If you read the 'Code Like a Pythonista' article about long lines it talks about good code practice. I linked to the part about long lines: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#long-lines-continuations
4 months ago
so apparently you can't edit comments after you post them, but here's an actual link to the Code Like a Pythonista book, specifically about line length
Sign up or log in to comment