MIT OpenCourseWare 6.00 Introduction to Computer Science and Programming

Class length: 13 weeks. Start anytime.

Creator: duallain

Status: Under Construction

Assignment 2

There 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:

  • Assignment 1 = 6.00 Wordgame (ps5.py)
  • Assignment 2 = Ghost (ps5_ghost.py)

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):

shaggorama (Self-grade: Outstanding)
Submitted 5 months ago

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

Comments:

piratelax40
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

piratelax40
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

zpritchard (Self-grade: Outstanding)
Submitted 3 months ago
# 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
BTheMad (Self-grade: Pretty good)
Submitted 1 month ago
# 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
hendrix (Self-grade: Outstanding)
Submitted 1 month ago

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
Joe (Self-grade: Outstanding)
Submitted 1 month ago

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
chip (Self-grade: Outstanding)
Submitted 3 weeks ago
#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

Recent Class Activity

hendrix submitted Lesson 12 HW 1
2 days ago
ndwhite13 submitted Lesson 1 HW 1
3 days ago
NawXela submitted Lesson 3 HW 1
5 days ago
chip submitted Lesson 12 HW 1
2 weeks ago
chip submitted Lesson 11 HW 1
2 weeks ago
hendrix submitted Lesson 11 HW 1
3 weeks ago
rs031759 submitted Lesson 2 HW 1
3 weeks ago
rs031759 submitted Lesson 1 HW 1
3 weeks ago

Class Members (198)

ndwhite13
Joined 3 days ago
chrixian
Joined 5 days ago
marcosdecarvalho
Joined 1 week ago
pangor
Joined 2 weeks ago
paroxysm
Joined 2 weeks ago
mkaymer
Joined 2 weeks ago
sundeep
Joined 2 weeks ago
reddog69
Joined 3 weeks ago

All members


License

Attribution Non-Commercial Share Alike