#Dan Schafer
#2-7-05

import os
import time
import sys
import random

#Import the dicitonary and return it
def getWords():

	file = open("dictionary.txt","r")
	text = file.readlines()
	file.close()
	ref = [i[0:-1] for i in text]
	return ref

#Get an array of names of length numPlayers
def getNames(numPlayers):

	names = [""]*numPlayers
	for i in range(numPlayers):
		names[i] = raw_input("Enter name for player "+str(i+1)+": ")
	return names

#Get an array of types of length numPlayers
def getTypes(numPlayers):

	types = [""]*numPlayers
	for i in range(numPlayers):
		types[i] = raw_input("Enter type of player "+str(i+1)+" (C)PU or (H)uman: ")
		if types[i] == "C" or types[i] == "c":
			types[i] = "CPU"
		else:
			types[i] = "Human"
	return types
	

#Test for whether "word" is in "dic"
def isWord(word, dic):

	return (word in dic and len(word) > 3)

	#lowerWord = word.lower()
	#for testWord in dic:
	#	if lowerWord == testWord:
	#		return True
	#return False
	


#Test for whether "word" is the start of any word in "dic"
def isStartOfWord(word, dic):

	lowerWord = word.lower()
	wordLength = len(word)
	for testWord in dic:
		if lowerWord == testWord[0:wordLength]:
			return testWord
	return False

#Adds the next letter to the current score
def getNextStatus(currStatus, gameString):

	currLen = len(currStatus)
	return gameString[0:currLen+1]

#Check to see if there are any winners
def anyWinners(score, gameString):

	for s in score:
		if s == gameString:
			return True
	return False

#Get input
def getInput(player, typeOfPlayer, dic, word, numP):

	if typeOfPlayer[0].lower() == "h":
		string = raw_input("Next Letter from "+typeOfPlayer+" "+player+": ").lower();
	else:
		string = getAI(player, dic, word, numP)
		print "Next Letter from "+typeOfPlayer+" "+player+": "+string
	return string

#Get AI letter choice
def getAI(player, dic, word, numP):

	if isWord(word,dic):
		return "word"
	if not isStartOfWord(word,dic):
		return "cant"
	nextLetter = findLetter(word,dic, numP)
	return nextLetter

def findLetter(word, dic, numP):

	showThinking = False
	words = allPossibleWords(word,dic)
	patience = 100
	for tries in range(patience):
		test = random.choice(words)

		numTurns = (len(test) - len(word))
		isLonger = (len(test) - len(word)) > 0
		isMoreThanThree = len(test) > 3
		isItAWord = isWord(test[0:len(word)+1],dic)
		hasOtherWord = ifHasOtherWordInIt(test, dic, word)
		if showThinking:
			print "My logic tells me that the word "+test+" has:"
			print str(numTurns)+" turns until it is finished."
			print str(isLonger)+" is it longer than the current word." 
			print str(isMoreThanThree)+" is it longer than 3 letters."
			print str(isItAWord)+" it is actually a word."
			print str(hasOtherWord)+" it has another word in it."
			print
		if numTurns % numP == 0 and isLonger and isMoreThanThree and not isItAWord and not hasOtherWord:
			return test[len(word)]
	getBluff(word)
	return getBluff(word)

def getBluff(word):
	consonants = "bcdfghjklmnpqrstvwxyz"
	vowels = "aeiou"
	if word[-1] in consonants:
		return random.choice(vowels)
	return random.choice(consonants)

def allPossibleWords(word, dic):

	lowerWord = word.lower()
	wordLength = len(word)
	wordArray = []
	for testWord in dic:
		if lowerWord == testWord[0:wordLength]:
			wordArray.append(testWord)
	return wordArray

def ifHasOtherWordInIt(testWord, dic, currWord):
	for testStart in dic:
		if testWord.startswith(testStart) and not testWord == testStart and len(testStart) > len(currWord) and len(testStart) > 3:
			return True
	return False



#Main program
def main():

	os.system("clear")

	#Set player word for scoring
	gameString = "GHOST"

	#Get dictionary
	dic = getWords()

	#Set number of players
	numPlayers = int(raw_input("How many players will be playing: "))
	if numPlayers == 1:
		numPlayers = 2

	#Get player types and names
	playerType = [""]*numPlayers
	playerName = [""]*numPlayers
	for i in range(numPlayers):
		playerType[i] = raw_input("Enter type of player "+str(i+1)+" (C)PU or (H)uman: ")
		if playerType[i] == "C" or playerType[i] == "c":
			playerType[i] = "CPU"
		else:
			playerType[i] = "Human"
		playerName[i] = raw_input("Enter name for player "+str(i+1)+": ")

	#Start scores at 0
	score = ["" for n in range(numPlayers)]

	#Start big while loop
	while not anyWinners(score, gameString):
		
		#Reset players and word
		currPlayer = 1
		prevPlayer = 2
		word = ""
		
		#Print rules
		os.system("clear")

		print "Rules:"
		print "Print a letter to add it to the word."
		print "Print \"cant\" to challenge that the current word does not start any other words."
		print "Print \"word\" to challenge that the current word is a word already."
		print "Print \"quit\" to exit the program."
		print

		#Print score
		print "Current Score"
		for n in range(numPlayers):
			print playerType[n]+"\t"+playerName[n]+"\t"+score[n]
		print

		while True:
			#Get the input
			playerInput = getInput(playerName[currPlayer-1],playerType[currPlayer-1],dic,word,numPlayers)
		
			#If the player wants to quit

			#if playerInput == "j" and len(word) == 0:
				#playerInput = "s"

			if playerInput == "quit":
				print
				print "Goodbye!"
				sys.exit(0)
	
			#If the  player claims it's a word
			if playerInput == "word":
				if isWord(word, dic):
				#It is a word, and the previous player loses.
					print word + " is a word!"
					print playerType[prevPlayer-1]+" "+playerName[prevPlayer-1]+" loses!"
					score[prevPlayer-1] = getNextStatus(score[prevPlayer-1], gameString)
					break
				else:
					#Not a word, and the current player loses.
					print word + " is not a word!"
					print playerType[currPlayer-1]+" "+playerName[currPlayer-1]+" loses!"
					score[currPlayer-1] = getNextStatus(score[currPlayer-1], gameString)
					break

			#Otherwise, if the player claims it can't start a word
			elif playerInput == "cant":
				startWord = isStartOfWord(word, dic)
				if not startWord:
					#If it can't start a word, the previous player loses
					print word + " does not start any words!"
					print playerType[prevPlayer-1]+" "+playerName[prevPlayer-1]+" loses!"
					score[prevPlayer-1] = getNextStatus(score[prevPlayer-1], gameString)
					break
				else:
					#If it can, the current player loses.
					print word + " can start a word:"
					print "Possible word: " + startWord + "!"
					print playerType[currPlayer-1]+" "+playerName[currPlayer-1]+" loses!"
					score[currPlayer-1] = getNextStatus(score[currPlayer-1], gameString)
					break	

			#Otherwise, add to the letter
			else:
				word = word + playerInput[0]
	
			print "Current word: " + word
			print

			#Shift the players
			prevPlayer = currPlayer
			currPlayer = currPlayer + 1
			if currPlayer > numPlayers:
				currPlayer = 1
			
			time.sleep(.5)

			
		#Wait for 3 seconds to have it register
		time.sleep(3)


	#Display final score
	os.system("clear")
	print "FINAL SCORE"
	for n in range(numPlayers):
		print playerType[n]+"\t"+playerName[n]+"\t"+score[n]
	print
		
#Only run if executed

if __name__ == "__main__":
	try:
		main()
	except KeyboardInterrupt:
		print
		print "Goodbye!"
		sys.exit(0)


