[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] Text To Speech PYTTS
Hi!
Below is a nice demo game using the text to speech. It is a maze game
using it. I guess anything can go from here.
From: "kschnee" <kschnee@xxxxxxxxxx>
Sent: Friday, February 29, 2008 11:22 AM
Subject: Re: [pygame] Text To Speech PYTTS
On Fri, 29 Feb 2008 11:16:26 -0500, "FT" <chester_lab@xxxxxxxx> wrote:
>
> To get text to speech software, or PYTTS, this is the download page for
> the Text To Speech engine.
>
> North Carolina Assistive Technology Downloads:
> http://sourceforge.net/project/showfiles.php?group_id=65529#downloads
What features does it have?
I also note that there's a program called PyFlite, which is a version of
the Festival speech synth program developed at CMU.
The game to play using the text to speech:
# use the arrow keys to play. Up arrow moves you forward. Left arrow turns
90 degrees left.
# Right arrow turns 90 degrees right. Down arrow turns around 180 degrees.
Escape quits.
#
# Listen for the hint in the sound of the wind.
# Load Modules
import pygame
import random, sys
import time
import math
import pyTTS
tts = pyTTS.Create()
# go to the program directory
import os
mydir = os.path.dirname(sys.argv[0])
if mydir:
os.chdir(mydir)
# Constants -- cell marks
BOTTOMWALL = 0
RIGHTWALL = 1
VISITED = 2
PATH = 3
# Directions. I have numbered them so adding 1 rotates right and subtracting
one rotates left
NORTH = 0
SOUTH = 2
WEST = 3
EAST = 1
class Maze:
def __init__( self, n_rows, n_cols ):
"""Create a maze with given number of rows and cols.
member variable longest_path is the sequence of cells you pass
through to get to the end.
"""
self.n_rows = n_rows
self.n_cols = n_cols
self.maze = [ [ [True,True,False,tuple()] for c in range(n_cols) ]
for r in range(n_rows) ]
self.longest_path = tuple() # will be the longest path through the
maze
def randomize( self ):
# Choose a random end point
currCol = random.randrange(self.n_cols)
currRow = random.randrange(self.n_rows)
# The search can be quite deep
if self.n_rows*self.n_cols > sys.getrecursionlimit():
sys.setrecursionlimit( self.n_rows*self.n_cols+5 )
# Recursively Remove Walls - Depth First Algorithm
self._make_path( currRow, currCol, tuple() )
#*****************************************
def _make_path( self, R, C, path, D=None ):
'''Used internally to generate the maze.'''
maze = self.maze # speed up a bit
maze[R][C][PATH] = path
# track the longest path
path = ((R,C),) + path
if len(path) > len(self.longest_path):
self.longest_path = path
# Knock out wall between this and previous cell
maze[R][C][VISITED] = True;
if D==NORTH: maze[R] [C] [BOTTOMWALL] = False
elif D==SOUTH: maze[R-1][C] [BOTTOMWALL] = False
elif D==WEST: maze[R] [C] [RIGHTWALL] = False
elif D==EAST: maze[R] [C-1][RIGHTWALL] = False
# Build legal directions array
directions = []
if R>0 : directions.append(NORTH)
if R<self.n_rows-1: directions.append(SOUTH)
if C>0 : directions.append(WEST)
if C<self.n_cols-1: directions.append(EAST)
# Shuffle the directions array randomly
random.shuffle(directions)
# Call the function recursively
for dir in directions:
if dir==NORTH:
if not maze[R-1][C][VISITED]:
self._make_path( R-1,C,path,NORTH )
elif dir==SOUTH:
if not maze[R+1][C][VISITED]:
self._make_path( R+1,C,path,SOUTH )
elif dir==EAST:
if not maze[R][C+1][VISITED]:
self._make_path( R,C+1,path,EAST )
elif dir==WEST:
if not maze[R][C-1][VISITED]:
self._make_path( R,C-1,path,WEST )
def _find_path( self, R, C, path, goal=None):
'''Used internally to fill-in the maze.'''
maze = self.maze # speed up a bit
maze[R][C][PATH] = path
# track the longest path
path = ((R,C),) + path
if goal and goal == (R,C):
self.longest_path = path
elif not goal and len(path) > len(self.longest_path):
self.longest_path = path
# note that we've been here
maze[R][C][VISITED] = True;
# Build directions array
directions = []
if R>0 and not maze[R-1][C][BOTTOMWALL]: directions.append(NORTH)
if R<self.n_rows-1 and not maze[R][C][BOTTOMWALL]:
directions.append(SOUTH)
if C>0 and not maze[R][C-1][RIGHTWALL]: directions.append(WEST)
if C<self.n_cols-1 and not maze[R][C][RIGHTWALL]:
directions.append(EAST)
# Call the function recursively
for dir in directions:
if dir==NORTH:
if not maze[R-1][C][VISITED]:
self._find_path( R-1,C,path,goal )
elif dir==SOUTH:
if not maze[R+1][C][VISITED]:
self._find_path( R+1,C,path,goal )
elif dir==EAST:
if not maze[R][C+1][VISITED]:
self._find_path( R,C+1,path,goal )
elif dir==WEST:
if not maze[R][C-1][VISITED]:
self._find_path( R,C-1,path,goal )
def wayout(self, row, col):
'''The direction from this cell to the exit.'''
path = self.maze[row][col][PATH]
next = path[0]
dr = next[0] - row
dc = next[1] - col
distance = len(path)
if dr < 0: return NORTH, distance
if dr > 0: return SOUTH, distance
if dc > 0: return EAST, distance
if dc < 0: return WEST, distance
def openings(self, row, col):
'''For each direction indicate if there is an opening'''
result = [False]*4
result[NORTH] = row>0 and not self.maze[row-1][col][BOTTOMWALL]
result[SOUTH] = not self.maze[row][col][BOTTOMWALL]
result[EAST] = not self.maze[row][col][RIGHTWALL]
result[WEST] = col>0 and not self.maze[row][col-1][RIGHTWALL]
return result
def __str__(self):
"""Return a simple visual representation of the maze in ASCII"""
if self.longest_path:
result = str((self.longest_path[0],self.longest_path[-1]))+'\n'
else:
result = '((-1,-1),(-1,-1))\n'
result += '.' + self.n_cols*'_.'
result += '\n'
for i in range(self.n_rows):
result += '|'
for j in range(self.n_cols):
if i==self.n_rows-1 or self.maze[i][j][BOTTOMWALL]:
result += '_'
else:
result += ' '
if j==self.n_cols-1 or self.maze[i][j][RIGHTWALL]:
result += '|'
else:
result += '.'
result += '\n'
return result
def fromstring(self, init):
'''Parse the string we built in __str__ to initialize the maze.
No error checking. Assumes the maze is exactly in printed format.
Really needs lots of work.
'''
lines = init.split('\n')
start, goal = eval(lines[0])
lines = lines[2:] # toss the first row
for i in range(self.n_rows):
line = lines[i][1:] # toss the first col
for j in range(self.n_cols):
if i < self.n_rows-1 and line[2*j] == '_':
self.maze[i][j][BOTTOMWALL] = True
elif line[2*j] == ' ':
self.maze[i][j][BOTTOMWALL] = False
if j < self.n_cols-1 and line[2*j+1] == '|':
self.maze[i][j][RIGHTWALL] = True
elif line[2*j+1] == '.':
self.maze[i][j][RIGHTWALL] = False
self._find_path( goal[0], goal[1], tuple(), start )
directions = ['North', 'East', 'South', 'West'] # names for the directions
steps = [ (-1,0), (0,1), (1,0), (0,-1) ] # increments to step in each
direction
pygame.init()
screen = pygame.display.set_mode((320,240))
purge = pyTTS.tts_purge_before_speak
async = pyTTS.tts_async
def Game(maze):
facing = NORTH # direction you are facing currently
position = maze.longest_path[0]
goal = maze.longest_path[-1]
windsnd = pygame.mixer.Sound('wind.wav')
success = pygame.mixer.Sound('success.wav')
wind = windsnd.play(-1)
moves = 0
print maze
moved = True
while True:
# make the sound come from the right direction
if moved:
direction, distance = maze.wayout(position[0], position[1])
rotation = (facing - direction) % 4
vol = 1/math.sqrt(distance)
if rotation == 0:
wind.set_volume(vol)
elif rotation == 1:
wind.set_volume(vol, 0)
elif rotation == 3:
wind.set_volume(0, vol)
elif rotation == 2:
wind.set_volume(vol/2)
openings = maze.openings(position[0], position[1])
tts.Speak('In cell %d, %d, facing %s. There is %s here.' %
(position[0], position[1], directions[facing],
('a wall', 'an opening')[openings[facing]]), async,
purge)
event = pygame.event.poll()
moved = False
if event.type == pygame.QUIT:
return 0
elif event.type == pygame.KEYDOWN:
key = event.key
if key == 27: # escape
return 0
elif key == ord('s'):
tts.Speak("Directional Sound Toggle")
if chan.get_busy():
chan.pause()
else:
chan.unpause()
elif key == ord('d'):
tts.Speak("Destination: %s" % goal)
elif key == pygame.K_UP:
if openings[facing]:
step = steps[facing]
moves += 1
position = (position[0]+step[0], position[1]+step[1])
moved = True
if position == goal:
wind.stop()
chan = success.play()
tts.Speak("You found the end in %d moves!" % moves,
purge)
tts.Speak("Congratulations. You finished the
level!")
return 1
else:
tts.Speak("You bump into the wall!")
elif key == pygame.K_RIGHT: # right arrow
facing = (facing + 1) % 4
moved = True
elif key == pygame.K_DOWN: # down arrow
facing = (facing + 2) % 4
moved = True
elif key == pygame.K_LEFT: # left arrow
facing = (facing - 1) % 4
moved = True
pygame.display.flip()
if __name__ == '__main__':
n = 3
while True:
tts.Speak('This level is %d cells on a side.' % n)
m = Maze(n,n)
m.randomize()
if not Game(m):
pygame.quit()
break
n += 1