├── .gitignore
├── bombly
├── __init__.py
├── modules
│ ├── __init__.py
│ ├── needy
│ │ ├── __init__.py
│ │ └── knob.py
│ ├── passwords.py
│ ├── simon_says.py
│ ├── keypads.py
│ ├── the_button.py
│ ├── wire_sequences.py
│ ├── wires.py
│ ├── morse_code.py
│ ├── complicated_wires.py
│ ├── memory.py
│ ├── mazes.py
│ └── whos_on_first.py
└── bomb.py
├── images
├── h.png
├── c_left.png
├── column1.png
├── column2.png
├── column3.png
├── column4.png
├── column5.png
├── column6.png
├── kitty.png
├── lambda.png
├── oomlow.png
├── star1.png
├── tennis.png
├── tornado.png
├── copyright.png
├── lightning.png
├── question.png
└── alpha_tango.png
├── dfly-loader-wsr.py
├── README.md
├── bombly.py
└── '
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/bombly/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/bombly/modules/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/bombly/modules/needy/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/images/h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/h.png
--------------------------------------------------------------------------------
/images/c_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/c_left.png
--------------------------------------------------------------------------------
/images/column1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/column1.png
--------------------------------------------------------------------------------
/images/column2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/column2.png
--------------------------------------------------------------------------------
/images/column3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/column3.png
--------------------------------------------------------------------------------
/images/column4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/column4.png
--------------------------------------------------------------------------------
/images/column5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/column5.png
--------------------------------------------------------------------------------
/images/column6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/column6.png
--------------------------------------------------------------------------------
/images/kitty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/kitty.png
--------------------------------------------------------------------------------
/images/lambda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/lambda.png
--------------------------------------------------------------------------------
/images/oomlow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/oomlow.png
--------------------------------------------------------------------------------
/images/star1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/star1.png
--------------------------------------------------------------------------------
/images/tennis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/tennis.png
--------------------------------------------------------------------------------
/images/tornado.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/tornado.png
--------------------------------------------------------------------------------
/images/copyright.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/copyright.png
--------------------------------------------------------------------------------
/images/lightning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/lightning.png
--------------------------------------------------------------------------------
/images/question.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/question.png
--------------------------------------------------------------------------------
/images/alpha_tango.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ctfhacker/bombly/HEAD/images/alpha_tango.png
--------------------------------------------------------------------------------
/bombly/modules/needy/knob.py:
--------------------------------------------------------------------------------
1 | def knob(extras):
2 | words = str(extras['words'])
3 | print words
4 | words = ''.join([word for word in words.split() if word in ('one', 'zero')])
5 | print words
6 | leds = words.replace('one', '1').replace('zero', '0').replace(' ', '')
7 | print leds
8 | if leds == '111011' or leds == '011010':
9 | return 'Up'
10 | if leds == '111001' or leds == '010010':
11 | return 'Down'
12 | if leds == '100010' or leds == '000010':
13 | return 'Left'
14 | if leds == '111111' or leds == '111100':
15 | return 'Right'
16 |
--------------------------------------------------------------------------------
/bombly/modules/passwords.py:
--------------------------------------------------------------------------------
1 | # Password
2 | curr_password = []
3 |
4 |
5 | def solve_password(extras):
6 | global curr_password
7 | letters = str(extras['letters'])
8 | letters = [letter[0].lower() for letter in letters.split()]
9 | curr_password.append(letters)
10 | print curr_password
11 |
12 | passwords = ['about',
13 | 'after', 'again', 'below', 'could', 'every', 'first', 'found', 'great',
14 | 'house', 'large', 'learn', 'never', 'other', 'place', 'plant', 'point',
15 | 'right', 'small', 'sound', 'spell', 'still', 'study', 'their', 'there',
16 | 'these', 'thing', 'think', 'three', 'water', 'where', 'which', 'world',
17 | 'would', 'write']
18 |
19 | possibles = []
20 | if len(curr_password) == 2:
21 | for password in passwords:
22 | if password[0] in curr_password[0] and password[2] in curr_password[1]:
23 | possibles.append(password)
24 |
25 | print possibles
26 |
27 | return possibles
28 |
29 |
30 | def reset():
31 | global curr_password
32 | curr_password = []
33 | print curr_password
34 |
--------------------------------------------------------------------------------
/bombly/modules/simon_says.py:
--------------------------------------------------------------------------------
1 | def simon(extras, vowel):
2 | print str(extras['words'])
3 | # if vowel == 'vowel':
4 | # engine.speak("Serial contain vowel?")
5 | # return
6 |
7 | words = str(extras['words'])
8 | print words
9 | words = words.replace('read', 'red').replace('blew', 'blue')
10 | words = [word for word in words.split() if word in ('blue', 'yellow', 'red', 'green')]
11 |
12 | new_words = []
13 | print "Your words: {}".format(words)
14 | if vowel in ('true', 'yes'):
15 | colors = {'red': 'blue',
16 | 'blue': 'red',
17 | 'green': 'yellow',
18 | 'yellow': 'green'}
19 | for word in words:
20 | new_words.append(colors[word])
21 | else:
22 | colors = {'red': 'blue',
23 | 'blue': 'yellow',
24 | 'green': 'green',
25 | 'yellow': 'red'}
26 | for word in words:
27 | new_words.append(colors[word])
28 |
29 | new_words = ' '.join(new_words)
30 | print "My words: {}".format(new_words)
31 |
32 | return new_words
33 |
--------------------------------------------------------------------------------
/bombly/modules/keypads.py:
--------------------------------------------------------------------------------
1 | def keypad(extras):
2 | symbols = str(extras['symbols'])
3 |
4 | groups = [
5 | ['tennis', 'apple', 'a', 'l', 'lightning', 'spider', 'h', 'house', 'c', 'charlie'],
6 | ['e', 'echo', 'tennis', 'c', 'charlie', 'o', 'oscar', 'starr', 'star', 'h', 'house', 'question'],
7 | ['copyright', 'but', 'butt', 'o', 'oscar', 'k', 'r', 'romeo', 'l', 'starr', 'star'],
8 | ['six', 'paragraph', 'b', 'bravo', 'spider', 'k', 'question', 'smile'],
9 | ['goblet', 'smile', 'b', 'bravo', 'c', 'charlie', 'paragraph', 'three', 'star'],
10 | ['six', 'e', 'echo', 'equals', 'smash', 'goblet', 'in', 'omega']
11 | ]
12 |
13 | print symbols
14 | symbols = symbols.replace('butt', 'but')
15 | curr_symbols = symbols.replace('.', '').lower().split()
16 | print curr_symbols
17 |
18 | answer = ''
19 | for group in groups:
20 | for symbol in curr_symbols:
21 | if symbol not in group:
22 | break
23 | else:
24 | for symbol in group:
25 | if symbol in curr_symbols:
26 | answer += symbol + ' '
27 |
28 | return answer
29 |
--------------------------------------------------------------------------------
/bombly/modules/the_button.py:
--------------------------------------------------------------------------------
1 | def button(extras, batteries, car, freak):
2 | """
3 | spoken = 'need'
4 | print "Batteries: {}".format(batteries)
5 | print "Freak: {}".format(freak)
6 | print "Car: {}".format(car)
7 | if batteries == 99:
8 | spoken += ' batteries'
9 | if freak == 'freak':
10 | spoken += ' freak'
11 | if car == 'car':
12 | spoken += ' car identifier'
13 | if spoken != 'need':
14 | return spoken
15 | return
16 | """
17 |
18 | words = str(extras['words'])
19 | print words
20 | words = words.replace('read', 'red').replace('blew', 'blue')
21 | print words
22 | if 'blue' in words and 'abort' in words:
23 | return 'Press and hold'
24 | elif 'detonate' in words and batteries > 1:
25 | return 'Press and release'
26 | elif 'white' in words and car in ('true', 'yes'):
27 | return 'Press and hold'
28 | elif batteries > 2 and freak in ('true', 'yes'):
29 | return 'Press and release'
30 | elif 'yellow' in words:
31 | return 'Press and hold'
32 | elif 'red' in words and 'hold' in words:
33 | return 'Press and release'
34 | else:
35 | return 'Press and hold'
36 |
37 |
38 | def button_color(extras):
39 | words = str(extras['words'])
40 | print words
41 | words = words.replace('read', 'red').replace('blew', 'blue')
42 | print words
43 | if 'blue' in words:
44 | return 'four'
45 | elif 'yellow' in words:
46 | return 'five'
47 | else:
48 | return 'one'
49 |
--------------------------------------------------------------------------------
/bombly/modules/wire_sequences.py:
--------------------------------------------------------------------------------
1 | from collections import defaultdict
2 |
3 | counts = defaultdict(int)
4 | sequences = {}
5 | sequences['red'] = [
6 | ('c'),
7 | ('b'),
8 | ('a'),
9 | ('a', 'c'),
10 | ('b'),
11 | ('a', 'c'),
12 | ('a', 'b', 'c'),
13 | ('a', 'b'),
14 | ('b')
15 | ]
16 | sequences['blue'] = [
17 | ('b'),
18 | ('a', 'c'),
19 | ('b'),
20 | ('a'),
21 | ('b'),
22 | ('b','c'),
23 | ('c'),
24 | ('a', 'c'),
25 | ('a')
26 | ]
27 | sequences['black'] = [
28 | ('a', 'b', 'c'),
29 | ('a', 'c'),
30 | ('b'),
31 | ('a', 'c'),
32 | ('b'),
33 | ('b', 'c'),
34 | ('a', 'b'),
35 | ('c'),
36 | ('c')
37 | ]
38 |
39 |
40 | def wire_sequence(extras):
41 | global sequences
42 | words = str(extras['words'])
43 | print words
44 | words = words.replace('read', 'red').replace('blew', 'blue')
45 | print words
46 | words = [word for word in words.split() if word in ('red', 'blue', 'black', 'apple', 'bravo', 'charlie')]
47 | print words
48 | words = [words[x:x+2] for x in xrange(0, len(words), 2)]
49 | print words
50 | answer = []
51 | for index, item in enumerate(words):
52 | print index, item
53 | color, letter = item
54 | print "Color: {}".format(color)
55 | print "Letter: {}".format(letter)
56 | print "Count: {}".format(counts[color])
57 | print sequences[color]
58 | print counts[color]
59 | print sequences[color][counts[color]]
60 | print sequences[color][counts[color]]
61 | if letter[0] in sequences[color][counts[color]]:
62 | answer.append(str(index+1))
63 |
64 | counts[color] += 1
65 |
66 | if not answer:
67 | return 'cut nothing'
68 | else:
69 | return ', '.join(answer)
70 |
71 |
72 | def reset():
73 | global counts
74 | counts = defaultdict(int)
75 |
--------------------------------------------------------------------------------
/bombly/modules/wires.py:
--------------------------------------------------------------------------------
1 | def wires(extras, sanitize_colors, odd_serial):
2 | """
3 | spoken = 'need'
4 | if serial == 'serial':
5 | spoken += ' last digit of serial'
6 | if spoken != 'need':
7 | engine.speak(spoken)
8 | return
9 | """
10 |
11 | wire = str(extras['wires'])
12 | wire = sanitize_colors(wire)
13 | wire = wire.split()
14 |
15 | if len(wire) == 3:
16 | if 'red' not in wire:
17 | return 'cut second wire'
18 | elif wire[-1] == 'white':
19 | return 'cut last wire'
20 | elif wire.count('blue') > 1:
21 | return 'cut last blue wire'
22 | else:
23 | return 'cut last wire'
24 |
25 | elif len(wire) == 4:
26 | if wire.count('red') > 1 and odd_serial():
27 | return 'cut last red wire'
28 | elif wire[-1] == 'yellow' and wire.count('red') == 0:
29 | return 'cut first wire'
30 | elif wire.count('blue') == 1:
31 | return 'cut first wire'
32 | elif wire.count('yellow') > 1:
33 | return 'cut last wire'
34 | else:
35 | return 'cut second wire'
36 |
37 | elif len(wire) == 5:
38 | if wire[-1] == 'black' and odd_serial():
39 | return 'cut fourth wire'
40 | elif wire.count('red') and wire.count('yellow') > 1:
41 | return 'cut first wire'
42 | elif wire.count('black') == 0:
43 | return 'cut second wire'
44 | else:
45 | return 'cut first wire'
46 |
47 | elif len(wire) == 6:
48 | if wire.count('yellow') == 0 and odd_serial():
49 | return 'cut third wire'
50 | elif wire.count('yellow') == 1 and wire.count('white') > 1:
51 | return 'cut fourth wire'
52 | elif wire.count('red') == 0:
53 | return 'cut last wire'
54 | else:
55 | return 'cut fourth wire'
56 |
--------------------------------------------------------------------------------
/bombly/modules/morse_code.py:
--------------------------------------------------------------------------------
1 | # Morse
2 | morse_letters = []
3 |
4 |
5 | def morse_code(extras):
6 | global morse_letters
7 | words = str(extras['words'])
8 |
9 | words = ''.join([word for word in words.split() if word in ('one', 'zero')])
10 | print words
11 | code = words.replace('one', '-').replace('zero', '.')
12 | print code
13 |
14 | morse = {
15 | 'a': '.-',
16 | 'b': '-...',
17 | 'c': '-.-.',
18 | 'e': '.',
19 | 'f': '..-.',
20 | 'g': '--.',
21 | 'h': '....',
22 | 'i': '..',
23 | 'k': '-.-',
24 | 'l': '.-..',
25 | 'm': '--',
26 | 'n': '-.',
27 | 'o': '---',
28 | 'r': '.-.',
29 | 's': '...',
30 | 't': '-',
31 | 'v': '...-',
32 | 'x': '-..-',
33 | }
34 |
35 | codes = {}
36 | for key, val in morse.iteritems():
37 | if code == val:
38 | morse_letters.append(key)
39 |
40 | codes[val] = key
41 |
42 | print "Current morse letters: {}".format(morse_letters)
43 | if len(morse_letters) < 2:
44 | return
45 |
46 | words = {
47 | 'shell': '5 0 5',
48 | 'halls': '5 1 5',
49 | 'slick': '5 2 2',
50 | 'trick': '5 3 2',
51 | 'boxes': '5 3 5',
52 | 'leaks': '5 4 2',
53 | 'strobe': '5 4 5',
54 | 'bistro': '5 5 2',
55 | 'flick': '5 5 5',
56 | 'bombs': '5 6 5',
57 | 'break': '5 7 2',
58 | 'brick': '5 7 5',
59 | 'steak': '5 8 2',
60 | 'sting': '5 9 2',
61 | 'vector': '5 9 5',
62 | 'beats': '6 0 0',
63 | }
64 |
65 | code = ''.join(morse_letters)
66 |
67 | combos = {}
68 | for word in words:
69 | curr_combo = []
70 | for num in xrange(len(word)):
71 | curr_word = ''.join((word+word)[num:num+3])
72 | combos[curr_word] = word
73 |
74 | print code
75 | print combos.keys()
76 | if code in combos:
77 | return words[combos[code]]
78 |
79 | possibles = []
80 | for key, val in combos.iteritems():
81 | curr_word = ''.join([morse[letter] for letter in key])
82 | if code.startswith(curr_word):
83 | # print val, key, code, words[val]
84 | print words[val]
85 |
86 |
87 | def reset():
88 | global morse_letters
89 | morse_letters = []
90 |
--------------------------------------------------------------------------------
/bombly/modules/complicated_wires.py:
--------------------------------------------------------------------------------
1 | def complicated_wires(extras, batteries, serial, parallel):
2 | """
3 | spoken = 'need'
4 | if batteries == 99:
5 | spoken += ' batteries'
6 | if parallel == 'parallel':
7 | spoken += ' parallel port'
8 | if serial == 'serial':
9 | spoken += ' last digit of serial'
10 | if spoken != 'need':
11 | engine.speak(spoken)
12 | return
13 | """
14 |
15 | meaning = {
16 | int('0000', 2): 'cut',
17 | int('0001', 2): 'dont cut',
18 | int('0010', 2): 'cut',
19 | int('0011', 2): 'cut' if batteries > 1 else 'dont cut',
20 | int('0100', 2): 'cut' if serial in (0, 2, 4, 6, 8) else 'dont cut',
21 | int('0101', 2): 'cut' if parallel in ('true', 'yes') else 'dont cut',
22 | int('0110', 2): 'dont cut',
23 | int('0111', 2): 'cut' if parallel in ('true', 'yes') else 'dont cut',
24 | int('1000', 2): 'cut' if serial in (0, 2, 4, 6, 8) else 'dont cut',
25 | int('1001', 2): 'cut' if batteries > 1 else 'dont cut',
26 | int('1010', 2): 'cut',
27 | int('1011', 2): 'cut' if batteries > 1 else 'dont cut',
28 | int('1100', 2): 'cut' if serial in (0, 2, 4, 6, 8) else 'dont cut',
29 | int('1101', 2): 'cut' if serial in (0, 2, 4, 6, 8) else 'dont cut',
30 | int('1110', 2): 'cut' if parallel in ('true', 'yes') else 'dont cut',
31 | int('1111', 2): 'dont cut'
32 | }
33 |
34 | for key, val in meaning.iteritems():
35 | print key, val
36 |
37 | bad_words = [('read', 'red'), ('blew', 'blue'), ('start', 'star'),
38 | ('white', 'light')]
39 | wire = str(extras['wires'])
40 | print wire
41 | wires = [wire for wire in wire.split('next')]
42 | print wires
43 | print 'parallel', parallel
44 | print 'serial', serial
45 | print 'batteries', batteries
46 | final_wires = []
47 | answer = 'cut nothing'
48 | for index, wire in enumerate(wires):
49 | for bad, good in bad_words:
50 | wire = wire.replace(bad, good)
51 |
52 | wire = [item for item in wire.split() if item in ('red', 'blue', 'light',
53 | 'star', 'blank')]
54 |
55 | print wire
56 | total = 0
57 | for letter, value in [('red', 8), ('blue', 4), ('star', 2), ('light', 1)]:
58 | if letter in wire:
59 | total += value
60 |
61 | print wire, total
62 |
63 | if meaning[total] == 'cut':
64 | if answer == 'cut nothing':
65 | answer = 'cut '
66 | answer += str(index+1) + ', '
67 |
68 | return answer
69 |
--------------------------------------------------------------------------------
/bombly/modules/memory.py:
--------------------------------------------------------------------------------
1 | # Memory
2 | values = []
3 | positions = []
4 | curr_stage = 1
5 |
6 |
7 | def memory(extras):
8 | global values
9 | global positions
10 | global curr_stage
11 | words = str(extras['words'])
12 | print words
13 | words = [word for word in words.split() if word in ('one', 'two', 'three', 'four')]
14 | print words
15 | if len(words) != 5:
16 | return 'Try memory again'
17 |
18 | display = words[0]
19 | stage = words[1:]
20 |
21 | print "Current Stage: {}".format(curr_stage)
22 | print "Values: {}".format(values)
23 | print "Positions: {}".format(values)
24 | if curr_stage == 1:
25 | if display == 'one':
26 | answer = stage[1]
27 | if display == 'two':
28 | answer = stage[1]
29 | if display == 'three':
30 | answer = stage[2]
31 | if display == 'four':
32 | answer = stage[3]
33 | position = stage.index(answer)
34 |
35 | if curr_stage == 2:
36 | if display == 'one':
37 | answer = 'four'
38 | if display == 'two':
39 | answer = stage[positions[0]]
40 | if display == 'three':
41 | answer = stage[0]
42 | if display == 'four':
43 | answer = stage[positions[0]]
44 | position = stage.index(answer)
45 |
46 | if curr_stage == 3:
47 | if display == 'one':
48 | answer = values[1]
49 | position = 'one'
50 | if display == 'two':
51 | answer = values[0]
52 | position = 'two'
53 | if display == 'three':
54 | answer = stage[2]
55 | position = stage.index(answer)
56 | if display == 'four':
57 | answer = 'four'
58 | position = stage.index(answer)
59 |
60 | if curr_stage == 4:
61 | if display == 'one':
62 | answer = stage[positions[0]]
63 | position = stage.index(answer)
64 | if display == 'two':
65 | answer = stage[0]
66 | position = stage.index(answer)
67 | if display == 'three':
68 | answer = stage[positions[1]]
69 | position = stage.index(answer)
70 | if display == 'four':
71 | answer = stage[positions[1]]
72 | position = stage.index(answer)
73 |
74 | if curr_stage == 5:
75 | if display == 'one':
76 | answer = values[0]
77 | if display == 'two':
78 | answer = values[1]
79 | if display == 'three':
80 | answer = values[3]
81 | if display == 'four':
82 | answer = values[2]
83 | position = stage.index(answer)
84 |
85 | values.append(answer)
86 | positions.append(position)
87 | curr_stage += 1
88 | print "Answer: {}".format(answer)
89 | if curr_stage > 5:
90 | values = []
91 | positions = []
92 | curr_stage = 1
93 |
94 | return answer
95 |
96 |
97 | def reset():
98 | global positions
99 | global curr_stage
100 | global values
101 | positions = []
102 | values = []
103 | curr_stage = 1
104 |
--------------------------------------------------------------------------------
/bombly/bomb.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 | # Battery characteristics
4 | batteries = 99
5 | freak = 'freak'
6 | car = 'car'
7 | parallel = 'parallel'
8 | serial = 'serial'
9 | vowel = 'vowel'
10 |
11 |
12 | def odd_serial():
13 | return serial in (1, 3, 5, 7, 9)
14 |
15 |
16 | def even_serial():
17 | return serial in (0, 2, 4, 6, 8)
18 |
19 |
20 | def set_car(extras):
21 | global car
22 | car = str(extras['car'])
23 |
24 |
25 | def set_batteries(extras):
26 | global batteries
27 | batteries = int(str(extras['batteries']))
28 |
29 |
30 | def set_freak(extras):
31 | global freak
32 | freak = str(extras['word'])
33 |
34 |
35 | def set_parallel(extras):
36 | global parallel
37 | parallel = str(extras['word'])
38 |
39 |
40 | def set_serial(extras):
41 | global serial
42 | serial = extras['word']
43 |
44 |
45 | def set_vowel(extras):
46 | global vowel
47 | vowel = str(extras['word'])
48 |
49 |
50 | def status():
51 | global batteries
52 | global freak
53 | global car
54 | global parallel
55 | global serial
56 | global vowel
57 |
58 | from bombly.modules import morse_code, whos_on_first, memory, wire_sequences
59 |
60 | # Battery characteristics
61 | print 'batteries', batteries
62 | print 'frk', freak
63 | print 'car', car
64 | print 'parallel', parallel
65 | print 'serial', serial
66 | print 'vowel', vowel
67 |
68 | # Wire sequence
69 | print 'wire sequence', wire_sequences.counts
70 |
71 | # Memory
72 | print 'values', memory.values
73 | print 'position', memory.positions
74 | print 'curr_stage', memory.curr_stage
75 |
76 | # Morse
77 | print 'morse_letters', morse_code.morse_letters
78 |
79 | # On First Words
80 | print 'on first words', whos_on_first.on_first_words
81 |
82 |
83 | def done():
84 | lines = [
85 | "I AM YOUR BOMB DEFUSING OVERLORD",
86 | "BOOM SHAKALAKA",
87 | ]
88 |
89 | global batteries
90 | global freak
91 | global car
92 | global parallel
93 | global serial
94 | global vowel
95 |
96 | # Battery characteristics
97 | batteries = 99
98 | freak = 'freak'
99 | car = 'car'
100 | parallel = 'parallel'
101 | serial = 'serial'
102 | vowel = 'false'
103 |
104 | reset()
105 |
106 | return random.sample(lines, 1)
107 |
108 |
109 | def exploded():
110 | lines = [
111 | "YOU STUPID FUCK",
112 | "NOT MY FAULT!",
113 | "PLANNED..",
114 | "CRAP, BOMB EXPLODED",
115 | "HOW CAN YOU TELL ME THAT?",
116 | "IT'S ALL YOUR FAULT",
117 | ]
118 | return random.sample(lines, 1)
119 |
120 |
121 | def reset():
122 | global batteries
123 | global freak
124 | global car
125 | global parallel
126 | global serial
127 | global vowel
128 |
129 | # Battery characteristics
130 | batteries = 99
131 | freak = 'freak'
132 | car = 'car'
133 | parallel = 'parallel'
134 | serial = 'serial'
135 | vowel = 'vowel'
136 |
137 | from bombly.modules import morse_code, whos_on_first, memory, wire_sequences, passwords
138 |
139 | wire_sequences.reset()
140 | memory.reset()
141 | morse_code.reset()
142 | whos_on_first.reset()
143 | passwords.reset()
144 |
--------------------------------------------------------------------------------
/dfly-loader-wsr.py:
--------------------------------------------------------------------------------
1 | #
2 | # This file is a command-module for Dragonfly.
3 | # (c) Copyright 2008 by Christo Butcher
4 | # Licensed under the LGPL, see
5 | #
6 |
7 | """
8 | Command-module loader for WSR
9 | =============================
10 |
11 | This script can be used to look Dragonfly command-modules
12 | for use with Window Speech Recognition. It scans the
13 | directory it's in and loads any ``*.py`` it finds.
14 |
15 | """
16 |
17 |
18 | import time
19 | import os.path
20 | import logging
21 | import pythoncom
22 |
23 | from dragonfly.engines.backend_sapi5.engine import Sapi5InProcEngine
24 |
25 |
26 | #---------------------------------------------------------------------------
27 | # Set up basic logging.
28 |
29 | logging.basicConfig(level=logging.DEBUG)
30 | logging.getLogger("compound.parse").setLevel(logging.INFO)
31 |
32 |
33 | #---------------------------------------------------------------------------
34 | # Command module class; wraps a single command-module.
35 |
36 | class CommandModule(object):
37 |
38 | _log = logging.getLogger("module")
39 |
40 | def __init__(self, path):
41 | self._path = os.path.abspath(path)
42 | self._namespace = None
43 | self._loaded = False
44 |
45 | def __str__(self):
46 | return "%s(%r)" % (self.__class__.__name__,
47 | os.path.basename(self._path))
48 |
49 | def load(self):
50 | self._log.info("%s: Loading module: '%s'" % (self, self._path))
51 |
52 | # Prepare namespace in which to execute the
53 | namespace = {}
54 | namespace["__file__"] = self._path
55 |
56 | # Attempt to execute the module; handle any exceptions.
57 | try:
58 | execfile(self._path, namespace)
59 | except Exception, e:
60 | self._log.error("%s: Error loading module: %s" % (self, e))
61 | self._loaded = False
62 | return
63 |
64 | self._loaded = True
65 | self._namespace = namespace
66 |
67 | def unload(self):
68 | self._log.info("%s: Unloading module: '%s'" % (self, self._path))
69 |
70 | def check_freshness(self):
71 | pass
72 |
73 |
74 | #---------------------------------------------------------------------------
75 | # Command module directory class.
76 |
77 | class CommandModuleDirectory(object):
78 |
79 | _log = logging.getLogger("directory")
80 |
81 | def __init__(self, path, excludes=None):
82 | self._path = os.path.abspath(path)
83 | self._excludes = excludes
84 | self._modules = {}
85 |
86 | def load(self):
87 | valid_paths = self._get_valid_paths()
88 |
89 | # Remove any deleted modules.
90 | for path, module in self._modules.items():
91 | if path not in valid_paths:
92 | del self._modules[path]
93 | module.unload()
94 |
95 | # Add any new modules.
96 | for path in valid_paths:
97 | if path not in self._modules:
98 | module = CommandModule(path)
99 | module.load()
100 | self._modules[path] = module
101 | else:
102 | module = self._modules[path]
103 | module.check_freshness()
104 |
105 | def _get_valid_paths(self):
106 | self._log.info("Looking for command modules here: %s" % (self._path,))
107 | valid_paths = []
108 | for filename in os.listdir(self._path):
109 | path = os.path.abspath(os.path.join(self._path, filename))
110 | if not os.path.isfile(path):
111 | continue
112 | if not os.path.splitext(path)[1] == ".py":
113 | continue
114 | if path in self._excludes:
115 | continue
116 | valid_paths.append(path)
117 | self._log.info("Valid paths: %s" % (", ".join(valid_paths),))
118 | return valid_paths
119 |
120 |
121 | #---------------------------------------------------------------------------
122 | # Main event driving loop.
123 |
124 | def main():
125 | logging.basicConfig(level=logging.INFO)
126 |
127 | try:
128 | path = os.path.dirname(__file__)
129 | except NameError:
130 | # The "__file__" name is not always available, for example
131 | # when this module is run from PythonWin. In this case we
132 | # simply use the current working directory.
133 | path = os.getcwd()
134 | __file__ = os.path.join(path, "dfly-loader-wsr.py")
135 |
136 | engine = Sapi5InProcEngine()
137 | engine.connect()
138 |
139 | directory = CommandModuleDirectory(path, excludes=[__file__])
140 | directory.load()
141 |
142 | engine.speak('beginning loop!')
143 | while 1:
144 | pythoncom.PumpWaitingMessages()
145 | time.sleep(.1)
146 |
147 | if __name__ == "__main__":
148 | main()
149 |
--------------------------------------------------------------------------------
/bombly/modules/mazes.py:
--------------------------------------------------------------------------------
1 | from collections import defaultdict
2 | from Queue import Queue
3 |
4 | mazes = {
5 | (('1','2'), ('6','3')): """
6 | x x x|x x x
7 | - - -
8 | x|x x|x x x
9 | - - -
10 | x|x x|x x x
11 | - -
12 | x|x x x|x x
13 | - - - -
14 | x x x|x x|x
15 | - -
16 | x x|x x|x x
17 | """,
18 | (('5','2'), ('2','4')): """
19 | x x x|x x x
20 | - - -
21 | x x|x x|x x
22 | - - -
23 | x|x x|x x x
24 | - -
25 | x x|x x|x|x
26 | - -
27 | x|x|x|x x|x
28 | -
29 | x|x x|x x x
30 | """,
31 | (('4','4'), ('6','4')): """
32 | x x x|x|x x
33 | -
34 | x|x|x|x x|x
35 | - - -
36 | x x|x|x x|x
37 |
38 | x|x|x|x|x|x
39 |
40 | x|x x|x|x|x
41 | - -
42 | x x x x|x x
43 | """,
44 | (('1','1'), ('1','4')): """
45 | x x|x x x x
46 | - - -
47 | x|x|x x x x
48 | - -
49 | x|x x|x x|x
50 | - - -
51 | x|x x x x x
52 | - - - -
53 | x x x x x|x
54 | - - -
55 | x x x|x x|x
56 | """,
57 | (('5','3'), ('4','6')): """
58 | x x x x x x
59 | - - - -
60 | x x x x x|x
61 | - - - -
62 | x x|x x|x x
63 | - -
64 | x|x x x|x|x
65 | - - -
66 | x|x x x x|x
67 | - - -
68 | x|x x x x x
69 | """,
70 | (('5','1'), ('3','5')): """
71 | x|x x|x x x
72 | -
73 | x|x|x|x x|x
74 | -
75 | x x|x|x|x x
76 | - - -
77 | x x|x x|x|x
78 | -
79 | x x|x|x|x x
80 | - - -
81 | x x x x|x x
82 | """,
83 | (('2','1'), ('2','6')): """
84 | x x x x|x x
85 | - -
86 | x|x x|x x|x
87 | - - -
88 | x x|x x|x x
89 | - - - -
90 | x x|x x x|x
91 | - -
92 | x|x|x x x|x
93 | - - -
94 | x x x x x x
95 | """,
96 | (('4','1'), ('3','4')): """
97 | x|x x x|x x
98 | -
99 | x x x|x x|x
100 | - - - -
101 | x|x x x x|x
102 | - -
103 | x|x x|x x x
104 | - - - -
105 | x|x|x x x x
106 | - - - -
107 | x x x x x x
108 | """,
109 | (('3','2'), ('1','5')): """
110 | x|x x x x x
111 | - -
112 | x|x|x x|x|x
113 | -
114 | x x x|x x|x
115 | - - -
116 | x|x|x x|x x
117 | - -
118 | x|x|x|x x|x
119 | -
120 | x x|x x|x x
121 | """,
122 | }
123 |
124 |
125 | def get_maze_dict(maze):
126 | maze_dict = defaultdict(list)
127 | maze = maze[1:]
128 | maze = maze.split('\n')
129 |
130 | # Ensure all lines have enough spacing to fill the maze
131 | maze = [row.ljust(12, ' ') for row in maze]
132 |
133 | for row_index, line in enumerate(maze):
134 | for col_index, item in enumerate(line):
135 | if item == 'x':
136 | col = col_index/2+1
137 | row = row_index/2+1
138 | try:
139 | if maze[row_index+1][col_index] == ' ':
140 | maze_dict[(col, row)].append(('D', (col, row+1)))
141 | except:
142 | pass
143 | try:
144 | if maze[row_index-1][col_index] == ' ':
145 | maze_dict[(col, row)].append(('U', (col, row-1)))
146 | except:
147 | pass
148 | try:
149 | if maze[row_index][col_index+1] == ' ':
150 | maze_dict[(col, row)].append(('R', (col+1, row)))
151 | except:
152 | pass
153 | try:
154 | if maze[row_index][col_index-1] == ' ':
155 | maze_dict[(col, row)].append(('L', (col-1, row)))
156 | except:
157 | pass
158 |
159 | return maze_dict
160 |
161 |
162 | def traverse_maze(maze_dict, start, finish):
163 | path = Queue()
164 | path.put([('x', start)])
165 | loop = {'D': 'U', 'U': 'D', 'L':'R', 'R':'L', 'x':''}
166 | while not path.empty():
167 | curr_path = path.get()
168 | temp_path = curr_path[:]
169 | new_paths = maze_dict[temp_path[-1][1]]
170 | # Check that we are not looping back and forth
171 | new_paths = [place for place in new_paths if place[0] != loop[curr_path[-1][0]]]
172 | for new_path in new_paths:
173 | if finish == new_path[1]:
174 | answer = ''
175 | for pair in (temp_path + [new_path])[1:]:
176 | answer += pair[0]
177 |
178 | return answer
179 | else:
180 | path.put(temp_path + [new_path])
181 | return None
182 |
183 |
184 | def get_maze(indicator):
185 | for indicators, maze in mazes.iteritems():
186 | if indicator in indicators:
187 | return maze
188 |
189 | return ''
190 |
191 |
192 | def solve_maze(extras):
193 | maze = str(extras['maze'])
194 | maze = ' '.join([x for x in maze.split() if x in ['one', 'two','three', 'four', 'five', 'six', 'seven', 'eight', 'nine']])
195 | print maze
196 | for word, num in [('one', '1'), ('two', '2'), ('three', '3'), ('four', '4'), ('five', '5'), ('six', '6'), ('seven', '7'), ('eight', '8'), ('nine', '9')]:
197 | maze = maze.replace(word, num)
198 |
199 | maze = maze.replace(' ', '')
200 | # If users input , or spaces, we ignore them
201 | indicator = tuple(maze[0:2])
202 | start = tuple([int(x) for x in maze[2:4]])
203 | finish = tuple([int(x) for x in maze[4:6]])
204 |
205 | if len(indicator) != 2 or len(start) != 2 or len(finish) != 2:
206 | return ['Try Maze Again',]
207 |
208 | maze = get_maze(indicator)
209 | print maze
210 | maze_dict = get_maze_dict(maze)
211 | letters = {'L': 'left', 'R': 'right', 'D':'down', 'U':'up'}
212 | path = []
213 | for letter in traverse_maze(maze_dict, start, finish):
214 | path.append(letters[letter])
215 |
216 | answer = []
217 | for path in [path[x:x+3] for x in range(0, len(path), 3)]:
218 | answer.append(path)
219 |
220 | return answer
221 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Bombly - Keep Talking and Nobody Explodes Robot
2 |
3 | ## Product
4 |
5 | [](http://www.youtube.com/watch?v=ydQEb6zyAuE)
6 |
7 | ### THIS IS BETA.. USE AT YOUR OWN RISK
8 |
9 | This is a "expert" robot written in Python to assist in playing Keep Talking and Nobody Explodes.
10 |
11 | In its traditional form, the bomb defuse talks with an expert who holds the [Bomb Manual](http://www.bombmanual.com). Based on the information given by the defuser, the expert scrambles through the manual give information back to the defuser to correctly secure the bomb.
12 |
13 | This is just a problem waiting to be solved with Python. Below is my attempt to solve this problem.
14 |
15 | WARNING: This does ruin the fun of the game. You have been warned!
16 |
17 | ## Installation
18 |
19 | ### Windows only
20 |
21 | Install dragonfly
22 |
23 | ```
24 | git clone https://github.com/t4ngo/dragonfly
25 | cd dragonfly
26 | python setup.py install
27 | ```
28 |
29 | Start the bot
30 |
31 | ```
32 | python dfly-loader-wsr.py
33 | ```
34 |
35 | I believe dragonfly should work with Dragon NaturallySpeaking, however, I did not use it.
36 |
37 | ## Commands available
38 |
39 | The general idea is to speak a `command` then a series of words about that command.
40 |
41 | ### Bomb variables
42 |
43 | ```
44 | batteries <#> - Number of batteries on bomb
45 | serial <#> - Last digit of serial
46 | vowel - Vowel in serial number
47 | car - CAR indicator on bomb
48 | freak - FRK indicator on bomb
49 | parallel - Parallel port on bomb
50 | ```
51 |
52 | ### Metabomb
53 |
54 | ```
55 | bomb reset - Reset global bomb variables
56 | bomb status - Print current values of global attributes
57 | ```
58 |
59 | ### Simple Wires
60 |
61 | ```
62 | simple wires - Where wires is in (red, blue, yellow, black, white)
63 | ```
64 |
65 | Example:
66 |
67 | ```
68 | simple wires red red blue blue yellow black
69 | ```
70 |
71 | ### Complex Wires
72 |
73 | ```
74 | complex wires - Where wires is in (light, red, blue, star, blank, next)
75 | ```
76 |
77 | Seperate each wire from left to right with `next`. `blank` is the reserved word for no attributes
78 |
79 | Example:
80 |
81 | ```
82 | 4 Wires:
83 | Red
84 | Blue with Star
85 | Red/Blue with Light/Star
86 | No attributes
87 | ```
88 |
89 | ```
90 | complex wires red next blue star next light red blue star next blank
91 | ```
92 |
93 | ### Maze
94 |
95 | ```
96 | maze - Where coords are 3 pairs of numbers for indicator, start, stop
97 | ```
98 | Note: Coords start at upper left (1, 1) and go horizontally then vertically.
99 |
100 |
101 | Example maze and command:
102 |
103 | ```
104 | X O X X
105 | X X X X
106 | S X X X
107 | X X X F
108 |
109 | Indicator - (2, 1)
110 | Start - (1, 3)
111 | Finish - (4, 4)
112 | ```
113 |
114 | ```
115 | maze 2 1 1 3 4 4
116 | ```
117 |
118 | ### Simon
119 |
120 | ```
121 | simon - Where colors are in (red, blue, yellow, green)
122 | ```
123 |
124 | Example:
125 |
126 | ```
127 | simon red blue blue red
128 | ```
129 |
130 | ### Wire sequence
131 |
132 | Say each wire in increasing order.
133 |
134 | ```
135 | wire sequence - where color in (red, blue, black) and destination in (apple, bravo, charlie)
136 | ```
137 |
138 | Example:
139 |
140 | ```
141 | 1 -blue-- A
142 |
143 | 2 -red--- B
144 |
145 | 3 -black- C
146 | ```
147 |
148 | ```
149 | wire sequence blue apple red bravo black charlie
150 | ```
151 |
152 | If two wire sequences in the same bomb, be sure to reset the wire sequence state between sequences.
153 |
154 | ```
155 | wire sequence reset
156 | ```
157 |
158 | ### Button
159 |
160 | Step 1:
161 | ```
162 | button
163 | ```
164 |
165 | If press and hold:
166 |
167 | ```
168 | button color
169 | ```
170 |
171 | ### Memory
172 |
173 | ```
174 | memory
175 | ```
176 |
177 | Example:
178 |
179 | ```
180 | 4
181 | 2 3 4 1
182 | ```
183 |
184 | ```
185 | memory 4 2 3 4 1
186 | ```
187 |
188 | If two memory modules in the same bomb, be sure to reset the memory state:
189 |
190 | ```
191 | memory reset
192 | ```
193 |
194 | ### Morse
195 |
196 | ```
197 | morse <0/1 for one letter> - Where 0 is short and 1 is long
198 | ```
199 |
200 | Rules for morse:
201 | * Give the morse module one morse letter at a time.
202 | * Be sure the letters are in succession of each other.
203 | * Only three letters are necessary.
204 |
205 | Example:
206 |
207 | ```
208 | -... ... -.-.
209 | ```
210 |
211 | ```
212 | morse 1 0 0 0
213 | morse 0 0 0
214 | morse 1 0 1 0
215 | ```
216 |
217 | If two morse modules in the same bomb, be sure to reset the morse state:
218 |
219 | ```
220 | morse reset
221 | ```
222 |
223 | ### Symbols
224 |
225 | ```
226 | symbols
227 | ```
228 |
229 | 
230 |
231 | ```
232 | tennis, a, l, lightning, kitty, h, c
233 | ```
234 |
235 | 
236 |
237 | ```
238 | e, tennis, c, o, star, h, question
239 | ```
240 |
241 | 
242 |
243 | ```
244 | copyright, butt, o, k, r, l, star
245 | ```
246 |
247 | 
248 |
249 | ```
250 | six, paragraph, b, kitty, k, question, smile
251 | ```
252 |
253 | 
254 |
255 | ```
256 | goblet, smile, b, c, paragraph, three, star
257 | ```
258 |
259 | 
260 |
261 | ```
262 | six, e, equals, smash, goblet, n, omega
263 | ```
264 |
265 | ### Who's on First
266 |
267 | Now for the fun module. This is still a work in progress (check out the code for all of the cases)
268 |
269 | ```
270 | words one - Step 1 of Who's on First, lookup position
271 | ```
272 |
273 | ```
274 | words two - Step 2 of Who's on First, start giving words from lookup table
275 | ```
276 |
277 | Below is the table of what spoken words coorelate to the words necessary to complete the challenge.
278 |
279 | ```
280 | ' ' - literally blank
281 | blank - blank
282 | c - c letter
283 | c - see letter
284 | cee - c c
285 | display - display
286 | done - don
287 | done - done
288 | done - done
289 | first - first
290 | hold - hold
291 | hold - hold
292 | hold on - hold on two
293 | lead - lead
294 | lead - mead
295 | led - L. E. D.
296 | left - left
297 | like - like
298 | middle - middle
299 | next - next
300 | no - no
301 | nothing - nothing
302 | okay - OK
303 | okay - okay
304 | press - press
305 | read - read
306 | ready - ready
307 | red - red short
308 | reed - read too
309 | right - right
310 | right - write
311 | says - says
312 | see - c s
313 | sure - sure
314 | their - e i r
315 | there - e r e
316 | they are - they are words
317 | they're - they are marked
318 | they're - they mark
319 | u - you letter
320 | uh huh - five letters
321 | uh uh - four letters
322 | uhhh - three h
323 | ur - you are letters
324 | wait - wait
325 | what - what no mark
326 | what? - what mark
327 | yes - yes
328 | yes - yes
329 | you - you word
330 | you are - you are words
331 | you are - your words
332 | you're - you are mark
333 | you're - your mark
334 | your - you're word
335 | your - your word
336 | ```
337 |
338 | ### Needy knobs
339 |
340 | ```
341 | knobs <0/1 of LEDs> - LEDs of bottom left 3 then upper right 3
342 | ```
343 |
344 | Example:
345 |
346 | ```
347 | Up
348 |
349 | < . >
350 |
351 | v
352 |
353 | 0 1 0 1 0 1
354 | 1 1 1 0 0 1
355 | ```
356 |
357 | ```
358 | knobs 1 1 1 1 0 1
359 | ```
360 |
361 | ### Password
362 |
363 | Not implemented...yet.
364 |
--------------------------------------------------------------------------------
/bombly/modules/whos_on_first.py:
--------------------------------------------------------------------------------
1 | # On first words
2 | on_first_words = []
3 | curr_wordlist = []
4 |
5 |
6 | def whos_on_first(extras):
7 | global curr_wordlist
8 | words = str(extras['words'])
9 |
10 | combos = {
11 | ('you', 'are', 'words'): 'you are',
12 | ('your', 'words'): 'you are',
13 | ('done',): 'done',
14 | ('don',): 'done',
15 | ('you', 'are', 'letters'): 'ur',
16 | ('uniform', 'romeo'): 'ur',
17 | ('sure',): 'sure',
18 | ('shore',): 'sure',
19 | ('you', 'word'): 'you',
20 | ('you', 'were'): 'you',
21 | ('you', 'were', 'to'): 'you',
22 | ('you', 'work'): 'you',
23 | ('hold',): 'hold',
24 | ('you', 'letter'): 'u',
25 | ('uniform'): 'u',
26 | ('yes',): 'yes',
27 | ('first',): 'first',
28 | ('display',): 'display',
29 | ('okay',): 'okay',
30 | ('OK',): 'okay',
31 | ('says',): 'says',
32 | ('nothing',): 'nothing',
33 | ('literally', 'blank'): ' ',
34 | ('literally', 'nothing'): ' ',
35 | ('blank',): 'blank',
36 | ('no',): 'no',
37 | ('L. E. D.'): 'led',
38 | ('lead',): 'lead',
39 | ('mead',): 'lead',
40 | ('read',): 'read',
41 | ('red', 'short'): 'red',
42 | ('read', 'too'): 'reed',
43 | ('hold', 'on', 'two'): 'hold on',
44 | ("you're", 'word'): 'your',
45 | ("your", 'word'): 'your',
46 | ('your', 'mark'): "you're",
47 | ('your', 'contraction'): "you're",
48 | ('your', 'apostrophe'): "you're",
49 | ('you', 'are', 'marked'): "you're",
50 | ('you', 'are', 'mark'): "you're",
51 | ('you', 'are', 'contraction'): "you're",
52 | ('you', 'are', 'apostrophe'): "you're",
53 | ("Sierra", "echo", "echo"): "see",
54 | ('they', 'are', 'words'): "they are",
55 | ("echo", "india", "romeo"): "their",
56 | ("echo", "romeo", "echo"): "there",
57 | ('they', 'are', 'marked'): "they're",
58 | ('they', 'are', 'contraction'): "they're",
59 | ('they', 'are', 'apostrophe'): "they're",
60 | ('they', 'mark'): "they're",
61 | ('their', 'mark'): "they're",
62 | ('there', 'mark'): "they're",
63 | ('Sierra', 'echo', 'echo'): "see",
64 | ('charlie',): "c",
65 | ('see', 'letter'): "c",
66 | ('charlie', 'echo', 'echo'): "cee",
67 | ('ready',): 'ready',
68 | ('yes',): 'yes',
69 | ('what', 'no', 'mark'): 'what',
70 | ('what', 'know', 'mark'): 'what',
71 | ('three', 'H.'): 'uhhh',
72 | ('left',): 'left',
73 | ('right',): 'right',
74 | ('write',): 'right',
75 | ('middle',): 'middle',
76 | ('metal',): 'middle',
77 | ('wait',): 'wait',
78 | ('press',): 'press',
79 | ('five', 'letters'): 'uh huh',
80 | ('hotel', 'uniform', 'hotel'): 'uh huh',
81 | ('four', 'letters'): 'uh uh',
82 | ('uniform', 'hotel'): 'uh uh',
83 | ('what', 'mark'): 'what?',
84 | ('done',): 'done',
85 | ('next',): 'next',
86 | ('hold',): 'hold',
87 | ('sure',): 'sure',
88 | ('like',): 'like',
89 | ('mike',): 'like',
90 | ('might',): 'like',
91 | ('white',): 'like',
92 | ('light',): 'like',
93 | }
94 |
95 | positions = {
96 | 'yes': 3,
97 | 'first': 2,
98 | 'display': 6,
99 | 'okay': 2,
100 | 'says': 6,
101 | 'nothing': 3,
102 | ' ': 5,
103 | 'blank': 4,
104 | 'no': 6,
105 | 'led': 3,
106 | 'lead': 6,
107 | 'read': 4,
108 | 'red': 4,
109 | 'reed': 5,
110 | 'leed': 5,
111 | 'hold on': 6,
112 | 'you': 4,
113 | 'you are': 6,
114 | 'your': 4,
115 | "you're": 4,
116 | 'ur': 1,
117 | 'there': 6,
118 | "they're": 5,
119 | 'their': 4,
120 | 'they are': 3,
121 | 'see': 6,
122 | 'c': 2,
123 | 'cee': 6
124 | }
125 |
126 | table = {
127 | "ready": ["yes", "okay", "what", "middle", "left", "press", "right", "blank", "ready"],
128 | "first": ["left", "okay", "yes", "middle", "no", "right", "nothing", "uhhh", "wait", "ready", "blank", "what", "press", "first"],
129 | "no": ["blank", "uhhh", "wait", "first", "what", "ready", "right", "yes", "nothing", "left", "press", "okay", "no", "middle"],
130 | "blank": ["wait", "right", "okay", "middle", "blank"],
131 | "nothing": ["uhhh", "right", "okay", "middle", "yes", "blank", "no", "press", "left", "what", "wait", "first", "nothing", "ready"],
132 | "yes": ["okay", "right", "uhhh", "middle", "first", "what", "press", "ready", "nothing", "yes"],
133 | "what": ["uhhh", "what"],
134 | "uhhh": ["ready", "nothing", "left", "what", "okay", "yes", "right", "no", "press", "blank", "uhhh"],
135 | "left": ["right", "left"],
136 | "right": ["yes", "nothing", "ready", "press", "no", "wait", "what", "right"],
137 | "middle": ["blank", "ready", "okay", "what", "nothing", "press", "no", "wait", "left", "middle"],
138 | "okay": ["middle", "no", "first", "yes", "uhhh", "nothing", "wait", "okay"],
139 | "wait": ["uhhh", "no", "blank", "okay", "yes", "left", "first", "press", "what", "wait"],
140 | "press": ["right", "middle", "yes", "ready", "press"],
141 | "you": ["sure", "you are", "your", "you're", "next", "uh huh", "ur", "hold", "what?", "you"],
142 | "you are": ["your", "next", "like", "uh huh", "what?", "done", "uh uh", "hold", "you", "u", "you're", "sure", "ur", "you are"],
143 | "your": ["uh uh", "you are", "uh huh", "your"],
144 | "you're": ["you", "you're"],
145 | "ur": ["done", "u", "ur"],
146 | "u": ["uh huh", "sure", "next", "what?", "you're", "ur", "uh uh", "done", "u"],
147 | "uh huh": ["uh huh"],
148 | "uh uh": ["ur", "u", "you are", "you", "done", "hold", "uh uh", "next", "sure", "like", "your", "sure", "hold", "what?"],
149 | "what?": ["you", "hold", "you're", "your", "u", "done", "uh uh", "like", "you are", "uh huh", "ur", "next", "what?"],
150 | "done": ["sure", "uh huh", "next", "what?", "your", "ur", "you're", "hold", "like", "you", "u", "you are", "uh uh", "done"],
151 | "next": ["what?", "uh huh", "uh uh", "your", "hold", "sure", "next"],
152 | "hold": ["you are", "u", "done", "uh uh", "you", "ur", "sure", "what?", "you're", "next", "hold"],
153 | "sure": ["you are", "done", "like", "you're", "you", "hold", "uh huh", "ur", "sure"],
154 | "like": ["you're", "next", "u", "ur", "hold", "uh uh", "what?", "uh huh", "you", "like"],
155 | }
156 |
157 | responses = {
158 | "you are": ("you" "are", "words"),
159 | "done": ("done",),
160 | "ur": ("you", "are", "letters"),
161 | "sure": ("sure",),
162 | "you": ("you", "word"),
163 | "hold": ("hold",),
164 | "u": ("you", "letter"),
165 | "yes": ("yes",),
166 | "first": ("first",),
167 | "display": ("display",),
168 | "okay": ("okay",),
169 | "says": ("says",),
170 | "nothing": ("nothing",),
171 | " ": ("literally", "blank"),
172 | "blank": ("blank",),
173 | "no": ("no",),
174 | "led": ("L.", "E.", "D."),
175 | "lead": ("lead",),
176 | "read": ("read",),
177 | "red": ("red", "short"),
178 | "reed": ("read", "too"),
179 | "hold on": ("hold", "on", "two"),
180 | "your": ("your", "word"),
181 | "you're": ("you", "are", "mark"),
182 | "see": ("Sierra", "echo", "echo"),
183 | "they are": ("they", "are", "words"),
184 | "their": ("E.", "I.", "R."),
185 | "there": ("E.", "R.", "E."),
186 | "they're": ("they", "are", "marked"),
187 | "c": ("charlie"),
188 | "cee": ("charlie", "echo", "echo"),
189 | "ready": ("ready",),
190 | "yes": ("yes",),
191 | "what": ("what", "no", "mark"),
192 | "uhhh": ("three", "H."),
193 | "left": ("left",),
194 | "right": ("right",),
195 | "right": ("write",),
196 | "middle": ("middle",),
197 | "wait": ("wait",),
198 | "press": ("press",),
199 | "uh huh": ("five", "letters"),
200 | "uh uh": ("four", "letters"),
201 | "what?": ("what", "question"),
202 | "done": ("done",),
203 | "next": ("next",),
204 | "hold": ("hold",),
205 | "sure": ("sure",),
206 | "like": ("like",),
207 | }
208 | print "Voice receive: ", words
209 |
210 | for combo, select in reversed(sorted(combos.iteritems(), key=lambda x: len(x[0]))):
211 | for word in combo:
212 | if word not in words.split():
213 | break
214 | else:
215 | print 'Words', words
216 | print "Found word: {}".format(select)
217 | if 'one' in words.split():
218 | curr_wordlist = []
219 | return positions[select]
220 |
221 | if 'two' in words.split():
222 | print 'select', select
223 | wordlist = table[select]
224 | answer = []
225 | new_length = min(4, len(wordlist))
226 | curr_wordlist = []
227 | print wordlist
228 |
229 | # Cache next set of words in case we need to ask for more
230 | # words
231 | for word in wordlist[new_length:]:
232 | print 'word:', word
233 | curr_wordlist.append(' '.join(responses[word]))
234 |
235 | for word in wordlist[:new_length]:
236 | answer.append(' '.join(responses[word]))
237 |
238 | return ', '.join(answer)
239 | break
240 |
241 |
242 | def more():
243 | global curr_wordlist
244 | speak = ', '.join(curr_wordlist[:4])
245 | new_length = min(4, len(curr_wordlist))
246 | curr_wordlist = curr_wordlist[new_length:]
247 | return speak
248 |
249 |
250 | def remove():
251 | global on_first_words
252 | on_first_words = on_first_words[:-1]
253 |
254 |
255 | def reset():
256 | global on_first_words
257 | on_first_words = []
258 |
--------------------------------------------------------------------------------
/bombly.py:
--------------------------------------------------------------------------------
1 | from dragonfly import *
2 | from dragonfly.engines.backend_sapi5.engine import Sapi5InProcEngine
3 |
4 |
5 | engine = Sapi5InProcEngine()
6 | engine.connect()
7 |
8 |
9 | def easy_answer(answer):
10 | count = 0
11 | curr_letter = answer[0]
12 | curr_answer = ''
13 |
14 | for index, letter in enumerate(answer):
15 | left = start[index:]
16 | if letter != curr_letter:
17 | curr_answer += curr_letter + str(count) + ' '
18 | curr_letter = letter
19 | count = 1
20 | else:
21 | count += 1
22 |
23 | curr_answer += curr_letter + str(count)
24 |
25 | return curr_answer
26 |
27 |
28 | def sanitize_colors(words):
29 | print "Sanitizing: {}".format(words)
30 | words = words.replace('read', 'red').replace('blew', 'blue')
31 | words = ' '.join([word for word in words.split() if word in ('yellow', 'red', 'black', 'blue', 'white')])
32 | print "Sanitized: {}".format(words)
33 | return words
34 |
35 | class SampleRule(CompoundRule):
36 | spec = "simple wires " # Spoken form of command.
37 | extras = [Dictation("wires")]
38 | def _process_recognition(self, node, extras): # Callback when command is spoken.
39 | wire = str(extras['wires'])
40 |
41 | class BombResetRule(CompoundRule):
42 | spec = "bomb reset"
43 |
44 | def _process_recognition(self, node, extras): # Callback when command is spoken.
45 | from bombly.bomb import reset
46 | reset()
47 |
48 |
49 | class BombStatusRule(CompoundRule):
50 | spec = "bomb status"
51 |
52 | def _process_recognition(self, node, extras): # Callback when command is spoken.
53 | from bombly.bomb import status
54 | status()
55 |
56 |
57 | class BombCarRule(CompoundRule):
58 | spec = "car "
59 | extras = [IntegerRef('car', 0, 10)]
60 |
61 | def _process_recognition(self, node, extras): # Callback when command is spoken.
62 | from bombly.bomb import set_car
63 | set_car(extras)
64 |
65 |
66 | class BombBatteriesRule(CompoundRule):
67 | spec = "batteries "
68 | extras = [IntegerRef('batteries', 0, 10)]
69 |
70 | def _process_recognition(self, node, extras): # Callback when command is spoken.
71 | from bombly.bomb import set_batteries
72 | set_batteries(extras)
73 |
74 |
75 | class BombFreakRule(CompoundRule):
76 | spec = "freak "
77 | extras = [Dictation('word')]
78 |
79 | def _process_recognition(self, node, extras): # Callback when command is spoken.
80 | from bombly.bomb import set_freak
81 | set_freak(extras)
82 |
83 |
84 | class BombParallelRule(CompoundRule):
85 | spec = "parallel "
86 | extras = [
87 | Dictation('word'),
88 | ]
89 |
90 | def _process_recognition(self, node, extras): # Callback when command is spoken.
91 | from bombly.bomb import set_parallel
92 | set_parallel(extras)
93 |
94 |
95 | class BombSerialRule(CompoundRule):
96 | spec = "serial "
97 | extras = [
98 | IntegerRef('word', 0, 10),
99 | ]
100 |
101 | def _process_recognition(self, node, extras): # Callback when command is spoken.
102 | from bombly.bomb import set_serial
103 | set_serial(extras)
104 |
105 |
106 | class BombVowelRule(CompoundRule):
107 | spec = "set vowel "
108 | extras = [
109 | Dictation('word')
110 | ]
111 |
112 | def _process_recognition(self, node, extras): # Callback when command is spoken.
113 | from bombly.bomb import set_vowel
114 | set_vowel(extras)
115 |
116 |
117 | # Voice command rule combining spoken form and recognition processing.
118 | class SimpleWiresRule(CompoundRule):
119 | spec = "simple wires " # Spoken form of command.
120 | extras = [Dictation("wires")]
121 | def _process_recognition(self, node, extras): # Callback when command is spoken.
122 | from bombly.modules.wires import wires
123 | from bombly.bomb import odd_serial
124 | engine.speak(wires(extras, sanitize_colors, odd_serial))
125 |
126 | class ComplexWiresRule(CompoundRule):
127 | spec = "complex wires " # Spoken form of command.
128 | extras = [Dictation("wires")]
129 |
130 | def _process_recognition(self, node, extras): # Callback when command is spoken.
131 | from bombly.modules.complicated_wires import complicated_wires
132 | from bombly.bomb import batteries, serial, parallel
133 | engine.speak(complicated_wires(extras, batteries, serial, parallel))
134 |
135 |
136 | class MazeRule(CompoundRule):
137 | spec = "maze " # Spoken form of command.
138 | extras = [Dictation("maze")]
139 | def _process_recognition(self, node, extras): # Callback when command is spoken.
140 | from bombly.modules.mazes import solve_maze
141 | answer = solve_maze(extras)
142 | for item in answer:
143 | engine.speak(item)
144 |
145 | class SimonRule(CompoundRule):
146 | spec = "simon " # Spoken form of command.
147 | extras = [Dictation("words")]
148 | def _process_recognition(self, node, extras): # Callback when command is spoken.
149 | from bombly.modules.simon_says import simon
150 | from bombly.bomb import vowel
151 | engine.speak(simon(extras, vowel))
152 |
153 |
154 | class WireSequenceRule(CompoundRule):
155 | spec = "wire sequence " # Spoken form of command.
156 | extras = [Dictation("words")]
157 | def _process_recognition(self, node, extras): # Callback when command is spoken.
158 | from bombly.modules.wire_sequences import wire_sequence
159 | engine.speak(wire_sequence(extras))
160 |
161 | class WireSequenceResetRule(CompoundRule):
162 | spec = "wire sequence reset" # Spoken form of command.
163 | def _process_recognition(self, node, extras): # Callback when command is spoken.
164 | from bombly.modules.wire_sequences import reset
165 | reset()
166 |
167 | class ButtonRule(CompoundRule):
168 | spec = "button " # Spoken form of command.
169 | extras = [Dictation("words")]
170 | def _process_recognition(self, node, extras): # Callback when command is spoken.
171 | from bombly.modules.the_button import button
172 | from bombly.bomb import batteries, car, freak
173 | engine.speak(button(extras, batteries, car, freak))
174 |
175 | class ButtonColorRule(CompoundRule):
176 | spec = "button color " # Spoken form of command.
177 | extras = [Dictation("words")]
178 | def _process_recognition(self, node, extras): # Callback when command is spoken.
179 | from bombly.modules.the_button import button_color
180 | engine.speak(button_color(extras))
181 |
182 | class KnobsRule(CompoundRule):
183 | spec = "knobs " # Spoken form of command.
184 | extras = [Dictation("words")]
185 | def _process_recognition(self, node, extras): # Callback when command is spoken.
186 | from bombly.modules.needy.knob import knob
187 | engine.speak(knob(extras))
188 |
189 |
190 | class MemoryRule(CompoundRule):
191 | spec = "memory " # Spoken form of command.
192 | extras = [Dictation("words")]
193 | def _process_recognition(self, node, extras): # Callback when command is spoken.
194 | from bombly.modules.memory import memory
195 | engine.speak(memory(extras))
196 |
197 |
198 | class MemoryResetRule(CompoundRule):
199 | spec = "memory reset" # Spoken form of command.
200 | def _process_recognition(self, node, extras): # Callback when command is spoken.
201 | from bombly.modules.memory import reset
202 | reset()
203 |
204 | class MorseRule(CompoundRule):
205 | spec = "morse " # Spoken form of command.
206 | extras = [Dictation("words")]
207 | def _process_recognition(self, node, extras): # Callback when command is spoken.
208 | from bombly.modules.morse_code import morse_code
209 | engine.speak(morse_code(extras))
210 |
211 |
212 | class MorseResetRule(CompoundRule):
213 | spec = "morse reset" # Spoken form of command.
214 | def _process_recognition(self, node, extras): # Callback when command is spoken.
215 | from bombly.modules.morse_code import reset
216 | reset()
217 |
218 |
219 | class WordsResetRule(CompoundRule):
220 | spec = "words reset" # Spoken form of command.
221 | def _process_recognition(self, node, extras): # Callback when command is spoken.
222 | from bombly.modules.whos_on_first import reset
223 | reset()
224 |
225 |
226 | class WordsRemoveRule(CompoundRule):
227 | spec = "words remove" # Spoken form of command.
228 | def _process_recognition(self, node, extras): # Callback when command is spoken.
229 | from bombly.modules.whos_on_first import remove
230 | remove()
231 |
232 |
233 | class SymbolsRule(CompoundRule):
234 | spec = "symbols " # Spoken form of command.
235 | extras = [Dictation("symbols")]
236 | def _process_recognition(self, node, extras): # Callback when command is spoken.
237 | from bombly.modules.keypads import keypad
238 | engine.speak(keypad(extras))
239 |
240 |
241 | class WordsRule(CompoundRule):
242 | spec = "words " # Spoken form of command.
243 | extras = [Dictation("words")]
244 | def _process_recognition(self, node, extras): # Callback when command is spoken.
245 | from bombly.modules.whos_on_first import whos_on_first
246 | engine.speak(whos_on_first(extras))
247 |
248 |
249 | class WordsMoreRule(CompoundRule):
250 | spec = "words more" # Spoken form of command.
251 | def _process_recognition(self, node, extras): # Callback when command is spoken.
252 | from bombly.modules.whos_on_first import more
253 | engine.speak(more())
254 |
255 |
256 | class PasswordResetRule(CompoundRule):
257 | spec = "password reset" # Spoken form of command.
258 | def _process_recognition(self, node, extras): # Callback when command is spoken.
259 | from bombly.modules.passwords import reset
260 | reset()
261 |
262 |
263 | class PasswordRule(CompoundRule):
264 | spec = "password " # Spoken form of command.
265 | extras = [Dictation("letters")]
266 | def _process_recognition(self, node, extras): # Callback when command is spoken.
267 | from bombly.modules.passwords import solve_password
268 | for word in solve_password(extras):
269 | engine.speak(word)
270 |
271 |
272 | class BombDoneRule(CompoundRule):
273 | spec = "bomb done" # Spoken form of command.
274 | def _process_recognition(self, node, extras): # Callback when command is spoken.
275 | from bombly.bomb import done
276 | engine.speak(done())
277 |
278 |
279 | class BombExplodedRule(CompoundRule):
280 | spec = "bomb exploded" # Spoken form of command.
281 | def _process_recognition(self, node, extras): # Callback when command is spoken.
282 | from bombly.bomb import exploded
283 | engine.speak(exploded())
284 |
285 |
286 | # Create a grammar which contains and loads the command rule.
287 | grammar = Grammar("Keep Talking") # Create a grammar to contain the command rule.
288 | grammar.add_rule(BombBatteriesRule()) # Add the command rule to the grammar.
289 | grammar.add_rule(BombVowelRule()) # Add the command rule to the grammar.
290 | grammar.add_rule(BombParallelRule()) # Add the command rule to the grammar.
291 | grammar.add_rule(BombSerialRule()) # Add the command rule to the grammar.
292 | grammar.add_rule(BombFreakRule()) # Add the command rule to the grammar.
293 | grammar.add_rule(BombCarRule()) # Add the command rule to the grammar.
294 | grammar.add_rule(BombResetRule()) # Add the command rule to the grammar.
295 | grammar.add_rule(BombStatusRule()) # Add the command rule to the grammar.
296 | grammar.add_rule(SimpleWiresRule()) # Add the command rule to the grammar.
297 | grammar.add_rule(ComplexWiresRule()) # Add the command rule to the grammar.
298 | grammar.add_rule(MazeRule()) # Add the command rule to the grammar.
299 | grammar.add_rule(SimonRule()) # Add the command rule to the grammar.
300 | grammar.add_rule(WireSequenceRule()) # Add the command rule to the grammar.
301 | grammar.add_rule(WireSequenceResetRule()) # Add the command rule to the grammar.
302 | grammar.add_rule(ButtonRule()) # Add the command rule to the grammar.
303 | grammar.add_rule(ButtonColorRule()) # Add the command rule to the grammar.
304 | grammar.add_rule(KnobsRule()) # Add the command rule to the grammar.
305 | grammar.add_rule(MemoryRule()) # Add the command rule to the grammar.
306 | grammar.add_rule(MemoryResetRule()) # Add the command rule to the grammar.
307 | grammar.add_rule(MorseRule()) # Add the command rule to the grammar.
308 | grammar.add_rule(MorseResetRule()) # Add the command rule to the grammar.
309 | grammar.add_rule(SymbolsRule()) # Add the command rule to the grammar.
310 | grammar.add_rule(WordsRule()) # Add the command rule to the grammar.
311 | grammar.add_rule(WordsResetRule()) # Add the command rule to the grammar.
312 | grammar.add_rule(WordsRemoveRule()) # Add the command rule to the grammar.
313 | grammar.add_rule(WordsMoreRule()) # Add the command rule to the grammar.
314 | grammar.add_rule(PasswordResetRule()) # Add the command rule to the grammar.
315 | grammar.add_rule(PasswordRule()) # Add the command rule to the grammar.
316 | grammar.add_rule(BombDoneRule())
317 | grammar.add_rule(BombExplodedRule())
318 | grammar.load()
319 |
--------------------------------------------------------------------------------
/':
--------------------------------------------------------------------------------
1 | from dragonfly import *
2 | from dragonfly.engines.backend_sapi5.engine import Sapi5InProcEngine
3 |
4 | from collections import defaultdict
5 | import sys
6 |
7 | ################################################################################
8 | # Global variables
9 | ################################################################################
10 | engine = Sapi5InProcEngine()
11 | engine.connect()
12 |
13 | # Battery characteristics
14 | batteries = 99
15 | freak = 'freak'
16 | car = 'car'
17 | parallel = 'parallel'
18 | serial = 'serial'
19 | vowel = 'vowel'
20 |
21 | # Maxes
22 | mazes = {
23 | (('1','2'), ('6','3')): """
24 | x x x|x x x
25 | - - -
26 | x|x x|x x x
27 | - - -
28 | x|x x|x x x
29 | - -
30 | x|x x x|x x
31 | - - - -
32 | x x x|x x|x
33 | - -
34 | x x|x x|x x
35 | """,
36 | (('5','2'), ('2','4')): """
37 | x x x|x x x
38 | - - -
39 | x x|x x|x x
40 | - - -
41 | x|x x|x x x
42 | - -
43 | x x|x x|x|x
44 | - -
45 | x|x|x|x x|x
46 | -
47 | x|x x|x x x
48 | """,
49 | (('4','4'), ('6','4')): """
50 | x x x|x|x x
51 | -
52 | x|x|x|x x|x
53 | - - -
54 | x x|x|x x|x
55 |
56 | x|x|x|x|x|x
57 |
58 | x|x x|x|x|x
59 | - -
60 | x x x x|x x
61 | """,
62 | (('1','1'), ('1','4')): """
63 | x x|x x x x
64 | - - -
65 | x|x|x x x x
66 | - -
67 | x|x x|x x|x
68 | - - -
69 | x|x x x x x
70 | - - - -
71 | x x x x x|x
72 | - - -
73 | x x x|x x|x
74 | """,
75 | (('5','3'), ('4','6')): """
76 | x x x x x x
77 | - - - -
78 | x x x x x|x
79 | - - - -
80 | x x|x x|x x
81 | - -
82 | x|x x x|x|x
83 | - - -
84 | x|x x x x|x
85 | - - -
86 | x|x x x x x
87 | """,
88 | (('5','1'), ('3','5')): """
89 | x|x x|x x x
90 | -
91 | x|x|x|x x|x
92 | -
93 | x x|x|x|x x
94 | - - -
95 | x x|x x|x|x
96 | -
97 | x x|x|x|x x
98 | - - -
99 | x x x x|x x
100 | """,
101 | (('2','1'), ('2','6')): """
102 | x x x x|x x
103 | - -
104 | x|x x|x x|x
105 | - - -
106 | x x|x x|x x
107 | - - - -
108 | x x|x x x|x
109 | - -
110 | x|x|x x x|x
111 | - - -
112 | x x x x x x
113 | """,
114 | (('4','1'), ('3','4')): """
115 | x|x x x|x x
116 | -
117 | x x x|x x|x
118 | - - - -
119 | x|x x x x|x
120 | - -
121 | x|x x|x x x
122 | - - - -
123 | x|x|x x x x
124 | - - - -
125 | x x x x x x
126 | """,
127 | (('3','2'), ('1','5')): """
128 | x|x x x x x
129 | - -
130 | x|x|x x|x x
131 | -
132 | x x x|x x|x
133 | - - -
134 | x|x|x x|x x
135 | - -
136 | x|x|x|x x|x
137 | -
138 | x x|x x|x x
139 | """,
140 | }
141 |
142 | # Wire sequence
143 | counts = defaultdict(int)
144 | sequences = {}
145 | sequences['red'] = [
146 | ('c'),
147 | ('b'),
148 | ('a'),
149 | ('a', 'c'),
150 | ('b'),
151 | ('a', 'c'),
152 | ('a', 'b', 'c'),
153 | ('a', 'b'),
154 | ('b')
155 | ]
156 | sequences['blue'] = [
157 | ('b'),
158 | ('a', 'c'),
159 | ('b'),
160 | ('a'),
161 | ('b'),
162 | ('b','c'),
163 | ('c'),
164 | ('a', 'c'),
165 | ('a')
166 | ]
167 | sequences['black'] = [
168 | ('a', 'b', 'c'),
169 | ('a', 'c'),
170 | ('b'),
171 | ('a', 'c'),
172 | ('b'),
173 | ('b', 'c'),
174 | ('a', 'b'),
175 | ('c'),
176 | ('c')
177 | ]
178 |
179 | # Memory
180 | values = []
181 | positions = []
182 | curr_stage = 1
183 |
184 | # Morse
185 | morse_letters = []
186 |
187 | # On first words
188 | on_first_words = []
189 | curr_wordlist = []
190 |
191 | # Password
192 | curr_password = []
193 |
194 | def get_maze_dict(maze):
195 | maze_dict = defaultdict(list)
196 | maze = maze[1:]
197 | maze = maze.split('\n')
198 |
199 | for row_index, line in enumerate(maze):
200 | for col_index, item in enumerate(line):
201 | if item == 'x':
202 | col = col_index/2+1
203 | row = row_index/2+1
204 | try:
205 | if maze[row_index+1][col_index] == ' ':
206 | maze_dict[(col, row)].append(('D', (col, row+1)))
207 | except:
208 | pass
209 | try:
210 | if maze[row_index-1][col_index] == ' ':
211 | maze_dict[(col, row)].append(('U', (col, row-1)))
212 | except:
213 | pass
214 | try:
215 | if maze[row_index][col_index+1] == ' ':
216 | maze_dict[(col, row)].append(('R', (col+1, row)))
217 | except:
218 | pass
219 | try:
220 | if maze[row_index][col_index-1] == ' ':
221 | maze_dict[(col, row)].append(('L', (col-1, row)))
222 | except:
223 | pass
224 |
225 | return maze_dict
226 |
227 | def easy_answer(answer):
228 | count = 0
229 | curr_letter = answer[0]
230 | curr_answer = ''
231 |
232 | for index, letter in enumerate(answer):
233 | left = start[index:]
234 | if letter != curr_letter:
235 | curr_answer += curr_letter + str(count) + ' '
236 | curr_letter = letter
237 | count = 1
238 | else:
239 | count += 1
240 |
241 | curr_answer += curr_letter + str(count)
242 |
243 | return curr_answer
244 |
245 |
246 | def traverse_maze(maze_dict, start, finish):
247 | path = [[('x', start)]]
248 | while True:
249 | for curr_path in path:
250 | temp_path = curr_path[:]
251 | new_paths = maze_dict[temp_path[-1][1]]
252 | for new_path in new_paths:
253 | if finish == new_path[1]:
254 | answer = ''
255 | for pair in (temp_path + [new_path])[1:]:
256 | answer += pair[0]
257 |
258 | return answer
259 | else:
260 | path.append(temp_path + [new_path])
261 |
262 | def get_maze(indicator):
263 | for indicators,maze in mazes.iteritems():
264 | if indicator in indicators:
265 | return maze
266 |
267 | return ''
268 |
269 | def odd_serial():
270 | return serial in ('one', 'three', 'five', 'seven', 'nine')
271 |
272 | def even_serial():
273 | return serial in ('zero', 'two', 'four', 'six', 'eight')
274 |
275 | def sanitize_colors(words):
276 | print "Sanitizing: {}".format(words)
277 | words = words.replace('read', 'red').replace('blew', 'blue')
278 | words = ' '.join([word for word in words.split() if word in ('yellow', 'red', 'black', 'blue', 'white')])
279 | print "Sanitized: {}".format(words)
280 | return words
281 |
282 | class SampleRule(CompoundRule):
283 | spec = "simple wires " # Spoken form of command.
284 | extras = [Dictation("wires")]
285 | def _process_recognition(self, node, extras): # Callback when command is spoken.
286 | wire = str(extras['wires'])
287 |
288 | class BombResetRule(CompoundRule):
289 | spec = "bomb reset"
290 |
291 | def _process_recognition(self, node, extras): # Callback when command is spoken.
292 | global batteries
293 | global freak
294 | global car
295 | global paralle
296 | global serial
297 | global vowel
298 | global counts
299 | global values
300 | global positions
301 | global curr_stage
302 | global morse_letters
303 | global on_first_words
304 |
305 | # Battery characteristics
306 | batteries = 99
307 | freak = 'freak'
308 | car = 'car'
309 | parallel = 'parallel'
310 | serial = 'serial'
311 | vowel = 'vowel'
312 |
313 | # Wire sequence
314 | counts = defaultdict(int)
315 |
316 | # Memory
317 | values = []
318 | positions = []
319 | curr_stage = 1
320 |
321 | # Morse
322 | morse_letters = []
323 |
324 | # On First Words
325 | on_first_words = []
326 |
327 | # Password
328 | curr_password = []
329 |
330 | class BombStatusRule(CompoundRule):
331 | spec = "bomb status"
332 |
333 | def _process_recognition(self, node, extras): # Callback when command is spoken.
334 | global batteries
335 | global freak
336 | global car
337 | global paralle
338 | global serial
339 | global vowel
340 | global counts
341 | global values
342 | global positions
343 | global curr_stage
344 | global morse_letters
345 | global on_first_words
346 |
347 | # Battery characteristics
348 | print 'batteries', batteries
349 | print 'frk', freak
350 | print 'car', car
351 | print 'parallel', parallel
352 | print 'serial', serial
353 | print 'vowel', vowel
354 |
355 | # Wire sequence
356 | print 'wire sequence', counts
357 |
358 | # Memory
359 | print 'values', values
360 | print 'position', positions
361 | print 'curr_stage', curr_stage
362 |
363 | # Morse
364 | print 'morse_letters', morse_letters
365 |
366 | # On First Words
367 | print 'on first words', on_first_words
368 |
369 | class BombCarRule(CompoundRule):
370 | spec = "car "
371 | extras = [IntegerRef('car', 0, 10)]
372 |
373 | def _process_recognition(self, node, extras): # Callback when command is spoken.
374 | global car
375 | car = str(extras['car'])
376 |
377 | class BombBatteriesRule(CompoundRule):
378 | spec = "batteries "
379 | extras = [IntegerRef('batteries', 0, 10)]
380 |
381 | def _process_recognition(self, node, extras): # Callback when command is spoken.
382 | global batteries
383 | batteries = int(str(extras['batteries']))
384 |
385 | class BombFreakRule(CompoundRule):
386 | spec = "freak "
387 | extras = [Dictation('word')]
388 |
389 | def _process_recognition(self, node, extras): # Callback when command is spoken.
390 | global freak
391 | freak = str(extras['word'])
392 |
393 | class BombParallelRule(CompoundRule):
394 | spec = "parallel "
395 | extras = [
396 | Dictation('word'),
397 | ]
398 |
399 | def _process_recognition(self, node, extras): # Callback when command is spoken.
400 | global parallel
401 | parallel = str(extras['word'])
402 |
403 | class BombSerialRule(CompoundRule):
404 | spec = "serial "
405 | extras = [
406 | Dictation('word'),
407 | ]
408 |
409 | def _process_recognition(self, node, extras): # Callback when command is spoken.
410 | global serial
411 | serial = str(extras['word'])
412 |
413 | class BombVowelRule(CompoundRule):
414 | spec = "vowel "
415 | extras = [
416 | Dictation('word')
417 | ]
418 |
419 | def _process_recognition(self, node, extras): # Callback when command is spoken.
420 | global vowel
421 | vowel = str(extras['word'])
422 |
423 | # Voice command rule combining spoken form and recognition processing.
424 | class SimpleWiresRule(CompoundRule):
425 | spec = "simple wires " # Spoken form of command.
426 | extras = [Dictation("wires")]
427 | def _process_recognition(self, node, extras): # Callback when command is spoken.
428 | spoken = 'need'
429 | if serial == 'serial':
430 | spoken += ' last digit of serial'
431 | if spoken != 'need':
432 | engine.speak(spoken)
433 | return
434 |
435 | wire = str(extras['wires'])
436 | wire = sanitize_colors(wire)
437 | wire = wire.split()
438 |
439 | if len(wire) == 3:
440 | if 'red' not in wire:
441 | engine.speak('cut second wire')
442 | elif wire[-1] == 'white':
443 | engine.speak('cut last wire')
444 | elif wire.count('blue') > 1:
445 | engine.speak('cut last blue wire')
446 | else:
447 | engine.speak('cut last wire')
448 |
449 | elif len(wire) == 4:
450 | if wire.count('red') > 1 and odd_serial():
451 | engine.speak('cut last red wire')
452 | elif wire[-1] == 'yellow' and wire.count('red') == 0:
453 | engine.speak('cut first wire')
454 | elif wire.count('blue') == 1:
455 | engine.speak('cut first wire')
456 | elif wire.count('yellow') > 1:
457 | engine.speak('cut last wire')
458 | else:
459 | engine.speak('cut second wire')
460 |
461 | elif len(wire) == 5:
462 | if wire[-1] == 'black' and odd_serial():
463 | engine.speak('cut fourth wire')
464 | elif wire.count('red') and wire.count('yellow') > 1:
465 | engine.speak('cut first wire')
466 | elif wire.count('black') == 0:
467 | engine.speak('cut second wire')
468 | else:
469 | engine.speak('cut first wire')
470 |
471 | elif len(wire) == 6:
472 | if wire.count('yellow') == 0 and odd_serial():
473 | engine.speak('cut third wire')
474 | elif wire.count('yellow') == 1 and wire.count('white') > 1:
475 | engine.speak('cut fourth wire')
476 | elif wire.count('red') == 0:
477 | engine.speak('cut last wire')
478 | else:
479 | engine.speak('cut fourth wire')
480 |
481 | class ComplexWiresRule(CompoundRule):
482 | spec = "complex wires " # Spoken form of command.
483 | extras = [Dictation("wires")]
484 |
485 |
486 | def _process_recognition(self, node, extras): # Callback when command is spoken.
487 | global batteries
488 | global serial
489 | global parallel
490 | spoken = 'need'
491 | if batteries == 99:
492 | spoken += ' batteries'
493 | if parallel == 'parallel':
494 | spoken += ' parallel port'
495 | if serial == 'serial':
496 | spoken += ' last digit of serial'
497 | if spoken != 'need':
498 | engine.speak(spoken)
499 | return
500 |
501 | meaning = {
502 | int('0000', 2): 'cut',
503 | int('0001', 2): 'dont cut',
504 | int('0010', 2): 'cut',
505 | int('0011', 2): 'cut' if batteries > 1 else 'dont cut',
506 | int('0100', 2): 'cut' if serial in ('zero', 'two', 'four', 'six', 'eight') else 'dont cut',
507 | int('0101', 2): 'cut' if parallel in ('true', 'yes') else 'dont cut',
508 | int('0110', 2): 'dont cut',
509 | int('0111', 2): 'cut' if parallel in ('true', 'yes') else 'dont cut',
510 | int('1000', 2): 'cut' if serial in ('zero', 'two', 'four', 'six', 'eight') else 'dont cut',
511 | int('1001', 2): 'cut' if batteries > 1 else 'dont cut',
512 | int('1010', 2): 'cut',
513 | int('1011', 2): 'cut' if batteries > 1 else 'dont cut',
514 | int('1100', 2): 'cut' if serial in ('zero', 'two', 'four', 'six', 'eight') else 'dont cut',
515 | int('1101', 2): 'cut' if serial in ('zero', 'two', 'four', 'six', 'eight') else 'dont cut',
516 | int('1110', 2): 'cut' if parallel in ('true', 'yes') else 'dont cut',
517 | int('1111', 2): 'dont cut'
518 | }
519 |
520 | bad_words = [('read', 'red'), ('blew', 'blue'), ('start', 'star'),
521 | ('white', 'light')]
522 | wire = str(extras['wires'])
523 | print wire
524 | wires = [wire for wire in wire.split('next')]
525 | print wires
526 | print 'parallel', parallel
527 | print 'serial', serial
528 | print 'batteries', batteries
529 | final_wires = []
530 | answer = 'cut nothing'
531 | for index, wire in enumerate(wires):
532 | for bad, good in bad_words:
533 | wire = wire.replace(bad, good)
534 |
535 | wire = [item for item in wire.split() if item in ('red', 'blue', 'light',
536 | 'star', 'blank')]
537 |
538 | print wire
539 | total = 0
540 | for letter, value in [('red', 8), ('blue', 4), ('star', 2), ('light', 1)]:
541 | if letter in wire:
542 | total += value
543 |
544 | print wire, total
545 |
546 | if meaning[total] == 'cut':
547 | if answer == 'cut nothing':
548 | answer = 'cut '
549 | answer += str(index+1) + ', '
550 |
551 | engine.speak(answer)
552 |
553 | class MazeRule(CompoundRule):
554 | spec = "maze " # Spoken form of command.
555 | extras = [Dictation("maze")]
556 | def _process_recognition(self, node, extras): # Callback when command is spoken.
557 | maze = str(extras['maze'])
558 | maze = ' '.join([x for x in maze.split() if x in ['one', 'two','three', 'four', 'five', 'six', 'seven', 'eight', 'nine']])
559 | print maze
560 | for word, num in [('one', '1'), ('two', '2'), ('three', '3'), ('four', '4'), ('five', '5'), ('six', '6'), ('seven', '7'), ('eight', '8'), ('nine', '9')]:
561 | maze = maze.replace(word, num)
562 |
563 | maze = maze.replace(' ', '')
564 | # If users input , or spaces, we ignore them
565 | indicator = tuple(maze[0:2])
566 | start = tuple([int(x) for x in maze[2:4]])
567 | finish = tuple([int(x) for x in maze[4:6]])
568 |
569 | if len(indicator) != 2 or len(start) != 2 or len(finish) != 2:
570 | engine.speak("Try maze again")
571 | return
572 |
573 | maze = get_maze(indicator)
574 | print maze
575 | maze_dict = get_maze_dict(maze)
576 | letters = {'L': 'left', 'R': 'right', 'D':'down', 'U':'up'}
577 | path = []
578 | for letter in traverse_maze(maze_dict, start, finish):
579 | path.append(letters[letter])
580 |
581 | for path in [path[x:x+3] for x in range(0, len(path), 3)]:
582 | engine.speak(path)
583 |
584 | class SimonRule(CompoundRule):
585 | spec = "simon " # Spoken form of command.
586 | extras = [Dictation("words")]
587 | def _process_recognition(self, node, extras): # Callback when command is spoken.
588 | print str(extras['words'])
589 | if vowel == 'vowel':
590 | engine.speak("Serial contain vowel?")
591 | return
592 |
593 | words = str(extras['words'])
594 | print words
595 | words = words.replace('read', 'red').replace('blew', 'blue')
596 | words = [word for word in words.split() if word in ('blue', 'yellow', 'red', 'green')]
597 |
598 | new_words = []
599 | print "Your words: {}".format(words)
600 | if vowel in ('true', 'yes'):
601 | colors = {'red': 'blue',
602 | 'blue': 'red',
603 | 'green': 'yellow',
604 | 'yellow': 'green'}
605 | for word in words:
606 | new_words.append(colors[word])
607 | else:
608 | colors = {'red': 'blue',
609 | 'blue': 'yellow',
610 | 'green': 'green',
611 | 'yellow': 'red'}
612 | for word in words:
613 | new_words.append(colors[word])
614 |
615 | new_words = ' '.join(new_words)
616 | print "My words: {}".format(new_words)
617 | engine.speak(new_words)
618 |
619 | class WireSequenceRule(CompoundRule):
620 | spec = "wire sequence " # Spoken form of command.
621 | extras = [Dictation("words")]
622 | def _process_recognition(self, node, extras): # Callback when command is spoken.
623 | global sequences
624 | words = str(extras['words'])
625 | print words
626 | words = words.replace('read', 'red').replace('blew', 'blue')
627 | print words
628 | words = [word for word in words.split() if word in ('red', 'blue', 'black', 'apple', 'bravo', 'charlie')]
629 | print words
630 | words = [words[x:x+2] for x in xrange(0, len(words), 2)]
631 | print words
632 | answer = []
633 | for index, item in enumerate(words):
634 | print index, item
635 | color, letter = item
636 | print "Color: {}".format(color)
637 | print "Letter: {}".format(letter)
638 | print "Count: {}".format(counts[color])
639 | print sequences[color]
640 | print counts[color]
641 | print sequences[color][counts[color]]
642 | print sequences[color][counts[color]]
643 | if letter[0] in sequences[color][counts[color]]:
644 | answer.append(str(index+1))
645 |
646 | counts[color] += 1
647 |
648 | if not answer:
649 | engine.speak('cut nothing')
650 | else:
651 | engine.speak(', '.join(answer))
652 |
653 | class WireSequenceResetRule(CompoundRule):
654 | spec = "wire sequence reset" # Spoken form of command.
655 | def _process_recognition(self, node, extras): # Callback when command is spoken.
656 | global counts
657 | counts = defaultdict(int)
658 |
659 | class ButtonRule(CompoundRule):
660 | spec = "button " # Spoken form of command.
661 | extras = [Dictation("words")]
662 | def _process_recognition(self, node, extras): # Callback when command is spoken.
663 | spoken = 'need'
664 | print "Batteries: {}".format(batteries)
665 | print "Freak: {}".format(freak)
666 | print "Car: {}".format(car)
667 | if batteries == 99:
668 | spoken += ' batteries'
669 | if freak == 'freak':
670 | spoken += ' freak'
671 | if car == 'car':
672 | spoken += ' car identifier'
673 | if spoken != 'need':
674 | engine.speak(spoken)
675 | return
676 |
677 | words = str(extras['words'])
678 | print words
679 | words = words.replace('read', 'red').replace('blew', 'blue')
680 | print words
681 | if 'blue' in words and 'abort' in words:
682 | engine.speak('Press and hold')
683 | elif 'detonate' in words and batteries > 1:
684 | engine.speak('Press and release')
685 | elif 'white' in words and car in ('true', 'yes'):
686 | engine.speak('Press and hold')
687 | elif batteries > 2 and freak in ('true', 'yes'):
688 | engine.speak('Press and release')
689 | elif 'yellow' in words:
690 | engine.speak('Press and hold')
691 | elif 'red' in words and 'hold' in words:
692 | engine.speak('Press and release')
693 | else:
694 | engine.speak('Press and hold')
695 |
696 | class ButtonColorRule(CompoundRule):
697 | spec = "button color " # Spoken form of command.
698 | extras = [Dictation("words")]
699 | def _process_recognition(self, node, extras): # Callback when command is spoken.
700 | words = str(extras['words'])
701 | print words
702 | words = words.replace('read', 'red').replace('blew', 'blue')
703 | print words
704 | if 'blue' in words:
705 | engine.speak('four')
706 | elif 'yellow' in words:
707 | engine.speak('five')
708 | else:
709 | engine.speak('one')
710 |
711 | class KnobsRule(CompoundRule):
712 | spec = "knobs " # Spoken form of command.
713 | extras = [Dictation("words")]
714 | def _process_recognition(self, node, extras): # Callback when command is spoken.
715 | words = str(extras['words'])
716 | print words
717 | words = ''.join([word for word in words.split() if word in ('one', 'zero')])
718 | print words
719 | leds = words.replace('one', '1').replace('zero', '0').replace(' ', '')
720 | print leds
721 | if leds == '111011' or leds == '011010':
722 | engine.speak('Up')
723 | if leds == '111001' or leds == '010010':
724 | engine.speak('Down')
725 | if leds == '100010' or leds == '000010':
726 | engine.speak('Left')
727 | if leds == '111111' or leds == '111100':
728 | engine.speak('Right')
729 |
730 |
731 | class MemoryRule(CompoundRule):
732 | spec = "memory " # Spoken form of command.
733 | extras = [Dictation("words")]
734 | def _process_recognition(self, node, extras): # Callback when command is spoken.
735 | global values
736 | global positions
737 | global curr_stage
738 | words = str(extras['words'])
739 | print words
740 | words = [word for word in words.split() if word in ('one', 'two', 'three', 'four')]
741 | print words
742 | if len(words) != 5:
743 | engine.speak("Try memory again.")
744 | return
745 |
746 | display = words[0]
747 | stage = words[1:]
748 |
749 | print "Current Stage: {}".format(curr_stage)
750 | print "Values: {}".format(values)
751 | print "Positions: {}".format(values)
752 | if curr_stage == 1:
753 | if display == 'one':
754 | answer = stage[1]
755 | if display == 'two':
756 | answer = stage[1]
757 | if display == 'three':
758 | answer = stage[2]
759 | if display == 'four':
760 | answer = stage[3]
761 | position = stage.index(answer)
762 |
763 | if curr_stage == 2:
764 | if display == 'one':
765 | answer = 'four'
766 | if display == 'two':
767 | answer = stage[positions[0]]
768 | if display == 'three':
769 | answer = stage[0]
770 | if display == 'four':
771 | answer = stage[positions[0]]
772 | position = stage.index(answer)
773 |
774 | if curr_stage == 3:
775 | if display == 'one':
776 | answer = values[1]
777 | position = 'one'
778 | if display == 'two':
779 | answer = values[0]
780 | position = 'two'
781 | if display == 'three':
782 | answer = stage[2]
783 | position = stage.index(answer)
784 | if display == 'four':
785 | answer = 'four'
786 | position = stage.index(answer)
787 |
788 | if curr_stage == 4:
789 | if display == 'one':
790 | answer = stage[positions[0]]
791 | position = stage.index(answer)
792 | if display == 'two':
793 | answer = stage[0]
794 | position = stage.index(answer)
795 | if display == 'three':
796 | answer = stage[positions[1]]
797 | position = stage.index(answer)
798 | if display == 'four':
799 | answer = stage[positions[1]]
800 | position = stage.index(answer)
801 |
802 | if curr_stage == 5:
803 | if display == 'one':
804 | answer = values[0]
805 | if display == 'two':
806 | answer = values[1]
807 | if display == 'three':
808 | answer = values[3]
809 | if display == 'four':
810 | answer = values[2]
811 | position = stage.index(answer)
812 |
813 | values.append(answer)
814 | positions.append(position)
815 | curr_stage += 1
816 | print "Answer: {}".format(answer)
817 | engine.speak(answer)
818 | if curr_stage > 5:
819 | values = []
820 | positions = []
821 | curr_stage = 1
822 |
823 |
824 | class MemoryResetRule(CompoundRule):
825 | spec = "memory reset" # Spoken form of command.
826 | def _process_recognition(self, node, extras): # Callback when command is spoken.
827 | global positions
828 | global curr_stage
829 | global values
830 | positions = []
831 | values = []
832 | curr_stage = 1
833 |
834 | class MorseRule(CompoundRule):
835 | spec = "morse " # Spoken form of command.
836 | extras = [Dictation("words")]
837 | def _process_recognition(self, node, extras): # Callback when command is spoken.
838 | global morse_letters
839 | words = str(extras['words'])
840 |
841 | words = ''.join([word for word in words.split() if word in ('one', 'zero')])
842 | print words
843 | code = words.replace('one', '-').replace('zero', '.')
844 | print code
845 |
846 | morse = {
847 | 'a': '.-',
848 | 'b': '-...',
849 | 'c': '-.-.',
850 | 'e': '.',
851 | 'f': '..-.',
852 | 'g': '--.',
853 | 'h': '....',
854 | 'i': '..',
855 | 'k': '-.-',
856 | 'l': '.-..',
857 | 'm': '--',
858 | 'n': '-.',
859 | 'o': '---',
860 | 'r': '.-.',
861 | 's': '...',
862 | 't': '-',
863 | 'v': '...-',
864 | 'x': '-..-',
865 | }
866 |
867 | codes = {}
868 | for key, val in morse.iteritems():
869 | if code == val:
870 | morse_letters.append(key)
871 |
872 | codes[val] = key
873 |
874 | print "Current morse letters: {}".format(morse_letters)
875 | if len(morse_letters) < 2:
876 | return
877 |
878 | words = {
879 | 'shell': '5 0 5',
880 | 'halls': '5 1 5',
881 | 'slick': '5 2 2',
882 | 'trick': '5 3 2',
883 | 'boxes': '5 3 5',
884 | 'leaks': '5 4 2',
885 | 'strobe': '5 4 5',
886 | 'bistro': '5 5 2',
887 | 'flick': '5 5 5',
888 | 'bombs': '5 6 5',
889 | 'break': '5 7 2',
890 | 'brick': '5 7 5',
891 | 'steak': '5 8 2',
892 | 'sting': '5 9 2',
893 | 'vector': '5 9 5',
894 | 'beats': '6 0 0',
895 | }
896 |
897 | code = ''.join(morse_letters)
898 |
899 | combos = {}
900 | for word in words:
901 | curr_combo = []
902 | for num in xrange(len(word)):
903 | curr_word = ''.join((word+word)[num:num+3])
904 | combos[curr_word] = word
905 |
906 | print code
907 | print combos.keys()
908 | if code in combos:
909 | engine.speak(words[combos[code]])
910 |
911 | possibles = []
912 | for key, val in combos.iteritems():
913 | curr_word = ''.join([morse[letter] for letter in key])
914 | if code.startswith(curr_word):
915 | # print val, key, code, words[val]
916 | print words[val]
917 |
918 | class MorseResetRule(CompoundRule):
919 | spec = "morse reset" # Spoken form of command.
920 | def _process_recognition(self, node, extras): # Callback when command is spoken.
921 | global morse_letters
922 | morse_letters = []
923 |
924 | class WordsResetRule(CompoundRule):
925 | spec = "words reset" # Spoken form of command.
926 | def _process_recognition(self, node, extras): # Callback when command is spoken.
927 | global on_first_words
928 | on_first_words = []
929 |
930 | class WordsRemoveRule(CompoundRule):
931 | spec = "words remove" # Spoken form of command.
932 | def _process_recognition(self, node, extras): # Callback when command is spoken.
933 | global on_first_words
934 | on_first_words = on_first_words[:-1]
935 |
936 | class SymbolsRule(CompoundRule):
937 | spec = "symbols " # Spoken form of command.
938 | extras = [Dictation("symbols")]
939 | def _process_recognition(self, node, extras): # Callback when command is spoken.
940 | symbols = str(extras['symbols'])
941 |
942 | groups = [
943 | ['tennis', 'a', 'l', 'lightning', 'cat', 'h', 'c'],
944 | ['e', 'tennis', 'c', 'o', 'star', 'h', 'question'],
945 | ['copyright', 'but', 'o', 'k', 'r', 'l', 'star'],
946 | ['six', 'paragraph', 'b', 'cat', 'k', 'question', 'smile'],
947 | ['goblet', 'smile', 'b', 'c', 'paragraph', 'three', 'star'],
948 | ['six', 'e', 'equals', 'smash', 'goblet', 'in', 'omega']
949 | ]
950 |
951 | print symbols
952 | symbols = symbols.replace('butt', 'but')
953 | curr_symbols = symbols.replace('.', '').lower().split()
954 | print curr_symbols
955 |
956 | answer = ''
957 | for group in groups:
958 | for symbol in curr_symbols:
959 | if symbol not in group:
960 | break
961 | else:
962 | for symbol in group:
963 | if symbol in curr_symbols:
964 | answer += symbol + ' '
965 |
966 | engine.speak(answer)
967 |
968 | class WordsRule(CompoundRule):
969 | spec = "words " # Spoken form of command.
970 | extras = [Dictation("words")]
971 | def _process_recognition(self, node, extras): # Callback when command is spoken.
972 | global curr_wordlist
973 | words = str(extras['words'])
974 |
975 | combos = {
976 | ('you', 'are', 'words'): 'you are',
977 | ('your', 'words'): 'you are',
978 | ('done',): 'done',
979 | ('don',): 'done',
980 | ('you', 'are', 'letters'): 'ur',
981 | ('sure',): 'sure',
982 | ('shore',): 'sure',
983 | ('you', 'word'): 'you',
984 | ('you', 'were'): 'you',
985 | ('you', 'were', 'to'): 'you',
986 | ('you', 'work'): 'you',
987 | ('hold',): 'hold',
988 | ('you', 'letter'): 'u',
989 | ('yes',): 'yes',
990 | ('first',): 'first',
991 | ('display',): 'display',
992 | ('okay',): 'okay',
993 | ('OK',): 'okay',
994 | ('says',): 'says',
995 | ('nothing',): 'nothing',
996 | ('literally', 'blank'): ' ',
997 | ('blank',): 'blank',
998 | ('no',): 'no',
999 | ('L.', 'E.', 'D.'): 'led',
1000 | ('lead',): 'lead',
1001 | ('mead',): 'lead',
1002 | ('read',): 'read',
1003 | ('red', 'short'): 'red',
1004 | ('read', 'too'): 'reed',
1005 | ('hold', 'on', 'two'): 'hold on',
1006 | ("you're", 'word'): 'your',
1007 | ("your", 'word'): 'your',
1008 | ('your', 'mark'): "you're",
1009 | ('you', 'are', 'marked'): "you're",
1010 | ('you', 'are', 'mark'): "you're",
1011 | ('C.', 'S.'): "see",
1012 | ('they', 'are', 'words'): "they are",
1013 | ('E.', 'I.', 'R.'): "their",
1014 | ('E.', 'R.', 'E.'): "there",
1015 | ('they', 'are', 'marked'): "they're",
1016 | ('they', 'mark'): "they're",
1017 | ('their', 'mark'): "they're",
1018 | ('there', 'mark'): "they're",
1019 | ('S.', 'E.', 'E.'): "see",
1020 | ('C.', 'letter'): "c",
1021 | ('see', 'letter'): "c",
1022 | ('C.', 'E.', 'E.'): "cee",
1023 | ('CC',): "cee",
1024 | ('ready',): 'ready',
1025 | ('yes',): 'yes',
1026 | ('what', 'no', 'mark'): 'what',
1027 | ('what', 'know', 'mark'): 'what',
1028 | ('three', 'H.'): 'uhhh',
1029 | ('left',): 'left',
1030 | ('right',): 'right',
1031 | ('write',): 'right',
1032 | ('middle',): 'middle',
1033 | ('metal',): 'middle',
1034 | ('wait',): 'wait',
1035 | ('press',): 'press',
1036 | ('five', 'letters'): 'uh huh',
1037 | ('four', 'letters'): 'uh uh',
1038 | ('what', 'mark'): 'what?',
1039 | ('done',): 'done',
1040 | ('next',): 'next',
1041 | ('hold',): 'hold',
1042 | ('sure',): 'sure',
1043 | ('like',): 'like',
1044 | ('mike',): 'like',
1045 | ('might',): 'like',
1046 | ('white',): 'like',
1047 | ('light',): 'like',
1048 | }
1049 |
1050 | positions = {
1051 | 'yes': 3,
1052 | 'first': 2,
1053 | 'display': 6,
1054 | 'okay': 2,
1055 | 'says': 6,
1056 | 'nothing': 3,
1057 | ' ': 5,
1058 | 'blank': 4,
1059 | 'no': 6,
1060 | 'led': 3,
1061 | 'lead': 6,
1062 | 'read': 4,
1063 | 'red': 4,
1064 | 'reed': 5,
1065 | 'leed': 5,
1066 | 'hold on': 6,
1067 | 'you': 4,
1068 | 'you are': 6,
1069 | 'your': 4,
1070 | "you're": 4,
1071 | 'ur': 1,
1072 | 'there': 6,
1073 | "they're": 5,
1074 | 'their': 4,
1075 | 'they are': 3,
1076 | 'see': 6,
1077 | 'c': 2,
1078 | 'cee': 6
1079 | }
1080 |
1081 | table = {
1082 | "ready": ["yes", "okay", "what", "middle", "left", "press", "right", "blank", "ready"],
1083 | "first": ["left", "okay", "yes", "middle", "no", "right", "nothing", "uhhh", "wait", "ready", "blank", "what", "press", "first"],
1084 | "no": ["blank", "uhhh", "wait", "first", "what", "ready", "right", "yes", "nothing", "left", "press", "okay", "no", "middle"],
1085 | "blank": ["wait", "right", "okay", "middle", "blank"],
1086 | "nothing": ["uhhh", "right", "okay", "middle", "yes", "blank", "no", "press", "left", "what", "wait", "first", "nothing", "ready"],
1087 | "yes": ["okay", "right", "uhhh", "middle", "first", "what", "press", "ready", "nothing", "yes"],
1088 | "what": ["uhhh", "what"],
1089 | "uhhh": ["ready", "nothing", "left", "what", "okay", "yes", "right", "no", "press", "blank", "uhhh"],
1090 | "left": ["right", "left"],
1091 | "right": ["yes", "nothing", "ready", "press", "no", "wait", "what", "right"],
1092 | "middle": ["blank", "ready", "okay", "what", "nothing", "press", "no", "wait", "left", "middle"],
1093 | "okay": ["middle", "no", "first", "yes", "uhhh", "nothing", "wait", "okay"],
1094 | "wait": ["uhhh", "no", "blank", "okay", "yes", "left", "first", "press", "what", "wait"],
1095 | "press": ["right", "middle", "yes", "ready", "press"],
1096 | "you": ["sure", "you are", "your", "you're", "next", "uh huh", "ur", "hold", "what?", "you"],
1097 | "you are": ["your", "next", "like", "uh huh", "what?", "done", "uh uh", "hold", "you", "u", "you're", "sure", "ur", "you are"],
1098 | "your": ["uh uh", "you are", "uh huh", "your"],
1099 | "you're": ["you", "you're"],
1100 | "ur": ["done", "u", "ur"],
1101 | "u": ["uh huh", "sure", "next", "what?", "you're", "ur", "uh uh", "done", "u"],
1102 | "uh huh": ["uh huh"],
1103 | "uh uh": ["ur", "u", "you are", "you", "done", "hold", "uh uh", "next", "sure", "like", "your", "sure", "hold", "what?"],
1104 | "what?": ["you", "hold", "you're", "your", "u", "done", "uh uh", "like", "you are", "uh huh", "ur", "next", "what?"],
1105 | "done": ["sure", "uh huh", "next", "what?", "your", "ur", "you're", "hold", "like", "you", "u", "you are", "uh uh", "done"],
1106 | "next": ["what?", "uh huh", "uh uh", "your", "hold", "sure", "next"],
1107 | "hold": ["you are", "u", "done", "uh uh", "you", "ur", "sure", "what?", "you're", "next", "hold"],
1108 | "sure": ["you are", "done", "like", "you're", "you", "hold", "uh huh", "ur", "sure"],
1109 | "like": ["you're", "next", "u", "ur", "hold", "uh uh", "what?", "uh huh", "you", "like"],
1110 | }
1111 |
1112 | responses = {
1113 | "you are": ("you" "are", "words"),
1114 | "done": ("done",),
1115 | "ur": ("you", "are", "letters"),
1116 | "sure": ("sure",),
1117 | "you": ("you", "word"),
1118 | "hold": ("hold",),
1119 | "u": ("you", "letter"),
1120 | "yes": ("yes",),
1121 | "first": ("first",),
1122 | "display": ("display",),
1123 | "okay": ("okay",),
1124 | "says": ("says",),
1125 | "nothing": ("nothing",),
1126 | " ": ("literally", "blank"),
1127 | "blank": ("blank",),
1128 | "no": ("no",),
1129 | "led": ("L.", "E.", "D."),
1130 | "lead": ("lead",),
1131 | "read": ("read",),
1132 | "red": ("red", "short"),
1133 | "reed": ("read", "too"),
1134 | "hold on": ("hold", "on", "two"),
1135 | "your": ("your", "word"),
1136 | "you're": ("you", "are", "mark"),
1137 | "see": ("C.", "S."),
1138 | "they are": ("they", "are", "words"),
1139 | "their": ("E.", "I.", "R."),
1140 | "there": ("E.", "R.", "E."),
1141 | "they're": ("they", "are", "marked"),
1142 | "see": ("s e e"),
1143 | "c": ("see", "letter"),
1144 | "cee": ("C.", "C."),
1145 | "cee": ("CC",),
1146 | "ready": ("ready",),
1147 | "yes": ("yes",),
1148 | "what": ("what", "no", "mark"),
1149 | "uhhh": ("three", "H."),
1150 | "left": ("left",),
1151 | "right": ("right",),
1152 | "right": ("write",),
1153 | "middle": ("middle",),
1154 | "wait": ("wait",),
1155 | "press": ("press",),
1156 | "uh huh": ("five", "letters"),
1157 | "uh uh": ("four", "letters"),
1158 | "what?": ("what", "mark"),
1159 | "done": ("done",),
1160 | "next": ("next",),
1161 | "hold": ("hold",),
1162 | "sure": ("sure",),
1163 | "like": ("like",),
1164 | }
1165 | print "Voice receive: ", words
1166 |
1167 | for combo, select in reversed(sorted(combos.iteritems(), key=lambda x: len(x[0]))):
1168 | for word in combo:
1169 | if word not in words.split():
1170 | break
1171 | else:
1172 | print 'Words', words
1173 | print "Found word: {}".format(select)
1174 | if 'one' in words:
1175 | curr_wordlist = []
1176 | engine.speak(positions[select])
1177 |
1178 | if 'two' in words:
1179 | print 'select', select
1180 | wordlist = table[select]
1181 | answer = []
1182 | new_length = min(4, len(wordlist))
1183 | curr_wordlist = []
1184 | print wordlist
1185 | # Cache next set of words in case we need to ask for more
1186 | # words
1187 | for word in wordlist[new_length:]:
1188 | print 'word:', word
1189 | curr_wordlist.append(' '.join(responses[word]))
1190 |
1191 | for word in wordlist[:new_length]:
1192 | answer.append(' '.join(responses[word]))
1193 |
1194 | engine.speak(', '.join(answer))
1195 | break
1196 |
1197 | class WordsMoreRule(CompoundRule):
1198 | spec = "words more" # Spoken form of command.
1199 | def _process_recognition(self, node, extras): # Callback when command is spoken.
1200 | global curr_wordlist
1201 | speak = ', '.join(curr_wordlist[:4])
1202 | new_length = min(4, len(curr_wordlist))
1203 | curr_wordlist = curr_wordlist[new_length:]
1204 | engine.speak(speak)
1205 |
1206 | class PasswordResetRule(CompoundRule):
1207 | spec = "password reset" # Spoken form of command.
1208 | def _process_recognition(self, node, extras): # Callback when command is spoken.
1209 | global curr_password
1210 | curr_password = []
1211 | print curr_password
1212 |
1213 | class PasswordRule(CompoundRule):
1214 | spec = "password " # Spoken form of command.
1215 | extras = [Dictation("letters")]
1216 | def _process_recognition(self, node, extras): # Callback when command is spoken.
1217 | global curr_password
1218 | letters = str(extras['letters'])
1219 | letters = [letter[0].lower() for letter in letters.split()]
1220 | curr_password.append(letters)
1221 | print curr_password
1222 |
1223 | passwords = ['about',
1224 | 'after', 'again', 'below', 'could', 'every', 'first', 'found', 'great',
1225 | 'house', 'large', 'learn', 'never', 'other', 'place', 'plant', 'point',
1226 | 'right', 'small', 'sound', 'spell', 'still', 'study', 'their', 'there',
1227 | 'these', 'thing', 'think', 'three', 'water', 'where', 'which', 'world',
1228 | 'would', 'write']
1229 |
1230 | possibles = []
1231 | if len(curr_password) == 2:
1232 | for password in passwords:
1233 | if password[0] in curr_password[0] and password[2] in curr_password[1]:
1234 | possibles.append(password)
1235 |
1236 | print possibles
1237 |
1238 | for word in possibles:
1239 | engine.speak(word)
1240 |
1241 | class BombDoneRule(CompoundRule):
1242 | spec = "bomb done" # Spoken form of command.
1243 | def _process_recognition(self, node, extras): # Callback when command is spoken.
1244 | engine.speak("I AM YOUR BOMB DEFUSING OVERLORD")
1245 |
1246 | global batteries
1247 | global freak
1248 | global car
1249 | global parallel
1250 | global serial
1251 | global vowel
1252 | global counts
1253 | global values
1254 | global positions
1255 | global curr_stage
1256 | global morse_letters
1257 | global on_first_words
1258 | global curr_wordlist
1259 |
1260 | # Battery characteristics
1261 | batteries = 99
1262 | freak = 'freak'
1263 | car = 'car'
1264 | parallel = 'parallel'
1265 | serial = 'serial'
1266 | vowel = 'vowel'
1267 |
1268 | # Wire sequence
1269 | counts = defaultdict(int)
1270 |
1271 | # Memory
1272 | values = []
1273 | positions = []
1274 | curr_stage = 1
1275 |
1276 | # Morse
1277 | morse_letters = []
1278 |
1279 | # On First Words
1280 | on_first_words = []
1281 |
1282 | # Who's on First
1283 | curr_wordlist = []
1284 |
1285 | # Create a grammar which contains and loads the command rule.
1286 | grammar = Grammar("Keep Talking") # Create a grammar to contain the command rule.
1287 | grammar.add_rule(BombBatteriesRule()) # Add the command rule to the grammar.
1288 | grammar.add_rule(BombVowelRule()) # Add the command rule to the grammar.
1289 | grammar.add_rule(BombParallelRule()) # Add the command rule to the grammar.
1290 | grammar.add_rule(BombSerialRule()) # Add the command rule to the grammar.
1291 | grammar.add_rule(BombFreakRule()) # Add the command rule to the grammar.
1292 | grammar.add_rule(BombCarRule()) # Add the command rule to the grammar.
1293 | grammar.add_rule(BombResetRule()) # Add the command rule to the grammar.
1294 | grammar.add_rule(BombStatusRule()) # Add the command rule to the grammar.
1295 | grammar.add_rule(SimpleWiresRule()) # Add the command rule to the grammar.
1296 | grammar.add_rule(ComplexWiresRule()) # Add the command rule to the grammar.
1297 | grammar.add_rule(MazeRule()) # Add the command rule to the grammar.
1298 | grammar.add_rule(SimonRule()) # Add the command rule to the grammar.
1299 | grammar.add_rule(WireSequenceRule()) # Add the command rule to the grammar.
1300 | grammar.add_rule(WireSequenceResetRule()) # Add the command rule to the grammar.
1301 | grammar.add_rule(ButtonRule()) # Add the command rule to the grammar.
1302 | grammar.add_rule(ButtonColorRule()) # Add the command rule to the grammar.
1303 | grammar.add_rule(KnobsRule()) # Add the command rule to the grammar.
1304 | grammar.add_rule(MemoryRule()) # Add the command rule to the grammar.
1305 | grammar.add_rule(MemoryResetRule()) # Add the command rule to the grammar.
1306 | grammar.add_rule(MorseRule()) # Add the command rule to the grammar.
1307 | grammar.add_rule(MorseResetRule()) # Add the command rule to the grammar.
1308 | grammar.add_rule(SymbolsRule()) # Add the command rule to the grammar.
1309 | grammar.add_rule(WordsRule()) # Add the command rule to the grammar.
1310 | grammar.add_rule(WordsResetRule()) # Add the command rule to the grammar.
1311 | grammar.add_rule(WordsRemoveRule()) # Add the command rule to the grammar.
1312 | grammar.add_rule(WordsMoreRule()) # Add the command rule to the grammar.
1313 | grammar.add_rule(PasswordResetRule()) # Add the command rule to the grammar.
1314 | grammar.add_rule(PasswordRule()) # Add the command rule to the grammar.
1315 | grammar.add_rule(BombDoneRule())
1316 | grammar.load()
1317 |
--------------------------------------------------------------------------------