├── planning
├── tests
│ ├── __init__.py
│ ├── test_my_air_cargo_problems.py
│ └── test_my_planning_graph.py
├── aimacode
│ ├── __init__.py
│ ├── LICENSE
│ ├── planning.py
│ └── search.py
├── images
│ ├── statespace.png
│ ├── twotofive.png
│ ├── Progression.PNG
│ └── eatcake-graphplan2.png
├── research_review.pdf
├── heuristic_analysis.pdf
├── .udacity-pa
│ └── projects.py
├── lp_utils.py
├── example_have_cake.py
├── run_search.py
├── heuristic_analysis.md
├── README.md
└── my_air_cargo_problems.py
├── sudoku
├── objects
│ ├── __init__.py
│ ├── GameResources.py
│ └── SudokuSquare.py
├── images
│ └── sudoku-board-bare.jpg
├── visualize.py
├── PySudoku.py
├── README.md
├── solution.py
└── solution_test.py
├── isolation
├── viz.gif
├── research_review.pdf
├── heuristic_analysis.pdf
├── isoviz
│ ├── img
│ │ └── chesspieces
│ │ │ └── wikipedia
│ │ │ ├── bN.png
│ │ │ └── wN.png
│ ├── LICENSE.txt
│ ├── css
│ │ └── chessboard.css
│ ├── display.html
│ └── js
│ │ └── json3.min.js
├── isolation
│ ├── __init__.py
│ ├── README.md
│ └── isolation.py
├── agent_test.py
├── competition_agent.py
├── tournament.py
├── sample_players.py
└── README.md
├── recognizer
├── data
│ ├── README.md
│ ├── speaker.csv
│ └── test_words.csv
├── asl_test_recognizer.py
├── my_recognizer.py
├── asl_test_model_selectors.py
├── README.md
├── asl_test.py
├── asl_utils.py
├── my_model_selectors.py
└── asl_data.py
├── .gitignore
└── README.md
/planning/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sudoku/objects/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/planning/aimacode/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/isolation/viz.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/isolation/viz.gif
--------------------------------------------------------------------------------
/isolation/research_review.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/isolation/research_review.pdf
--------------------------------------------------------------------------------
/planning/images/statespace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/planning/images/statespace.png
--------------------------------------------------------------------------------
/planning/images/twotofive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/planning/images/twotofive.png
--------------------------------------------------------------------------------
/planning/research_review.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/planning/research_review.pdf
--------------------------------------------------------------------------------
/isolation/heuristic_analysis.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/isolation/heuristic_analysis.pdf
--------------------------------------------------------------------------------
/planning/heuristic_analysis.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/planning/heuristic_analysis.pdf
--------------------------------------------------------------------------------
/planning/images/Progression.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/planning/images/Progression.PNG
--------------------------------------------------------------------------------
/sudoku/images/sudoku-board-bare.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/sudoku/images/sudoku-board-bare.jpg
--------------------------------------------------------------------------------
/planning/images/eatcake-graphplan2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/planning/images/eatcake-graphplan2.png
--------------------------------------------------------------------------------
/isolation/isoviz/img/chesspieces/wikipedia/bN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/isolation/isoviz/img/chesspieces/wikipedia/bN.png
--------------------------------------------------------------------------------
/isolation/isoviz/img/chesspieces/wikipedia/wN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-rz/udacity-aind/HEAD/isolation/isoviz/img/chesspieces/wikipedia/wN.png
--------------------------------------------------------------------------------
/sudoku/objects/GameResources.py:
--------------------------------------------------------------------------------
1 | import os, pygame
2 |
3 | def load_image(name):
4 | """A better load of images."""
5 | fullname = os.path.join("images", name)
6 | try:
7 | image = pygame.image.load(fullname)
8 | if image.get_alpha() == None:
9 | image = image.convert()
10 | else:
11 | image = image.convert_alpha()
12 | except pygame.error:
13 | print("Oops! Could not load image:", fullname)
14 | return image, image.get_rect()
15 |
--------------------------------------------------------------------------------
/isolation/isolation/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | This library provides a Python implementation of the game Isolation.
3 | Isolation is a deterministic, two-player game of perfect information in
4 | which the players alternate turns moving between cells on a square grid
5 | (like a checkerboard). Whenever either player occupies a cell, that
6 | location is blocked for the rest of the game. The first player with no
7 | legal moves loses, and the opponent is declared the winner.
8 | """
9 |
10 | # Make the Board class available at the root of the module for imports
11 | from .isolation import Board
12 |
--------------------------------------------------------------------------------
/planning/.udacity-pa/projects.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import shutil
3 | import os
4 | from udacity_pa import udacity
5 |
6 | nanodegree = 'nd889'
7 | projects = ['cargo_planning']
8 | filenames_all = ['my_air_cargo_problems.py', 'my_planning_graph.py', 'heuristic_analysis.pdf', 'research_review.pdf']
9 |
10 | def submit(args):
11 | filenames = []
12 | for filename in filenames_all:
13 | if os.path.isfile(filename):
14 | filenames.append(filename)
15 |
16 | udacity.submit(nanodegree, projects[0], filenames,
17 | environment = args.environment,
18 | jwt_path = args.jwt_path)
19 |
--------------------------------------------------------------------------------
/isolation/agent_test.py:
--------------------------------------------------------------------------------
1 | """This file is provided as a starting template for writing your own unit
2 | tests to run and debug your minimax and alphabeta agents locally. The test
3 | cases used by the project assistant are not public.
4 | """
5 |
6 | import unittest
7 |
8 | import isolation
9 | import game_agent
10 |
11 | from importlib import reload
12 |
13 |
14 | class IsolationTest(unittest.TestCase):
15 | """Unit tests for isolation agents"""
16 |
17 | def setUp(self):
18 | reload(game_agent)
19 | self.player1 = "Player1"
20 | self.player2 = "Player2"
21 | self.game = isolation.Board(self.player1, self.player2)
22 |
23 |
24 | if __name__ == '__main__':
25 | unittest.main()
26 |
--------------------------------------------------------------------------------
/sudoku/visualize.py:
--------------------------------------------------------------------------------
1 | from PySudoku import play
2 |
3 | def visualize_assignments(assignments):
4 | """ Visualizes the set of assignments created by the Sudoku AI"""
5 | last_assignment = None
6 | filtered_assignments = []
7 |
8 | for i in range(len(assignments)):
9 | if last_assignment:
10 | last_assignment_items = [item for item in last_assignment.items() if len(item[1]) == 1]
11 | current_assignment_items = [item for item in assignments[i].items() if len(item[1]) == 1]
12 | shared_items = set(last_assignment_items) & set(current_assignment_items)
13 | if len(shared_items) < len(current_assignment_items):
14 | filtered_assignments.append(assignments[i])
15 | last_assignment = assignments[i]
16 |
17 | play(filtered_assignments)
18 |
--------------------------------------------------------------------------------
/recognizer/data/README.md:
--------------------------------------------------------------------------------
1 | ## American Sign Language Data
2 | The data in this directory contained in `hands_condensed.csv` and `speaker.csv` has been derived from the [RWTH-BOSTON-104 Database](http://www-i6.informatik.rwth-aachen.de/~dreuw/database-rwth-boston-104.php) The hand positions are pulled directly from the database [boston104.handpositions.rybach-forster-dreuw-2009-09-25.full.xml](boston104.handpositions.rybach-forster-dreuw-2009-09-25.full.xml).
3 |
4 | The videos are sentences with translations provided in the database. For purposes of this project, the sentences have been segmented into words based on slow motion examination of the files. These segments are provided in the `test_words.csv` and `train_words.csv` files in the form of start and end frames (inclusive). Training and Test word files have been divided as they are in the database, which is based on sentence Train and Test divisions. The hand positions file has not been divided and contains all frame information.
5 |
--------------------------------------------------------------------------------
/planning/aimacode/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 aima-python contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/isolation/isoviz/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2013 Chris Oakman
2 | http://chessboardjs.com/
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/recognizer/asl_test_recognizer.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 |
3 | from asl_data import AslDb
4 | from asl_utils import train_all_words
5 | from my_model_selectors import SelectorConstant
6 | from my_recognizer import recognize
7 |
8 | FEATURES = ['right-y', 'right-x']
9 |
10 | class TestRecognize(TestCase):
11 | def setUp(self):
12 | self.asl = AslDb()
13 | self.training_set = self.asl.build_training(FEATURES)
14 | self.test_set = self.asl.build_test(FEATURES)
15 | self.models = train_all_words(self.training_set, SelectorConstant)
16 |
17 | def test_recognize_probabilities_interface(self):
18 | probs, _ = recognize(self.models, self.test_set)
19 | self.assertEqual(len(probs), self.test_set.num_items, "Number of test items in probabilities list incorrect.")
20 | self.assertIn('FRANK', probs[0], "Dictionary of probabilities does not contain correct keys")
21 | self.assertIn('CHICKEN', probs[-1], "Dictionary of probabilities does not contain correct keys")
22 |
23 | def test_recognize_guesses_interface(self):
24 | _, guesses = recognize(self.models, self.test_set)
25 | self.assertEqual(len(guesses), self.test_set.num_items, "Number of test items in guesses list incorrect.")
26 | self.assertIsInstance(guesses[0], str, "The guesses are not strings")
27 | self.assertIsInstance(guesses[-1], str, "The guesses are not strings")
28 |
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Python template
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | env/
14 | build/
15 | develop-eggs/
16 | dist/
17 | downloads/
18 | eggs/
19 | .eggs/
20 | lib/
21 | lib64/
22 | parts/
23 | sdist/
24 | var/
25 | wheels/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *,cover
49 | .hypothesis/
50 |
51 | # Translations
52 | *.mo
53 | *.pot
54 |
55 | # Django stuff:
56 | *.log
57 | local_settings.py
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # dotenv
85 | .env
86 |
87 | # virtualenv
88 | .venv
89 | venv/
90 | ENV/
91 |
92 | # Spyder project settings
93 | .spyderproject
94 |
95 | # Rope project settings
96 | .ropeproject
97 |
98 | .gitignore
99 | .idea/
100 |
101 |
--------------------------------------------------------------------------------
/recognizer/my_recognizer.py:
--------------------------------------------------------------------------------
1 | import warnings
2 | from asl_data import SinglesData
3 |
4 |
5 | def recognize(models: dict, test_set: SinglesData):
6 | """ Recognize test word sequences from word models set
7 |
8 | :param models: dict of trained models
9 | {'SOMEWORD': GaussianHMM model object, 'SOMEOTHERWORD': GaussianHMM model object, ...}
10 | :param test_set: SinglesData object
11 | :return: (list, list) as probabilities, guesses
12 | both lists are ordered by the test set word_id
13 | probabilities is a list of dictionaries where each key a word and value is Log Liklihood
14 | [{SOMEWORD': LogLvalue, 'SOMEOTHERWORD' LogLvalue, ... },
15 | {SOMEWORD': LogLvalue, 'SOMEOTHERWORD' LogLvalue, ... },
16 | ]
17 | guesses is a list of the best guess words ordered by the test set word_id
18 | ['WORDGUESS0', 'WORDGUESS1', 'WORDGUESS2',...]
19 | """
20 | warnings.filterwarnings("ignore", category=DeprecationWarning)
21 | probabilities = []
22 | guesses = []
23 | for _, (X, lengths) in test_set.get_all_Xlengths().items():
24 | probability_dict = {}
25 | best_score = float("-inf")
26 | best_guess = ""
27 | for trained_word, model in models.items():
28 | try:
29 | score = model.score(X, lengths)
30 | probability_dict[traned_word] = score
31 | except Exception as e:
32 | probability_dict[trained_word] = float("-inf")
33 |
34 | if score > best_score:
35 | best_score = score
36 | best_guess = trained_word
37 | probabilities.append(probability_dict)
38 | guesses.append(best_guess)
39 |
40 | return probabilities, guesses
41 |
--------------------------------------------------------------------------------
/recognizer/asl_test_model_selectors.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 |
3 | from asl_data import AslDb
4 | from my_model_selectors import (
5 | SelectorConstant, SelectorBIC, SelectorDIC, SelectorCV,
6 | )
7 |
8 | FEATURES = ['right-y', 'right-x']
9 |
10 | class TestSelectors(TestCase):
11 | def setUp(self):
12 | asl = AslDb()
13 | self.training = asl.build_training(FEATURES)
14 | self.sequences = self.training.get_all_sequences()
15 | self.xlengths = self.training.get_all_Xlengths()
16 |
17 | def test_select_constant_interface(self):
18 | model = SelectorConstant(self.sequences, self.xlengths, 'BUY').select()
19 | self.assertGreaterEqual(model.n_components, 2)
20 | model = SelectorConstant(self.sequences, self.xlengths, 'BOOK').select()
21 | self.assertGreaterEqual(model.n_components, 2)
22 |
23 | def test_select_bic_interface(self):
24 | model = SelectorBIC(self.sequences, self.xlengths, 'FRANK').select()
25 | self.assertGreaterEqual(model.n_components, 2)
26 | model = SelectorBIC(self.sequences, self.xlengths, 'VEGETABLE').select()
27 | self.assertGreaterEqual(model.n_components, 2)
28 |
29 | def test_select_cv_interface(self):
30 | model = SelectorCV(self.sequences, self.xlengths, 'JOHN').select()
31 | self.assertGreaterEqual(model.n_components, 2)
32 | model = SelectorCV(self.sequences, self.xlengths, 'CHICKEN').select()
33 | self.assertGreaterEqual(model.n_components, 2)
34 |
35 | def test_select_dic_interface(self):
36 | model = SelectorDIC(self.sequences, self.xlengths, 'MARY').select()
37 | self.assertGreaterEqual(model.n_components, 2)
38 | model = SelectorDIC(self.sequences, self.xlengths, 'TOY').select()
39 | self.assertGreaterEqual(model.n_components, 2)
40 |
--------------------------------------------------------------------------------
/isolation/isoviz/css/chessboard.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * chessboard.js v0.3.0
3 | *
4 | * Copyright 2013 Chris Oakman
5 | * Released under the MIT license
6 | * https://github.com/oakmac/chessboardjs/blob/master/LICENSE
7 | *
8 | * Date: 10 Aug 2013
9 | */
10 |
11 | td {
12 | font-size: 1.5em;
13 | }
14 |
15 | /* clearfix */
16 | .clearfix-7da63 {
17 | clear: both;
18 | }
19 |
20 | /* board */
21 | .board-b72b1 {
22 | border: 2px solid #404040;
23 | -moz-box-sizing: content-box;
24 | box-sizing: content-box;
25 | }
26 |
27 | /* square */
28 | .square-55d63 {
29 | float: left;
30 | position: relative;
31 |
32 | /* disable any native browser highlighting */
33 | -webkit-touch-callout: none;
34 | -webkit-user-select: none;
35 | -khtml-user-select: none;
36 | -moz-user-select: none;
37 | -ms-user-select: none;
38 | user-select: none;
39 | }
40 |
41 | /* white square */
42 | .white-1e1d7.blocked {
43 | background-color: #999999;
44 | color: #333333;
45 | }
46 |
47 | /* black square */
48 | .black-3c85d.blocked {
49 | background-color: #333333;
50 | color: #999999;
51 | }
52 |
53 | /* white square */
54 | .white-1e1d7 {
55 | background-color: #f0d9b5;
56 | color: #b58863;
57 | }
58 |
59 | /* black square */
60 | .black-3c85d {
61 | background-color: #b58863;
62 | color: #f0d9b5;
63 | }
64 |
65 | /* white square */
66 | .square-55d63.win {
67 | background-color: #339900;
68 | color: #999999;
69 | }
70 |
71 | /* black square */
72 | .square-55d63.lose {
73 | background-color: #990000;
74 | color: #333333;
75 | }
76 |
77 | /* notation */
78 | .notation-322f9 {
79 | cursor: default;
80 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
81 | font-size: 14px;
82 | position: absolute;
83 | }
84 | .alpha-d2270 {
85 | bottom: 1px;
86 | right: 3px;
87 | }
88 | .numeric-fc462 {
89 | top: 2px;
90 | left: 2px;
91 | }
--------------------------------------------------------------------------------
/sudoku/PySudoku.py:
--------------------------------------------------------------------------------
1 | import sys, os, random, pygame
2 | sys.path.append(os.path.join("objects"))
3 | import SudokuSquare
4 | from GameResources import *
5 |
6 | digits = '123456789'
7 | rows = 'ABCDEFGHI'
8 |
9 |
10 | def play(values_list):
11 | pygame.init()
12 |
13 |
14 | size = width, height = 700, 700
15 | screen = pygame.display.set_mode(size)
16 |
17 | background_image = pygame.image.load("./images/sudoku-board-bare.jpg").convert()
18 |
19 | clock = pygame.time.Clock()
20 |
21 | # The puzzleNumber sets a seed so either generate
22 | # a random number to fill in here or accept user
23 | # input for a duplicatable puzzle.
24 |
25 | for values in values_list:
26 | pygame.event.pump()
27 | theSquares = []
28 | initXLoc = 0
29 | initYLoc = 0
30 | startX, startY, editable, number = 0, 0, "N", 0
31 | for y in range(9):
32 | for x in range(9):
33 | if x in (0, 1, 2): startX = (x * 57) + 38
34 | if x in (3, 4, 5): startX = (x * 57) + 99
35 | if x in (6, 7, 8): startX = (x * 57) + 159
36 |
37 | if y in (0, 1, 2): startY = (y * 57) + 35
38 | if y in (3, 4, 5): startY = (y * 57) + 100
39 | if y in (6, 7, 8): startY = (y * 57) + 165
40 | col = digits[x]
41 | row = rows[y]
42 | string_number = values[row + col]
43 | if len(string_number) > 1 or string_number == '' or string_number == '.':
44 | number = None
45 | else:
46 | number = int(string_number)
47 | theSquares.append(SudokuSquare.SudokuSquare(number, startX, startY, editable, x, y))
48 |
49 | screen.blit(background_image, (0, 0))
50 | for num in theSquares:
51 | num.draw()
52 |
53 | pygame.display.flip()
54 | pygame.display.update()
55 | clock.tick(5)
56 |
57 | # leave game showing until closed by user
58 | while True:
59 | for event in pygame.event.get():
60 | if event.type == pygame.QUIT:
61 | pygame.quit()
62 | quit()
63 |
64 | if __name__ == "__main__":
65 | main()
66 | sys.exit()
--------------------------------------------------------------------------------
/planning/lp_utils.py:
--------------------------------------------------------------------------------
1 | from aimacode.logic import associate
2 | from aimacode.utils import expr
3 |
4 |
5 | class FluentState():
6 | """ state object for planning problems as positive and negative fluents
7 |
8 | """
9 |
10 | def __init__(self, pos_list, neg_list):
11 | self.pos = pos_list
12 | self.neg = neg_list
13 |
14 | def sentence(self):
15 | return expr(conjunctive_sentence(self.pos, self.neg))
16 |
17 | def pos_sentence(self):
18 | return expr(conjunctive_sentence(self.pos, []))
19 |
20 |
21 | def conjunctive_sentence(pos_list, neg_list):
22 | """ returns expr conjuntive sentence given positive and negative fluent lists
23 |
24 | :param pos_list: list of fluents
25 | :param neg_list: list of fluents
26 | :return: expr sentence of fluent conjunction
27 | e.g. "At(C1, SFO) ∧ ~At(P1, SFO)"
28 | """
29 | clauses = []
30 | for f in pos_list:
31 | clauses.append(expr("{}".format(f)))
32 | for f in neg_list:
33 | clauses.append(expr("~{}".format(f)))
34 | return associate('&', clauses)
35 |
36 |
37 | def encode_state(fs: FluentState, fluent_map: list) -> str:
38 | """ encode fluents to a string of T/F using mapping
39 |
40 | :param fs: FluentState object
41 | :param fluent_map: ordered list of possible fluents for the problem
42 | :return: str eg. "TFFTFT" string of mapped positive and negative fluents
43 | """
44 | state_tf = []
45 | for fluent in fluent_map:
46 | if fluent in fs.pos:
47 | state_tf.append('T')
48 | else:
49 | state_tf.append('F')
50 | return "".join(state_tf)
51 |
52 |
53 | def decode_state(state: str, fluent_map: list) -> FluentState:
54 | """ decode string of T/F as fluent per mapping
55 |
56 | :param state: str eg. "TFFTFT" string of mapped positive and negative fluents
57 | :param fluent_map: ordered list of possible fluents for the problem
58 | :return: fs: FluentState object
59 |
60 | lengths of state string and fluent_map list must be the same
61 | """
62 | fs = FluentState([], [])
63 | for idx, char in enumerate(state):
64 | if char == 'T':
65 | fs.pos.append(fluent_map[idx])
66 | else:
67 | fs.neg.append(fluent_map[idx])
68 | return fs
69 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [Udacity Artificial Intelligence Nanodegree](https://www.udacity.com/course/artificial-intelligence-nanodegree--nd889)
2 | A repository of multiple projects and labs done in the Udacity Artificial Intelligence Nanodegree (aind).
3 |
4 | ### [Sudoku](/sudoku)
5 |
6 | In this project, you will be writing code to implement two extensions of our sudoku solver. The first one will be to implement the technique called "naked twins". The second one will be to modify our existing code to solve a diagonal sudoku. To complete this project you will use the tools you learned about in the lesson, and build upon them.
7 |
8 | Your goals are to implement the naked twins function, and write an AI agent that will solve the Diagonal Sudoku game.
9 |
10 | ### [Build a Game-playing Agent(Isolation)](/isolation)
11 | In this project, students will develop an adversarial search agent to play the game "Isolation". Isolation is a deterministic, two-player game of perfect information in which the players alternate turns moving a single piece from one cell to another on a board. Whenever either player occupies a cell, that cell becomes blocked for the remainder of the game. The first player with no remaining legal moves loses, and the opponent is declared the winner. These rules are implemented in the isolation.Board class provided in the repository.
12 |
13 | ### [Lab: PAC-MAN](https://github.com/ruihanzou/Teaching-Pac-Man-to-Search)
14 |
15 | In this lab, you will teach Pac-Man to search his world to complete the following tasks:
16 |
17 | find a single obstacle.
18 | find multiple obstacles.
19 | find the fastest way to eat all the food in the map.
20 |
21 | ### [Planning](/planning)
22 |
23 | In this project, you will define a group of problems in classical PDDL (Planning Domain Definition Language) for the air cargo domain discussed in the lectures. You will then set up the problems for search, experiment with various automatically generated heuristics, including planning graph heuristics, to solve the problems, and then provide an analysis of the results. Additionally, you will write a short research review paper on the historical development of planning techniques and their use in artificial intelligence.
24 |
25 | ### [Recognizer](/recognizer)
26 |
27 | In this project, you will build a system that can recognize words communicated using the American Sign Language (ASL). You will be provided a preprocessed dataset of tracked hand and nose positions extracted from video. Your goal would be to train a set of Hidden Markov Models (HMMs) using part of this dataset to try and identify individual words from test sequences.
28 |
--------------------------------------------------------------------------------
/planning/aimacode/planning.py:
--------------------------------------------------------------------------------
1 | """Planning (Chapters 10-11)
2 | """
3 |
4 | from .utils import Expr
5 |
6 |
7 | class Action:
8 | """
9 | Defines an action schema using preconditions and effects
10 | Use this to describe actions in PDDL
11 | action is an Expr where variables are given as arguments(args)
12 | Precondition and effect are both lists with positive and negated literals
13 | Example:
14 | precond_pos = [expr("Human(person)"), expr("Hungry(Person)")]
15 | precond_neg = [expr("Eaten(food)")]
16 | effect_add = [expr("Eaten(food)")]
17 | effect_rem = [expr("Hungry(person)")]
18 | eat = Action(expr("Eat(person, food)"), [precond_pos, precond_neg], [effect_add, effect_rem])
19 | """
20 |
21 | def __init__(self, action, precond, effect):
22 | self.name = action.op
23 | self.args = action.args
24 | self.precond_pos = precond[0]
25 | self.precond_neg = precond[1]
26 | self.effect_add = effect[0]
27 | self.effect_rem = effect[1]
28 |
29 | def __call__(self, kb, args):
30 | return self.act(kb, args)
31 |
32 | def __str__(self):
33 | return "{}{!s}".format(self.name, self.args)
34 |
35 | def substitute(self, e, args):
36 | """Replaces variables in expression with their respective Propostional symbol"""
37 | new_args = list(e.args)
38 | for num, x in enumerate(e.args):
39 | for i in range(len(self.args)):
40 | if self.args[i] == x:
41 | new_args[num] = args[i]
42 | return Expr(e.op, *new_args)
43 |
44 | def check_precond(self, kb, args):
45 | """Checks if the precondition is satisfied in the current state"""
46 | # check for positive clauses
47 | for clause in self.precond_pos:
48 | if self.substitute(clause, args) not in kb.clauses:
49 | return False
50 | # check for negative clauses
51 | for clause in self.precond_neg:
52 | if self.substitute(clause, args) in kb.clauses:
53 | return False
54 | return True
55 |
56 | def act(self, kb, args):
57 | """Executes the action on the state's kb"""
58 | # check if the preconditions are satisfied
59 | if not self.check_precond(kb, args):
60 | raise Exception("Action pre-conditions not satisfied")
61 | # remove negative literals
62 | for clause in self.effect_rem:
63 | kb.retract(self.substitute(clause, args))
64 | # add positive literals
65 | for clause in self.effect_add:
66 | kb.tell(self.substitute(clause, args))
67 |
--------------------------------------------------------------------------------
/sudoku/README.md:
--------------------------------------------------------------------------------
1 | # Artificial Intelligence Nanodegree
2 |
3 |
4 | ## Introductory Project: Diagonal Sudoku Solver
5 |
6 | # Question 1 (Naked Twins)
7 | Q: How do we use constraint propagation to solve the naked twins problem?
8 | A: To solve the naked twins problem we apply the following steps:
9 | * From current sudoku board, we call naked_twins() to identify all naked twins grouped by unit (the complete rows, columns and 3x3 squares).
10 | * In each unit, recursively remove naked twins digits from the possible value of boxes (the individual squares at the intersection of rows and columns) so that no squares outside the two naked twins squares can contain the twins values.
11 | * We depth first search all boxes and repeatedly apply naked twins technique to narrow the search space of possible solutions iteratively.
12 |
13 | # Question 2 (Diagonal Sudoku)
14 | Q: How do we use constraint propagation to solve the diagonal sudoku problem?
15 | A: To solve the diagonal sudoku problem we apply the following steps:
16 | * Consider diagonal and reverse diagonal along with row, column, square units as part of constraints
17 | * apply elimination strategy, only choice strategy, and naked twins technique repeatedly
18 |
19 | ### Install
20 |
21 | This project requires **Python 3**.
22 |
23 | We recommend students install [Anaconda](https://www.continuum.io/downloads), a pre-packaged Python distribution that contains all of the necessary libraries and software for this project.
24 | Please try using the environment we provided in the Anaconda lesson of the Nanodegree.
25 |
26 | ##### Optional: Pygame
27 |
28 | Optionally, you can also install pygame if you want to see your visualization. If you've followed our instructions for setting up our conda environment, you should be all set.
29 |
30 | If not, please see how to download pygame [here](http://www.pygame.org/download.shtml).
31 |
32 | ### Code
33 |
34 | * `solution.py` - You'll fill this in as part of your solution.
35 | * `solution_test.py` - Do not modify this. You can test your solution by running `python solution_test.py`.
36 | * `PySudoku.py` - Do not modify this. This is code for visualizing your solution.
37 | * `visualize.py` - Do not modify this. This is code for visualizing your solution.
38 |
39 | ### Visualizing
40 |
41 | To visualize your solution, please only assign values to the values_dict using the ```assign_values``` function provided in solution.py
42 |
43 | ### Code Review
44 | You can find my project feedback from one of the Udacity reviewers in [here](https://review.udacity.com/#!/reviews/451359/shared)
--------------------------------------------------------------------------------
/planning/tests/test_my_air_cargo_problems.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | parent = os.path.dirname(os.path.realpath(__file__))
4 | sys.path.append(os.path.join(os.path.dirname(parent), "aimacode"))
5 | from aimacode.planning import Action
6 | from aimacode.utils import expr
7 | from aimacode.search import Node
8 | import unittest
9 | from lp_utils import decode_state
10 | from my_air_cargo_problems import (
11 | air_cargo_p1, air_cargo_p2, air_cargo_p3,
12 | )
13 |
14 | class TestAirCargoProb1(unittest.TestCase):
15 |
16 | def setUp(self):
17 | self.p1 = air_cargo_p1()
18 |
19 | def test_ACP1_num_fluents(self):
20 | self.assertEqual(len(self.p1.initial), 12)
21 |
22 | def test_ACP1_num_requirements(self):
23 | self.assertEqual(len(self.p1.goal),2)
24 |
25 |
26 | class TestAirCargoProb2(unittest.TestCase):
27 |
28 | def setUp(self):
29 | self.p2 = air_cargo_p2()
30 |
31 | def test_ACP2_num_fluents(self):
32 | self.assertEqual(len(self.p2.initial), 27)
33 |
34 | def test_ACP2_num_requirements(self):
35 | self.assertEqual(len(self.p2.goal),3)
36 |
37 |
38 | class TestAirCargoProb3(unittest.TestCase):
39 |
40 | def setUp(self):
41 | self.p3 = air_cargo_p3()
42 |
43 | def test_ACP3_num_fluents(self):
44 | self.assertEqual(len(self.p3.initial), 32)
45 |
46 | def test_ACP3_num_requirements(self):
47 | self.assertEqual(len(self.p3.goal),4)
48 |
49 |
50 | class TestAirCargoMethods(unittest.TestCase):
51 |
52 | def setUp(self):
53 | self.p1 = air_cargo_p1()
54 | self.act1 = Action(
55 | expr('Load(C1, P1, SFO)'),
56 | [[expr('At(C1, SFO)'), expr('At(P1, SFO)')], []],
57 | [[expr('In(C1, P1)')], [expr('At(C1, SFO)')]]
58 | )
59 |
60 | def test_AC_get_actions(self):
61 | # to see a list of the actions, uncomment below
62 | # print("\nactions for problem")
63 | # for action in self.p1.actions_list:
64 | # print("{}{}".format(action.name, action.args))
65 | self.assertEqual(len(self.p1.actions_list), 20)
66 |
67 | def test_AC_actions(self):
68 | # to see list of possible actions, uncomment below
69 | # print("\npossible actions:")
70 | # for action in self.p1.actions(self.p1.initial):
71 | # print("{}{}".format(action.name, action.args))
72 | self.assertEqual(len(self.p1.actions(self.p1.initial)), 4)
73 |
74 | def test_AC_result(self):
75 | fs = decode_state(self.p1.result(self.p1.initial, self.act1), self.p1.state_map)
76 | self.assertTrue(expr('In(C1, P1)') in fs.pos)
77 | self.assertTrue(expr('At(C1, SFO)') in fs.neg)
78 |
79 | def test_h_ignore_preconditions(self):
80 | n = Node(self.p1.initial)
81 | self.assertEqual(self.p1.h_ignore_preconditions(n),2)
82 |
83 | if __name__ == '__main__':
84 | unittest.main()
85 |
--------------------------------------------------------------------------------
/isolation/isolation/README.md:
--------------------------------------------------------------------------------
1 |
2 | # isolation.Board class
3 |
4 | ## Constructor
5 |
6 | Board.__init__(self, player_1, player_2, width=7, height=7)
7 |
8 | ## Attributes
9 |
10 | ### BLANK : 0 (constant)
11 |
12 | ### NOT_MOVED : None (constant)
13 |
14 | ### width : 7 (constant)
15 |
16 | Board width
17 |
18 | ### height : 7 (constant)
19 |
20 | Board height
21 |
22 | ### active_player : hashable
23 |
24 | Reference to a hashable object registered as a player with the initiative to move on the current board
25 |
26 | ### inactive_player : hashable
27 |
28 | Reference to a hashable object registered as a player awaiting initiative to move on the current board
29 |
30 | ### move_count : int
31 |
32 | Counter indicating the number of moves that have been applied to the game
33 |
34 | ## Public Methods
35 |
36 | ### apply_move(self, move)
37 |
38 | Modify the game object by moving the active player on the game board and disabling the vacated square (if any). The forecast_move method performs the same function, but returns a copy of the board, rather than modifying the state in-place.
39 |
40 | ### copy(self)
41 |
42 | Return a new Board object that is a copy of the current game state
43 |
44 | ### forecast_move(self, move)
45 |
46 | Equivalent to apply_move, but returns a copy of the board rather than modifying the state in-place.
47 |
48 | ### get_blank_spaces(self)
49 |
50 | Returns a list of tuples identifying the blank squares on the current board
51 |
52 | ### get_legal_moves(self, player=None)
53 |
54 | Returns a list of tuples identifying the legal moves for the specified player
55 |
56 | ### get_opponent(self, player)
57 |
58 | Returns the opponent of the specified player
59 |
60 | ### get_player_location(self, player)
61 |
62 | Returns a tuple (x, y) identifying the location of the specified player on the game board, or None of the player is a registered agent in the game but has not yet been placed on the board. Raises a RuntimeError if the specified player is not registered on the board.
63 |
64 | ### hash(self)
65 |
66 | Return a hash of the current state (public alias of __hash__ method). The hashed state includes occupied cells, current player locations, and which player has initiative on the board. An equivalent hash function can be added to the isolation.Board class from the isolation project:
67 |
68 | ### is_loser(self, player)
69 |
70 | Returns True if the specified player has lost the game in the current state, and False otherwise
71 |
72 | ### is_winner(self, player)
73 |
74 | Returns True if the specified player has won the game in the current state, and False otherwise
75 |
76 | ### move_is_legal(self, move)
77 |
78 | Returns True if the active player can legally make the specified move and False otherwise
79 |
80 | ### to_string(self, symbols=['1', '2'])
81 |
82 | Return a string representation of the current board position
83 |
84 | ### utility(self, player)
85 |
86 | Returns a floating point value: +inf if the specified player has won the game, -inf if the specified player has lost the game, and 0 otherwise.
--------------------------------------------------------------------------------
/recognizer/data/speaker.csv:
--------------------------------------------------------------------------------
1 | video,speaker
2 | 1,woman-1
3 | 3,woman-2
4 | 4,woman-1
5 | 5,woman-2
6 | 6,woman-2
7 | 8,man-1
8 | 9,woman-2
9 | 10,woman-1
10 | 11,woman-2
11 | 13,woman-2
12 | 14,woman-2
13 | 15,woman-2
14 | 16,man-1
15 | 17,woman-2
16 | 18,woman-1
17 | 19,woman-2
18 | 20,woman-2
19 | 22,woman-2
20 | 23,woman-2
21 | 24,woman-2
22 | 26,woman-2
23 | 27,woman-2
24 | 29,man-1
25 | 31,man-1
26 | 32,woman-2
27 | 33,woman-2
28 | 34,woman-2
29 | 35,man-1
30 | 37,woman-2
31 | 38,woman-2
32 | 39,man-1
33 | 41,woman-2
34 | 42,woman-1
35 | 44,woman-2
36 | 45,woman-1
37 | 46,woman-1
38 | 47,woman-2
39 | 48,woman-1
40 | 49,woman-1
41 | 51,woman-1
42 | 52,woman-1
43 | 53,woman-2
44 | 55,woman-2
45 | 56,man-1
46 | 58,man-1
47 | 59,woman-1
48 | 60,woman-1
49 | 61,woman-1
50 | 62,woman-1
51 | 63,woman-1
52 | 64,woman-1
53 | 65,woman-1
54 | 66,woman-1
55 | 68,woman-2
56 | 69,woman-2
57 | 70,woman-2
58 | 72,woman-2
59 | 73,man-1
60 | 75,woman-2
61 | 76,woman-2
62 | 78,woman-2
63 | 79,woman-2
64 | 80,woman-2
65 | 81,woman-2
66 | 82,woman-1
67 | 83,woman-1
68 | 85,woman-1
69 | 86,woman-1
70 | 87,woman-2
71 | 88,woman-2
72 | 91,woman-2
73 | 93,man-1
74 | 94,woman-2
75 | 95,man-1
76 | 96,man-1
77 | 97,woman-2
78 | 98,woman-1
79 | 99,woman-1
80 | 101,woman-1
81 | 102,woman-2
82 | 103,woman-1
83 | 104,woman-1
84 | 106,man-1
85 | 109,woman-2
86 | 110,woman-2
87 | 111,woman-2
88 | 112,man-1
89 | 114,man-1
90 | 115,woman-2
91 | 116,man-1
92 | 117,man-1
93 | 118,man-1
94 | 120,man-1
95 | 121,woman-2
96 | 123,woman-1
97 | 124,man-1
98 | 125,woman-1
99 | 126,woman-1
100 | 127,man-1
101 | 128,woman-1
102 | 129,man-1
103 | 130,man-1
104 | 131,man-1
105 | 132,man-1
106 | 133,man-1
107 | 134,woman-1
108 | 135,woman-1
109 | 136,woman-1
110 | 137,man-1
111 | 138,woman-1
112 | 140,woman-1
113 | 141,woman-1
114 | 143,man-1
115 | 144,woman-1
116 | 145,woman-1
117 | 146,woman-1
118 | 147,woman-1
119 | 148,man-1
120 | 149,man-1
121 | 150,woman-1
122 | 151,woman-1
123 | 152,man-1
124 | 153,man-1
125 | 154,woman-1
126 | 155,man-1
127 | 156,woman-1
128 | 157,man-1
129 | 159,man-1
130 | 160,woman-1
131 | 161,woman-1
132 | 162,woman-1
133 | 163,woman-1
134 | 164,woman-1
135 | 165,man-1
136 | 166,man-1
137 | 168,man-1
138 | 169,man-1
139 | 170,man-1
140 | 172,man-1
141 | 173,man-1
142 | 175,man-1
143 | 176,man-1
144 | 177,man-1
145 | 178,man-1
146 | 179,man-1
147 | 180,man-1
148 | 182,man-1
149 | 183,man-1
150 | 185,man-1
151 | 186,man-1
152 | 187,man-1
153 | 188,man-1
154 | 190,man-1
155 | 191,man-1
156 | 192,man-1
157 | 194,woman-1
158 | 195,woman-2
159 | 196,man-1
160 | 197,man-1
161 | 198,man-1
162 | 200,woman-1
163 | 2,woman-1
164 | 7,man-1
165 | 12,woman-2
166 | 21,woman-2
167 | 25,woman-2
168 | 28,woman-2
169 | 30,man-1
170 | 36,man-1
171 | 40,man-1
172 | 43,woman-1
173 | 50,woman-1
174 | 54,woman-2
175 | 57,man-1
176 | 67,woman-1
177 | 71,woman-2
178 | 74,man-1
179 | 77,woman-2
180 | 84,woman-1
181 | 89,woman-2
182 | 90,man-1
183 | 92,woman-2
184 | 100,woman-1
185 | 105,woman-1
186 | 107,man-1
187 | 108,woman-2
188 | 113,man-1
189 | 119,man-1
190 | 122,woman-2
191 | 139,man-1
192 | 142,woman-1
193 | 158,man-1
194 | 167,man-1
195 | 171,man-1
196 | 174,man-1
197 | 181,man-1
198 | 184,man-1
199 | 189,man-1
200 | 193,man-1
201 | 199,woman-1
202 | 201,woman-2
203 |
--------------------------------------------------------------------------------
/recognizer/README.md:
--------------------------------------------------------------------------------
1 | # Artificial Intelligence Engineer Nanodegree
2 | ## Probabilistic Models
3 | ## Project: Sign Language Recognition System
4 |
5 | ### Install
6 |
7 | This project requires **Python 3** and the following Python libraries installed:
8 |
9 | - [NumPy](http://www.numpy.org/)
10 | - [SciPy](https://www.scipy.org/)
11 | - [scikit-learn](http://scikit-learn.org/0.17/install.html)
12 | - [pandas](http://pandas.pydata.org/)
13 | - [matplotlib](http://matplotlib.org/)
14 | - [jupyter](http://ipython.org/notebook.html)
15 | - [hmmlearn](http://hmmlearn.readthedocs.io/en/latest/)
16 |
17 | Notes:
18 | 1. It is highly recommended that you install the [Anaconda](http://continuum.io/downloads) distribution of Python and load the environment included in the "Your conda env for AI ND" lesson.
19 | 2. The most recent development version of hmmlearn, 0.2.1, contains a bugfix related to the log function, which is used in this project. In order to install this version of hmmearn, install it directly from its repo with the following command from within your activated Anaconda environment:
20 | ```sh
21 | pip install git+https://github.com/hmmlearn/hmmlearn.git
22 | ```
23 |
24 | ### Code
25 |
26 | A template notebook is provided as `asl_recognizer.ipynb`. The notebook is a combination tutorial and submission document. Some of the codebase and some of your implementation will be external to the notebook. For submission, complete the **Submission** sections of each part. This will include running your implementations in code notebook cells, answering analysis questions, and passing provided unit tests provided in the codebase and called out in the notebook.
27 |
28 | ### Run
29 |
30 | In a terminal or command window, navigate to the top-level project directory `AIND_recognizer/` (that contains this README) and run one of the following command:
31 |
32 | `jupyter notebook asl_recognizer.ipynb`
33 |
34 | This will open the Jupyter Notebook software and notebook in your browser which is where you will directly edit and run your code. Follow the instructions in the notebook for completing the project.
35 |
36 |
37 | ### Additional Information
38 | ##### Provided Raw Data
39 |
40 | The data in the `asl_recognizer/data/` directory was derived from
41 | the [RWTH-BOSTON-104 Database](http://www-i6.informatik.rwth-aachen.de/~dreuw/database-rwth-boston-104.php).
42 | The handpositions (`hand_condensed.csv`) are pulled directly from
43 | the database [boston104.handpositions.rybach-forster-dreuw-2009-09-25.full.xml](boston104.handpositions.rybach-forster-dreuw-2009-09-25.full.xml). The three markers are:
44 |
45 | * 0 speaker's left hand
46 | * 1 speaker's right hand
47 | * 2 speaker's nose
48 | * X and Y values of the video frame increase left to right and top to bottom.
49 |
50 | Take a look at the sample [ASL recognizer video](http://www-i6.informatik.rwth-aachen.de/~dreuw/download/021.avi)
51 | to see how the hand locations are tracked.
52 |
53 | The videos are sentences with translations provided in the database.
54 | For purposes of this project, the sentences have been pre-segmented into words
55 | based on slow motion examination of the files.
56 | These segments are provided in the `train_words.csv` and `test_words.csv` files
57 | in the form of start and end frames (inclusive).
58 |
59 | The videos in the corpus include recordings from three different ASL speakers.
60 | The mappings for the three speakers to video are included in the `speaker.csv`
61 | file.
62 | ### Code Review
63 | You can find my project feedback from one of the Udacity reviewers in [here](https://review.udacity.com/#!/reviews/584428/shared)
--------------------------------------------------------------------------------
/recognizer/asl_test.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 |
3 | from asl_data import AslDb
4 | from asl_utils import train_all_words
5 | from my_model_selectors import (
6 | SelectorConstant, SelectorBIC, SelectorDIC, SelectorCV,
7 | )
8 | from my_recognizer import recognize
9 |
10 | """ DEPRECATED MODULE
11 | This module has been split into two new modules: asl_test_model_selectors.py and asl_test_recognizer.py
12 | This module is included in the repo for the sake of legacy code that still uses it.
13 | """
14 | FEATURES = ['right-y', 'right-x']
15 |
16 |
17 | class TestSelectors(TestCase):
18 | def setUp(self):
19 | asl = AslDb()
20 | self.training = asl.build_training(FEATURES)
21 | self.sequences = self.training.get_all_sequences()
22 | self.xlengths = self.training.get_all_Xlengths()
23 |
24 | def test_select_constant_interface(self):
25 | model = SelectorConstant(self.sequences, self.xlengths, 'BUY').select()
26 | self.assertGreaterEqual(model.n_components, 2)
27 | model = SelectorConstant(self.sequences, self.xlengths, 'BOOK').select()
28 | self.assertGreaterEqual(model.n_components, 2)
29 |
30 | def test_select_bic_interface(self):
31 | model = SelectorBIC(self.sequences, self.xlengths, 'FRANK').select()
32 | self.assertGreaterEqual(model.n_components, 2)
33 | model = SelectorBIC(self.sequences, self.xlengths, 'VEGETABLE').select()
34 | self.assertGreaterEqual(model.n_components, 2)
35 |
36 | def test_select_cv_interface(self):
37 | model = SelectorCV(self.sequences, self.xlengths, 'JOHN').select()
38 | self.assertGreaterEqual(model.n_components, 2)
39 | model = SelectorCV(self.sequences, self.xlengths, 'CHICKEN').select()
40 | self.assertGreaterEqual(model.n_components, 2)
41 |
42 | def test_select_dic_interface(self):
43 | model = SelectorDIC(self.sequences, self.xlengths, 'MARY').select()
44 | self.assertGreaterEqual(model.n_components, 2)
45 | model = SelectorDIC(self.sequences, self.xlengths, 'TOY').select()
46 | self.assertGreaterEqual(model.n_components, 2)
47 |
48 |
49 | class TestRecognize(TestCase):
50 | def setUp(self):
51 | self.asl = AslDb()
52 | self.training_set = self.asl.build_training(FEATURES)
53 | self.test_set = self.asl.build_test(FEATURES)
54 | self.models = train_all_words(self.training_set, SelectorConstant)
55 |
56 | def test_recognize_probabilities_interface(self):
57 | probs, _ = recognize(self.models, self.test_set)
58 | self.assertEqual(len(probs), self.test_set.num_items, "Number of test items in probabilities list incorrect.")
59 | self.assertEqual(len(probs[0]), self.training_set.num_items,
60 | "Number of training word probabilities in test item dictionary incorrect.")
61 | self.assertEqual(len(probs[-1]), self.training_set.num_items,
62 | "Number of training word probabilities in test item dictionary incorrect.")
63 | self.assertIn('FRANK', probs[0], "Dictionary of probabilities does not contain correct keys")
64 | self.assertIn('CHICKEN', probs[-1], "Dictionary of probabilities does not contain correct keys")
65 |
66 | def test_recognize_guesses_interface(self):
67 | _, guesses = recognize(self.models, self.test_set)
68 | self.assertEqual(len(guesses), self.test_set.num_items, "Number of test items in guesses list incorrect.")
69 | self.assertIsInstance(guesses[0], str, "The guesses are not strings")
70 | self.assertIsInstance(guesses[-1], str, "The guesses are not strings")
71 |
--------------------------------------------------------------------------------
/isolation/competition_agent.py:
--------------------------------------------------------------------------------
1 | """Implement your own custom search agent using any combination of techniques
2 | you choose. This agent will compete against other students (and past
3 | champions) in a tournament.
4 |
5 | COMPLETING AND SUBMITTING A COMPETITION AGENT IS OPTIONAL
6 | """
7 | import random
8 |
9 |
10 | class SearchTimeout(Exception):
11 | """Subclass base exception for code clarity. """
12 | pass
13 |
14 |
15 | def custom_score(game, player):
16 | """Calculate the heuristic value of a game state from the point of view
17 | of the given player.
18 |
19 | This should be the best heuristic function for your project submission.
20 |
21 | Parameters
22 | ----------
23 | game : `isolation.Board`
24 | An instance of `isolation.Board` encoding the current state of the
25 | game (e.g., player locations and blocked cells).
26 |
27 | player : object
28 | A player instance in the current game (i.e., an object corresponding to
29 | one of the player objects `game.__player_1__` or `game.__player_2__`.)
30 |
31 | Returns
32 | -------
33 | float
34 | The heuristic value of the current game state to the specified player.
35 | """
36 | raise NotImplementedError
37 |
38 |
39 | class CustomPlayer:
40 | """Game-playing agent to use in the optional player vs player Isolation
41 | competition.
42 |
43 | You must at least implement the get_move() method and a search function
44 | to complete this class, but you may use any of the techniques discussed
45 | in lecture or elsewhere on the web -- opening books, MCTS, etc.
46 |
47 | **************************************************************************
48 | THIS CLASS IS OPTIONAL -- IT IS ONLY USED IN THE ISOLATION PvP
49 | COMPETITION. IT IS NOT REQUIRED FOR THE ISOLATION PROJECT REVIEW.
50 | **************************************************************************
51 |
52 | Parameters
53 | ----------
54 | data : string
55 | The name of the search method to use in get_move().
56 |
57 | timeout : float (optional)
58 | Time remaining (in milliseconds) when search is aborted. Note that
59 | the PvP competition uses more accurate timers that are not cross-
60 | platform compatible, so a limit of 1ms (vs 10ms for the other classes)
61 | is generally sufficient.
62 | """
63 |
64 | def __init__(self, data=None, timeout=1.):
65 | self.score = custom_score
66 | self.time_left = None
67 | self.TIMER_THRESHOLD = timeout
68 |
69 | def get_move(self, game, time_left):
70 | """Search for the best move from the available legal moves and return a
71 | result before the time limit expires.
72 |
73 | **********************************************************************
74 | NOTE: If time_left < 0 when this function returns, the agent will
75 | forfeit the game due to timeout. You must return _before_ the
76 | timer reaches 0.
77 | **********************************************************************
78 |
79 | Parameters
80 | ----------
81 | game : `isolation.Board`
82 | An instance of `isolation.Board` encoding the current state of the
83 | game (e.g., player locations and blocked cells).
84 |
85 | time_left : callable
86 | A function that returns the number of milliseconds left in the
87 | current turn. Returning with any less than 0 ms remaining forfeits
88 | the game.
89 |
90 | Returns
91 | -------
92 | (int, int)
93 | Board coordinates corresponding to a legal move; may return
94 | (-1, -1) if there are no available legal moves.
95 | """
96 | # OPTIONAL: Finish this function!
97 | raise NotImplementedError
98 |
--------------------------------------------------------------------------------
/sudoku/objects/SudokuSquare.py:
--------------------------------------------------------------------------------
1 | import pygame
2 |
3 | from pygame import *
4 |
5 | def AAfilledRoundedRect(surface,rect,color,radius=0.4):
6 |
7 | """
8 | AAfilledRoundedRect(surface,rect,color,radius=0.4)
9 |
10 | surface : destination
11 | rect : rectangle
12 | color : rgb or rgba
13 | radius : 0 <= radius <= 1
14 | """
15 |
16 | rect = Rect(rect)
17 | color = Color(*color)
18 | alpha = color.a
19 | color.a = 0
20 | pos = rect.topleft
21 | rect.topleft = 0,0
22 | rectangle = Surface(rect.size,SRCALPHA)
23 |
24 | circle = Surface([min(rect.size)*3]*2,SRCALPHA)
25 | draw.ellipse(circle,(0,0,0),circle.get_rect(),0)
26 | circle = transform.smoothscale(circle,[int(min(rect.size)*radius)]*2)
27 |
28 | radius = rectangle.blit(circle,(0,0))
29 | radius.bottomright = rect.bottomright
30 | rectangle.blit(circle,radius)
31 | radius.topright = rect.topright
32 | rectangle.blit(circle,radius)
33 | radius.bottomleft = rect.bottomleft
34 | rectangle.blit(circle,radius)
35 |
36 | rectangle.fill((0,0,0),rect.inflate(-radius.w,0))
37 | rectangle.fill((0,0,0),rect.inflate(0,-radius.h))
38 |
39 | rectangle.fill(color,special_flags=BLEND_RGBA_MAX)
40 | rectangle.fill((255,255,255,alpha),special_flags=BLEND_RGBA_MIN)
41 |
42 | return surface.blit(rectangle,pos)
43 |
44 | class SudokuSquare:
45 | """A sudoku square class."""
46 | def __init__(self, number=None, offsetX=0, offsetY=0, edit="Y", xLoc=0, yLoc=0):
47 | if number != None:
48 | number = str(number)
49 | self.color = (2, 204, 186)
50 | else:
51 | number = ""
52 | self.color = (255, 255, 255)
53 | # print("FONTS", pygame.font.get_fonts())
54 | self.font = pygame.font.SysFont('opensans', 21)
55 | self.text = self.font.render(number, 1, (255, 255, 255))
56 | self.textpos = self.text.get_rect()
57 | self.textpos = self.textpos.move(offsetX + 17, offsetY + 4)
58 |
59 | # self.collide = pygame.Surface((25, 22))
60 | # self.collide = self.collide.convert()
61 | # AAfilledRoundedRect(pygame.display.get_surface(), (xLoc, yLoc, 25, 22), (255, 255, 255))
62 | # self.collide.fill((2, 204, 186))
63 | # self.collideRect = self.collide.get_rect()
64 | # self.collideRect = self.collideRect.move(offsetX + 1, offsetY + 1)
65 | # The rect around the text is 11 x 28
66 |
67 | self.edit = edit
68 | self.xLoc = xLoc
69 | self.yLoc = yLoc
70 | self.offsetX = offsetX
71 | self.offsetY = offsetY
72 |
73 | def draw(self):
74 | screen = pygame.display.get_surface()
75 | AAfilledRoundedRect(screen, (self.offsetX, self.offsetY, 45, 40), self.color)
76 |
77 | # screen.blit(self.collide, self.collideRect)
78 | screen.blit(self.text, self.textpos)
79 |
80 |
81 | def checkCollide(self, collision):
82 | if len(collision) == 2:
83 | return self.collideRect.collidepoint(collision)
84 | elif len(collision) == 4:
85 | return self.collideRect.colliderect(collision)
86 | else:
87 | return False
88 |
89 |
90 | def highlight(self):
91 | self.collide.fill((190, 190, 255))
92 | self.draw()
93 |
94 |
95 | def unhighlight(self):
96 | self.collide.fill((255, 255, 255, 255))
97 | self.draw()
98 |
99 |
100 | def change(self, number):
101 | if number != None:
102 | number = str(number)
103 | else:
104 | number = ""
105 |
106 | if self.edit == "Y":
107 | self.text = self.font.render(number, 1, (0, 0, 0))
108 | self.draw()
109 | return 0
110 | else:
111 | return 1
112 |
113 |
114 | def currentLoc(self):
115 | return self.xLoc, self.yLoc
--------------------------------------------------------------------------------
/isolation/isoviz/display.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |