Skip to content

Commit

Permalink
added cozmogram, cozword, fortune-teller
Browse files Browse the repository at this point in the history
  • Loading branch information
ankit01217 committed Dec 7, 2016
1 parent 627c8a9 commit 5547b64
Show file tree
Hide file tree
Showing 3 changed files with 424 additions and 0 deletions.
220 changes: 220 additions & 0 deletions cozmogram/cozmogram.py
@@ -0,0 +1,220 @@
import asyncio
import codecs
import json
import urllib.request
import cozmo
import random
from cozmo.util import degrees, Pose
from common.custom_display import CustomDisplay
from random import shuffle
from common.custom_cube import CustomCube
from common.cube_color import CubeColor
from common.cozgame import CozGame

'''
3-letter anagram game
- cozmo's screen will display 3 letter word in random order and each letter on screen will be mapped to cube by index
- goal of the player is to quickly rearrange letters by moving cubes as fast as possible before it times out
@class Anagram
@author - Team Cozplay
'''


class Anagram(CozGame):
Z_THRESHOLD = 15
DISP_THRESHOLD = 30
DEBUG = False

def __init__(self, *a, **kw):
CozGame.__init__(self)

# init cozmo
cozmo.world.World.light_cube_factory = CustomCube
cozmo.setup_basic_logging()
cozmo.connect(self.run)

async def run(self, coz_conn):
asyncio.set_event_loop(coz_conn._loop)
#setup robot
self.robot = await coz_conn.wait_for_robot()

asyncio.ensure_future(self.update())
while not self.exit_flag:
await asyncio.sleep(0)
self.robot.abort_all_actions()

async def update(self):
#init game
await self.init_game()

await self.disp_word()
while True:
await self.on_update()
await asyncio.sleep(0)


async def init_game(self):
await self.robot.set_lift_height(0, duration=0.5).wait_for_completed()
await self.robot.go_to_pose(Pose(0, 0, 0, angle_z=degrees(0)), relative_to_robot=True).wait_for_completed()
await self.robot.set_head_angle(cozmo.util.Angle(degrees=10)).wait_for_completed()
# setup cubes
self.cubes = await self.robot.world.wait_until_observe_num_objects(num=3, object_type=cozmo.objects.LightCube)
self.ori_z = self.cubes[0].pose.position.z


self.ori_seq = None
self.cur_word = None
self.cur_seq = None
self.disp_timer = 0
self.correct_check_enabled = False
self.paused = False
self.word_index = -1
self.score = 0
self.idle_count = 0
self.pos_index = 0
self.neg_index = 0
self.anagram_words = ["apt","tap", "are", "ear", "arm", "mar", "ram", "art", "rat", "tar", "asp",
"pas", "sap", "spa", "ate", "eat", "era", "bat", "tab", "now", "own", "won", "opt",
"pot", "top", "own", "now", "won","zoo", "yet", "yes", "wow","win","who","vow","rug","rub","rip","put","pub",
"pie","pet","pen","pic","pig","out","oil","odd","off","nut","nod","aim","air","awe","ban","big","bio","bin"]
shuffle(self.anagram_words)

if not Anagram.DEBUG:
await self.robot.say_text(text="let's play, anagram", play_excited_animation=False,
duration_scalar=1.5).wait_for_completed()
self.ori_pose = self.robot.pose

await self.disp_word()

async def disp_word(self):

#await self.robot.go_to_pose(self.ori_pose, relative_to_robot=False).wait_for_completed()
await self.robot.set_head_angle(cozmo.util.Angle(degrees=10)).wait_for_completed()

self.word_index += 1
if self.word_index == self.anagram_words.__len__():
shuffle(self.anagram_words)
self.word_index = 0
self.cur_word = self.anagram_words[self.word_index]

# await self.robot.say_text(text="", duration_scalar=1.7, play_excited_animation=True).wait_for_completed()
seq = ''.join(random.sample(self.cur_word, self.cur_word.__len__()))
while seq in self.anagram_words:
seq = ''.join(random.sample(self.cur_word, self.cur_word.__len__()))

self.ori_seq = self.cur_seq = seq
self.paused = False
self.correct_check_enabled = True
self.turn_on_lights(cozmo.lights.Light(on_color=CubeColor.MAGENTA, off_color=CubeColor.MAGENTA))
await self.map_cube_keys(self.cur_seq)
CustomDisplay.display_text(robot=self.robot, text=self.get_disp_text(self.cur_seq), duration=5, size=32, xoffset=25, yoffset=0)

async def on_update(self):
all_grounded = True
for c in self.cubes:
diff = c.pose.position.z - self.ori_z
if diff > Anagram.Z_THRESHOLD:
all_grounded = False
self.idle_count = 0
break

self.idle_count += 1
if(self.idle_count == 1000):
self.idle_count = 0
await self.robot.play_anim("ID_test_shiver").wait_for_completed()

if all_grounded and not self.paused:
await self.update_cube_keys()
if (self.cur_seq in self.anagram_words):
self.idle_count = 0

if(self.disp_timer < Anagram.DISP_THRESHOLD):
self.disp_timer += 1
CustomDisplay.display_text(robot=self.robot, text=self.get_disp_text(self.cur_seq), duration=10, size=32, xoffset=25, yoffset=0)
elif (self.disp_timer == Anagram.DISP_THRESHOLD):
self.disp_timer = 0
self.score += 1
self.paused = True
await self.on_positive_response()
await self.disp_word()
elif self.ori_seq != self.cur_seq and self.correct_check_enabled:
self.idle_count = 0

if (self.disp_timer < Anagram.DISP_THRESHOLD):
self.disp_timer += 1
CustomDisplay.display_text(robot=self.robot, text=self.get_disp_text(self.cur_seq), duration=10,
size=32, xoffset=25, yoffset=0)
elif (self.disp_timer == Anagram.DISP_THRESHOLD):
self.disp_timer = 0
self.paused = True
await self.on_negative_response()
await self.disp_word()

await asyncio.sleep(0)

async def on_positive_response(self):
self.turn_on_lights(cozmo.lights.green_light)
await self.robot.say_text(text=self.cur_seq, play_excited_animation=False,
duration_scalar=1.5).wait_for_completed()
self.pos_index += 1
anim_arr = ["good","great","awesome","correct","right","perfect"]
await self.robot.say_text(text=anim_arr[self.pos_index % anim_arr.__len__()], duration_scalar = 1.3).wait_for_completed()
await self.robot.play_anim(random.choice(
["anim_hiking_rtnewarea_01","anim_hiking_rtnewarea_02","anim_hiking_rtnewarea_03"])).wait_for_completed()

async def on_negative_response(self):
self.turn_on_lights(cozmo.lights.red_light)
self.neg_index += 1
anim_arr = ["no","nope","incorrect"]
await self.robot.say_text(text=anim_arr[self.neg_index % anim_arr.__len__()]).wait_for_completed()
await self.robot.say_text(text="it was, " + self.cur_word, play_excited_animation=False,
duration_scalar=1.3).wait_for_completed()
await self.robot.play_anim(random.choice(
["anim_hiking_rtpmarker_01","anim_hiking_observe_01","anim_hiking_react_01","anim_hiking_react_02","anim_hiking_react_03","anim_hiking_react_05"])).wait_for_completed()

async def map_cube_keys(self, word):
await self.sort_cubes(self.cubes)
index = 0
for cube in self.cubes:
cube.key = word[index]
index += 1

if word != None:
CustomDisplay.display_text(robot=self.robot, text=word, duration=5, size=32, xoffset=25, yoffset=0)

async def update_cube_keys(self):
await self.sort_cubes(self.cubes)
index = 0
newseq = ''
for cube in self.cubes:
newseq += cube.key
index += 1
self.cur_seq = newseq
CustomDisplay.display_text(robot=self.robot, text=self.get_disp_text(self.cur_seq), duration=5, size=32, xoffset=25, yoffset=0)

def get_disp_text(self, word):
disp = ""
for c in word:
disp += c + " "
return disp

async def sort_cubes(self,l):
for passes_left in range(len(l) - 1, 0, -1):
for index in range(passes_left):
if l[index].pose.position.y > l[index + 1].pose.position.y:
l[index], l[index + 1] = l[index + 1], l[index]

def turn_on_lights(self, light = cozmo.lights.white_light):
for i in range(len(self.cubes)):
self.cubes[i].set_lights(light)


def get_json_data(self, url):
reader = codecs.getreader("utf-8")
response = urllib.request.urlopen(url)
obj = json.load(reader(response))
return obj


if __name__ == '__main__':
Anagram()
116 changes: 116 additions & 0 deletions cozword/word_of_the_day.py
@@ -0,0 +1,116 @@
import asyncio
import sys
import cozmo
from PyDictionary import PyDictionary
from random_words import RandomWords

try:
from PIL import Image, ImageDraw, ImageFont
except ImportError:
sys.exit("Cannot import from PIL: Do `pip3 install Pillow` to install")


'''
Word of the day interaction
- Displays random dictionary word on cozmo screen when he finds any face
- Also says word meaning
@class WordOfTheDay
@author Ankit Patel
'''
class WordOfTheDay:
GAME_TIME = 10 * 60

def __init__(self, *a, **kw):
# init cozmo
cozmo.setup_basic_logging()
cozmo.connect_with_tkviewer(self.run)

async def run(self, coz_conn):
asyncio.set_event_loop(coz_conn._loop)
self.is_saying = False
self.say_action = None
self.dictionary = PyDictionary()
self.rw = RandomWords()

self.robot = await coz_conn.wait_for_robot()
await self.robot.set_head_angle(cozmo.util.Angle(degrees=40)).wait_for_completed()

try:
await self.find_face()

except KeyboardInterrupt:
print("")
print("Exit requested by user")

await asyncio.sleep(WordOfTheDay.GAME_TIME)

async def find_face(self):

while True:
# find a visible face, timeout if nothing found after a short while
try:
await self.robot.world.wait_for_observed_face(timeout=30)
await self.disp_dic_word()

except asyncio.TimeoutError:
print("Didn't find a face - exiting!")
return

asyncio.sleep(.1)

async def disp_dic_word(self, len=5):

word = self.rw.random_word()
meaning_dic = self.dictionary.meaning(word)
if meaning_dic and meaning_dic['Noun']:
meaning = meaning_dic['Noun'][0]
print(word)
await self.robot.say_text(text=word, duration_scalar = 1.3, play_excited_animation=False).wait_for_completed()
self.display_text(word, duration=100000, size=25)
await asyncio.sleep(3)
await self.robot.say_text(text=meaning, duration_scalar=1.3, play_excited_animation=False).wait_for_completed()
await asyncio.sleep(4)

def display_text(self, text, duration, size):
# get a font - location depends on OS so try a couple of options
# failing that the default of None will just use a default font
font = None
try:
font = ImageFont.truetype("arial.ttf", size)
except IOError:
try:
font = ImageFont.truetype("/Library/Fonts/Arial.ttf", 24)
except IOError:
pass

text_image = self.make_text_image(text, 15, 2, font)
lcd_face_data = cozmo.oled_face.convert_image_to_screen_data(text_image)
self.robot.display_oled_face_image(lcd_face_data, duration)

def make_text_image(self,text_to_draw, x, y, font=None):
'''Make a Pillow.Image with the current time printed on it
Args:
text_to_draw (string): the text to draw to the image
x (int): x pixel location
y (int): y pixel location
font (PIL.ImageFont): the font to use
Returns:
:class:(`PIL.Image.Image`): a Pillow image with the text drawn on it
'''

# make a blank image for the text, initialized to opaque black
txt = Image.new('RGBA', cozmo.oled_face.dimensions(), (0, 0, 0, 255))

# get a drawing context
dc = ImageDraw.Draw(txt)

# draw the text
dc.text((x, y), text_to_draw, fill=(255, 255, 255, 255), font=font)

return txt

if __name__ == '__main__':
WordOfTheDay()

0 comments on commit 5547b64

Please sign in to comment.