Added missing classes from final year at OSU

This commit is contained in:
2019-06-17 14:04:15 -07:00
parent 8fa1ffb1b0
commit c717a0316f
166 changed files with 653934 additions and 308 deletions

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.6" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
</project>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/CS 325 - Analysis of Algorithms.iml" filepath="$PROJECT_DIR$/.idea/CS 325 - Analysis of Algorithms.iml" />
</modules>
</component>
</project>

View File

@@ -1,285 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="8463bdd4-0c68-42b0-84f5-1c2abf1a6d5f" name="Default" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="CoverageDataManager">
<SUITE FILE_PATH="coverage/CS_325___Analysis_of_Algorithms$test.coverage" NAME="test Coverage Results" MODIFIED="1517016348937" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/CS_325___Analysis_of_Algorithms$HW_5.coverage" NAME="HW 5 Coverage Results" MODIFIED="1518853467198" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/HW 5" />
<SUITE FILE_PATH="coverage/CS_325___Analysis_of_Algorithms$HW_2.coverage" NAME="HW 2 Coverage Results" MODIFIED="1517020025345" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/HW 2" />
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="hw2.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/HW 2/hw2.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="160">
<caret line="107" column="56" lean-forward="false" selection-start-line="107" selection-start-column="56" selection-end-line="107" selection-end-column="56" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="hw4.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/HW 4/hw4.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#26#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="hw5.py" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/HW 5/hw5.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="153">
<caret line="9" column="0" lean-forward="true" selection-start-line="9" selection-start-column="0" selection-end-line="9" selection-end-column="0" />
<folding>
<element signature="e#0#21#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/temp.py" />
<option value="$PROJECT_DIR$/HW 2/hw2.py" />
<option value="$PROJECT_DIR$/HW 5/hw5.py" />
</list>
</option>
</component>
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsGulpfileManager">
<detection-done>true</detection-done>
<sorting>DEFINITION_ORDER</sorting>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="-8" />
<option name="y" value="-8" />
<option name="width" value="2576" />
<option name="height" value="1426" />
</component>
<component name="ProjectView">
<navigator currentView="ProjectPane" proportions="" version="1">
<flattenPackages />
<showMembers />
<showModules />
<showLibraryContents />
<hideEmptyPackages />
<abbreviatePackageNames />
<autoscrollToSource />
<autoscrollFromSource />
<sortByType />
<manualOrder />
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Scope" />
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="CS 325 - Analysis of Algorithms" type="b2602c69:ProjectViewProjectNode" />
<item name="CS 325 - Analysis of Algorithms" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="CS 325 - Analysis of Algorithms" type="b2602c69:ProjectViewProjectNode" />
<item name="CS 325 - Analysis of Algorithms" type="462c0819:PsiDirectoryNode" />
<item name="HW 4" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="CS 325 - Analysis of Algorithms" type="b2602c69:ProjectViewProjectNode" />
<item name="CS 325 - Analysis of Algorithms" type="462c0819:PsiDirectoryNode" />
<item name="HW 5" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scratches" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/HW 5/hw5.py" />
<property name="restartRequiresConfirmation" value="false" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration name="HW 5" type="PythonConfigurationType" factoryName="Python" singleton="true">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/HW 5" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="CS 325 - Analysis of Algorithms" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/HW 5/hw5.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
</configuration>
</component>
<component name="ShelveChangesManager" show_recycled="false">
<option name="remove_strategy" value="false" />
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="8463bdd4-0c68-42b0-84f5-1c2abf1a6d5f" name="Default" comment="" />
<created>1516999834836</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1516999834836</updated>
</task>
<servers />
</component>
<component name="ToolWindowManager">
<frame x="-8" y="-8" width="2576" height="1426" extended-state="6" />
<layout>
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="true" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.47753236" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.17629407" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.13710937" sideWeight="0.5" order="1" side_tool="false" content_ui="combo" />
<window_info id="Docker" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="SciView" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3998477" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="true" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="combo" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
</layout>
<layout-to-restore>
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="true" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32933232" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.17629407" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.1375494" sideWeight="0.5" order="1" side_tool="false" content_ui="combo" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="combo" />
<window_info id="Docker" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="SciView" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.39984995" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="true" content_ui="tabs" />
</layout-to-restore>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<default-breakpoints>
<breakpoint type="python-exception">
<properties notifyOnTerminate="true" exception="BaseException">
<option name="notifyOnTerminate" value="true" />
</properties>
</breakpoint>
</default-breakpoints>
<option name="time" value="2" />
</breakpoint-manager>
<watches-manager />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/HW 2/hw2.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file:///usr/lib/python3.5/timeit.py" />
<entry file="file://$PROJECT_DIR$/temp.py" />
<entry file="file://$PROJECT_DIR$/HW 2/hw2.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="160">
<caret line="107" column="56" lean-forward="false" selection-start-line="107" selection-start-column="56" selection-end-line="107" selection-end-column="56" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/HW 4/hw4.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#26#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/HW 5/hw5.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="153">
<caret line="9" column="0" lean-forward="true" selection-start-line="9" selection-start-column="0" selection-end-line="9" selection-end-column="0" />
<folding>
<element signature="e#0#21#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</component>
</project>

View File

@@ -0,0 +1,9 @@
For insertsort.py and mergesort.py, ensure data.txt is in the same directory, then run:
python3 insertsort.py
python3 mergesort.py
For insertTime.py and mergeTime.py, simply run:
python3 insertTime.py
python3 mergeTime.py

View File

@@ -0,0 +1,3 @@
10 10 9 8 7 6 5 4 3 2 1
3 8 8 8
8 1 3 4 1 4 7 3 5

View File

@@ -0,0 +1,34 @@
from random import randint
from time import time
MIN_INT = 0
MAX_INT = 10000
def insert_sort(data):
for current_value_index in range(1, len(data)):
current = data[current_value_index]
while current_value_index > 0 and data[current_value_index - 1] > current:
data[current_value_index] = data[current_value_index - 1]
current_value_index -= 1
data[current_value_index] = current
return data
if __name__ == "__main__":
start = 5000
step = 1000
n_values = [start + i * step for i in range(10)]
n_generated_list = [[randint(MIN_INT, MAX_INT) for _ in range(n_value)] for n_value in n_values]
print("n_value, time")
for current_list in n_generated_list:
current_length = len(current_list)
start_time = time()
insert_sort(current_list)
print("{}, {}".format(current_length, time() - start_time))

View File

@@ -0,0 +1,41 @@
INPUT_FILENAME = "data.txt"
OUTPUT_FILENAME = "insert.txt"
def insert_sort(data):
for current_value_index in range(1, len(data)):
current = data[current_value_index]
while current_value_index > 0 and data[current_value_index - 1] > current:
data[current_value_index] = data[current_value_index - 1]
current_value_index -= 1
data[current_value_index] = current
return data
if __name__ == "__main__":
output = []
with open(INPUT_FILENAME, "r") as input_file:
file_lines = input_file.readlines()
for line in file_lines:
line = line.strip("\n\r")
line_items = line.split(" ")
data_values = [int(item) for item in line_items[1:]]
output.append(insert_sort(data_values))
with open(OUTPUT_FILENAME, "w") as output_file:
output_last_index = len(output) - 1
for index, line in enumerate(output):
line_string = " ".join([str(value) for value in line])
output_file.write(line_string)
if index != output_last_index:
output_file.write("\n")

View File

@@ -0,0 +1,64 @@
from random import randint
from time import time
MIN_INT = 0
MAX_INT = 10000
def merge_sort(data, top_level=False):
data_length = len(data)
if data_length > 1:
list_midpoint = data_length // 2
left_data = data[:list_midpoint]
left_data_length = len(left_data)
right_data = data[list_midpoint:]
right_data_length = len(right_data)
merge_sort(left_data)
merge_sort(right_data)
left_data_index = 0
right_data_index = 0
final_data_index = 0
while left_data_index < left_data_length and right_data_index < right_data_length:
if left_data[left_data_index] < right_data[right_data_index]:
data[final_data_index] = left_data[left_data_index]
left_data_index += 1
else:
data[final_data_index] = right_data[right_data_index]
right_data_index += 1
final_data_index += 1
while left_data_index < left_data_length:
data[final_data_index] = left_data[left_data_index]
left_data_index += 1
final_data_index += 1
while right_data_index < right_data_length:
data[final_data_index] = right_data[right_data_index]
right_data_index += 1
final_data_index += 1
if top_level:
return data
if __name__ == "__main__":
start = 200000
step = 250000
n_values = [start + i * step for i in range(10)]
n_generated_list = [[randint(MIN_INT, MAX_INT) for _ in range(n_value)] for n_value in n_values]
print("n_value, time")
for current_list in n_generated_list:
current_length = len(current_list)
start_time = time()
merge_sort(current_list, top_level=True)
print("{}, {}".format(current_length, time() - start_time))

View File

@@ -0,0 +1,72 @@
INPUT_FILENAME = "data.txt"
OUTPUT_FILENAME = "merge.txt"
def merge_sort(data, top_level=False):
data_length = len(data)
if data_length > 1:
list_midpoint = data_length // 2
left_data = data[:list_midpoint]
left_data_length = len(left_data)
right_data = data[list_midpoint:]
right_data_length = len(right_data)
merge_sort(left_data)
merge_sort(right_data)
left_data_index = 0
right_data_index = 0
final_data_index = 0
while left_data_index < left_data_length and right_data_index < right_data_length:
if left_data[left_data_index] < right_data[right_data_index]:
data[final_data_index] = left_data[left_data_index]
left_data_index += 1
else:
data[final_data_index] = right_data[right_data_index]
right_data_index += 1
final_data_index += 1
while left_data_index < left_data_length:
data[final_data_index] = left_data[left_data_index]
left_data_index += 1
final_data_index += 1
while right_data_index < right_data_length:
data[final_data_index] = right_data[right_data_index]
right_data_index += 1
final_data_index += 1
if top_level:
return data
if __name__ == "__main__":
output = []
with open(INPUT_FILENAME, "r") as input_file:
file_lines = input_file.readlines()
for line in file_lines:
line = line.strip("\n\r")
line_items = line.split(" ")
item_count = int(line_items[0])
data_values = [int(item) for item in line_items[1:]]
output.append(merge_sort(data_values, top_level=True))
with open(OUTPUT_FILENAME, "w") as output_file:
output_last_index = len(output) - 1
for index, line in enumerate(output):
line_string = " ".join([str(value) for value in line])
output_file.write(line_string)
if index != output_last_index:
output_file.write("\n")

View File

@@ -0,0 +1,7 @@
Ensure data.txt is in the same directory, then run:
python3 stoogesort.py
For stoogeTime, simply run:
python3 stoogeTime.py

View File

@@ -0,0 +1,41 @@
from random import randint
from time import time
MIN_INT = 0
MAX_INT = 10000
def stooge_sort(data, start_index=0, end_index=None):
if end_index is None:
end_index = len(data) - 1
data_length = end_index - start_index
if data[start_index] > data[end_index]:
data[start_index], data[end_index] = data[end_index], data[start_index]
if data_length > 1:
split_point = (end_index - start_index + 1) // 3
stooge_sort(data, 0, end_index - split_point)
stooge_sort(data, start_index + split_point, end_index)
stooge_sort(data, 0, end_index - split_point)
return data
if __name__ == "__main__":
start = 4
step = 1
n_values = [start + i * step for i in range(10)]
n_generated_list = [[randint(MIN_INT, MAX_INT) for _ in range(n_value)] for n_value in n_values]
print("n_value, time")
for current_list in n_generated_list:
current_length = len(current_list)
start_time = time()
stooge_sort(current_list)
print("{}, {}".format(current_length, time() - start_time))

View File

@@ -0,0 +1,48 @@
INPUT_FILENAME = "data.txt"
OUTPUT_FILENAME = "stooge.out"
def stooge_sort(data, start_index=0, end_index=None):
if end_index is None:
end_index = len(data) - 1
data_length = end_index - start_index
if data[start_index] > data[end_index]:
data[start_index], data[end_index] = data[end_index], data[start_index]
if data_length > 1:
split_point = (end_index - start_index + 1) // 3
stooge_sort(data, 0, end_index - split_point)
stooge_sort(data, start_index + split_point, end_index)
stooge_sort(data, 0, end_index - split_point)
return data
if __name__ == "__main__":
output = []
with open(INPUT_FILENAME, "r") as input_file:
file_lines = input_file.readlines()
for line in file_lines:
line = line.strip("\n\r")
line_items = line.split(" ")
item_count = int(line_items[0])
data_values = [int(item) for item in line_items[1:]]
output.append(stooge_sort(data_values))
with open(OUTPUT_FILENAME, "w") as output_file:
output_last_index = len(output) - 1
for index, line in enumerate(output):
line_string = " ".join([str(value) for value in line])
output_file.write(line_string)
if index != output_last_index:
output_file.write("\n")

View File

@@ -0,0 +1,3 @@
To run this program, place the file "shopping.txt" in the same directory, then run
python3 shopping.py

View File

@@ -0,0 +1,61 @@
Test Case 1
Total Price 0
Member Items:
1:
2:
Test Case 2
Total Price 435
Member Items:
1: 3 4 5 6
2: 2 4 5
3: 3 4 6
4: 3 4 5
Test Case 3
Total Price 83
Member Items:
1: 3
2: 2 3
3: 1 2 3
4: 2 3 4
5: 1 2 3 4
6: 1 2 3 4
7: 2 3 5
8: 1 2 3 5
9: 2 3 4 5
10: 1 2 3 4 5
Test Case 4
Total Price 646
Member Items:
1: 1
2: 1
3: 2
4: 1 2
5: 1 5
6: 2 3
7: 7
8: 1 7
9: 10
10: 2 7
11: 1 2 7
12: 2 10
13: 2 3 7
14: 1 2 3 7
15: 7 9
16: 7 10
17: 1 7 10
18: 2 7 9
19: 2 7 10
20: 1 2 7 10
21: 2 3 7 9
22: 2 3 7 10
23: 1 2 3 7 10
24: 7 9 10
25: 2 6 7 10
26: 2 3 5 7 10
27: 2 7 9 10
28: 2 3 6 7 10
29: 1 2 3 6 7 10
30: 2 3 7 9 10

View File

@@ -0,0 +1,131 @@
INPUT_FILE = "shopping.txt"
OUTPUT_FILE = "results.txt"
def shopping_solver(max_individual_weight, shopping_items):
num_items = len(shopping_items["weights"])
# Each element of the table is (z, (a, b)) where z is the max value, and (a, b) are the x and y
# coordinates in the table for the parent that was used to create this value
lookup_table = [[(0, (0, 0)) for _ in range(num_items + 1)] for _ in range(max_individual_weight + 1)]
# Run the solver
for current_weight in range(max_individual_weight + 1):
for current_item in range(num_items + 1):
last_item_index = current_item - 1
if current_weight == 0 or current_item == 0:
lookup_table[current_weight][current_item] = 0, (0, 0)
elif shopping_items["weights"][last_item_index] <= current_weight:
included_weight = current_weight - shopping_items["weights"][last_item_index]
included = shopping_items["prices"][last_item_index] + lookup_table[included_weight][last_item_index][0]
not_included = lookup_table[current_weight][last_item_index][0]
if included > not_included:
lookup_table[current_weight][current_item] = included, (included_weight, last_item_index)
else:
lookup_table[current_weight][current_item] = not_included, (current_weight, last_item_index)
else:
lookup_table[current_weight][current_item] = \
lookup_table[current_weight][last_item_index][0], (current_weight, last_item_index)
# Trace parents to find the path
solved_path = []
last_weight_index, last_item_index = max_individual_weight, num_items
current_weight_index, current_item_index = lookup_table[max_individual_weight][num_items][1]
while [current_weight_index == 0,
current_item_index == 0,
last_weight_index == 0,
last_item_index == 0] != [True, True, True, True]:
if current_item_index != last_item_index and current_weight_index != last_weight_index:
solved_path.append(current_item_index + 1)
last_item_index = current_item_index
last_weight_index = current_weight_index
current_weight_index, current_item_index = lookup_table[current_weight_index][current_item_index][1]
return lookup_table[max_individual_weight][num_items][0], list(reversed(solved_path))
def get_tests_from_file(filename):
tests_from_file = []
with open(filename, "r") as shopping_file:
lines = shopping_file.readlines()
line_index = 0
num_tests = int(lines[line_index])
for test_number in range(num_tests):
current_test = {"items": {"weights": [], "prices": []}, "family": []}
line_index += 1
num_items = int(lines[line_index])
for item_number in range(num_items):
line_index += 1
item = lines[line_index]
item_split = item.split(" ")
current_test["items"]["weights"].append(int(item_split[1]))
current_test["items"]["prices"].append(int(item_split[0]))
line_index += 1
num_family = int(lines[line_index])
for family_number in range(num_family):
line_index += 1
current_test["family"].append(int(lines[line_index]))
tests_from_file.append(current_test)
return tests_from_file
def print_and_save_results(all_testing_results):
output_string = ""
for test_number, current_test in enumerate(all_testing_results):
output_string += "Test Case {}\n".format(test_number + 1)
output_string += "Total Price {}\n".format(current_test[0])
output_string += "Member Items:\n"
for member_number, items in enumerate(current_test[1]):
if items:
output_string += "{}: {}\n".format(member_number + 1, " ".join([str(item) for item in items]) + " ")
else:
output_string += "{}: \n".format(member_number + 1)
output_string += "\n"
print(output_string, end="")
with open(OUTPUT_FILE, "w") as output_file:
output_file.write(output_string)
if __name__ == "__main__":
tests = get_tests_from_file(INPUT_FILE)
all_test_results = []
for test in tests:
test_sum = 0
family_member_items = []
for family_member in test["family"]:
max_value, item_indexes = shopping_solver(family_member, test["items"])
test_sum += max_value
family_member_items.append(item_indexes)
all_test_results.append((test_sum, family_member_items))
print_and_save_results(all_test_results)

View File

@@ -0,0 +1,78 @@
4
2
77 7
66 6
2
5
5
6
32 16
43 12
26 4
50 8
20 3
27 9
4
25
23
21
19
5
1 1
2 1
3 1
2 2
5 5
10
1
2
3
4
5
6
7
8
9
10
10
1 1
4 3
4 3
4 4
5 4
8 6
10 7
9 7
11 8
13 9
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

View File

@@ -0,0 +1,3 @@
To run this program, place the file "act.txt" in the same directory, then run
python3 activity_selection.py

View File

@@ -0,0 +1,23 @@
11
1 1 4
2 3 5
3 0 6
4 5 7
5 3 9
6 5 9
7 6 10
8 8 11
9 8 12
10 2 14
11 12 16
3
3 6 8
1 7 9
2 1 2
6
1 1 5
2 3 6
3 6 10
4 8 11
5 11 15
6 12 15

View File

@@ -0,0 +1,58 @@
INPUT_FILE = "act.txt"
def greedy_activity_selector(activity_set):
activity_num_index = 0
activity_start_index = 1
activity_finish_index = 2
activity_set.sort(key=lambda activity: activity[activity_start_index], reverse=True)
selections = [activity_set[0][activity_num_index]]
comparison_activity_index = 0
for i in range(1, len(activity_set)):
if activity_set[i][activity_finish_index] <= activity_set[comparison_activity_index][activity_start_index]:
selections.append(activity_set[i][activity_num_index])
comparison_activity_index = i
return list(reversed(selections))
def get_activity_sets(input_filename):
file_activity_sets = []
with open(input_filename, "r") as input_file:
lines = input_file.readlines()
last_index = len(lines) - 1
line_index = -1
while line_index != last_index:
current_set = []
line_index += 1
num_activities = int(lines[line_index])
for activity_number in range(num_activities):
line_index += 1
activity = lines[line_index]
activity_split = activity.split(" ")
current_set.append(list((int(value) for value in activity_split)))
file_activity_sets.append(current_set)
return file_activity_sets
if __name__ == "__main__":
activity_sets = get_activity_sets(INPUT_FILE)
for set_number, current_activity_set in enumerate(activity_sets):
selected_activities = greedy_activity_selector(current_activity_set)
print("Set {}".format(set_number + 1))
print("Number of activities selected = {}".format(len(selected_activities)))
print("Activities: {}".format(" ".join([str(activity) for activity in selected_activities])))
print()

View File

@@ -0,0 +1,7 @@
To run this program, place the file with wrestling information in the same directory, then run
python3 wrestler.py filename
An example would be
python3 wrestler.py wrestler.txt

View File

@@ -0,0 +1,116 @@
import argparse
from collections import deque
class Wrestler(object):
def __init__(self, name):
self._name = name
self._rivals = deque()
self._parent = None
self.depth = 0
def __repr__(self):
return "{}: {}".format(self._name, [rival.name for rival in self._rivals])
@property
def name(self):
return self._name
@property
def rivals(self):
return self._rivals
def add_rival(self, rival):
self._rivals.append(rival)
def wrestler_bfs(wrestlers):
seen = set()
bfs_babyfaces = []
bfs_heels = []
for wrestler in wrestlers:
current_wrestlers = deque([wrestler])
while current_wrestlers:
current_wrestler = current_wrestlers.popleft()
if current_wrestler.name not in seen:
seen.add(current_wrestler.name)
wrestlers_to_expand = deque(current_wrestler.rivals)
if current_wrestler.depth % 2 == 0:
should_append = True
for rival_wrestler in wrestlers_to_expand:
if rival_wrestler.name in bfs_babyfaces:
should_append = False
break
if should_append:
bfs_babyfaces.append(current_wrestler.name)
else:
should_append = True
for rival_wrestler in wrestlers_to_expand:
if rival_wrestler.name in bfs_heels:
should_append = False
break
if should_append:
bfs_heels.append(current_wrestler.name)
for rival_wrestler in wrestlers_to_expand:
rival_wrestler.depth = current_wrestler.depth + 1
current_wrestlers += wrestlers_to_expand
return bfs_babyfaces, bfs_heels
def get_wrestler_info_from_file(filename):
found_wrestlers = deque()
found_wrestler_indexes = {}
with open(filename, "r") as input_file:
lines = input_file.readlines()
current_line = 0
file_num_wrestlers = int(lines[current_line])
for i in range(file_num_wrestlers):
current_line += 1
wrestler_name = lines[current_line].strip("\n")
found_wrestlers.append(Wrestler(wrestler_name))
found_wrestler_indexes[wrestler_name] = len(found_wrestlers) - 1
current_line += 1
num_rivalries = int(lines[current_line])
for _ in range(num_rivalries):
current_line += 1
rival_1_name, rival_2_name = lines[current_line].strip("\n").split(" ")
rival_1_index = found_wrestler_indexes[rival_1_name]
rival_2_index = found_wrestler_indexes[rival_2_name]
found_wrestlers[rival_1_index].add_rival(found_wrestlers[rival_2_index])
found_wrestlers[rival_2_index].add_rival(found_wrestlers[rival_1_index])
return found_wrestlers
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Tool to determine which wrestlers are babyfaces or heels")
parser.add_argument("input_filename", help="Filename of wrestler information to use")
args = parser.parse_args()
all_wrestlers = get_wrestler_info_from_file(args.input_filename)
babyfaces, heels = wrestler_bfs(all_wrestlers)
num_wrestlers = len(all_wrestlers)
num_assigned = len(babyfaces) + len(heels)
if num_wrestlers == num_assigned:
print("Yes")
print("Babyfaces: {}".format(" ".join(babyfaces)))
print("Heels: {}".format(" ".join(heels)))
else:
print("No")

View File

@@ -0,0 +1,28 @@
10
A
B
C
D
E
V
W
X
Y
Z
10
A W
A V
A Z
B Z
B Y
C X
D W
E Z
E Y
E W
// Sample Output
Yes possible
Babyfaces : A B C D E
Heels : V W X Y Z

View File

@@ -0,0 +1,16 @@
6
Bear
Maxxx
Killer
Knight
Duke
Samson
6
Bear Samson
Bear Duke
Killer Bear
Samson Duke
Killer Duke
Maxxx Knight
// Impossible

View File

@@ -0,0 +1,18 @@
6
Bear
Maxxx
Killer
Knight
Duke
Samson
5
Bear Samson
Killer Bear
Samson Duke
Killer Duke
Maxxx Knight
// Sample Solution
Yes Possible
Babyfaces: Bear Maxx Duke
Heels: Killer Knight Samson

View File

@@ -0,0 +1,18 @@
5
Ace
Duke
Jax
Biggs
Stone
6
Ace Duke
Ace Biggs
Jax Duke
Stone Biggs
Stone Duke
Biggs Jax
// Sample Output:
Yes
Babyfaces: Ace Jax Stone
Heels: Biggs Duke

View File

@@ -0,0 +1,3 @@
To run this program, place the file bin.txt in the same directory, then run
python3 binpack.py

View File

@@ -0,0 +1,12 @@
3
10
6
5 10 2 5 4 4
20
19
9 10 2 1 7 3 3 3 3 14 6 5 2 8 6 4 6 2 6
10
20
4 4 4 4 4 4 4 4 4 4 6 6 6 6 6 6 6 6 6 6

View File

@@ -0,0 +1,121 @@
from time import time
from collections import deque
from copy import copy
INPUT_FILENAME = "bin.txt"
class BinPacker(object):
def __init__(self, bin_pack_test_case):
self._bin_size = bin_pack_test_case["bin_capacity"]
self._items = deque(list(bin_pack_test_case["items"]))
self._bins = []
self._run_time = 0
def _solve(self):
raise NotImplemented
def solve_and_time(self):
start_time = time() * 1000
self._solve()
self._run_time = (time() * 1000) - start_time
return len(self._bins), self._run_time
class FirstFit(BinPacker):
def _solve(self):
while self._items:
current_item = self._items.popleft()
item_placed = False
for bin_index in range(len(self._bins)):
new_sum = self._bins[bin_index] + current_item
if new_sum <= self._bin_size:
self._bins[bin_index] = new_sum
item_placed = True
break
if not item_placed:
self._bins.append(current_item)
class FirstFitDecreasing(FirstFit):
def _solve(self):
sorted_descending = list(self._items)
sorted_descending.sort(reverse=True)
self._items = deque(sorted_descending)
super(FirstFitDecreasing, self)._solve()
class BestFit(BinPacker):
def _solve(self):
while self._items:
current_item = self._items.popleft()
min_room_left_over = self._bin_size
best_index_sum = None
best_index = None
for bin_index in range(len(self._bins)):
new_sum = self._bins[bin_index] + current_item
bin_difference = self._bin_size - new_sum
if 0 <= bin_difference < min_room_left_over:
best_index = bin_index
best_index_sum = new_sum
min_room_left_over = bin_difference
if best_index is not None:
self._bins[best_index] = best_index_sum
else:
self._bins.append(current_item)
# print(self._bins)
def get_test_cases_from_file(filename):
input_test_cases = []
with open(filename, "r") as input_file:
file_lines = input_file.readlines()
current_line = 0
num_test_cases = int(file_lines[current_line])
for _ in range(num_test_cases):
current_test_case = {}
current_line += 1
current_test_case["bin_capacity"] = int(file_lines[current_line])
current_line += 1
num_items = int(file_lines[current_line])
current_line += 1
items_split = file_lines[current_line].split(" ")
current_test_case["items"] = [int(item_str) for item_str in items_split[:num_items]]
input_test_cases.append(current_test_case)
return input_test_cases
if __name__ == "__main__":
test_cases = get_test_cases_from_file(INPUT_FILENAME)
for test_index, test_case in enumerate(test_cases):
first_fit_num_bins, first_fit_run_time = FirstFit(test_case).solve_and_time()
first_fit_dec_num_bins, first_fit_dec_run_time = FirstFitDecreasing(test_case).solve_and_time()
best_fit_num_bins, best_fit_run_time = BestFit(test_case).solve_and_time()
print("Test Case {} First Fit: {}, {} ms. First Fit Decreasing {}, {} ms. Best Fit: {}, {} ms.".format(
test_index + 1,
first_fit_num_bins, first_fit_run_time,
first_fit_dec_num_bins, first_fit_dec_run_time,
best_fit_num_bins, best_fit_run_time
))

View File

@@ -0,0 +1,5 @@
To run...
python3 wolves_and_chickens.py startfile goalfile mode outputfile
Note that this MUST be run with python 3...

View File

@@ -0,0 +1,3 @@
Corwin Perren
I worked with no teammates...

View File

@@ -0,0 +1,411 @@
import argparse
import csv
from collections import deque
from copy import copy
from queue import PriorityQueue
from time import time
import sys
class BankState(object):
def __init__(self, chickens=0, wolves=0, has_boat=False):
self.chickens = chickens
self.wolves = wolves
self.has_boat = has_boat
def __eq__(self, other):
chickens_eq = self.chickens == other.chickens
wolves_eq = self.wolves == other.wolves
has_boat_eq = self.has_boat == other.has_boat
return chickens_eq and wolves_eq and has_boat_eq
def __hash__(self):
return hash((self.chickens, self.wolves, self.has_boat))
def __str__(self):
return "Chickens: {}, Wolves: {}, Has Boat: {}".format(self.chickens, self.wolves, self.has_boat)
def __copy__(self):
return type(self)(self.chickens, self.wolves, self.has_boat)
def valid_state(self):
return (self.wolves <= self.chickens or self.chickens == 0) and (self.wolves >= 0) and (self.chickens >= 0)
class GameState(object):
AVAILABLE_ACTIONS = [
{"chickens": 1, "wolves": 0},
{"chickens": 2, "wolves": 0},
{"chickens": 0, "wolves": 1},
{"chickens": 1, "wolves": 1},
{"chickens": 0, "wolves": 2},
]
def __init__(self, left_bank=None, right_bank=None, total_chickens=0, total_wolves=0):
self.left_bank = BankState() if left_bank is None else left_bank
self.right_bank = BankState() if right_bank is None else right_bank
self.total_chickens = total_chickens
self.total_wolves = total_wolves
def __eq__(self, other):
return self.left_bank == other.left_bank and self.right_bank == other.right_bank
def __hash__(self):
return hash((self.left_bank, self.right_bank))
def __str__(self):
return "[Left Bank -> {} | Right Bank -> {}]".format(self.left_bank, self.right_bank)
def __copy__(self):
return type(self)(
copy(self.left_bank), copy(self.right_bank), copy(self.total_chickens), copy(self.total_wolves)
)
def valid_state(self):
banks_valid = self.left_bank.valid_state() and self.right_bank.valid_state()
chickens_valid = (self.left_bank.chickens + self.right_bank.chickens) == self.total_chickens
wolves_valid = (self.left_bank.wolves + self.right_bank.wolves) == self.total_wolves
return banks_valid and chickens_valid and wolves_valid
def apply_action(self, action, left_to_right_bank=True):
if left_to_right_bank:
self.right_bank.chickens += action["chickens"]
self.right_bank.wolves += action["wolves"]
self.right_bank.has_boat = True
self.left_bank.chickens -= action["chickens"]
self.left_bank.wolves -= action["wolves"]
self.left_bank.has_boat = False
else:
self.right_bank.chickens -= action["chickens"]
self.right_bank.wolves -= action["wolves"]
self.right_bank.has_boat = False
self.left_bank.chickens += action["chickens"]
self.left_bank.wolves += action["wolves"]
self.left_bank.has_boat = True
def set_from_file(self, file_path):
with open(file_path, "r") as game_state_file:
read_csv = list(csv.reader(game_state_file))
left_bank_state, right_bank_state = read_csv[0], read_csv[1]
self.left_bank.chickens = int(left_bank_state[0])
self.left_bank.wolves = int(left_bank_state[1])
self.left_bank.has_boat = left_bank_state[2] == "1"
self.right_bank.chickens = int(right_bank_state[0])
self.right_bank.wolves = int(right_bank_state[1])
self.right_bank.has_boat = right_bank_state[2] == "1"
self.total_chickens = self.left_bank.chickens + self.right_bank.chickens
self.total_wolves = self.left_bank.wolves + self.right_bank.wolves
class Node(object):
def __init__(self, parent_node, game_state, path_cost, depth):
self.parent_node = parent_node
self.game_state = game_state
self.depth = depth
self.path_cost = path_cost
def __str__(self):
return "{} | {} | {}".format(self.game_state, self.depth, self.path_cost)
def __hash__(self):
return hash((self.parent_node, self.game_state, self.depth, self.path_cost))
def __lt__(self, other):
return hash(self) < hash(other)
class GameSolver(object):
def __init__(self, start_state, goal_state):
self.start_state = start_state
self.goal_state = goal_state
self.expanded_nodes_count = 0
self.fringe = deque()
self.solution = None
def solution_string(self):
solutions_strings = deque()
sentinel = self.solution
while sentinel is not None:
solutions_strings.appendleft(str(sentinel.game_state))
sentinel = sentinel.parent_node
return "\n".join(solutions_strings)
def show_and_save_solution(self, file_path):
if solver.solution:
solution_string = self.solution_string()
print(solution_string)
with open(file_path, "w") as output_file:
output_file.write(solution_string)
output_file.write("\n")
print()
print("{} nodes were expanded for a solution with a depth of {}".format(
solver.expanded_nodes_count,
solver.solution.depth)
)
else:
print("No solution found in {} expanded nodes".format(solver.expanded_nodes_count))
@staticmethod
def valid_states_from_current_node(current_node):
valid_states = []
current_state = current_node.game_state
left_to_right_bank = current_state.left_bank.has_boat
for action in current_state.AVAILABLE_ACTIONS:
test_state = copy(current_state)
test_state.apply_action(action, left_to_right_bank)
if test_state.valid_state():
valid_states.append(test_state)
return valid_states
def is_goal(self, node):
return node.game_state == self.goal_state
def expand(self, node):
pass
def solve(self):
pass
class BFSGameSolver(GameSolver):
def expand(self, current_node):
successors = deque()
new_path_cost = current_node.path_cost + 1
new_depth = current_node.depth + 1
for state in self.valid_states_from_current_node(current_node):
successors.append(Node(current_node, state, new_path_cost, new_depth))
return successors
def solve(self):
closed = set()
self.fringe.append(Node(None, self.start_state, 0, 0))
while True:
if not self.fringe:
self.solution = None
return
current_node = self.fringe.popleft()
current_state = current_node.game_state
if self.is_goal(current_node):
self.solution = current_node
return
self.expanded_nodes_count += 1
if current_state not in closed:
closed.add(current_state)
self.fringe += self.expand(current_node)
class DFSGameSolver(GameSolver):
def expand(self, current_node):
successors = deque()
new_path_cost = current_node.path_cost + 1
new_depth = current_node.depth + 1
for state in reversed(self.valid_states_from_current_node(current_node)):
successors.append(Node(current_node, state, new_path_cost, new_depth))
return successors
def solve(self):
closed = set()
self.fringe.append(Node(None, self.start_state, 0, 0))
while True:
if not self.fringe:
self.solution = None
return
current_node = self.fringe.pop()
current_state = current_node.game_state
if self.is_goal(current_node):
self.solution = current_node
return
self.expanded_nodes_count += 1
if current_state not in closed:
closed.add(current_state)
self.fringe += self.expand(current_node)
class IDDFSGameSolver(GameSolver):
def __init__(self, start_state, goal_state, starting_depth=1):
super(IDDFSGameSolver, self).__init__(start_state, goal_state)
self.current_depth = starting_depth
self.max_depth = 1000000
def expand(self, current_node):
successors = deque()
if current_node.depth == self.current_depth:
return successors
new_path_cost = current_node.path_cost + 1
new_depth = current_node.depth + 1
for state in reversed(self.valid_states_from_current_node(current_node)):
successors.append(Node(current_node, state, new_path_cost, new_depth))
return successors
def solve(self):
closed = set()
start_state_node = Node(None, self.start_state, 0, 0)
self.fringe.append(start_state_node)
while True:
if not self.fringe:
if self.current_depth != self.max_depth:
self.current_depth += 1
closed = set()
self.fringe.append(Node(None, self.start_state, 0, 0))
else:
self.solution = None
return
current_node = self.fringe.pop()
current_state = current_node.game_state
if self.is_goal(current_node):
self.solution = current_node
return
self.expanded_nodes_count += 1
if current_state not in closed:
closed.add(current_state)
self.fringe += self.expand(current_node)
class AStarGameSolver(GameSolver):
def __init__(self, start_state, goal_state):
super(AStarGameSolver, self).__init__(start_state, goal_state)
self.fringe = PriorityQueue()
self.left_to_right_chickens = self.goal_state.left_bank.chickens < self.goal_state.right_bank.chickens
self.left_to_right_wolves = self.goal_state.left_bank.wolves < self.goal_state.right_bank.wolves
def astar_heuristic(self, current_node):
current_state = current_node.game_state
if self.left_to_right_chickens:
min_moves_chickens = (self.goal_state.right_bank.chickens - current_state.right_bank.chickens) / 2.0
else:
min_moves_chickens = (self.goal_state.left_bank.chickens - current_state.left_bank.chickens) / 2.0
if self.left_to_right_wolves:
min_moves_wolves = (self.goal_state.right_bank.wolves - current_state.right_bank.wolves) / 2.0
else:
min_moves_wolves = (self.goal_state.left_bank.wolves - current_state.left_bank.wolves) / 2.0
return min_moves_chickens + min_moves_wolves
def astar_evaluator(self, current_node):
return self.astar_heuristic(current_node) + current_node.path_cost
def expand(self, current_node):
new_path_cost = current_node.path_cost + 1
new_depth = current_node.depth + 1
for state in self.valid_states_from_current_node(current_node):
new_node = Node(current_node, state, new_path_cost, new_depth)
evaluated_priority = self.astar_evaluator(new_node)
self.fringe.put((evaluated_priority, new_node))
def solve(self):
closed = set()
self.fringe.put((1, Node(None, self.start_state, 0, 0)))
while True:
if not self.fringe:
self.solution = None
return
_, current_node = self.fringe.get()
current_state = current_node.game_state
if self.is_goal(current_node):
self.solution = current_node
return
self.expanded_nodes_count += 1
if current_state not in closed:
closed.add(current_state)
self.expand(current_node)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Solves the chicken and wolves game")
parser.add_argument("initial_state_file", help="Filename of the state file in the current directory")
parser.add_argument("goal_state_file", help="Filename of the goal state file in the current directory")
parser.add_argument("mode", choices=["bfs", "dfs", "iddfs", "astar"], help="Mode to run the solver with")
parser.add_argument("output_file", help="Desired filename of the output file in the current directory")
args = parser.parse_args()
print("Starting chickens and wolves game solver\n")
sys.setrecursionlimit(10000)
starting_state = GameState()
ending_state = GameState()
starting_state.set_from_file(args.initial_state_file)
ending_state.set_from_file(args.goal_state_file)
if args.mode == "bfs":
print("Running bfs on start_state {} with goal {}".format(starting_state, ending_state))
solver = BFSGameSolver(starting_state, ending_state)
elif args.mode == "dfs":
print("Running dfs on start_state {} with goal {}".format(starting_state, ending_state))
solver = DFSGameSolver(starting_state, ending_state)
elif args.mode == "iddfs":
print("Running iddfs on start_state {} with goal {}".format(starting_state, ending_state))
solver = IDDFSGameSolver(starting_state, ending_state)
else:
print("Running astar on start_state {} with goal {}".format(starting_state, ending_state))
solver = AStarGameSolver(starting_state, ending_state)
print()
start_time = time()
solver.solve()
end_time = time() - start_time
solver.show_and_save_solution(args.output_file)
print("Solve ran in {} seconds".format(end_time))

View File

@@ -0,0 +1,5 @@
To run, use...
python3 othello.py human minimax
You must use python3!

View File

@@ -0,0 +1,106 @@
#include <iostream>
#include <assert.h>
#include "Board.h"
void Board::delete_grid() {
for (int c = 0; c < num_cols; c++) {
delete[] grid[c];
}
delete[] grid;
}
Board::Board(int cols, int rows) :
num_cols(cols), num_rows(rows) {
grid = new char*[num_cols];
for (int c = 0; c < num_cols; c++) {
grid[c] = new char[num_rows];
for (int r = 0; r < num_rows; r++) {
grid[c][r] = EMPTY;
}
}
}
Board::Board(const Board& other) {
num_cols = other.num_cols;
num_rows = other.num_rows;
grid = new char*[num_cols];
for (int c = 0; c < num_cols; c++) {
grid[c] = new char[num_rows];
for (int r = 0; r < num_rows; r++) {
grid[c][r] = other.grid[c][r];
}
}
}
Board& Board::operator=(const Board& rhs) {
if (this == &rhs) {
return *this;
} else {
num_cols = rhs.num_cols;
num_rows = rhs.num_rows;
if (grid != NULL) {
delete_grid();
}
grid = new char*[num_cols];
for (int c = 0; c < num_cols; c++) {
grid[c] = new char[num_rows];
for (int r = 0; r < num_rows; r++) {
grid[c][r] = rhs.grid[c][r];
}
}
return *this;
}
}
Board::~Board() {
delete_grid();
}
char Board::get_cell(int col, int row) const {
assert((col >= 0) && (col < num_cols));
assert((row >= 0) && (row < num_rows));
return grid[col][row];
}
void Board::set_cell(int col, int row, char val) {
assert((col >= 0) && (col < num_cols));
assert((row >= 0) && (row < num_rows));
grid[col][row] = val;
}
bool Board::is_cell_empty(int col, int row) const {
if (grid[col][row] == EMPTY) {
return true;
} else {
return false;
}
}
bool Board::is_in_bounds(int col, int row) const {
if ((col >= 0) && (col < num_cols) && (row >= 0) && (row < num_rows)) {
return true;
} else {
return false;
}
}
void Board::display() const {
for (int r = get_num_rows() - 1; r >= 0; r--) {
std::cout << r << ":| ";
for (int c = 0; c < get_num_cols(); c++) {
std::cout << get_cell(c, r) << " ";
}
std::cout << std::endl;
}
std::cout << " -";
for (int c = 0; c < get_num_cols(); c++) {
std::cout << "--";
}
std::cout << "\n";
std::cout << " ";
for (int c = 0; c < get_num_cols(); c++) {
std::cout << c << " ";
}
std::cout << "\n\n";
}

View File

@@ -0,0 +1,112 @@
/**
* Board class
*/
#ifndef BOARD_H
#define BOARD_H
#define EMPTY '.'
/** Directions enum for the Othello Board */
enum Direction {N,NE,E,SE,S,SW,W,NW};
/**
* This is a generic board class that serves as a wrapper for a 2D array.
* It will be used for board games like Othello, Tic-Tac-Toe and Connect 4.
*/
class Board {
public:
/**
* @param cols The number of columns in the board
* @param rows The number of rows in the board
* Constructor that creates a 2D board with the given number of columns
* and rows
*/
Board(int cols, int rows);
/**
* @param other A reference to the Board object being copied
* This is the copy constructor for the Board class
*/
Board(const Board& other);
/**
* Destructor for the Board class
*/
~Board();
/**
* @param rhs The "right-hand side" for the assignment ie. the object
* you are copying from.
* @return Returns a reference to the "left-hand side" of the assignment ie.
* the object the values are assigned to
* Overloaded assignment operator for the Board class
*/
Board& operator=(const Board& rhs);
/**
* @return Returns the number of rows in the board
* An accessor that gets the number of rows in the board
*/
int get_num_rows() const { return num_rows; }
/**
* @return Returns the number of columns in the board
* An accessor to get the number of columns in the board
*/
int get_num_cols() const { return num_cols; }
/**
* @param col The column of the cell you want to retrieve
* @param row The row of the cell you want to retrieve
* @return Returns the character at the specified cell
* Returns the character at the specified column and row
*/
char get_cell(int col, int row) const;
/**
* @param col The column of the cell you want to set
* @param row The row of the cell you want to set
* @param val The value you want to set the cell to
* Sets the cell at the given row and column to the specified value
*/
void set_cell(int col, int row, char val);
/**
* @param col The column of the cell you are checking
* @param row The row of the cell you are checking
* @return true if the cell is empty and false otherwise
*/
bool is_cell_empty(int col, int row) const;
/**
* @param col The column value for the in-bounds check
* @param row The row value for the in-bounds check
* @return true if the column is >= 0 and < num_cols and if the row is >= 0 and < num_rows. Returns false otherwise.
*/
bool is_in_bounds(int col, int row) const;
/**
* Prints the board to screen. Should probably have overloaded >> but oh well.
*/
void display() const;
protected:
/** The number of rows in the board */
int num_rows;
/** The number of columns in the board */
int num_cols;
/** A 2D array of chars representing the board */
char** grid;
/**
* Deletes the 2D array.
*/
void delete_grid();
};
#endif

View File

@@ -0,0 +1,137 @@
#include <iostream>
#include <cstring>
#include <stdlib.h>
#include "GameDriver.h"
GameDriver::GameDriver(char* p1type, char* p2type, int num_rows, int num_cols) {
if( strcmp(p1type,"human") == 0 ) {
p1 = new HumanPlayer('X');
} else if( strcmp(p1type,"minimax") == 0 ) {
p1 = new MinimaxPlayer('X');
} else {
std::cout << "Invalid type of player for player 1" << std::endl;
}
if( strcmp(p2type,"human") == 0 ) {
p2 = new HumanPlayer('O');
} else if( strcmp(p2type,"minimax") == 0 ) {
p2 = new MinimaxPlayer('O');
} else {
std::cout << "Invalid type of player for player 2" << std::endl;
}
board = new OthelloBoard(num_rows, num_cols,p1->get_symbol(), p2->get_symbol());
board->initialize();
}
GameDriver::GameDriver(const GameDriver& other) {
board = new OthelloBoard(*(other.board));
p1 = other.p1->clone();
p2 = other.p2->clone();
}
GameDriver& GameDriver::operator=(const GameDriver& rhs) {
if (this == &rhs) {
return *this;
} else {
if( board != NULL ) {
delete board;
}
board = new OthelloBoard(*(rhs.board));
if( p1 != NULL ) {
delete p1;
p1 = rhs.p1->clone();
}
if( p2 != NULL ) {
delete p2;
p2 = rhs.p2->clone();
}
return *this;
}
}
GameDriver::~GameDriver() {
delete board;
delete p1;
delete p2;
}
void GameDriver::display() {
std::cout << std::endl << "Player 1 (" << p1->get_symbol() << ") score: "
<< board->count_score(p1->get_symbol()) << std::endl;
std::cout << "Player 2 (" << p2->get_symbol() << ") score: "
<< board->count_score(p2->get_symbol()) << std::endl << std::endl;
board->display();
}
void GameDriver::process_move(Player* curr_player, Player* opponent) {
int col = -1;
int row = -1;
bool invalid_move = true;
while (invalid_move) {
curr_player->get_move(board, col, row);
if (!board->is_legal_move(col, row, curr_player->get_symbol())) {
std::cout << "Invalid move.\n";
continue;
} else {
std::cout << "Selected move: col = " << col << ", row = " << row << std::endl;
board->play_move(col,row,curr_player->get_symbol());
invalid_move = false;
}
}
}
void GameDriver::run() {
int toggle = 0;
int cant_move_counter=0;
Player* current = p1;
Player* opponent = p2;
display();
std::cout << "Player 1 (" << p1->get_symbol() << ") move:\n";
while (1) {
if( board->has_legal_moves_remaining(current->get_symbol())) {
cant_move_counter = 0;
process_move(current, opponent);
display();
} else {
std::cout << "Can't move\n";
if( cant_move_counter == 1 ) {
// Both players can't move, game over
break;
} else {
cant_move_counter++;
}
}
toggle = (toggle + 1) % 2;
if (toggle == 0) {
current = p1;
opponent = p2;
std::cout << "Player 1 (" << p1->get_symbol() << ") move:\n";
} else {
current = p2;
opponent = p1;
std::cout << "Player 2 (" << p2->get_symbol() << ") move:\n";
}
}
if ( board->count_score(p1->get_symbol()) == board->count_score(p2->get_symbol())) {
std::cout << "Tie game" << std::endl;
} else if ( board->count_score(p1->get_symbol()) > board->count_score(p2->get_symbol())) {
std::cout << "Player 1 wins" << std::endl;
} else {
std::cout << "Player 2 wins" << std::endl;
}
}
int main(int argc, char** argv) {
if( argc != 3 ) {
std::cout << "Usage: othello <player1 type> <player2 type>" << std::endl;
exit(-1);
}
GameDriver* game = new GameDriver(argv[1],argv[2],4,4);
game->run();
return 0;
}

View File

@@ -0,0 +1,72 @@
#ifndef GAMEDRIVER_H
#define GAMEDRIVER_H
#include "OthelloBoard.h"
#include "Player.h"
#include "HumanPlayer.h"
#include "MinimaxPlayer.h"
/**
* This class represents the main driver for the game. The driver controls the turn-based behavior
* of the game.
*/
class GameDriver {
public:
/**
* @param p1type A string (human or minimax) describing the type of Player1
* @param p2type A string (human or minimax) describing the type of Player2
* @param num_rows The number of rows in Othello
* @param num_cols The number of columns in Othello
* This is the constructor for the GameDriver
*/
GameDriver(char* p1type, char* p2type, int num_rows, int num_cols);
/**
* @param other The GameDriver object you are copying from
* Copy constructor for the GameDriver class
*/
GameDriver(const GameDriver& other);
/**
* @param rhs The right-hand side of the assignment
* @return The left-hand side of the assignment
* Overloaded assignment operator for the GameDriver class.
*/
GameDriver& operator=(const GameDriver& rhs);
/**
* Destructor for the GameDriver class
*/
virtual ~GameDriver();
/**
* Runs the game and keeps track of the turns.
*/
void run();
/**
* Displays the game.
*/
void display();
private:
/** Internal Othello board object */
OthelloBoard* board;
/** Player 1 object */
Player* p1;
/** Player 2 object */
Player* p2;
/**
* @param curr_player A pointer to the player that has the current move
* @param opponent A pointer to the opponent for the player that has the current move
* Handles actually making a move in the game.
*/
void process_move(Player* curr_player, Player* opponent);
};
#endif

View File

@@ -0,0 +1,22 @@
#include <iostream>
#include "HumanPlayer.h"
HumanPlayer::HumanPlayer(char symb) : Player(symb) {
}
HumanPlayer::~HumanPlayer() {
}
void HumanPlayer::get_move(OthelloBoard* b, int& col, int& row) {
std::cout << "Enter col: ";
std::cin >> col;
std::cout << "Enter row: ";
std::cin >> row;
}
HumanPlayer* HumanPlayer::clone() {
HumanPlayer *result = new HumanPlayer(symbol);
return result;
}

View File

@@ -0,0 +1,41 @@
#ifndef HUMAN_PLAYER
#define HUMAN_PLAYER
#include "Player.h"
#include "OthelloBoard.h"
/**
* This class represents a human player
*/
class HumanPlayer : public Player {
public:
/**
* @symb The symbol used for the human player's pieces
* The constructor for the HumanPlayer class
*/
HumanPlayer(char symb);
/**
* Destructor
*/
virtual ~HumanPlayer();
/**
* @param b The current board for the game.
* @param col Holds the return value for the column of the move
* @param row Holds the return value for the row of the move
* Obtains the (col,row) coordinates for the current move
*/
void get_move(OthelloBoard* b, int& col, int& row);
/**
* @return A pointer to a copy of the HumanPlayer object
* This is a virtual copy constructor
*/
HumanPlayer *clone();
private:
};
#endif

View File

@@ -0,0 +1,14 @@
CXX = g++
CXXFLAGS = -std=c++0x
SRCS = Board.cpp OthelloBoard.cpp Player.cpp HumanPlayer.cpp GameDriver.cpp MinimaxPlayer.cpp
HEADERS = Board.h OthelloBoard.h Player.h HumanPlayer.h GameDriver.h MinimaxPlayer.h
OBJS = Board.o OthelloBoard.o Player.o HumanPlayer.o GameDriver.o MinimaxPlayer.o
all: ${SRCS} ${HEADERS}
${CXX} ${CXXFLAGS} ${SRCS} -o othello
${OBJS}: ${SRCS}
${CXX} -c $(@:.o=.cpp)
clean:
rm -f *.o othello

View File

@@ -0,0 +1,29 @@
/*
* MinimaxPlayer.cpp
*
* Created on: Apr 17, 2015
* Author: wong
*/
#include <iostream>
#include <assert.h>
#include "MinimaxPlayer.h"
using std::vector;
MinimaxPlayer::MinimaxPlayer(char symb) :
Player(symb) {
}
MinimaxPlayer::~MinimaxPlayer() {
}
void MinimaxPlayer::get_move(OthelloBoard* b, int& col, int& row) {
// To be filled in by you
}
MinimaxPlayer* MinimaxPlayer::clone() {
MinimaxPlayer* result = new MinimaxPlayer(symbol);
return result;
}

View File

@@ -0,0 +1,50 @@
/*
* MinimaxPlayer.h
*
* Created on: Apr 17, 2015
* Author: wong
*/
#ifndef MINIMAXPLAYER_H
#define MINIMAXPLAYER_H
#include "OthelloBoard.h"
#include "Player.h"
#include <vector>
/**
* This class represents an AI player that uses the Minimax algorithm to play the game
* intelligently.
*/
class MinimaxPlayer : public Player {
public:
/**
* @param symb This is the symbol for the minimax player's pieces
*/
MinimaxPlayer(char symb);
/**
* Destructor
*/
virtual ~MinimaxPlayer();
/**
* @param b The board object for the current state of the board
* @param col Holds the return value for the column of the move
* @param row Holds the return value for the row of the move
*/
void get_move(OthelloBoard* b, int& col, int& row);
/**
* @return A copy of the MinimaxPlayer object
* This is a virtual copy constructor
*/
MinimaxPlayer* clone();
private:
};
#endif

View File

@@ -0,0 +1,179 @@
/*
* OthelloBoard.cpp
*
* Created on: Apr 18, 2015
* Author: wong
*/
#include <assert.h>
#include "OthelloBoard.h"
OthelloBoard::OthelloBoard(int cols, int rows, char p1_symb, char p2_symb) :
Board(cols, rows), p1_symbol(p1_symb), p2_symbol(p2_symb) {
}
OthelloBoard::OthelloBoard(const OthelloBoard& other) :
Board(other), p1_symbol(other.p1_symbol), p2_symbol(other.p2_symbol) {
}
OthelloBoard::~OthelloBoard() {
}
void OthelloBoard::initialize() {
set_cell(num_cols / 2 - 1, num_rows / 2 - 1, p1_symbol);
set_cell(num_cols / 2, num_rows / 2, p1_symbol);
set_cell(num_cols / 2 - 1, num_rows / 2, p2_symbol);
set_cell(num_cols / 2, num_rows / 2 - 1, p2_symbol);
}
OthelloBoard& OthelloBoard::operator=(const OthelloBoard& rhs) {
Board::operator=(rhs);
p1_symbol = rhs.p1_symbol;
p2_symbol = rhs.p2_symbol;
return *this;
}
void OthelloBoard::set_coords_in_direction(int col, int row, int& next_col,
int& next_row, int dir) const {
switch (dir) {
case N:
next_col = col;
next_row = row + 1;
break;
case NE:
next_col = col + 1;
next_row = row + 1;
break;
case E:
next_col = col + 1;
next_row = row;
break;
case SE:
next_col = col + 1;
next_row = row - 1;
break;
case S:
next_col = col;
next_row = row - 1;
break;
case SW:
next_col = col - 1;
next_row = row - 1;
break;
case W:
next_col = col - 1;
next_row = row;
break;
case NW:
next_col = col - 1;
next_row = row + 1;
break;
default:
assert("Invalid direction");
}
}
bool OthelloBoard::check_endpoint(int col, int row, char symbol, int dir,
bool match_symbol) const {
int next_row = -1;
int next_col = -1;
if (!is_in_bounds(col, row) || is_cell_empty(col, row)) {
return false;
} else {
if (match_symbol) {
if (get_cell(col, row) == symbol) {
return true;
} else {
set_coords_in_direction(col, row, next_col, next_row, dir);
return check_endpoint(next_col, next_row, symbol, dir,
match_symbol);
}
} else {
if (get_cell(col, row) == symbol) {
return false;
} else {
set_coords_in_direction(col, row, next_col, next_row, dir);
return check_endpoint(next_col, next_row, symbol, dir,
!match_symbol);
}
}
}
}
bool OthelloBoard::is_legal_move(int col, int row, char symbol) const {
bool result = false;
int next_row = -1;
int next_col = -1;
if (!is_in_bounds(col, row) || !is_cell_empty(col, row)) {
return result;
}
for (int d = N; d <= NW; d++) {
set_coords_in_direction(col, row, next_col, next_row, d);
if (check_endpoint(next_col, next_row, symbol, d, false)) {
result = true;
break;
}
}
return result;
}
int OthelloBoard::flip_pieces_helper(int col, int row, char symbol, int dir) {
int next_row = -1;
int next_col = -1;
if (get_cell(col, row) == symbol) {
return 0;
} else {
set_cell(col, row, symbol);
set_coords_in_direction(col, row, next_col, next_row, dir);
return 1 + flip_pieces_helper(next_col, next_row, symbol, dir);
}
}
int OthelloBoard::flip_pieces(int col, int row, char symbol) {
int pieces_flipped = 0;
int next_row = -1;
int next_col = -1;
assert(is_in_bounds(col, row));
for (int d = N; d <= NW; d++) {
set_coords_in_direction(col, row, next_col, next_row, d);
if (check_endpoint(next_col, next_row, symbol, d, false)) {
pieces_flipped += flip_pieces_helper(next_col, next_row, symbol, d);
}
}
return pieces_flipped;
}
bool OthelloBoard::has_legal_moves_remaining(char symbol) const {
for (int c = 0; c < num_cols; c++) {
for (int r = 0; r < num_rows; r++) {
if (is_cell_empty(c, r) && is_legal_move(c, r, symbol)) {
return true;
}
}
}
return false;
}
int OthelloBoard::count_score(char symbol) const {
int score = 0;
for (int c = 0; c < num_cols; c++) {
for (int r = 0; r < num_rows; r++) {
if (grid[c][r] == symbol) {
score++;
}
}
}
return score;
}
void OthelloBoard::play_move(int col, int row, char symbol) {
set_cell(col, row, symbol);
flip_pieces(col, row, symbol);
}

View File

@@ -0,0 +1,152 @@
/*
* OthelloBoard.h
*
* Created on: Apr 18, 2015
* Author: wong
*/
#ifndef OTHELLOBOARD_H_
#define OTHELLOBOARD_H_
#include "Board.h"
/**
* This class is a specialized version of the Board class for Othello. The OthelloBoard
* class respects the rules of Othello and also keeps track of the symbols for Player
* 1 and Player 2.
*/
class OthelloBoard : public Board {
public:
/**
* @cols The number of columns in the game of Othello
* @rows The number of rows in the game of Othello
* @p1_symbol The symbol used for Player 1's pieces on the board
* @p2_symbol The symbol used for Player 2's pieces on the board
* This is a constructor for an OthelloBoard clas.
*/
OthelloBoard(int cols, int rows, char p1_symbol, char p2_symbol);
/**
* @param other The OthelloBoard object you are copying from.
* This is the copy constructor for the OthelloBoard class.
*/
OthelloBoard(const OthelloBoard& other);
/**
* The destructor for the OthelloBoard class.
*/
virtual ~OthelloBoard();
/**
* Initializes the Othello board to the starting position of the pieces
* for Players 1 and 2
*/
void initialize();
/**
* @param rhs The right-hand side object of the assignment
* @return The left-hand side object of the assignment
* This is the overloaded assignment operator for the OthelloBoard class
*/
OthelloBoard& operator=(const OthelloBoard& rhs);
/**
* @param col The column for where your piece goes
* @param row The row for where your piece goes
* @return true if the move is legal, false otherwise.
* Checks the legality of a move that places a piece at the specified col and
* row.
*/
bool is_legal_move(int col, int row, char symbol) const;
/**
* @param symbol This is the symbol for the current player.
* @param col The column for where your piece goes
* @param row The row for where your piece goes
* Flips the in-between pieces once you put down a piece the specified
* col and row position. The symbol argument specifies who the
* current move belongs to.
*/
int flip_pieces(int col, int row, char symbol);
/**
* @param symbol This symbol specifies the symbol for the current player (i.e.
* who the current move belongs to)
* @return true if there are still moves remaining, false otherwise
* Checks if the game is over.
*/
bool has_legal_moves_remaining(char symbol) const;
/**
* @param symbol The symbol representing a particular player.
* Returns the score for the player with the specified symbol.
*/
int count_score(char symbol) const;
/**
* @param col The column where the piece goes
* @param row The row where the piece goes
* Plays the move by placing a piece, with the given symbol, down at the specified
* col and row. Then, any pieces sandwiched in between the two endpoints are flipped.
*/
void play_move(int col, int row, char symbol);
/**
* @return Returns the symbol for Player 1 (the maximizing player)'s pieces
* Returns the symbol for Player 1's pieces
*/
char get_p1_symbol() { return p1_symbol; }
/**
* @return Returns the symbol for Player 2 (the minimizing player)'s pieces
* Returns the symbol for Player 2's pieces
*/
char get_p2_symbol() { return p2_symbol; }
private:
/** The symbol for Player 1's pieces */
char p1_symbol;
/** The symbol for Player 2's pieces */
char p2_symbol;
/**
* @param col The column of the starting point
* @param row The row of the starting point
* @param next_col The return value for the column
* @param next_row The return value for the row
* @param dir The direction you want to move
* Sets the coordinates of next_col and next_row to be the coordinates if you were
* moving in the direction specified by the argument dir starting at position (col,row)
*/
void set_coords_in_direction(int col, int row, int& next_col, int& next_row, int dir) const;
/**
* @param col The column of the starting point
* @param row The row of the starting point
* @param symbol The symbol of the current player. You will match (or not match) this symbol
* at the endpoint
* @param dir The direction you are moving in
* @param match_symbol If true, it will return true if the arg symbol matches the endpoint. If false,
* it will return true if the arg symbol doesn't match the endpoint.
* If you start at (col,row) and move in direction dir, this function will check the endpoint
* of a trail of pieces. If match_symbol is true, it will return true if the endpoint matches
* the argument symbol (and false otherwise). If match_symbol is false, it will return true
* if the endpoint doesn't match the argument symbol (and false otherwise).
*/
bool check_endpoint(int col, int row, char symbol, int dir,
bool match_symbol) const;
/**
* @param col The column of the starting point
* @param row The row of the starting point
* @param symbol This is the symbol at the endpoint that terminates the row of pieces flipped
* @param dir The direction you are moving
* This is a helper function for the recursive flip_pieces function.
*/
int flip_pieces_helper(int col, int row, char symbol, int dir);
};
#endif /* OTHELLOBOARD_H_ */

View File

@@ -0,0 +1,9 @@
#include "Player.h"
Player::Player(char symb) : symbol(symb) {
}
Player::~Player() {
}

View File

@@ -0,0 +1,50 @@
/**
* Player class
*/
#ifndef PLAYER_H
#define PLAYER_H
#include "OthelloBoard.h"
/**
* This is an abstract base class for a Player
*/
class Player {
public:
/**
* @param symb The symbol for the player's pieces
*/
Player(char symb);
/**
* Destructor
*/
virtual ~Player();
/**
* @return The player's symbol
* Gets the symbol for the player's pieces
*/
char get_symbol() { return symbol; }
/**
* @param b The current board
* @param col Holds the column of the player's move
* @param row Holds the row of the player's move
* Gets the next move for the player
*/
virtual void get_move(OthelloBoard* b, int& col, int& row) = 0;
/**
* @return A copy of the Player object
* Virtual copy constructor
*/
virtual Player* clone() = 0;
protected:
/** The symbol for the player's pieces*/
char symbol;
};
#endif

View File

@@ -0,0 +1,328 @@
import argparse
import math
from copy import deepcopy
class Player:
def __init__(self, player_number, board_symbol):
self._player_number = player_number
self._board_symbol = board_symbol
@property
def board_symbol(self):
return self._board_symbol
@property
def player_number(self):
return self._player_number
def get_move(self, board):
raise NotImplementedError
class HumanPlayer(Player):
def __init__(self, player_number, board_symbol):
super(HumanPlayer, self).__init__(player_number, board_symbol)
def get_move(self, _):
valid_input = False
column = None
row = None
while not valid_input:
try:
column = int(input("Enter Column: "))
row = int(input("Enter Row: "))
valid_input = True
except ValueError:
print("Value entered was not an integer, please input column and row again...")
return column, row
class MinimaxPlayer(Player):
def __init__(self, player_number, board_symbol):
super(MinimaxPlayer, self).__init__(player_number, board_symbol)
def utility(self, board, player_symbol):
if player_symbol == "X":
return board.count_score("O") - board.count_score("X")
else:
return board.count_score("X") - board.count_score("O")
def successors(self, board, player_symbol):
successors = []
for row in range(board.num_rows):
for column in range(board.num_columns):
if board.cell_empty(column, row):
if board.is_legal_move(column, row, player_symbol):
successors.append((column, row))
return successors
def minimax_max_value(self, board, current_player_symbol):
if not board.has_legal_moves_remaining(current_player_symbol):
return self.utility(board, current_player_symbol), (None, None)
best_found_value = -math.inf, (None, None)
for successor in self.successors(board, current_player_symbol):
new_board = deepcopy(board)
new_board.play_move(*successor, current_player_symbol)
next_player_symbol = "O" if current_player_symbol == "X" else "X"
new_board_minimax = self.minimax_min_value(new_board, next_player_symbol)
if new_board_minimax[0] > best_found_value[0]:
best_found_value = new_board_minimax[0], successor
return best_found_value
def minimax_min_value(self, board, current_player_symbol):
if not board.has_legal_moves_remaining(current_player_symbol):
return self.utility(board, current_player_symbol), (None, None)
best_found_value = math.inf, (None, None)
for successor in self.successors(board, current_player_symbol):
new_board = deepcopy(board)
new_board.play_move(*successor, current_player_symbol)
next_player_symbol = "O" if current_player_symbol == "X" else "X"
new_board_minimax = self.minimax_max_value(new_board, next_player_symbol)
if new_board_minimax[0] < best_found_value[0]:
best_found_value = new_board_minimax[0], successor
return best_found_value
def minimax_decision(self, board, current_player_symbol):
minimax_result = self.minimax_max_value(board, current_player_symbol)
return minimax_result[1]
def get_move(self, board):
return self.minimax_decision(board, self.board_symbol)
class OthelloBoard:
EMPTY = "."
DIRECTIONS = {
"N": {"column": 0, "row": 1},
"NE": {"column": 1, "row": 1},
"E": {"column": 1, "row": 0},
"SE": {"column": 1, "row": -1},
"S": {"column": 0, "row": -1},
"SW": {"column": -1, "row": -1},
"W": {"column": -1, "row": 0},
"NW": {"column": -1, "row": 1},
}
def __init__(self, num_columns, num_rows, player_1_board_symbol, player_2_board_symbol):
self._columns = num_columns
self._rows = num_rows
self.grid = [[self.EMPTY for _ in range(self.num_rows)] for _ in range(self.num_columns)]
self.set_cell(self.num_columns // 2, self.num_rows // 2, player_1_board_symbol)
self.set_cell(self.num_columns // 2 - 1, self.num_rows // 2 - 1, player_1_board_symbol)
self.set_cell(self.num_columns // 2 - 1, self.num_rows // 2, player_2_board_symbol)
self.set_cell(self.num_columns // 2, self.num_rows // 2 - 1, player_2_board_symbol)
self.display()
@property
def num_columns(self):
return self._columns
@property
def num_rows(self):
return self._rows
def in_bounds(self, column, row):
return (0 <= column < self.num_columns) and (0 <= row < self.num_rows)
def get_cell(self, column, row):
assert self.in_bounds(column, row)
return self.grid[row][column]
def set_cell(self, column, row, value):
assert self.in_bounds(column, row)
self.grid[row][column] = value
def cell_empty(self, column, row):
assert self.in_bounds(column, row)
return self.grid[row][column] == self.EMPTY
def display(self):
for row_index in reversed(range(self.num_rows)):
print("{}:| ".format(row_index), end="")
for column_index in range(self.num_rows):
print("{} ".format(self.get_cell(column_index, row_index)), end="")
print()
print(" -", end="")
for _ in range(self.num_columns):
print("--", end="")
print()
print(" ", end="")
for column_index in range(self.num_columns):
print("{} ".format(column_index), end="")
print("\n")
def set_coordinates_in_direction(self, column, row, direction):
direction_offsets = self.DIRECTIONS[direction]
return column + direction_offsets["column"], row + direction_offsets["row"]
def check_endpoint(self, column, row, player_symbol, direction, match_symbol):
if not self.in_bounds(column, row) or self.cell_empty(column, row):
return False
if match_symbol:
if self.get_cell(column, row) == player_symbol:
return True
else:
next_column, next_row = self.set_coordinates_in_direction(column, row, direction)
return self.check_endpoint(next_column, next_row, player_symbol, direction, match_symbol)
else:
if self.get_cell(column, row) == player_symbol:
return False
else:
next_column, next_row = self.set_coordinates_in_direction(column, row, direction)
return self.check_endpoint(next_column, next_row, player_symbol, direction, not match_symbol)
def flip_pieces_helper(self, column, row, player_symbol, direction):
if self.get_cell(column, row) == player_symbol:
return 0
self.set_cell(column, row, player_symbol)
next_column, next_row = self.set_coordinates_in_direction(column, row, direction)
return 1 + self.flip_pieces_helper(next_column, next_row, player_symbol, direction)
def flip_pieces(self, column, row, player_symbol):
assert self.in_bounds(column, row)
pieces_flipped = 0
for direction in self.DIRECTIONS.keys():
next_column, next_row = self.set_coordinates_in_direction(column, row, direction)
if self.check_endpoint(next_column, next_row, player_symbol, direction, False):
pieces_flipped += self.flip_pieces_helper(next_column, next_row, player_symbol, direction)
return pieces_flipped
def has_legal_moves_remaining(self, player_symbol):
for row in range(self.num_rows):
for column in range(self.num_columns):
if self.cell_empty(column, row) and self.is_legal_move(column, row, player_symbol):
return True
return False
def is_legal_move(self, column, row, player_symbol):
if not self.in_bounds(column, row) or not self.cell_empty(column, row):
return False
for direction in self.DIRECTIONS.keys():
next_column, next_row = self.set_coordinates_in_direction(column, row, direction)
if self.check_endpoint(next_column, next_row, player_symbol, direction, False):
return True
return False
def play_move(self, column, row, player_symbol):
self.set_cell(column, row, player_symbol)
self.flip_pieces(column, row, player_symbol)
def count_score(self, player_symbol):
score = 0
for row in self.grid:
for current_column_value in row:
if current_column_value == player_symbol:
score += 1
return score
class GameDriver:
VALID_PLAYER_TYPES = ["human", "minimax"]
def __init__(self, player_1_type, player_2_type, num_columns, num_rows):
self.player_1 = (HumanPlayer(1, "X") if player_1_type == "human" else MinimaxPlayer(1, "X"))
self.player_2 = (HumanPlayer(2, "O") if player_2_type == "human" else MinimaxPlayer(2, "O"))
self.board = OthelloBoard(num_columns, num_rows, self.player_1.board_symbol, self.player_2.board_symbol)
def display(self):
print()
print("Player 1 ({}) score: {}".format(self.player_1.board_symbol,
self.board.count_score(self.player_1.board_symbol)))
print("Player 2 ({}) score: {}".format(self.player_2.board_symbol,
self.board.count_score(self.player_2.board_symbol)))
self.board.display()
def process_move(self, current_player):
invalid_move = True
while invalid_move:
column, row = current_player.get_move(self.board)
if not self.board.is_legal_move(column, row, current_player.board_symbol):
print("Invalid move")
else:
print("Selected move: col = {}, row = {}".format(column, row))
self.board.play_move(column, row, current_player.board_symbol)
invalid_move = False
def run(self):
game_running = True
current_player = self.player_1
cant_move_counter = 0
while game_running:
print("Player {} ({}) move:".format(current_player.player_number, current_player.board_symbol))
if self.board.has_legal_moves_remaining(current_player.board_symbol):
cant_move_counter = 0
self.process_move(current_player)
self.display()
else:
print("No moves available for player {}".format(current_player.player_number))
cant_move_counter += 1
if cant_move_counter == 2:
game_running = False
current_player = (self.player_1 if current_player == self.player_2 else self.player_2)
player_1_score = self.board.count_score(self.player_1.board_symbol)
player_2_score = self.board.count_score(self.player_2.board_symbol)
print()
if player_1_score == player_2_score:
print("Tie Game")
elif player_1_score > player_2_score:
print("Player 1 Wins")
else:
print("Player 2 Wins")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="A command line version of the Othello board game")
parser.add_argument("player_1_type", choices=["human", "minimax"], help="Type for player 1")
parser.add_argument("player_2_type", choices=["human", "minimax"], help="Type for player 2")
args = parser.parse_args()
game = GameDriver(args.player_1_type, args.player_2_type, 4, 4)
game.run()

View File

@@ -0,0 +1,6 @@
To run this program, place the files testSet.txt and trainingSet.txt in the same directory, then run:
python3 sentiment_analyzer.py
Results will be saved in results.txt.
The files preprocessed_train.txt and preprocessed_test.txt will also be created.

View File

@@ -0,0 +1,23 @@
# assignment3 - Sentiment Analysis with Naive Bayes
- Rutger Farry & Simon Wu
- CS331
- Dr. Rebecca Hutchinson
- 8 June 2017
## Running the code
The program looks for two files, named trainingSet.txt and testSet.txt, and outputs the results to stdout. If these files don't exist, the program will crash. Specs for these files are found here: It is built in Python 3, so running them should be simple on most computers:
```bash
python3 main.py
```
## About
### Construction
The program is split into a library and executable. All the computations and processing happen in `lib.py`, while the executable, `main.py` just calls the correct functions and provides a CLI.
The code has been tested for compatibility down to Python 3.3.2. It may work with older versions, but they are not supported. :warning: The script will not work on Python 2.
### Accuracy
:chart: In our tests, the sentiment analyzer achieved **79.7% accuracy**. Some ideas for improving accuracy are:
1. Increasing our training data
2. Spell-correcting mispelled words
3. Trimming excess characters. For example `soooooooo good` should be considered the same as `soo good`.

View File

@@ -0,0 +1,89 @@
import re
from math import log
from collections import defaultdict
non_alphanum = re.compile(r'[\W_]+')
flatten = lambda l: [item for sublist in l for item in sublist]
def process_word(word):
return non_alphanum.sub('', word.lower())
def process_document(document):
""" Returns a tuple. The first element is the review split into array of words.
The second element is an int indicating whether the review was positive. """
return (
[process_word(word) for word in document.split()][:-1],
int(document.split()[-1])
)
def format_document(document, vocab):
return (
','.join(['1' if word in document[0] else '0' for word in vocab])
+ ',' + str(document[1])
)
def preprocess(infilename, outfilename):
""" Returns a tuple in the form of (vocab, documents).
Vocab: a set of words, e.g. { 'great', 'steak', 'gross', ... }
Documents: a tuple containing the array of words in the document followed
by the sentiment of the document, represented by a 1 or 0, e.g.
(['i', 'liked', 'the', 'food'], 1) """
# Process input file
infile = open(infilename, 'r')
raw_documents = infile.read().splitlines()
documents = [process_document(document) for document in raw_documents]
vocab = {process_word(word) for document in raw_documents for word in document.split()[:-1]}
vocab.discard('')
infile.close()
# Format text for outfile and write
outfile = open(outfilename, 'w')
formatted_vocab = ','.join(sorted(list(vocab)))
formatted_documents = '\n'.join([format_document(document, vocab) for document in documents])
outfile.write(formatted_vocab + '\n' + formatted_documents)
outfile.close()
return vocab, documents
def train_naive_bayes(vocab, documents, classes):
logprior = {}
loglikelihood = defaultdict(dict)
big_doc = {}
def get_logprior(documents, c):
class_document_count = len([doc for doc in documents if doc[1] == c])
total_document_count = len(documents)
return log(class_document_count / total_document_count)
def get_bigdoc(documents, c):
return flatten([doc[0] for doc in documents if doc[1] == c])
for c in classes:
logprior[c] = get_logprior(documents, c)
big_doc[c] = get_bigdoc(documents, c)
words_in_class_count = sum([big_doc[c].count(w) for w in vocab])
for word in vocab:
word_count = big_doc[c].count(word)
loglikelihood[word][c] = log((word_count + 1) / (words_in_class_count + 1))
return logprior, loglikelihood
def test_naive_bayes(document, logprior, loglikelihood, classes, vocab):
# Filter words not in the vocab
document = [word for word in document[0] if word in vocab]
prob = {}
for c in classes:
prob[c] = logprior[c]
for word in document:
prob[c] = prob[c] + loglikelihood[word][c]
return max(prob.keys(), key=(lambda key: prob[key]))

View File

@@ -0,0 +1,54 @@
import sys
from lib import preprocess, train_naive_bayes, test_naive_bayes
def print_test_results(results, test_docs):
misclassified_docs = []
for result, doc in zip(results, test_docs):
if result != doc[1]:
misclassified_docs.append(doc + tuple([result]))
for doc in misclassified_docs:
print('misclassified {}: actual: {}, expected: {}'.format(doc[0], doc[2], doc[1]))
correct = len(test_docs) - len(misclassified_docs)
incorrect = len(misclassified_docs)
accuracy = correct / len(test_docs)
print("\n")
print("****************************************")
print("* RESULTS:")
print("* Correct: {}".format(correct))
print("* Incorrect: {}".format(incorrect))
print("*")
print("* Accuracy: {}".format(accuracy))
print("****************************************")
def test(test_docs, prior, likelihood, classes, vocab):
results = []
for test_doc in test_docs:
results.append(test_naive_bayes(test_doc, prior, likelihood, classes, vocab))
print_test_results(results, test_documents)
# Prevent running if imported as a module
if __name__ == '__main__':
classes = [0, 1]
# perform test on the training data
sys.stdout = open('output.txt', 'wt')
vocab, documents = preprocess('trainingSet.txt', 'preprocessed_train.txt')
_, test_documents = preprocess('trainingSet.txt', 'preprocessed_train.txt')
prior, likelihood = train_naive_bayes(vocab, documents, classes)
print("\n")
print("testing on training data")
test(documents, prior, likelihood, classes, vocab)
# perform test on the testing data
vocab, documents = preprocess('trainingSet.txt', 'preprocessed_train.txt')
_, test_documents = preprocess('testSet.txt', 'preprocessed_test.txt')
prior, likelihood = train_naive_bayes(vocab, documents, classes)
print("\n")
print("testing on testing data")
test(test_documents, prior, likelihood, classes, vocab)

View File

@@ -0,0 +1,246 @@
import re
from math import log
from os.path import exists
from os import remove
TRAINING_SET_FILENAME = "trainingSet.txt"
TEST_SET_FILENAME = "testSet.txt"
PREPROCESSED_TRAIN_OUTPUT_FILENAME = "preprocessed_train.txt"
PREPROCESSED_TEST_OUTPUT_FILENAME = "preprocessed_test.txt"
RESULTS_OUTPUT_FILENAME = "results.txt"
POSITIVE_LABEL = 1
NEGATIVE_LABEL = 0
VALID_LABELS = [NEGATIVE_LABEL, POSITIVE_LABEL]
# ##################################################
# ########## Functions for pre-processing ##########
# ##################################################
def get_lines_in_file(filename):
with open(filename, "r") as current_file:
return current_file.readlines()
def line_to_word_list_and_class(current_line):
split_by_tabs = current_line.split("\t")
review_sentence = split_by_tabs[0]
review_sentence = review_sentence.strip() # Remove beginning and ending whitespace
review_sentence = re.sub(r"[^a-zA-Z ]", "", review_sentence) # Strip everything but a-z, A-Z, and spaces
review_sentence = review_sentence.lower() # Make everything lowercase
sentence_words = review_sentence.split(" ") # Split sentence into words
sentence_words = [word for word in sentence_words if word != ""] # Remove empty strings
sentence_words.sort() # Put everything in alphabetical order
return sentence_words, int(split_by_tabs[1])
def create_vocabulary_from_sentences_with_classes(raw_sentences):
vocabulary_set = set()
for current_sentence, _ in raw_sentences:
for word in current_sentence:
vocabulary_set.add(word)
vocabulary_list = list(vocabulary_set)
vocabulary_list.sort()
vocabulary_indexer = {word: index for index, word in enumerate(vocabulary_list)}
return vocabulary_list, vocabulary_indexer
def get_features_from_vocab_and_sentence(vocab_info, sentence_and_class):
vocab_list, vocab_indexer = vocab_info
sentence_words, sentence_class = sentence_and_class
features = [0 for _ in range(len(vocab_list))]
features.append(sentence_class)
for word in sentence_words:
if word in vocab_indexer:
features[vocab_indexer[word]] = 1
return features
def get_all_features_from_vocab_and_sentences(vocab_info, sentences):
all_features = []
for sentence in sentences:
all_features.append(get_features_from_vocab_and_sentence(vocab_info, sentence))
return all_features
def write_post_processed_data_to_file(vocab_info, features, filename):
vocab_list, _ = vocab_info
vocab_header = ",".join(vocab_list + ["classlabel"])
with open(filename, "w+") as output_file:
output_file.write(vocab_header + "\n")
for feature in features:
feature_output_string = ",".join([str(value) for value in feature])
output_file.write(feature_output_string + "\n")
# ###################################################
# ########## Functions for naive bayes net ##########
# ###################################################
def train_net(vocabulary, features):
vocab_info, vocab_mapping = vocabulary
p_label = {}
p_label_count = {}
p_word_given_label = {
word: {} for word in vocab_info
}
# Calculate p(CD)
for label in VALID_LABELS:
num_features_with_label = [feature[-1] for feature in features].count(label)
num_features_total = len(features)
p_label[label] = log(num_features_with_label / num_features_total)
p_label_count[label] = num_features_with_label
# Calculate p(word | label) for all words
for cd_label in VALID_LABELS:
for word in vocab_info:
word_index = vocab_mapping[word]
num_featuers_with_word_and_label = len([
feature for feature in features
if feature[-1] == cd_label and feature[word_index]
])
p_word_given_label[word][cd_label] = log(
(num_featuers_with_word_and_label + 1) / (p_label_count[cd_label] + len(VALID_LABELS))
)
return p_word_given_label, p_label
def test_net_on_features(vocabulary, features, probabilities):
vocab_info, vocab_mapping = vocabulary
p_word_given_label, p_label = probabilities
results = []
for feature in features:
word_indices = [index for index, value in enumerate(feature[:-1]) if value]
feature_probabilities = {}
for label in VALID_LABELS:
feature_probabilities[label] = p_label[label]
for index in word_indices:
feature_probabilities[label] += p_word_given_label[vocab_info[index]][label]
feature_result = max(feature_probabilities, key=lambda x: feature_probabilities[x])
results.append(feature_result)
return results
# ##########################################
# ########## Functions for output ##########
# ##########################################
# ##########################################
def clean_output_file(filename):
if exists(filename):
remove(filename)
def evaluate_and_export_results(training_filename, testing_filename, output_filename, vocabulary, features, results):
vocab_info, vocab_mapping = vocabulary
total_count = len(results)
correct_count = 0
incorrect = []
for row_index, result in enumerate(results):
current_feature = features[row_index]
feature_class_actual = current_feature[-1]
if feature_class_actual == result:
correct_count += 1
else:
words = [vocab_info[index] for index, value in enumerate(current_feature[:-1]) if value]
incorrect.append((row_index, words, feature_class_actual, result))
correct_percent = (correct_count / total_count) * 100.0
results_string = "####################################################################\n"
results_string += "Trained with file: {}\nTested with file: {}\n\n".format(training_filename, testing_filename)
results_string += "Correct reviews: {}\nIncorrect reviews: {}\n".format(correct_count,
len(incorrect))
results_string += "Correct: {:.1f}%\n\n".format(correct_percent)
for row_index, words, feature_class_actual, result in incorrect:
results_string += "Failed on file row index {} with expected value {} and result {}.\n".format(
row_index, feature_class_actual, result
)
results_string += "####################################################################\n\n\n"
with open(output_filename, "a") as output_file:
output_file.write(results_string)
# ##########################
# ########## Main ##########
# ##########################
if __name__ == "__main__":
# ##### Pre-processing #####
# Get vocabulary and training features
training_file_lines = get_lines_in_file(TRAINING_SET_FILENAME)
training_sentences_raw = [line_to_word_list_and_class(line) for line in training_file_lines]
vocabulary_info = create_vocabulary_from_sentences_with_classes(training_sentences_raw)
training_features = get_all_features_from_vocab_and_sentences(vocabulary_info, training_sentences_raw)
# Get test features from existing vocabulary
test_file_lines = get_lines_in_file(TEST_SET_FILENAME)
test_sentences_raw = [line_to_word_list_and_class(line) for line in test_file_lines]
test_features = get_all_features_from_vocab_and_sentences(vocabulary_info, test_sentences_raw)
# Output pre-processed files
write_post_processed_data_to_file(vocabulary_info, training_features, PREPROCESSED_TRAIN_OUTPUT_FILENAME)
write_post_processed_data_to_file(vocabulary_info, test_features, PREPROCESSED_TEST_OUTPUT_FILENAME)
# ##### Bayes net processing #####
bayes_net_probabilities = train_net(vocabulary_info, training_features)
training_results = test_net_on_features(vocabulary_info, training_features, bayes_net_probabilities)
test_results = test_net_on_features(vocabulary_info, test_features, bayes_net_probabilities)
# ##### Output results #####
clean_output_file(RESULTS_OUTPUT_FILENAME)
evaluate_and_export_results(TRAINING_SET_FILENAME,
TRAINING_SET_FILENAME,
RESULTS_OUTPUT_FILENAME,
vocabulary_info,
training_features,
training_results)
evaluate_and_export_results(TRAINING_SET_FILENAME,
TEST_SET_FILENAME,
RESULTS_OUTPUT_FILENAME,
vocabulary_info,
test_features,
test_results)

View File

@@ -0,0 +1,497 @@
Crust is not good. 0
Would not go back. 0
I was shocked because no signs indicate cash only. 0
The food, amazing. 1
Service is also cute. 1
I could care less... The interior is just beautiful. 1
So they performed. 1
This hole in the wall has great Mexican street tacos, and friendly staff. 1
The worst was the salmon sashimi. 0
Also there are combos like a burger, fries, and beer for 23 which is a decent deal. 1
This was like the final blow! 0
I found this place by accident and I could not be happier. 1
seems like a good quick place to grab a bite of some familiar pub food, but do yourself a favor and look elsewhere. 0
Ample portions and good prices. 1
Service sucks. 0
Frozen pucks of disgust, with some of the worst people behind the register. 0
It's too bad the food is so damn generic. 0
If you want a sandwich just go to any Firehouse!!!!! 1
My side Greek salad with the Greek dressing was so tasty, and the pita and hummus was very refreshing. 1
Their chow mein is so good! 1
The portion was huge! 1
Loved it...friendly servers, great food, wonderful and imaginative menu. 1
The Heart Attack Grill in downtown Vegas is an absolutely flat-lined excuse for a restaurant. 0
The salad had just the right amount of sauce to not over power the scallop, which was perfectly cooked. 1
The ripped banana was not only ripped, but petrified and tasteless. 0
Great food and service, huge portions and they give a military discount. 1
Update.....went back for a second time and it was still just as amazing 1
We got the food and apparently they have never heard of salt and the batter on the fish was chewy. 0
The deal included 5 tastings and 2 drinks, and Jeff went above and beyond what we expected. 1
- Really, really good rice, all the time. 1
The service was meh. 0
It took over 30 min to get their milkshake, which was nothing more than chocolate milk. 0
I guess I should have known that this place would suck, because it is inside of the Excalibur, but I didn't use my common sense. 0
2 times - Very Bad Customer Service ! 0
The sweet potato fries were very good and seasoned well. 1
Today is the second time I've been to their lunch buffet and it was pretty good. 1
walked in and the place smelled like an old grease trap and only 2 others there eating. 0
The pan cakes everyone are raving about taste like a sugary disaster tailored to the palate of a six year old. 0
The poor batter to meat ratio made the chicken tenders very unsatisfying. 0
All I have to say is the food was amazing!!! 1
Everything was fresh and delicious! 1
Never been to Hard Rock Casino before, WILL NEVER EVER STEP FORWARD IN IT AGAIN! 0
say bye bye to your tip lady! 0
We'll never go again. 0
Food arrived quickly! 1
It was not good. 0
On the up side, their cafe serves really good food. 1
I LOVED their mussels cooked in this wine reduction, the duck was tender, and their potato dishes were delicious. 1
This is one of the better buffets that I have been to. 1
Sooooo good!! 1
Check it out. 1
It was pretty gross! 0
I've had better atmosphere. 0
Kind of hard to mess up a steak but they did. 0
Although I very much liked the look and sound of this place, the actual experience was a bit disappointing. 0
Worst service to boot, but that is the least of their worries. 0
Service was fine and the waitress was friendly. 1
The guys all had steaks, and our steak loving son who has had steak at the best and worst places said it was the best steak he's ever eaten. 1
We thought you'd have to venture further away to get good sushi, but this place really hit the spot that night. 1
Phenomenal food, service and ambiance. 1
I wouldn't return. 0
Definitely worth venturing off the strip for the pork belly, will return next time I'm in Vegas. 1
Penne vodka excellent! 1
I had a seriously solid breakfast here. 1
This is one of the best bars with food in Vegas. 1
My drink was never empty and he made some really great menu suggestions. 1
Don't do it!!!! 0
My husband and I ate lunch here and were very disappointed with the food and service. 0
This is a great restaurant at the Mandalay Bay. 1
We waited for forty five minutes in vain. 0
Crostini that came with the salad was stale. 0
I ordered the Voodoo pasta and it was the first time I'd had really excellent pasta since going gluten free several years ago. 1
I came back today since they relocated and still not impressed. 0
Their menu is diverse, and reasonably priced. 1
So don't go there if you are looking for good food... 0
I've never been treated so bad. 0
Bacon is hella salty. 1
This really is how Vegas fine dining used to be, right down to the menus handed to the ladies that have no prices listed. 1
Everything on the menu is terrific and we were also thrilled that they made amazing accommodations for our vegetarian daughter. 1
Perhaps I caught them on an off night judging by the other reviews, but I'm not inspired to go back. 0
The service here leaves a lot to be desired. 0
Not a weekly haunt, but definitely a place to come back to every once in a while. 1
We literally sat there for 20 minutes with no one asking to take our order. 0
The burger had absolutely no flavor - the meat itself was totally bland, the burger was overcooked and there was no charcoal flavor. 0
It was probably dirt. 0
Love this place, hits the spot when I want something healthy but not lacking in quantity or flavor. 1
Also were served hot bread and butter, and home made potato chips with bacon bits on top....very original and very good. 1
Both of the egg rolls were fantastic. 1
When my order arrived, one of the gyros was missing. 0
I'm not really sure how Joey's was voted best hot dog in the Valley by readers of Phoenix Magazine. 0
The best place to go for a tasty bowl of Pho! 1
Very friendly staff. 1
It is worth the drive. 1
I had heard good things about this place, but it exceeding every hope I could have dreamed of. 1
Food was great and so was the serivce! 1
The warm beer didn't help. 0
I've lived here since 1979 and this was the first (and last) time I've stepped foot into this place. 0
Must have been an off night at this place. 0
For about 10 minutes, we we're waiting for her salad when we realized that it wasn't coming any time soon. 0
Won't go back. 0
Extremely Tasty! 1
Waitress was good though! 1
The Jamaican mojitos are delicious. 1
- the food is rich so order accordingly. 1
The shower area is outside so you can only rinse, not take a full shower, unless you don't mind being nude for everyone to see! 0
The service was a bit lacking. 0
Lobster Bisque, Bussell Sprouts, Risotto, Filet ALL needed salt and pepper..and of course there is none at the tables. 0
It was either too cold, not enough flavor or just bad. 0
The folks at Otto always make us feel so welcome and special. 1
This is the place where I first had pho and it was amazing!! 1
This wonderful experience made this place a must-stop whenever we are in town again. 1
If the food isn't bad enough for you, then enjoy dealing with the world's worst/annoying drunk people. 0
Ordered a double cheeseburger & got a single patty that was falling apart (picture uploaded) Yeah, still sucks. 0
If it were possible to give them zero stars, they'd have it. 0
The descriptions said yum yum sauce and another said eel sauce , yet another said spicy mayo ...well NONE of the rolls had sauces on them. 0
If she had not rolled the eyes we may have stayed... Not sure if we will go back and try it again. 0
Everyone is very attentive, providing excellent customer service. 1
Horrible - don't waste your time and money. 0
Now this dish was quite flavourful. 1
(It wasn't busy either) Also, the building was FREEZING cold. 0
like the other reviewer said you couldn't pay me to eat at this place again. 0
Seriously flavorful delights, folks. 1
Much better than the other AYCE sushi place I went to in Vegas. 1
There is nothing privileged about working/eating there. 0
Overall, I don't think that I would take my parents to this place again because they made most of the similar complaints that I silently felt too. 0
Fantastic service here. 1
very tough and very short on flavor! 0
I hope this place sticks around. 1
I have been in more than a few bars in Vegas, and do not ever recall being charged for tap water. 0
The seafood was fresh and generous in portion. 1
You can't beat that. 1
The goat taco didn't skimp on the meat and wow what FLAVOR! 1
I went to Bachi Burger on a friend's recommendation and was not disappointed. 1
This place is not quality sushi, it is not a quality restaurant. 0
Great Pizza and Salads! 1
This place is amazing! 1
I hate to disagree with my fellow Yelpers, but my husband and I were so disappointed with this place. 0
I live in the neighborhood so I am disappointed I won't be back here, because it is a convenient location. 0
Before I go in to why I gave a 1 star rating please know that this was my third time eating at Bachi burger before writing a review. 0
I love the fact that everything on their menu is worth it. 1
Never again will I be dining at this place! 0
Please stay away from the shrimp stir fried noodles. 0
This greedy corporation will NEVER see another dime from me! 0
Will never, ever go back. 0
In the summer, you can dine in a charming outdoor patio - so very delightful. 1
Fantastic food! 1
She ordered a toasted English muffin that came out untoasted. 0
The food was very good. 1
Great food for the price, which is very high quality and house made. 1
Back to good BBQ, lighter fare, reasonable pricing and tell the public they are back to the old ways. 1
And considering the two of us left there very full and happy for about $20, you just can't go wrong. 1
All the bread is made in-house! 1
Service was exceptional and food was a good as all the reviews. 1
The black eyed peas and sweet potatoes... UNREAL! 1
You won't be disappointed. 1
I go to far too many places and I've never seen any restaurant that serves a 1 egg breakfast, especially for $4.00. 0
Both of them were truly unbelievably good, and I am so glad we went back. 1
We had fantastic service, and were pleased by the atmosphere. 1
I love this place. 1
Great service and food. 1
First - the bathrooms at this location were dirty- Seat covers were not replenished & just plain yucky!!! 0
The burger... I got the Gold Standard a $17 burger and was kind of disappointed. 0
OMG, the food was delicioso! 1
There is nothing authentic about this place. 0
Of all the dishes, the salmon was the best, but all were great. 1
Pretty good beer selection too. 1
Classy/warm atmosphere, fun and fresh appetizers, succulent steaks (Baseball steak!!!!! 1
We sat another ten minutes and finally gave up and left. 0
He was terrible! 0
Everyone is treated equally special. 1
It shouldn't take 30 min for pancakes and eggs. 0
It was delicious!!! 1
Sadly, Gordon Ramsey's Steak is a place we shall sharply avoid during our next trip to Vegas. 0
Best fish I've ever had in my life! 1
(The bathroom is just next door and very nice.) 1
This is an Outstanding little restaurant with some of the Best Food I have ever tasted. 1
Definitely a turn off for me & i doubt I'll be back unless someone else is buying. 0
Server did a great job handling our large rowdy table. 1
I find wasting food to be despicable, but this just wasn't food. 0
Would come back again if I had a sushi craving while in Vegas. 1
He deserves 5 stars. 1
I left with a stomach ache and felt sick the rest of the day. 0
They dropped more than the ball. 0
RUDE & INCONSIDERATE MANAGEMENT. 0
They have great dinners. 1
This place deserves one star and 90% has to do with the food. 0
Def coming back to bowl next time 1
I will continue to come here on ladies night andddd date night ... highly recommend this place to anyone who is in the area (; 1
We walked away stuffed and happy about our first Vegas buffet experience. 1
To summarize... the food was incredible, nay, transcendant... but nothing brings me joy quite like the memory of the pneumatic condiment dispenser. 1
I'm probably one of the few people to ever go to Ians and not like it. 0
Cooked to perfection and the service was impeccable. 1
This one is simply a disappointment. 0
Overall, I was very disappointed with the quality of food at Bouchon. 0
I don't have to be an accountant to know I'm getting screwed! 0
Service was fantastic. 1
I don't know what kind it is but they have the best iced tea. 1
Come hungry, leave happy and stuffed! 1
I can assure you that you won't be disappointed. 1
I can take a little bad service but the food sucks. 0
I really enjoyed eating here. 1
Our server was very nice, and even though he looked a little overwhelmed with all of our needs, he stayed professional and friendly until the end. 1
Furthermore, you can't even find hours of operation on the website! 0
We've tried to like this place but after 10+ times I think we're done with them. 0
What a mistake that was! 0
No complaints! 1
Strike 2, who wants to be rushed. 0
I never come again. 0
We loved the biscuits!!! 1
Ordered an appetizer and took 40 minutes and then the pizza another 10 minutes. 0
So absolutley fantastic. 1
definitely will come back here again. 1
I like Steiners because it's dark and it feels like a bar. 1
If you're not familiar, check it out. 1
Nothing special. 0
Will not be back. 0
My ribeye steak was cooked perfectly and had great mesquite flavor. 1
I don't think we'll be going back anytime soon. 0
I am far from a sushi connoisseur but I can definitely tell the difference between good food and bad food and this was certainly bad food. 0
I was so insulted. 0
Nargile - I think you are great. 1
We loved the place. 1
Definitely not worth the $3 I paid. 0
The vanilla ice cream was creamy and smooth while the profiterole (choux) pastry was fresh enough. 1
The inside is really quite nice and very clean. 1
The food was outstanding and the prices were very reasonable. 1
This is was due to the fact that it took 20 minutes to be acknowledged, then another 35 minutes to get our food...and they kept forgetting things. 0
Love the margaritas, too! 1
This was my first and only Vegas buffet and it did not disappoint. 1
Very good, though! 1
The one down note is the ventilation could use some upgrading. 0
Great pork sandwich. 1
Third, the cheese on my friend's burger was cold. 0
We enjoy their pizza and brunch. 1
This place is a jewel in Las Vegas, and exactly what I've been hoping to find in nearly ten years living here. 1
The selection of food was not the best. 0
They had a toro tartare with a cavier that was extraordinary and I liked the thinly sliced wagyu with white truffle. 1
It was attached to a gas station, and that is rarely a good sign. 0
How awesome is that. 1
The menu had so much good stuff on it i could not decide! 1
Worse of all, he humiliated his worker right in front of me..Bunch of horrible name callings. 0
CONCLUSION: Very filling meals. 1
Their daily specials are always a hit with my group. 1
The pancake was also really good and pretty large at that. 1
This was my first crawfish experience, and it was delicious! 1
Their monster chicken fried steak and eggs is my all time favorite. 1
I'd rather eat airline food, seriously. 0
The ambiance was incredible. 1
My gyro was basically lettuce only. 0
Terrible service! 0
Thoroughly disappointed! 0
I don't each much pasta, but I love the homemade /hand made pastas and thin pizzas here. 1
Give it a try, you will be happy you did. 1
By far the BEST cheesecurds we have ever had! 1
Reasonably priced also! 1
it was a drive to get there. 0
Point your finger at any item on the menu, order it and you won't be disappointed. 1
first time there and might just be the last. 0
Similarly, the delivery man did not say a word of apology when our food was 45 minutes late. 0
And it was way to expensive. 0
The bartender was also nice. 1
Everything was good and tasty! 1
The best place in Vegas for breakfast (just check out a Sat, or Sun. 1
If you love authentic Mexican food and want a whole bunch of interesting, yet delicious meats to choose from, you need to try this place. 1
An excellent new restaurant by an experienced Frenchman. 1
If there were zero stars I would give it zero stars. 0
Worst martini ever! 0
I had the opportunity today to sample your amazing pizzas! 1
The yellowtail carpaccio was melt in your mouth fresh. 1
No, I'm going to eat the potato that I found some strangers hair in it. 0
not even a hello, we will be right with you. 0
I really do recommend this place, you can go wrong with this donut place! 1
I guess maybe we went on an off night but it was disgraceful. 0
However, my recent experience at this particular location was not so good. 0
I know this is not like the other restaurants at all, something is very off here! 0
AVOID THIS ESTABLISHMENT! 0
I think this restaurant suffers from not trying hard enough. 0
All of the tapas dishes were delicious! 1
I *heart* this place. 1
My salad had a bland vinegrette on the baby greens and hearts of Palm. 0
After two I felt disgusting. 0
I believe that this place is a great stop for those with a huge belly and hankering for sushi. 1
I will never go back to this place and will never ever recommended this place to anyone! 0
The servers went back and forth several times, not even so much as an Are you being helped? 0
AN HOUR... seriously? 0
Eew... This location needs a complete overhaul. 0
He also came back to check on us regularly, excellent service. 1
Our server was super nice and checked on us many times. 1
The pizza tasted old, super chewy in not a good way. 0
As for the service: I'm a fan, because it's quick and you're being served by some nice folks. 1
Boy was that sucker dry!!. 0
Over rated. 0
After I pulled up my car I waited for another 15 minutes before being acknowledged. 0
Great food and great service in a clean and friendly setting. 1
All in all, I can assure you I'll be back. 1
My breakfast was perpared great, with a beautiful presentation of 3 giant slices of Toast, lightly dusted with powdered sugar. 1
OMG I felt like I had never eaten Thai food until this dish. 1
It was extremely crumby and pretty tasteless. 0
It'll be a regular stop on my trips to Phoenix! 1
We got sitting fairly fast, but, ended up waiting 40 minutes just to place our order, another 30 minutes before the food arrived. 0
Couldn't ask for a more satisfying meal. 1
I just wanted to leave. 0
I will not be eating there again. 0
Sorry, I will not be getting food from here anytime soon :( 0
The cow tongue and cheek tacos are amazing. 1
My friend did not like his Bloody Mary. 0
They really want to make your experience a good one. 1
Very disappointing!!! 0
a drive thru means you do not want to wait around for half an hour for your food, but somehow when we end up going here they make us wait and wait. 0
Ambience is perfect. 1
Best of luck to the rude and non-customer service focused new management. 0
Any grandmother can make a roasted chicken better than this one. 0
I asked multiple times for the wine list and after some time of being ignored I went to the hostess and got one myself. 0
Same evening, him and I are both drastically sick. 0
High-quality chicken on the chicken Caesar salad. 1
We were promptly greeted and seated. 1
Tried to go here for lunch and it was a madhouse. 0
After waiting an hour and being seated, I was not in the greatest of moods. 0
The Macarons here are insanely good. 1
Our waiter was very attentive, friendly, and informative. 1
Maybe if they weren't cold they would have been somewhat edible. 0
Great food. 1
Hands down my favorite Italian restaurant! 1
That just SCREAMS LEGIT in my book...somethat's also pretty rare here in Vegas. 1
It was just not a fun experience. 1
The atmosphere was great with a lovely duo of violinists playing songs we requested. 1
Very convenient, since we were staying at the MGM! 1
The sweet potato tots were good but the onion rings were perfection or as close as I have had. 1
Google mediocre and I imagine Smashburger will pop up. 0
dont go here. 0
I promise they won't disappoint. 1
As a sushi lover avoid this place by all means. 0
What a great double cheeseburger! 1
Awesome service and food. 1
A fantastic neighborhood gem !!! 1
Service was slow and not attentive. 0
I gave it 5 stars then, and I'm giving it 5 stars now. 1
Dessert: Panna Cotta was amazing. 1
Very good food, great atmosphere.1 1
Prices are very reasonable, flavors are spot on, the sauce is home made, and the slaw is not drenched in mayo. 1
The steak was amazing...rge fillet relleno was the best seafood plate i have ever had! 1
Good food , good service . 1
It was absolutely amazing. 1
will definitely be back! 1
Hawaiian Breeze, Mango Magic, and Pineapple Delight are the smoothies that I've tried so far and they're all good. 1
Needless to say, we will never be back here again. 0
Anyways, The food was definitely not filling at all, and for the price you pay you should expect more. 0
The chips that came out were dripping with grease, and mostly not edible. 0
Our server was very nice and attentive as were the other serving staff. 1
I work in the hospitality industry in Paradise Valley and have refrained from recommending Cibo any longer. 0
The atmosphere here is fun. 1
Service is quick and even to go orders are just like we like it! 1
That said, our mouths and bellies were still quite pleased. 1
Not my thing. 0
If you are reading this please don't go there. 0
I loved the grilled pizza, reminded me of legit Italian pizza. 1
Only Pros : Large seating area/ Nice bar area/ Great simple drink menu/ The BEST brick oven pizza with homemade dough! 1
After one bite, I was hooked. 1
The food was great as always, compliments to the chef. 1
Awesome selection of beer. 1
One nice thing was that they added gratuity on the bill since our party was larger than 6 or 8, and they didn't expect more tip than that. 1
The Han Nan Chicken was also very tasty. 1
As for the service, I thought it was good. 1
Ryan's Bar is definitely one Edinburgh establishment I won't be revisiting. 0
Nicest Chinese restaurant I've been in a while. 1
Friend's pasta -- also bad, he barely touched it. 0
I love the decor with the Chinese calligraphy wall paper. 1
I'm not sure how long we stood there but it was long enough for me to begin to feel awkwardly out of place. 0
When I opened the sandwich, I was impressed, but not in a good way. 0
There was a warm feeling with the service and I felt like their guest for a special treat. 1
I always order from the vegetarian menu during dinner, which has a wide array of options to choose from. 1
I got to enjoy the seafood salad, with a fabulous vinegrette. 1
The wontons were thin, not thick and chewy, almost melt in your mouth. 1
We were sat right on time and our server from the get go was FANTASTIC! 1
Main thing I didn't enjoy is that the crowd is of older crowd, around mid 30s and up. 0
I had to wait over 30 minutes to get my drink and longer to get 2 arepas. 0
This is a GREAT place to eat! 1
The jalapeno bacon is soooo good. 1
The service was poor and thats being nice. 0
Food was good, service was good, Prices were good. 1
The place was not clean and the food oh so stale! 0
But the service was beyond bad. 0
I'm so happy to be here!!!" 1
Tasted like dirt. 0
One of the few places in Phoenix that I would definately go back to again . 1
It's close to my house, it's low-key, non-fancy, affordable prices, good food. 1
My sashimi was poor quality being soggy and tasteless. 0
the food is not tasty at all, not to say its real traditional Hunan style . 0
The flair bartenders are absolutely amazing! 1
These were so good we ordered them twice. 1
So in a nutshell: 1) The restaraunt smells like a combination of a dirty fish market and a sewer. 0
My girlfriend's veal was very bad. 0
Join the club and get awesome offers via email. 1
Perfect for someone (me) who only likes beer ice cold, or in this case, even colder. 1
The nachos are a MUST HAVE! 1
We will not be coming back. 0
I don't have very many words to say about this place, but it does everything pretty well. 1
The staff is super nice and very quick even with the crazy crowds of the downtown juries, lawyers, and court staff. 1
Great atmosphere, friendly and fast service. 1
When I received my Pita it was huge it did have a lot of meat in it so thumbs up there. 1
The classic Maine Lobster Roll was fantastic. 1
This place is great!!!!!!!!!!!!!! 1
I'm super pissd. 0
Lastly, the mozzarella sticks, they were the best thing we ordered. 1
The service was terrible though. 0
I love this place. 1
I can say that the desserts were yummy. 1
The food was terrible. 0
Do not waste your money here! 0
I love that they put their food in nice plastic containers as opposed to cramming it in little paper takeout boxes. 1
Won't ever go here again. 0
Food quality has been horrible. 0
For that price I can think of a few place I would have much rather gone. 0
I do love sushi, but I found Kabuki to be over-priced, over-hip and under-services. 0
Do yourself a favor and stay away from this dish. 0
Very poor service. 0
I have never had such bland food which surprised me considering the article we read focused so much on their spices and flavor. 0
Food is way overpriced and portions are fucking small. 0
I recently tried Caballero's and I have been back every week since! 1
for 40 bucks a head, i really expect better food. 0
I won't be back. 0
This place deserves no stars. 0
In fact I'm going to round up to 4 stars, just because she was so awesome. 1
I probably would not go here again. 0
The price is reasonable and the service is great. 1
The Wife hated her meal (coconut shrimp), and our friends really did not enjoy their meals, either. 0
My fella got the huevos rancheros and they didn't look too appealing. 0
I probably won't be coming back here. 0
Worst food/service I've had in a while. 0
Hot dishes are not hot, cold dishes are close to room temp.I watched staff prepare food with BARE HANDS, no gloves.Everything is deep fried in oil. 0
Always a pleasure dealing with him. 1
This place is awesome if you want something light and healthy during the summer. 1
The service was great, even the manager came and helped with our table. 1
this is the worst sushi i have ever eat besides Costco's. 0
All in all an excellent restaurant highlighted by great service, a unique menu, and a beautiful setting. 1
My boyfriend and i sat at the bar and had a completely delightful experience. 1
Go To Place for Gyros. 1
I found a six inch long piece of wire in my salsa. 0
We definately enjoyed ourselves. 1
I had about two bites and refused to eat anymore. 0
Seriously killer hot chai latte. 1
Their rotating beers on tap is also a highlight of this place. 1
Pricing is a bit of a concern at Mellow Mushroom. 0
Worst Thai ever. 0
If you stay in Vegas you must get breakfast here at least once. 1
Highly unprofessional and rude to a loyal patron! 0
Overall, a great experience. 1
Also, I feel like the chips are bought, not made in house. 0
After the disappointing dinner we went elsewhere for dessert. 0
The chips and sals a here is amazing!!!!!!!!!!!!!!!!!!! 1
We won't be returning. 0
This is my new fav Vegas buffet spot. 1
I seriously cannot believe that the owner has so many unexperienced employees that all are running around like chickens with their heads cut off. 0
i felt insulted and disrespected, how could you talk and judge another human being like that? 0
How can you call yourself a steakhouse if you can't properly cook a steak, I don't understand! 0
The only thing I wasn't too crazy about was their guacamole as I don't like it puréed. 0
There is really nothing for me at postinos, hope your experience is better 0
This place is disgusting! 0
Every time I eat here, I see caring teamwork to a professional degree. 1
However, there was so much garlic in the fondue, it was barely edible. 0
I could barely stomach the meal, but didn't complain because it was a business lunch. 0
It also took her forever to bring us the check when we asked for it. 0
Disappointing experience. 0
If you want to wait for mediocre food and downright terrible service, then this is the place for you. 0
We won't be going back. 0
The place was fairly clean but the food simply wasn't worth it. 0
The meat was pretty dry, I had the sliced brisket and pulled pork. 0
It was equally awful. 0
very slow at seating even with reservation. 0
The chipolte ranch dipping sause was tasteless, seemed thin and watered down with no heat. 0
I was VERY disappointed!! 0
Maybe it's just their Vegetarian fare, but I've been twice and I thought it was average at best. 0
The tables outside are also dirty a lot of the time and the workers are not always friendly and helpful with the menu. 0
But then they came back cold. 0
Then our food came out, disappointment ensued. 0
The only reason to eat here would be to fill up before a night of binge drinking just to get some carbs in your stomach. 0
Insults, profound deuchebaggery, and had to go outside for a smoke break while serving just to solidify it. 0
If someone orders two tacos don't' you think it may be part of customer service to ask if it is combo or ala cart? 0
After all the rave reviews I couldn't wait to eat here......what a disappointment! 0
It's NOT hard to make a decent hamburger. 0
But I don't like it. 0
Hell no will I go back 0
I don't know what the big deal is about this place, but I won't be back ya'all . 0
I immediately said I wanted to talk to the manager but I did not want to talk to the guy who was doing shots of fireball behind the bar. 0
Your servers suck, wait, correction, our server Heimer sucked. 0
What happened next was pretty....off putting. 0
Overpriced for what you are getting. 0
I vomited in the bathroom mid lunch. 0
I have been to very few places to eat that under no circumstances would I ever return to, and this tops the list. 0
All in all, Ha Long Bay was a bit of a flop. 0
Shrimp- When I unwrapped it (I live only 1/2 a mile from Brushfire) it was literally ice cold. 0
It really is impressive that the place hasn't closed down. 0
I would avoid this place if you are staying in the Mirage. 0
Spend your money and time some place else. 0
the presentation of the food was awful. 0
I can't tell you how disappointed I was. 0
I think food should have flavor and texture and both were lacking. 0

View File

@@ -0,0 +1,499 @@
Wow... Loved this place. 1
Not tasty and the texture was just nasty. 0
Stopped by during the late May bank holiday off Rick Steve recommendation and loved it. 1
The selection on the menu was great and so were the prices. 1
Now I am getting angry and I want my damn pho. 0
Honeslty it didn't taste THAT fresh.) 0
The potatoes were like rubber and you could tell they had been made up ahead of time being kept under a warmer. 0
The fries were great too. 1
A great touch. 1
Service was very prompt. 1
The cashier had no care what so ever on what I had to say it still ended up being wayyy overpriced. 0
I tried the Cape Cod ravoli, chicken,with cranberry...mmmm! 1
I was disgusted because I was pretty sure that was human hair. 0
Highly recommended. 1
Waitress was a little slow in service. 0
This place is not worth your time, let alone Vegas. 0
did not like at all. 0
The Burrittos Blah! 0
That's right....the red velvet cake.....ohhh this stuff is so good. 1
- They never brought a salad we asked for. 0
Took an hour to get our food only 4 tables in restaurant my food was Luke warm, Our sever was running around like he was totally overwhelmed. 0
Overall, I like this place a lot. 1
The only redeeming quality of the restaurant was that it was very inexpensive. 1
Poor service, the waiter made me feel like I was stupid every time he came to the table. 0
My first visit to Hiro was a delight! 1
The shrimp tender and moist. 1
There is not a deal good enough that would drag me into that establishment again. 0
Hard to judge whether these sides were good because we were grossed out by the melted styrofoam and didn't want to eat it for fear of getting sick. 0
On a positive note, our server was very attentive and provided great service. 1
The only thing I did like was the prime rib and dessert section. 1
The burger is good beef, cooked just right. 1
We ordered the duck rare and it was pink and tender on the inside with a nice char on the outside. 1
He came running after us when he realized my husband had left his sunglasses on the table. 1
They have horrible attitudes towards customers, and talk down to each one when customers don't enjoy their food. 0
Not much seafood and like 5 strings of pasta at the bottom. 0
At least think to refill my water before I struggle to wave you over for 10 minutes. 0
This place receives stars for their APPETIZERS!!! 1
The cocktails are all handmade and delicious. 1
We'd definitely go back here again. 1
We are so glad we found this place. 1
Always a great time at Dos Gringos! 1
A great way to finish a great. 1
The scallop dish is quite appalling for value as well. 0
There is so much good food in Vegas that I feel cheated for wasting an eating opportunity by going to Rice and Company. 0
Coming here is like experiencing an underwhelming relationship where both parties can't wait for the other person to ask to break up. 0
The turkey and roast beef were bland. 0
This place has it! 1
I love the Pho and the spring rolls oh so yummy you have to try. 1
Omelets are to die for! 1
In summary, this was a largely disappointing dining experience. 0
It's like a really sexy party in your mouth, where you're outrageously flirting with the hottest person at the party. 1
Best breakfast buffet!!! 1
Will be back again! 1
Our server was fantastic and when he found out the wife loves roasted garlic and bone marrow, he added extra to our meal and another marrow to go! 1
The only good thing was our waiter, he was very helpful and kept the bloddy mary's coming. 1
Best Buffet in town, for the price you cannot beat it. 1
So we went to Tigerlilly and had a fantastic afternoon! 1
The food was delicious, our bartender was attentive and personable AND we got a great deal! 1
The ambience is wonderful and there is music playing. 1
Will go back next trip out. 1
REAL sushi lovers, let's be honest - Yama is not that good. 0
At least 40min passed in between us ordering and the food arriving, and it wasn't that busy. 0
This is a really fantastic Thai restaurant which is definitely worth a visit. 1
Nice, spicy and tender. 1
Good prices. 1
I just don't know how this place managed to served the blandest food I have ever eaten when they are preparing Indian cuisine. 0
Host staff were, for lack of a better word, BITCHES! 0
Bland... Not a liking this place for a number of reasons and I don't want to waste time on bad reviewing.. I'll leave it at that... 0
This place is way too overpriced for mediocre food. 0
They have a good selection of food including a massive meatloaf sandwich, a crispy chicken wrap, a delish tuna melt and some tasty burgers. 1
The management is rude. 0
Delicious NYC bagels, good selections of cream cheese, real Lox with capers even. 1
Great Subway, in fact it's so good when you come here every other Subway will not meet your expectations. 1
He was extremely rude and really, there are so many other restaurants I would love to dine at during a weekend in Vegas. 0
The waiter wasn't helpful or friendly and rarely checked on us. 0
And the red curry had so much bamboo shoots and wasn't very tasty to me. 0
Nice blanket of moz over top but i feel like this was done to cover up the subpar food. 1
The bathrooms are clean and the place itself is well decorated. 1
The menu is always changing, food quality is going down & service is extremely slow. 0
The service was a little slow , considering that were served by 3 people servers so the food was coming in a slow pace. 0
I give it 2 thumbs down 0
We watched our waiter pay a lot more attention to other tables and ignore us. 0
My fiancé and I came in the middle of the day and we were greeted and seated right away. 1
Some highlights : Great quality nigiri here! 1
the staff is friendly and the joint is always clean. 1
this was a different cut than the piece the other day but still wonderful and tender s well as well flavored. 1
this place is good. 1
Unfortunately, we must have hit the bakery on leftover day because everything we ordered was STALE. 0
I was seated immediately. 1
Avoid at all cost! 0
Restaurant is always full but never a wait. 1
DELICIOUS!! 1
This place is hands-down one of the best places to eat in the Phoenix metro area. 1
We also ordered the spinach and avocado salad; the ingredients were sad and the dressing literally had zero taste. 0
The waitresses are very friendly. 1
Lordy, the Khao Soi is a dish that is not to be missed for curry lovers! 1
The atmosphere is modern and hip, while maintaining a touch of coziness. 1
I also decided not to send it back because our waitress looked like she was on the verge of having a heart attack. 0
I dressed up to be treated so rudely! 0
I ordered the Lemon raspberry ice cocktail which was also incredible. 1
The food sucked, which we expected but it sucked more than we could have imagined. 0
Interesting decor. 1
What I really like there is the crepe station. 1
you can watch them preparing the delicious food!) 1
I had a salad with the wings, and some ice cream for dessert and left feeling quite satisfied. 1
The live music on Fridays totally blows. 0
I've never been more insulted or felt disrespected. 0
Great brunch spot. 1
Service is friendly and inviting. 1
Very good lunch spot. 1
The WORST EXPERIENCE EVER. 0
The sides are delish - mixed mushrooms, yukon gold puree, white corn - beateous. 1
If that bug never showed up I would have given a 4 for sure, but on the other side of the wall where this bug was climbing was the kitchen. 0
My friend loved the salmon tartar. 1
Soggy and not good. 0
Which are small and not worth the price. 0
Hopefully this bodes for them going out of business and someone who can cook can come in. 0
I loved the bacon wrapped dates. 1
This is an unbelievable BARGAIN! 1
As for the mains, also uninspired. 0
Very very fun chef. 1
Great place to have a couple drinks and watch any and all sporting events as the walls are covered with TV's. 1
I'd say that would be the hardest decision... Honestly, all of M's dishes taste how they are supposed to taste (amazing). 1
By this time our side of the restaurant was almost empty so there was no excuse. 0
-Drinks took close to 30 minutes to come out at one point. 0
The lighting is just dark enough to set the mood. 1
Based on the sub-par service I received and no effort to show their gratitude for my business I won't be going back. 0
Owner's are really great people.! 1
The Greek dressing was very creamy and flavorful. 1
Now the pizza itself was good the peanut sauce was very tasty. 1
We had 7 at our table and the service was pretty fast. 1
I as well would've given godfathers zero stars if possible. 0
They know how to make them here. 1
The restaurant atmosphere was exquisite. 1
Good service, very clean, and inexpensive, to boot! 1
Plus, it's only 8 bucks. 1
The service was not up to par, either. 0
Thus far, have only visited twice and the food was absolutely delicious each time. 1
Just as good as when I had it more than a year ago! 1
For a self proclaimed coffee cafe, I was wildly disappointed. 0
The Veggitarian platter is out of this world! 1
You cant go wrong with any of the food here. 1
Stopped by this place while in Madison for the Ironman, very friendly, kind staff. 1
The chefs were friendly and did a good job. 1
I've had better, not only from dedicated boba tea spots, but even from Jenni Pho. 0
I liked the patio and the service was outstanding. 1
I think not again 0
I had the mac salad and it was pretty bland so I will not be getting that again. 0
Service stinks here! 0
I waited and waited. 0
I would definitely recommend the wings as well as the pizza. 1
Things that went wrong: - They burned the saganaki. 0
We waited an hour for what was a breakfast I could have done 100 times better at home. 0
Waited 2 hours & never got either of our pizzas as many other around us who came in later did! 0
Just don't know why they were so slow. 0
The staff is great, the food is delish, and they have an incredible beer selection. 1
I didn't know pulled pork could be soooo delicious. 1
You get incredibly fresh fish, prepared with care. 1
The food was excellent and service was very good. 1
Good beer & drink selection and good food selection. 1
The potato chip order was sad... I could probably count how many chips were in that box and it was probably around 12. 0
Food was really boring. 0
Good Service-check! 1
As much as I'd like to go back, I can't get passed the atrocious service and will never return. 0
I did not expect this to be so good! 1
Never going back. 0
The bus boy on the other hand was so rude. 0
By this point, my friends and I had basically figured out this place was a joke and didn't mind making it publicly and loudly known. 0
The only downside is the service. 0
Also, the fries are without a doubt the worst fries I've ever had. 0
A couple of months later, I returned and had an amazing meal. 1
Favorite place in town for shawarrrrrrma!!!!!! 1
They could serve it with just the vinaigrette and it may make for a better overall dish, but it was still very good. 1
When my mom and I got home she immediately got sick and she only had a few bites of salad. 0
The servers are not pleasant to deal with and they don't always honor Pizza Hut coupons. 0
Everything was gross. 0
the spaghetti is nothing special whatsoever. 0
The vegetables are so fresh and the sauce feels like authentic Thai. 1
It's worth driving up from Tucson! 1
The selection was probably the worst I've seen in Vegas.....there was none. 0
This place is like Chipotle, but BETTER. 1
5 stars for the brick oven bread app! 1
I have eaten here multiple times, and each time the food was delicious. 1
On the good side, the staff was genuinely pleasant and enthusiastic - a real treat. 1
As always the evening was wonderful and the food delicious! 1
The buffet is small and all the food they offered was BLAND. 0
Pretty cool I would say. 1
My wife had the Lobster Bisque soup which was lukewarm. 0
The staff are great, the ambiance is great. 1
The dining space is tiny, but elegantly decorated and comfortable. 1
They will customize your order any way you'd like, my usual is Eggplant with Green Bean stir fry, love it! 1
And the beans and rice were mediocre at best. 0
Best tacos in town by far!! 1
I took back my money and got outta there. 0
In an interesting part of town, this place is amazing. 1
The staff are now not as friendly, the wait times for being served are horrible, no one even says hi for the first 10 minutes. 0
I won't be back. 0
The service was outshining & I definitely recommend the Halibut. 1
The food was terrible. 0
WILL NEVER EVER GO BACK AND HAVE TOLD MANY PEOPLE WHAT HAD HAPPENED. 0
I don't recommend unless your car breaks down in front of it and you are starving. 0
I will come back here every time I'm in Vegas. 1
This is a disgrace. 0
If you want healthy authentic or ethic food, try this place. 1
I have been here several times in the past, and the experience has always been great. 1
Service was excellent and prices are pretty reasonable considering this is Vegas and located inside the Crystals shopping mall by Aria. 1
Kids pizza is always a hit too with lots of great side dish options for the kiddos! 1
Service is perfect and the family atmosphere is nice to see. 1
Great place to eat, reminds me of the little mom and pop shops in the San Francisco Bay Area. 1
Today was my first taste of a Buldogis Gourmet Hot Dog and I have to tell you it was more than I ever thought possible. 1
Left very frustrated. 0
I'll definitely be in soon again. 1
Food was really good and I got full petty fast. 1
TOTAL WASTE OF TIME. 0
For service, I give them no stars. 0
Gave up trying to eat any of the crust (teeth still sore). 0
But now I was completely grossed out. 0
First time going but I think I will quickly become a regular. 1
From what my dinner companions told me...everything was very fresh with nice texture and taste. 1
On the ground, right next to our table was a large, smeared, been-stepped-in-and-tracked-everywhere pile of green bird poop. 0
This is some seriously good pizza and I'm an expert/connisseur on the topic. 1
Waiter was a jerk. 0
These are the nicest restaurant owners I've ever come across. 1
Service is quick and friendly. 1
It was a huge awkward 1.5lb piece of cow that was 3/4ths gristle and fat. 0
Wow very spicy but delicious. 1
I'll take my business dinner dollars elsewhere. 0
I'd love to go back. 1
Anyway, this FS restaurant has a wonderful breakfast/lunch. 1
Each day of the week they have a different deal and it's all so delicious! 1
Not to mention the combination of pears, almonds and bacon is a big winner! 1
Sauce was tasteless. 0
The food is delicious and just spicy enough, so be sure to ask for spicier if you prefer it that way. 1
Food was so gooodd. 1
The last 3 times I had lunch here has been bad. 0
The chicken wings contained the driest chicken meat I have ever eaten. 0
The food was very good and I enjoyed every mouthful, an enjoyable relaxed venue for couples small family groups etc. 1
Best tater tots in the southwest. 1
Im in AZ all the time and now have my new spot. 1
The manager was the worst. 0
I don't think I'll be running back to Carly's anytime soon for food. 0
Don't waste your time here. 0
Total letdown, I would much rather just go to the Camelback Flower Shop and Cartel Coffee. 0
The steaks are all well trimmed and also perfectly cooked. 1
We had a group of 70+ when we claimed we would only have 40 and they handled us beautifully. 1
I LOVED it! 1
We asked for the bill to leave without eating and they didn't bring that either. 0
Seafood was limited to boiled shrimp and crab legs but the crab legs definitely did not taste fresh. 0
Delicious and I will absolutely be back! 1
This isn't a small family restaurant, this is a fine dining establishment. 1
I dont think I will be back for a very long time. 0
I will be back many times soon. 1
And then tragedy struck. 0
Waitress was sweet and funny. 1
I also had to taste my Mom's multi-grain pumpkin pancakes with pecan butter and they were amazing, fluffy, and delicious! 1
Cant say enough good things about this place. 1
The waitress and manager are so friendly. 1
I would not recommend this place. 0
Overall I wasn't very impressed with Noca. 0
Everything was perfect the night we were in. 1
The food is very good for your typical bar food. 1
At first glance it is a lovely bakery cafe - nice ambiance, clean, friendly staff. 1
Anyway, I do not think i will go back there. 0
Oh this is such a thing of beauty, this restaurant. 1
If you haven't gone here GO NOW! 1
A greasy, unhealthy meal. 0
Those burgers were amazing. 1
Be sure to order dessert, even if you need to pack it to-go - the tiramisu and cannoli are both to die for. 1
This was my first time and I can't wait until the next. 1
This place is two thumbs up....way up. 1
Terrible management. 0
Great steak, great sides, great wine, amazing desserts. 1
The steak and the shrimp are in my opinion the best entrees at GC. 1
We waited for thirty minutes to be seated (although there were 8 vacant tables and we were the only folks waiting). 0
I won't try going back there even if it's empty. 0
Just spicy enough.. Perfect actually. 1
Last night was my second time dining here and I was so happy I decided to go back! 1
The desserts were a bit strange. 0
My boyfriend and I came here for the first time on a recent trip to Vegas and could not have been more pleased with the quality of food and service. 1
Nice ambiance. 1
I would recommend saving room for this! 1
A good time! 1
Generous portions and great taste. 1
Food was delicious! 1
I consider this theft. 0
We recently witnessed her poor quality of management towards other guests as well. 0
Waited and waited and waited. 0
I swung in to give them a try but was deeply disappointed. 0
Service was good and the company was better! 1
The staff are also very friendly and efficient. 1
If you look for authentic Thai food, go else where. 0
Their steaks are 100% recommended! 1
I hate those things as much as cheap quality black olives. 0
The kids play area is NASTY! 0
Great place fo take out or eat in. 1
The waitress was friendly and happy to accomodate for vegan/veggie options. 1
It was a pale color instead of nice and char and has NO flavor. 0
The croutons also taste homemade which is an extra plus. 1
I got home to see the driest damn wings ever! 0
I really enjoyed Crema Café before they expanded; I even told friends they had the BEST breakfast. 1
Not good for the money. 0
I miss it and wish they had one in Philadelphia! 1
They also have the best cheese crisp in town. 1
Good value, great food, great service. 1
The food is good. 1
It was awesome. 1
We made the drive all the way from North Scottsdale... and I was not one bit disappointed! 1
!....THE OWNERS REALLY REALLY need to quit being soooooo cheap let them wrap my freaking sandwich in two papers not one! 0
I checked out this place a couple years ago and was not impressed. 0
The chicken I got was definitely reheated and was only ok, the wedges were cold and soggy. 0
An absolute must visit! 1
Despite how hard I rate businesses, its actually rare for me to give a 1 star. 0
I will not return. 0
I had the chicken Pho and it tasted very bland. 0
The grilled chicken was so tender and yellow from the saffron seasoning. 1
Pretty awesome place. 1
The staff is always super friendly and helpful, which is especially cool when you bring two small boys and a baby! 1
Four stars for the food & the guy in the blue shirt for his great vibe & still letting us in to eat ! 1
The roast beef sandwich tasted really good! 1
Ordered burger rare came in we'll done. 0
I was proven dead wrong by this sushi bar, not only because the quality is great, but the service is fast and the food, impeccable. 1
This is a good joint. 1
I'm not eating here! 0
This place has a lot of promise but fails to deliver. 0
Very bad Experience! 0
What a mistake. 0
Food was average at best. 0
We won't be going back anytime soon! 0
Very Very Disappointed ordered the $35 Big Bay Plater. 0
Great place to relax and have an awesome burger and beer. 1
It is PERFECT for a sit-down family meal or get together with a few friends. 1
Not much flavor to them, and very poorly constructed. 0
The patio seating was very comfortable. 1
The fried rice was dry as well. 0
I personally love the hummus, pita, baklava, falafels and Baba Ganoush (it's amazing what they do with eggplant!). 1
The owners are super friendly and the staff is courteous. 1
Both great! 1
Eclectic selection. 1
The staff was very attentive. 1
And the chef was generous with his time (even came around twice so we can take pictures with him). 1
The owner used to work at Nobu, so this place is really similar for half the price. 1
I can't wait to go back. 1
The plantains were the worst I've ever tasted. 0
It's a great place and I highly recommend it. 1
Your staff spends more time talking to themselves than me. 0
Damn good steak. 1
Total brunch fail. 0
The decor is nice, and the piano music soundtrack is pleasant. 1
I probably won't be back, to be honest. 0
The sergeant pepper beef sandwich with auju sauce is an excellent sandwich as well. 1
Went for lunch - service was slow. 0
We had so much to say about the place before we walked in that he expected it to be amazing, but was quickly disappointed. 0
I was mortified. 0
I wasn't really impressed with Strip Steak. 0
Have been going since 2007 and every meal has been awesome!! 1
The cashier was friendly and even brought the food out to me. 1
Would not recommend to others. 0
I mean really, how do you get so famous for your fish and chips when it's so terrible!?! 0
2 Thumbs Up!! 1
They have a really nice atmosphere. 1
Tonight I had the Elk Filet special...and it sucked. 0
We ordered some old classics and some new dishes after going there a few times and were sorely disappointed with everything. 0
Cute, quaint, simple, honest. 1
The chicken was deliciously seasoned and had the perfect fry on the outside and moist chicken on the inside. 1
Special thanks to Dylan T. for the recommendation on what to order :) All yummy for my tummy. 1
Great food and awesome service! 1
A FLY was in my apple juice.. A FLY!!!!!!!! 0
The food was barely lukewarm, so it must have been sitting waiting for the server to bring it out to us. 0
Overall, I like there food and the service. 1
They also now serve Indian naan bread with hummus and some spicy pine nut sauce that was out of this world. 1
Probably never coming back, and wouldn't recommend it. 0
Try them in the airport to experience some tasty food and speedy, friendly service. 1
Never had anything to complain about here. 1
The restaurant is very clean and has a family restaurant feel to it. 1
It was way over fried. 0
Will not be back! 0
An extensive menu provides lots of options for breakfast. 1
I have watched their prices inflate, portions get smaller and management attitudes grow rapidly! 0
Wonderful lil tapas and the ambience made me feel all warm and fuzzy inside. 1
Level 5 spicy was perfect, where spice didn't over-whelm the soup. 1
When I'm on this side of town, this will definitely be a spot I'll hit up again! 1
The chicken dishes are OK, the beef is like shoe leather. 0
The block was amazing. 1
* Both the Hot & Sour & the Egg Flower Soups were absolutely 5 Stars! 1
Great time - family dinner on a Sunday night. 1
What did bother me, was the slow service. 0
Their frozen margaritas are WAY too sugary for my taste. 0
Unfortunately, it was not good. 0
I had a pretty satifying experience. 1
Bland and flavorless is a good way of describing the barely tepid meat. 0
The chains, which I'm no fan of, beat this place easily. 0
Once your food arrives it's meh. 0
Paying $7.85 for a hot dog and fries that looks like it came out of a kid's meal at the Wienerschnitzel is not my idea of a good meal. 0
My brother in law who works at the mall ate here same day, and guess what he was sick all night too. 0
So good I am going to have to review this place twice - once hereas a tribute to the place and once as a tribute to an event held here last night. 1
The chips and salsa were really good, the salsa was very fresh. 1
Mediocre food. 0
Once you get inside you'll be impressed with the place. 1
And service was super friendly. 1
Why are these sad little vegetables so overcooked? 0
This place was such a nice surprise! 1
They were golden-crispy and delicious. 1
I had high hopes for this place since the burgers are cooked over a charcoal grill, but unfortunately the taste fell flat, way flat. 0
I could eat their bruschetta all day it is devine. 1
Not a single employee came out to see if we were OK or even needed a water refill once they finally served us our food. 0
The first time I ever came here I had an amazing experience, I still tell people how awesome the duck was. 1
The server was very negligent of our needs and made us feel very unwelcome... I would not suggest this place! 0
This place is overpriced, not consistent with their boba, and it really is OVERPRICED! 0
It was packed!! 0
The seasonal fruit was fresh white peach puree. 1
It kept getting worse and worse so now I'm officially done. 0
This place should honestly be blown up. 0
But I definitely would not eat here again. 0
The crêpe was delicate and thin and moist. 1
Awful service. 0
The service here is fair at best. 0
No one at the table thought the food was above average or worth the wait that we had for it. 0
Best service and food ever, Maria our server was so good and friendly she made our day. 1
They were excellent. 1
I paid the bill but did not tip because I felt the server did a terrible job. 0
Just had lunch here and had a great experience. 1
The food came out at a good pace. 1
I ate there twice on my last visit, and especially enjoyed the salmon salad. 1
We could not believe how dirty the oysters were! 0
I would not recommend this place. 0
To my disbelief, each dish qualified as the worst version of these foods I have ever tasted. 0
Bad day or not, I have a very low tolerance for rude customer service people, it is your job to be nice and polite, wash dishes otherwise!! 0
the potatoes were great and so was the biscuit. 1
So flavorful and has just the perfect amount of heat. 1
Went in for happy hour, great list of wines. 1
Some may say this buffet is pricey but I think you get what you pay for and this place you are getting quite a lot! 1
This place is pretty good, nice little vibe in the restaurant. 1
Talk about great customer service of course we will be back. 1
I love their fries and their beans. 1
They have a plethora of salads and sandwiches, and everything I've tried gets my seal of approval. 1
For sushi on the Strip, this is the place to go. 1
The feel of the dining room was more college cooking course than high class dining and the service was slow at best. 0
I started this review with two stars, but I'm editing it to give it only one. 0
Weird vibe from owners. 0
There was hardly any meat. 0
I've had better bagels from the grocery store. 0
I love the owner/chef, his one authentic Japanese cool dude! 1
Now the burgers aren't as good, the pizza which used to be amazing is doughy and flavorless. 0
The service was terrible, food was mediocre. 0
I ordered Albondigas soup - which was just warm - and tasted like tomato soup with frozen meatballs. 0
On three different occasions I asked for well done or medium well, and all three times I got the bloodiest piece of meat on my plate. 0
The service was extremely slow. 0
After 20 minutes wait, I got a table. 0
No allergy warnings on the menu, and the waitress had absolutely no clue as to which meals did or did not contain peanuts. 0
My boyfriend tried the Mediterranean Chicken Salad and fell in love. 1
I want to first say our server was great and we had perfect service. 1
The pizza selections are good. 1
I had strawberry tea, which was good. 1
Spend your money elsewhere. 0
Their regular toasted bread was equally satisfying with the occasional pats of butter... Mmmm...! 1
The Buffet at Bellagio was far from what I anticipated. 0
And the drinks are WEAK, people! 0
-My order was not correct. 0
Very, very sad. 0
I'm not impressed with the concept or the food. 0
I got food poisoning here at the buffet. 0
They brought a fresh batch of fries and I was thinking yay something warm but no! 0
What SHOULD have been a hilarious, yummy Christmas Eve dinner to remember was the biggest fail of the entire trip for us. 0
Needless to say, I won't be going back anytime soon. 0
The RI style calamari was a joke. 0
It was so bad, I had lost the heart to finish it. 0
We aren't ones to make a scene at restaurants but I just don't get it...definitely lost the love after this one! 0
The food is about on par with Denny's, which is to say, not good at all. 0
WAAAAAAyyyyyyyyyy over rated is all I am saying. 0
This place lacked style!! 0
The sangria was about half of a glass wine full and was $12, ridiculous. 0
Don't bother coming here. 0
The building itself seems pretty neat; the bathroom is pretty trippy, but I wouldn't eat here again. 0
Probably not in a hurry to go back. 0
Not good by any stretch of the imagination. 0
The cashew cream sauce was bland and the vegetables were undercooked. 0
It was a bit too sweet, not really spicy enough, and lacked flavor. 0
This place is horrible and way overpriced. 0
It wasn't busy at all and now we know why. 0
The ambiance here did not feel like a buffet setting, but more of a douchey indoor garden for tea and biscuits. 0
Con: spotty service. 0
The fries were not hot, and neither was my burger. 0
The real disappointment was our waiter. 0
My husband said she was very rude... did not even apologize for the bad food or anything. 0
She was quite disappointed although some blame needs to be placed at her door. 0
Del Taco is pretty nasty and should be avoided if possible. 0
We've have gotten a much better service from the pizza place next door than the services we received from this restaurant. 0
The ambiance isn't much better. 0
Unfortunately, it only set us up for disapppointment with our entrees. 0
The food wasn't good. 0
too bad cause I know it's family owned, I really wanted to like this place. 0
I kept looking at the time and it had soon become 35 minutes, yet still no food. 0
We started with the tuna sashimi which was brownish in color and obviously wasn't fresh. 0
Food was below average. 0
It sure does beat the nachos at the movies but I would expect a little bit more coming from a restaurant. 0
The problem I have is that they charge $11.99 for a sandwich that is no bigger than a Subway sub (which offers better and more amount of vegetables). 0
It lacked flavor, seemed undercooked, and dry. 0
The refried beans that came with my meal were dried out and crusty and the food was bland. 0
A lady at the table next to us found a live green caterpillar In her salad. 0

View File

@@ -0,0 +1,37 @@
##### To Run This Program #####
Run one of the lines below replacing arguments as necessary:
./bloom_filter.py -d dictionary.txt -i input.txt -o output3.txt output5.txt
OR
python3 bloom_filter.py -d dictionary.txt -i input.txt -o output3.txt output5.txt
Both of the above commands have been tested on this program on the OSU Flip servers.
There is no guarantee that this will run on any computers other than these servers!!!
No makefile is needed for this program.
##### Answers to Questions #####
a.
The functions I chose were ripemd160, sha256, whirlpool, md5, and DSA. These are all cryptographic hashes. I chose
them because they are less likely to generate collisions than non-cryptographic ones (at the expense of being slower),
as well as because they are the ones build into the hashlib library for python3 on the flip servers, which guarantees
that the grader will be able to run the program without having to install or include additional libraries.
b.
ripemd160: 0.000006914
sha256: 0.00001025
whirlpool: 0.00001121
md5: 0.00001025
DSA: 0.000009298
ripemd160 and DSA are the fastest, though not by much. They perform better as their algorithms to generate the hash
computer more quickly than the others. It is also likely that the length of the hash output is shorter than ones like
sha256, which are quite large.
c.
The probability of false positives is 1% as I set the hash bit array size to 5976456, which I calculated using a
dictionary size of 623518. The result of the false positive equation -((623518 * log(0.01)/(log^2(2))) = 5976456.
The probability of false negatives is 0%. It is not possible to have a false negative with a bloom filter.
d.
The rate of false positives can be reduced by increasing the number of storable positions for the the hash bit array, or
by reducing the number of hash functions used to reduce collisions.

View File

@@ -0,0 +1,125 @@
#!/usr/bin/env python3
# ##### Includes #####
# System includes
import sys
import getopt
import hashlib
import random
from time import time
# ##### Global Variables #####
USAGE_STRING = "usage: ./bloom_filter.py -d dictionary.txt -i input.txt -o output3.txt output5.txt"
NUM_ARGUMENTS_CORRECT = 7
HASH_ARRAY_SIZE = 5976456 # should be a 1% false positive rate
ARGUMENT_MAPPING = {
"dictionary": 1,
"input": 3,
"three_hash": 5,
"five_hash": 6
}
AVAILABLE_HASHES = [
"ripemd160",
"sha256",
"whirlpool",
"md5",
"DSA"
]
# ##### Bloom Filter Class #####
class BloomFilter(object):
def __init__(self, arguments):
super(BloomFilter, self).__init__()
if len(arguments) != NUM_ARGUMENTS_CORRECT:
print(USAGE_STRING)
sys.exit(2)
self.dictionary_path = None
self.input_file_path = None
self.three_hash_output_path = None
self.five_hash_output_path = None
self.three_hash_dictionary = {i: 0 for i in range(HASH_ARRAY_SIZE)}
self.five_hash_dictionary = {i: 0 for i in range(HASH_ARRAY_SIZE)}
self.dictionary_path = arguments[ARGUMENT_MAPPING["dictionary"]]
self.input_file_path = arguments[ARGUMENT_MAPPING["input"]]
self.three_hash_output_path = arguments[ARGUMENT_MAPPING["three_hash"]]
self.five_hash_output_path = arguments[ARGUMENT_MAPPING["five_hash"]]
def generate_filters(self):
dictionary_file = open(self.dictionary_path, "r", encoding="latin-1")
lines = dictionary_file.read().splitlines()
print("Generating filter using \"%s\". This will take a few moments." % self.dictionary_path)
for password in lines:
clean_password = password.strip()
for i in range(5):
five_hasher = hashlib.new(AVAILABLE_HASHES[i])
five_hasher.update(clean_password.encode())
current_hash = int(five_hasher.hexdigest(), 16)
self.five_hash_dictionary[current_hash % HASH_ARRAY_SIZE] = 1
for i in range(3):
three_hasher = hashlib.new(AVAILABLE_HASHES[i])
three_hasher.update(clean_password.encode())
current_hash = int(three_hasher.hexdigest(), 16)
self.three_hash_dictionary[current_hash % HASH_ARRAY_SIZE] = 1
print("Filter generation complete.")
dictionary_file.close()
def process_inputs_and_generate_outputs(self):
input_file = open(self.input_file_path, "r", encoding="latin-1")
lines = input_file.read().splitlines()
output_file_three_hash = open(self.three_hash_output_path, "w")
output_file_five_hash = open(self.five_hash_output_path, "w")
print("Processing input file \"%s\" and writing outputs to \"%s\" and \"%s\"." %
(self.input_file_path, self.three_hash_output_path, self.five_hash_output_path))
for password in lines[1:]:
in_set_three = True
in_set_five = True
clean_password = password.strip()
for i in range(5):
five_hasher = hashlib.new(AVAILABLE_HASHES[i])
five_hasher.update(clean_password.encode())
current_hash = int(five_hasher.hexdigest(), 16)
if self.five_hash_dictionary[current_hash % HASH_ARRAY_SIZE] == 0:
in_set_five = False
for i in range(3):
three_hasher = hashlib.new(AVAILABLE_HASHES[i])
three_hasher.update(clean_password.encode())
current_hash = int(three_hasher.hexdigest(), 16)
if self.three_hash_dictionary[current_hash % HASH_ARRAY_SIZE] == 0:
in_set_three = False
output_file_three_hash.write("%s\n" % ("no" if not in_set_three else "maybe"))
output_file_five_hash.write("%s\n" % ("no" if not in_set_five else "maybe"))
print("Processing complete.")
input_file.close()
output_file_three_hash.close()
output_file_five_hash.close()
# ##### Main #####
if __name__ == "__main__":
bloom_filter = BloomFilter(sys.argv[1:])
bloom_filter.generate_filters()
bloom_filter.process_inputs_and_generate_outputs()

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
17
*holly&ben
*homo*
*vanusa*
010605
010605
walton-dutch-luzon-post
012190
0121909334
maskflower
2,,{H99*X(
darry-bethel-cube-mess
masking
undersupplied
undersupplies
7^*.$?GC86
undersupply
9Ca5B>w8.Q}bhU=ss*sK
karl

View File

@@ -0,0 +1,12 @@
no
maybe
no
no
no
maybe
no
maybe
maybe
maybe
no
maybe

View File

@@ -0,0 +1,235 @@
;***********************************************************
;*
;* BasicBumpBot.asm - V2.0
;*
;* This program contains the neccessary code to enable the
;* the TekBot to behave in the traditional BumpBot fashion.
;* It is written to work with the latest TekBots platform.
;* If you have an earlier version you may need to modify
;* your code appropriately.
;*
;* The behavior is very simple. Get the TekBot moving
;* forward and poll for whisker inputs. If the right
;* whisker is activated, the TekBot backs up for a second,
;* turns left for a second, and then moves forward again.
;* If the left whisker is activated, the TekBot backs up
;* for a second, turns right for a second, and then
;* continues forward.
;*
;***********************************************************
;*
;* Author: David Zier and Mohammed Sinky (modification Jan 8, 2009)
;* Date: January 8, 2009
;* Company: TekBots(TM), Oregon State University - EECS
;* Version: 2.0
;*
;***********************************************************
;* Rev Date Name Description
;*----------------------------------------------------------
;* - 3/29/02 Zier Initial Creation of Version 1.0
;* - 1/08/09 Sinky Version 2.0 modifictions
;*
;***********************************************************
.include "m128def.inc" ; Include definition file
;************************************************************
;* Variable and Constant Declarations
;************************************************************
.def mpr = r16 ; Multi-Purpose Register
.def waitcnt = r17 ; Wait Loop Counter
.def ilcnt = r18 ; Inner Loop Counter
.def olcnt = r19 ; Outer Loop Counter
.equ WTime = 100 ; Time to wait in wait loop, used to be 100
.equ RWTime = 200 ; Time to wait in wait loop, used to be 100
.equ WskrR = 0 ; Right Whisker Input Bit
.equ WskrL = 1 ; Left Whisker Input Bit
.equ EngEnR = 4 ; Right Engine Enable Bit
.equ EngEnL = 7 ; Left Engine Enable Bit
.equ EngDirR = 5 ; Right Engine Direction Bit
.equ EngDirL = 6 ; Left Engine Direction Bit
;/////////////////////////////////////////////////////////////
;These macros are the values to make the TekBot Move.
;/////////////////////////////////////////////////////////////
.equ MovFwd = (1<<EngDirR|1<<EngDirL) ; Move Forward Command
.equ MovBck = $00 ; Move Backward Command
.equ TurnR = (1<<EngDirL) ; Turn Right Command
.equ TurnL = (1<<EngDirR) ; Turn Left Command
.equ Halt = (1<<EngEnR|1<<EngEnL) ; Halt Command
;============================================================
; NOTE: Let me explain what the macros above are doing.
; Every macro is executing in the pre-compiler stage before
; the rest of the code is compiled. The macros used are
; left shift bits (<<) and logical or (|). Here is how it
; works:
; Step 1. .equ MovFwd = (1<<EngDirR|1<<EngDirL)
; Step 2. substitute constants
; .equ MovFwd = (1<<5|1<<6)
; Step 3. calculate shifts
; .equ MovFwd = (b00100000|b01000000)
; Step 4. calculate logical or
; .equ MovFwd = b01100000
; Thus MovFwd has a constant value of b01100000 or $60 and any
; instance of MovFwd within the code will be replaced with $60
; before the code is compiled. So why did I do it this way
; instead of explicitly specifying MovFwd = $60? Because, if
; I wanted to put the Left and Right Direction Bits on different
; pin allocations, all I have to do is change thier individual
; constants, instead of recalculating the new command and
; everything else just falls in place.
;==============================================================
;**************************************************************
;* Beginning of code segment
;**************************************************************
.cseg
;--------------------------------------------------------------
; Interrupt Vectors
;--------------------------------------------------------------
.org $0000 ; Reset and Power On Interrupt
rjmp INIT ; Jump to program initialization
.org $0046 ; End of Interrupt Vectors
;--------------------------------------------------------------
; Program Initialization
;--------------------------------------------------------------
INIT:
; Initialize the Stack Pointer (VERY IMPORTANT!!!!)
ldi mpr, low(RAMEND)
out SPL, mpr ; Load SPL with low byte of RAMEND
ldi mpr, high(RAMEND)
out SPH, mpr ; Load SPH with high byte of RAMEND
; Initialize Port B for output
ldi mpr, $FF ; Set Port B Data Direction Register
out DDRB, mpr ; for output
ldi mpr, $00 ; Initialize Port B Data Register
out PORTB, mpr ; so all Port B outputs are low
; Initialize Port D for input
ldi mpr, $00 ; Set Port D Data Direction Register
out DDRD, mpr ; for input
ldi mpr, $FF ; Initialize Port D Data Register
out PORTD, mpr ; so all Port D inputs are Tri-State
; Initialize TekBot Forward Movement
ldi mpr, MovFwd ; Load Move Forward Command
out PORTB, mpr ; Send command to motors
;---------------------------------------------------------------
; Main Program
;---------------------------------------------------------------
MAIN:
in mpr, PIND ; Get whisker input from Port D
andi mpr, (1<<WskrR|1<<WskrL)
cpi mpr, (1<<WskrL) ; Check for Right Whisker input (Recall Active Low)
brne NEXT ; Continue with next check
rcall HitRight ; Call the subroutine HitRight
rjmp MAIN ; Continue with program
NEXT: cpi mpr, (1<<WskrR) ; Check for Left Whisker input (Recall Active)
brne MAIN ; No Whisker input, continue program
rcall HitLeft ; Call subroutine HitLeft
rjmp MAIN ; Continue through main
;****************************************************************
;* Subroutines and Functions
;****************************************************************
;----------------------------------------------------------------
; Sub: HitRight
; Desc: Handles functionality of the TekBot when the right whisker
; is triggered.
;----------------------------------------------------------------
HitRight:
push mpr ; Save mpr register
push waitcnt ; Save wait register
in mpr, SREG ; Save program state
push mpr ;
; Move Backwards for a second
ldi mpr, MovBck ; Load Move Backward command
out PORTB, mpr ; Send command to port
ldi waitcnt, RWTime ; Wait for 1 second
rcall Wait ; Call wait function
; Turn left for a second
ldi mpr, TurnL ; Load Turn Left Command
out PORTB, mpr ; Send command to port
ldi waitcnt, WTime ; Wait for 1 second
rcall Wait ; Call wait function
; Move Forward again
ldi mpr, MovFwd ; Load Move Forward command
out PORTB, mpr ; Send command to port
pop mpr ; Restore program state
out SREG, mpr ;
pop waitcnt ; Restore wait register
pop mpr ; Restore mpr
ret ; Return from subroutine
;----------------------------------------------------------------
; Sub: HitLeft
; Desc: Handles functionality of the TekBot when the left whisker
; is triggered.
;----------------------------------------------------------------
HitLeft:
push mpr ; Save mpr register
push waitcnt ; Save wait register
in mpr, SREG ; Save program state
push mpr ;
; Move Backwards for a second
ldi mpr, MovBck ; Load Move Backward command
out PORTB, mpr ; Send command to port
ldi waitcnt, RWTime ; Wait for 1 second
rcall Wait ; Call wait function
; Turn right for a second
ldi mpr, TurnR ; Load Turn Left Command
out PORTB, mpr ; Send command to port
ldi waitcnt, WTime ; Wait for 1 second
rcall Wait ; Call wait function
; Move Forward again
ldi mpr, MovFwd ; Load Move Forward command
out PORTB, mpr ; Send command to port
pop mpr ; Restore program state
out SREG, mpr ;
pop waitcnt ; Restore wait register
pop mpr ; Restore mpr
ret ; Return from subroutine
;----------------------------------------------------------------
; Sub: Wait
; Desc: A wait loop that is 16 + 159975*waitcnt cycles or roughly
; waitcnt*10ms. Just initialize wait for the specific amount
; of time in 10ms intervals. Here is the general eqaution
; for the number of clock cycles in the wait loop:
; ((3 * ilcnt + 3) * olcnt + 3) * waitcnt + 13 + call
;----------------------------------------------------------------
Wait:
push waitcnt ; Save wait register
push ilcnt ; Save ilcnt register
push olcnt ; Save olcnt register
Loop: ldi olcnt, 224 ; load olcnt register
OLoop: ldi ilcnt, 237 ; load ilcnt register
ILoop: dec ilcnt ; decrement ilcnt
brne ILoop ; Continue Inner Loop
dec olcnt ; decrement olcnt
brne OLoop ; Continue Outer Loop
dec waitcnt ; Decrement wait
brne Loop ; Continue Wait loop
pop olcnt ; Restore olcnt register
pop ilcnt ; Restore ilcnt register
pop waitcnt ; Restore wait register
ret ; Return from subroutine

View File

@@ -0,0 +1,13 @@
:020000020000FC
:0200000045C0F9
:10008C000FEF0DBF00E10EBF0FEF07BB00E008BB89
:10009C0000E001BB0FEF02BB00E608BB00B303702E
:1000AC00023011F405D0FACF0130C1F714D0F6CFDD
:1000BC000F931F930FB70F9300E008BB18EC1ED0E3
:1000CC0000E208BB14E61AD000E608BB0F910FBF84
:1000DC001F910F9108950F931F930FB70F9300E08B
:1000EC0008BB18EC0BD000E408BB14E607D000E604
:1000FC0008BB0F910FBF1F910F9108951F932F9362
:10010C003F9330EE2DEE2A95F1F73A95D9F71A95E3
:0A011C00C1F73F912F911F91089544
:00000001FF

View File

@@ -0,0 +1,6 @@
#!/bin/bash
# alternate avra BasicBumpBot.asm
/opt/gavrasm/gavrasm -X BasicBumpBot.asm
avrdude -c usbasp -p m128 -U flash:w:BasicBumpBot.hex
rm BasicBumpBot.lst

View File

@@ -0,0 +1,36 @@
/*
This code will cause a TekBot connected to a mega128 board to 'dance' in a cool
pattern. No pins are used as input, and four Port B pins are used for output.
PORT MAP
Port B, Pin 4 -> Output -> Right Motor Enable
Port B, Pin 5 -> Output -> Right Motor Direction
Port B, Pin 7 -> Output -> Left Motor Enable
Port B, Pin 6 -> Output -> Left Motor Direction
*/
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
int main(void)
{
DDRB = 0b11110000; // configure Port B pins for input/output
PORTB = 0b11110000; // set initial value for Port B outputs
// (initially, disable both motors)
while (1) { // loop forever
PORTB = 0b01100000; // make TekBot move forward
_delay_ms(500); // wait for 500 ms
PORTB = 0b00000000; // move backward
_delay_ms(500); // wait for 500 ms
PORTB = 0b00100000; // turn left
_delay_ms(1000); // wait for 1 s
PORTB = 0b01000000; // turn right
_delay_ms(2000); // wait for 2 s
PORTB = 0b00100000; // turn left
_delay_ms(1000); // wait for 1 s
}
}

View File

@@ -0,0 +1,19 @@
:100000000C9446000C9450000C9450000C9450003A
:100010000C9450000C9450000C9450000C94500020
:100020000C9450000C9450000C9450000C94500010
:100030000C9450000C9450000C9450000C94500000
:100040000C9450000C9450000C9450000C945000F0
:100050000C9450000C9450000C9450000C945000E0
:100060000C9450000C9450000C9450000C945000D0
:100070000C9450000C9450000C9450000C945000C0
:100080000C9450000C9450000C94500011241FBE8E
:10009000CFEFD0E1DEBFCDBF0E9452000C948B00A9
:1000A0000C94000080EF87BB88BB20E680E290E4E0
:1000B00028BB3FEF49E658E1315040405040E1F75E
:1000C00000C0000018BA3FEF49E658E13150404007
:1000D0005040E1F700C0000088BB3FEF43ED50E324
:1000E000315040405040E1F700C0000098BB3FEF66
:1000F00047EA51E6315040405040E1F700C000006F
:1001000088BB3FEF43ED50E3315040405040E1F7B2
:0A01100000C00000CDCFF894FFCF2F
:00000001FF

View File

@@ -0,0 +1,16 @@
MCU=atmega128
CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS=-std=c99 -Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
TARGET=main
SRCS=DanceBot.c
all:
${CC} ${CFLAGS} -o ${TARGET}.bin ${SRCS}
${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.bin ${TARGET}.hex
flash:
avrdude -p ${MCU} -c usbasp -U flash:w:${TARGET}.hex:i -F -P usb
clean:
rm -f *.bin *.hex

View File

@@ -0,0 +1,136 @@
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
// Generic register bitwise operators
#define REG_SET(reg, pin) (reg |= _BV(pin))
#define REG_CLR(reg, pin) (reg &= ~(_BV(pin)))
#define REG_WRITE(reg, pin, value) ((value == 1) ? REG_SET(reg, pin) : REG_CLR(reg, pin))
#define REG_CHECK(reg, pin) ((reg &= (_BV(pin))) > 0)
// Right motor enable
#define RME_DDR DDRB
#define RME_OUT PORTB
#define RME_IN PINB
#define RME_PIN 4
#define RME_IO_OUT() (REG_SET(RME_DDR, RME_PIN))
#define RME_IO_IN() (REG_CLR(RME_DDR, RME_PIN))
#define RME_SET() (REG_SET(RME_OUT, RME_PIN))
#define RME_CLR() (REG_CLR(RME_OUT, RME_PIN))
#define RME_WRITE(value) (REG_WRITE(RME_OUT, RME_PIN, value))
#define RME_STATE() (REG_CHECK(RME_IN, RME_PIN))
// Right motor drive
#define RMD_DDR DDRB
#define RMD_OUT PORTB
#define RMD_IN PINB
#define RMD_PIN 5
#define RMD_IO_OUT() (REG_SET(RMD_DDR, RMD_PIN))
#define RMD_IO_IN() (REG_CLR(RMD_DDR, RMD_PIN))
#define RMD_SET() (REG_SET(RMD_OUT, RMD_PIN))
#define RMD_CLR() (REG_CLR(RMD_OUT, RMD_PIN))
#define RMD_WRITE(value) (REG_WRITE(RMD_OUT, RMD_PIN, value))
#define RMD_STATE() (REG_CHECK(RMD_IN, RMD_PIN))
// Left motor enable
#define LME_DDR DDRB
#define LME_OUT PORTB
#define LME_IN PINB
#define LME_PIN 7
#define LME_IO_OUT() (REG_SET(LME_DDR, LME_PIN))
#define LME_IO_IN() (REG_CLR(LME_DDR, LME_PIN))
#define LME_SET() (REG_SET(LME_OUT, LME_PIN))
#define LME_CLR() (REG_CLR(LME_OUT, LME_PIN))
#define LME_WRITE(value) (REG_WRITE(LME_OUT, LME_PIN, value))
#define LME_STATE() (REG_CHECK(LME_IN, LME_PIN))
// Left motor drive
#define LMD_DDR DDRB
#define LMD_OUT PORTB
#define LMD_IN PINB
#define LMD_PIN 6
#define LMD_IO_OUT() (REG_SET(LMD_DDR, LMD_PIN))
#define LMD_IO_IN() (REG_CLR(LMD_DDR, LMD_PIN))
#define LMD_SET() (REG_SET(LMD_OUT, LMD_PIN))
#define LMD_CLR() (REG_CLR(LMD_OUT, LMD_PIN))
#define LMD_WRITE(value) (REG_WRITE(LMD_OUT, LMD_PIN, value))
#define LMD_STATE() (REG_CHECK(LMD_IN, LMD_PIN))
// Left whisker
#define LW_DDR DDRD
#define LW_OUT PORTD
#define LW_IN PIND
#define LW_PIN 1
#define LW_IO_OUT() (REG_SET(LW_DDR, LW_PIN))
#define LW_IO_IN() (REG_CLR(LW_DDR, LW_PIN))
#define LW_SET() (REG_SET(LW_OUT, LW_PIN))
#define LW_CLR() (REG_CLR(LW_OUT, LW_PIN))
#define LW_WRITE(value) (REG_WRITE(LW_OUT, LW_PIN, value))
#define LW_STATE() (REG_CHECK(LW_IN, LW_PIN))
// Right whisker
#define RW_DDR DDRD
#define RW_OUT PORTD
#define RW_IN PIND
#define RW_PIN 0
#define RW_IO_OUT() (REG_SET(RW_DDR, RW_PIN))
#define RW_IO_IN() (REG_CLR(RW_DDR, RW_PIN))
#define RW_SET() (REG_SET(RW_OUT, RW_PIN))
#define RW_CLR() (REG_CLR(RW_OUT, RW_PIN))
#define RW_WRITE(value) (REG_WRITE(RW_OUT, RW_PIN, value))
#define RW_STATE() (REG_CHECK(RW_IN, RW_PIN))
const unsigned int backup_time = 1000; //ms
const unsigned int debounce_time = 200; //ms
int main(void){
// Set motor enable and direction to outputs
RME_IO_OUT();
RMD_IO_OUT();
LME_IO_OUT();
LMD_IO_OUT();
// Set whiskers to inputs and enable pullup resistors
LW_IO_IN();
LW_SET();
RW_IO_IN();
RW_SET();
// Enables motors and sets bot to move forward
RMD_SET();
LMD_SET();
RME_CLR(); // Setting to zero enables motors
LME_CLR(); // Setting to zero enables motors
// Main program loop
while (1){
// Get states of whiskers
unsigned char lw_pressed = !LW_STATE();
unsigned char rw_pressed = !RW_STATE();
// Handle noise from button press
_delay_ms(debounce_time);
// Logic if the right whisker is pressed
if(rw_pressed){
RMD_CLR();
LMD_CLR();
_delay_ms(backup_time);
RMD_SET();
_delay_ms(backup_time);
LMD_SET();
// Logic if the right whisker is pressed
}else if(lw_pressed){
RMD_CLR();
LMD_CLR();
_delay_ms(backup_time);
LMD_SET();
_delay_ms(backup_time);
RMD_SET();
}
}
}

View File

@@ -0,0 +1,24 @@
:100000000C9446000C945D000C945D000C945D0013
:100010000C945D000C945D000C945D000C945D00EC
:100020000C945D000C945D000C945D000C945D00DC
:100030000C945D000C945D000C945D000C945D00CC
:100040000C945D000C945D000C945D000C945D00BC
:100050000C945D000C945D000C945D000C945D00AC
:100060000C945D000C945D000C945D000C945D009C
:100070000C945D000C945D000C945D000C945D008C
:100080000C945D000C945D000C945D0011241FBE67
:10009000CFEFD0E1DEBFCDBF11E0A0E0B1E0ECE5F5
:1000A000F1E000E00BBF02C007900D92A430B10751
:1000B000D9F70E945F000C94AC000C940000BC9A2D
:1000C000BD9ABF9ABE9A8998919A8898909AC59A33
:1000D000C69AC498C79880B3827080BB90B3917061
:1000E00090BB2FEF33EC49E0215030404040E1F726
:1000F00000C00000911117C0C598C6988FEF93ED0E
:1001000020E3815090402040E1F700C00000C59AF4
:100110003FEF43ED80E3315040408040E1F700C0C5
:100120000000C69AD8CF8111D6CFC598C6989FEF48
:1001300023ED30E3915020403040E1F700C0000053
:10014000C69A4FEF83ED90E3415080409040E1F735
:0C01500000C00000C59ABFCFF894FFCF9C
:04015C00C800E803EC
:00000001FF

View File

@@ -0,0 +1,16 @@
MCU=atmega128
CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS=-std=c99 -Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
TARGET=main
SRCS=Corwin_Perren_Lab2_sourcecode.c
all:
${CC} ${CFLAGS} -o ${TARGET}.bin ${SRCS}
${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.bin ${TARGET}.hex
flash:
avrdude -p ${MCU} -c usbasp -U flash:w:${TARGET}.hex:i -F -P usb
clean:
rm -f *.bin *.hex

View File

@@ -0,0 +1,148 @@
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
// Generic register bitwise operators
#define REG_SET(reg, pin) (reg |= _BV(pin))
#define REG_CLR(reg, pin) (reg &= ~(_BV(pin)))
#define REG_WRITE(reg, pin, value) ((value == 1) ? REG_SET(reg, pin) : REG_CLR(reg, pin))
#define REG_CHECK(reg, pin) ((reg &= (_BV(pin))) > 0)
// Right motor enable
#define RME_DDR DDRB
#define RME_OUT PORTB
#define RME_IN PINB
#define RME_PIN 4
#define RME_IO_OUT() (REG_SET(RME_DDR, RME_PIN))
#define RME_IO_IN() (REG_CLR(RME_DDR, RME_PIN))
#define RME_SET() (REG_SET(RME_OUT, RME_PIN))
#define RME_CLR() (REG_CLR(RME_OUT, RME_PIN))
#define RME_WRITE(value) (REG_WRITE(RME_OUT, RME_PIN, value))
#define RME_STATE() (REG_CHECK(RME_IN, RME_PIN))
// Right motor drive
#define RMD_DDR DDRB
#define RMD_OUT PORTB
#define RMD_IN PINB
#define RMD_PIN 5
#define RMD_IO_OUT() (REG_SET(RMD_DDR, RMD_PIN))
#define RMD_IO_IN() (REG_CLR(RMD_DDR, RMD_PIN))
#define RMD_SET() (REG_SET(RMD_OUT, RMD_PIN))
#define RMD_CLR() (REG_CLR(RMD_OUT, RMD_PIN))
#define RMD_WRITE(value) (REG_WRITE(RMD_OUT, RMD_PIN, value))
#define RMD_STATE() (REG_CHECK(RMD_IN, RMD_PIN))
// Left motor enable
#define LME_DDR DDRB
#define LME_OUT PORTB
#define LME_IN PINB
#define LME_PIN 7
#define LME_IO_OUT() (REG_SET(LME_DDR, LME_PIN))
#define LME_IO_IN() (REG_CLR(LME_DDR, LME_PIN))
#define LME_SET() (REG_SET(LME_OUT, LME_PIN))
#define LME_CLR() (REG_CLR(LME_OUT, LME_PIN))
#define LME_WRITE(value) (REG_WRITE(LME_OUT, LME_PIN, value))
#define LME_STATE() (REG_CHECK(LME_IN, LME_PIN))
// Left motor drive
#define LMD_DDR DDRB
#define LMD_OUT PORTB
#define LMD_IN PINB
#define LMD_PIN 6
#define LMD_IO_OUT() (REG_SET(LMD_DDR, LMD_PIN))
#define LMD_IO_IN() (REG_CLR(LMD_DDR, LMD_PIN))
#define LMD_SET() (REG_SET(LMD_OUT, LMD_PIN))
#define LMD_CLR() (REG_CLR(LMD_OUT, LMD_PIN))
#define LMD_WRITE(value) (REG_WRITE(LMD_OUT, LMD_PIN, value))
#define LMD_STATE() (REG_CHECK(LMD_IN, LMD_PIN))
// Left whisker
#define LW_DDR DDRD
#define LW_OUT PORTD
#define LW_IN PIND
#define LW_PIN 1
#define LW_IO_OUT() (REG_SET(LW_DDR, LW_PIN))
#define LW_IO_IN() (REG_CLR(LW_DDR, LW_PIN))
#define LW_SET() (REG_SET(LW_OUT, LW_PIN))
#define LW_CLR() (REG_CLR(LW_OUT, LW_PIN))
#define LW_WRITE(value) (REG_WRITE(LW_OUT, LW_PIN, value))
#define LW_STATE() (REG_CHECK(LW_IN, LW_PIN))
// Right whisker
#define RW_DDR DDRD
#define RW_OUT PORTD
#define RW_IN PIND
#define RW_PIN 0
#define RW_IO_OUT() (REG_SET(RW_DDR, RW_PIN))
#define RW_IO_IN() (REG_CLR(RW_DDR, RW_PIN))
#define RW_SET() (REG_SET(RW_OUT, RW_PIN))
#define RW_CLR() (REG_CLR(RW_OUT, RW_PIN))
#define RW_WRITE(value) (REG_WRITE(RW_OUT, RW_PIN, value))
#define RW_STATE() (REG_CHECK(RW_IN, RW_PIN))
const unsigned int drive_forward_time = 500;
const unsigned int backup_time = 250; //ms
const unsigned int debounce_time = 20; //ms
int main(void){
// Set motor enable and direction to outputs
RME_IO_OUT();
RMD_IO_OUT();
LME_IO_OUT();
LMD_IO_OUT();
// Set whiskers to inputs and enable pullup resistors
LW_IO_IN();
LW_SET();
RW_IO_IN();
RW_SET();
// Enables motors and sets bot to move forward
RMD_SET();
LMD_SET();
RME_CLR(); // Setting to zero enables motors
LME_CLR(); // Setting to zero enables motors
// Main program loop
while (1){
// Get states of whiskers
unsigned char lw_pressed = !LW_STATE();
unsigned char rw_pressed = !RW_STATE();
// Handle noise from button press
_delay_ms(debounce_time);
// Logic if the both whiskers are pressed
if(rw_pressed && lw_pressed){
_delay_ms(drive_forward_time);
RMD_CLR();
LMD_CLR();
_delay_ms(backup_time);
LMD_SET();
RMD_SET();
// Logic if the right whisker is pressed
}else if(rw_pressed){
_delay_ms(drive_forward_time);
RMD_CLR();
LMD_CLR();
_delay_ms(backup_time);
LMD_SET();
_delay_ms(backup_time);
RMD_SET();
// Logic if the left whisker is pressed
}else if(lw_pressed){
_delay_ms(drive_forward_time);
RMD_CLR();
LMD_CLR();
_delay_ms(backup_time);
RMD_SET();
_delay_ms(backup_time);
LMD_SET();
}
}
}

View File

@@ -0,0 +1,29 @@
:100000000C9446000C945D000C945D000C945D0013
:100010000C945D000C945D000C945D000C945D00EC
:100020000C945D000C945D000C945D000C945D00DC
:100030000C945D000C945D000C945D000C945D00CC
:100040000C945D000C945D000C945D000C945D00BC
:100050000C945D000C945D000C945D000C945D00AC
:100060000C945D000C945D000C945D000C945D009C
:100070000C945D000C945D000C945D000C945D008C
:100080000C945D000C945D000C945D0011241FBE67
:10009000CFEFD0E1DEBFCDBF11E0A0E0B1E0E0EBFB
:1000A000F1E000E00BBF02C007900D92A630B1074F
:1000B000D9F70E945F000C94D6000C940000BC9A03
:1000C000BD9ABF9ABE9A8998919A8898909AC59A33
:1000D000C69AC498C79880B3827080BB90B3917061
:1000E00090BB2FEF39EF40E0215030404040E1F726
:1000F00000C00000911138C0811116C08FEF99E641
:1001000028E1815090402040E1F700C00000C598F0
:10011000C6983FEF44E38CE0315040408040E1F727
:1001200000C00000C69A1EC09FEF29E638E191503A
:1001300020403040E1F700C00000C598C6984FEF5E
:1001400084E39CE0415080409040E1F700C0000013
:10015000C69A2FEF34E34CE0215030404040E1F7A5
:1001600000C00000C59AB7CF8111B5CF8FEF99E6D7
:1001700028E1815090402040E1F700C00000C59880
:10018000C6983FEF44E38CE0315040408040E1F7B7
:1001900000C00000C59A9FEF24E33CE0915020404E
:1001A0003040E1F700C00000C69A95CFF894FFCF29
:0601B0001400FA00F40146
:00000001FF

View File

@@ -0,0 +1,16 @@
MCU=atmega128
CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS=-std=c99 -Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
TARGET=main
SRCS=Corwin_Perren_Lab2_challenge_sourcecode.c
all:
${CC} ${CFLAGS} -o ${TARGET}.bin ${SRCS}
${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.bin ${TARGET}.hex
flash:
avrdude -p ${MCU} -c usbasp -U flash:w:${TARGET}.hex:i -F -P usb
clean:
rm -f *.bin *.hex

View File

@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Atmel Studio Solution File, Format Version 11.00
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{18226A42-8477-4023-8AD2-40C49DA407C9}") = "Corwin_Perren_Lab4_challengecode", "Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asmproj", "{59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AVR = Debug|AVR
Release|AVR = Release|AVR
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}.Debug|AVR.ActiveCfg = Debug|AVR
{59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}.Debug|AVR.Build.0 = Debug|AVR
{59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}.Release|AVR.ActiveCfg = Release|AVR
{59B1D629-9DCC-43ED-A0FD-8AB0E4D622AB}.Release|AVR.Build.0 = Release|AVR
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,193 @@
;***********************************************************
;*
;* Corwin_Perren_Lab4_challengecode.asm
;*
;* This program loads a two line string from program memory,
;* then cycles it around the lines of the display.
;*
;* This is the skeleton file for Lab 4 of ECE 375
;*
;***********************************************************
;*
;* Author: Corwin Perren
;* Date: 10/17/2018
;*
;***********************************************************
.include "m128def.inc" ; Include definition file
;***********************************************************
;* Internal Register Definitions and Constants
;***********************************************************
.def mpr = r16 ; Multipurpose register is
.def mpr2 = r10
.def dataloopcountreg = r23
.equ WTime = 25 ; Time to wait in wait loop
.equ datamemstart = 0x0100
.equ stringlen = 32
;***********************************************************
;* Start of Code Segment
;***********************************************************
.cseg ; Beginning of code segment
;***********************************************************
;* Interrupt Vectors
;***********************************************************
.org $0000 ; Beginning of IVs
rjmp INIT ; Reset interrupt
.org $0046 ; End of Interrupt Vectors
;***********************************************************
;* Program Initialization
;***********************************************************
INIT: ; The initialization routine
; Initialize Stack Pointer
ldi mpr, low(RAMEND) ; Load the low and high bytes of ram end to the stack pointer
out SPL, mpr
ldi mpr, high(RAMEND)
out SPH, mpr
; Initialize LCD Display
rcall LCDInit ; Call the lcd init function
; Move strings from Program Memory to Data Memory
ldi ZL, low(STRING_BEG << 1) ; Low byte of first byte in string into ZL
ldi ZH, high(STRING_BEG << 1) ; High byte of first byte in string into ZH
ldi YL, low(datamemstart) ; Low byte of data memory start into YL
ldi YH, high(datamemstart)
ldi dataloopcountreg, stringlen ; Initialize count for loop to string length
INIT_MEMCOPYLOOP: ; Loop to read data from progmem to datamem
lpm mpr, Z+ ; Get byte from address pointed to be Z,
; store in reg, move to next byte
st Y+, mpr ; Store byte from reg into data mem address
; pointed to by Y, then move Y to next open spot
dec dataloopcountreg ; Decrement count as we're done with byte
brne INIT_MEMCOPYLOOP ; If we haven't read in the whole string, loop again
; NOTE that there is no RET or RJMP from INIT, this
; is because the next instruction executed is the
; first instruction of the main program
;***********************************************************
;* Main Program
;***********************************************************
MAIN: ; The Main program
; Display the strings on the LCD Display
rcall LCDWrite ; This writes the data mem to the display,
; based on fixed mem addresses in LCDDriver.asm
ldi mpr, WTime ; Copied from lab 1, copy time into general reg
mov wait, mpr ; Copy into wait reg
rcall AVRWait ; Call wait subroutine
rcall ROTATE_TEXT ; Call subroutine to rotate text by one char
rjmp MAIN ; jump back to main and create an infinite
; while loop. Generally, every main program is an
; infinite while loop, never let the main program
; just run off
;-----------------------------------------------------------
; Func: ROTATE_TEXT
; Desc: This rotates a text string by one character, looping around the end
;-----------------------------------------------------------
ROTATE_TEXT: ; Begin a function with a label
; Save variables by pushing them to the stack
push mpr
push mpr2
push dataloopcountreg
push XL
push XH
; Get pointer to start of data memory for the lcd
ldi XL, low(datamemstart)
ldi XH, high(datamemstart)
ld mpr, X+ ; Get the first element, point to next
; Initialize counter
ldi dataloopcountreg, stringlen ; Initialize count for loop to string length
dec dataloopcountreg ; The last one we want to take care of
; specifically, so dec to skip the first char
ROTATE_TEXT_LOOP:
ld mpr2, X ; Save value in current text mem location
st X, mpr ; Overwrite current text mem with char from prev location
inc XL ; Move to next byte location
mov mpr, mpr2 ; Move stored prev char value into main mpr for overwrite
dec dataloopcountreg ; Dec loop counter
brne ROTATE_TEXT_LOOP ; If not done with all chars, loop
; Go back to start
ldi XL, low(datamemstart) ; Repoint to beginning of string array
ldi XH, high(datamemstart)
; Store last element as first
st X, mpr ; Overwrite first char with previous last character
; Restore variables by popping them from the stack,
; in reverse order
pop XH
pop XL
pop dataloopcountreg
pop mpr2
pop mpr
ret ; End a function with RET
; This was copied and modified from lab 1
;----------------------------------------------------------------
; Sub: AVRWait
; Desc: A wait loop that is 16 + 159975*waitcnt cycles or roughly
; waitcnt*10ms. Just initialize wait for the specific amount
; of time in 10ms intervals. Here is the general eqaution
; for the number of clock cycles in the wait loop:
; ((3 * ilcnt + 3) * olcnt + 3) * waitcnt + 13 + call
;----------------------------------------------------------------
AVRWait:
push wait ; Save wait register
push count ; Save ilcnt register
push line ; Save olcnt register
Loop: ldi line, 224 ; load olcnt register
OLoop: ldi count, 237 ; load ilcnt register
ILoop: dec count ; decrement ilcnt
brne ILoop ; Continue Inner Loop
dec line ; decrement olcnt
brne OLoop ; Continue Outer Loop
dec wait ; Decrement wait
brne Loop ; Continue Wait loop
pop line ; Restore olcnt register
pop count ; Restore ilcnt register
pop wait ; Restore wait register
ret ; Return from subroutine
;***********************************************************
;* Stored Program Data
;***********************************************************
;-----------------------------------------------------------
; An example of storing a string. Note the labels before and
; after the .DB directive; these can help to access the data
;-----------------------------------------------------------
STRING_BEG:
.DB " Corwin Perren Hello World! " ; Declaring data in ProgMem
STRING_END:
;***********************************************************
;* Additional Program Includes
;***********************************************************
.include "LCDDriver.asm" ; Include the LCD Driver

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<ProjectVersion>7.0</ProjectVersion>
<ToolchainName>com.Atmel.AVRAssembler</ToolchainName>
<ProjectGuid>59B1D629-9DCC-43ed-A0FD-8AB0E4D622AB</ProjectGuid>
<avrdeviceseries>none</avrdeviceseries>
<avrdevice>ATmega128</avrdevice>
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
<OutputFileExtension>.obj</OutputFileExtension>
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
<Language>ASSEMBLY</Language>
<AssemblyName>Corwin_Perren_Lab4_challengecode</AssemblyName>
<Name>Corwin_Perren_Lab4_challengecode</Name>
<RootNamespace>Corwin_Perren_Lab4_challengecode</RootNamespace>
<ToolchainFlavour>Native</ToolchainFlavour>
<EntryFile>$(MSBuildProjectDirectory)\Corwin_Perren_Lab4_challengecode.asm</EntryFile>
<KeepTimersRunning>true</KeepTimersRunning>
<OverrideVtor>false</OverrideVtor>
<CacheFlash>true</CacheFlash>
<ProgFlashFromRam>true</ProgFlashFromRam>
<RamSnippetAddress />
<UncachedRange />
<preserveEEPROM>true</preserveEEPROM>
<OverrideVtorValue />
<BootSegment>2</BootSegment>
<ResetRule>0</ResetRule>
<eraseonlaunchrule>0</eraseonlaunchrule>
<EraseKey />
<AsfFrameworkConfig>
<framework-data xmlns="">
<options />
<configurations />
<files />
<documentation help="" />
<offline-documentation help="" />
<dependencies>
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.40.0" />
</dependencies>
</framework-data>
</AsfFrameworkConfig>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings>
<AvrAssembler>
<avrasm.assembler.general.AdditionalIncludeDirectories>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\avrasm\inc</Value>
</ListValues>
</avrasm.assembler.general.AdditionalIncludeDirectories>
<avrasm.assembler.general.IncludeFile>m128def.inc</avrasm.assembler.general.IncludeFile>
</AvrAssembler>
</ToolchainSettings>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
<AvrAssembler>
<avrasm.assembler.general.AdditionalIncludeDirectories>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\avrasm\inc</Value>
</ListValues>
</avrasm.assembler.general.AdditionalIncludeDirectories>
<avrasm.assembler.general.IncludeFile>m128def.inc</avrasm.assembler.general.IncludeFile>
</AvrAssembler>
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
<Compile Include="Corwin_Perren_Lab4_challengecode.asm">
<SubType>Code</SubType>
</Compile>
<Compile Include="LCDDriver.asm">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Assembler.targets" />
</Project>

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Store xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="AtmelPackComponentManagement">
<ProjectComponents>
<ProjectComponent z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<CApiVersion></CApiVersion>
<CBundle></CBundle>
<CClass>Device</CClass>
<CGroup>Startup</CGroup>
<CSub></CSub>
<CVariant></CVariant>
<CVendor>Atmel</CVendor>
<CVersion>1.2.0</CVersion>
<DefaultRepoPath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs</DefaultRepoPath>
<DependentComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<Description></Description>
<Files xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d4p1:anyType i:type="FileInfo">
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\avrasm\inc</AbsolutePath>
<Attribute></Attribute>
<Category>include</Category>
<Condition>AVRASM</Condition>
<FileContentHash i:nil="true" />
<FileVersion></FileVersion>
<Name>avrasm/inc</Name>
<SelectString></SelectString>
<SourcePath></SourcePath>
</d4p1:anyType>
<d4p1:anyType i:type="FileInfo">
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\avrasm\inc\m128def.inc</AbsolutePath>
<Attribute></Attribute>
<Category>header</Category>
<Condition>AVRASM</Condition>
<FileContentHash>bd3TUV9UtxpdYQkn+6MWPA==</FileContentHash>
<FileVersion></FileVersion>
<Name>avrasm/inc/m128def.inc</Name>
<SelectString></SelectString>
<SourcePath></SourcePath>
</d4p1:anyType>
<d4p1:anyType i:type="FileInfo">
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\avrasm\templates\main.asm</AbsolutePath>
<Attribute>template</Attribute>
<Category>source</Category>
<Condition>AVRASM</Condition>
<FileContentHash>5CfmTmZmR6PbQJ065mg2IQ==</FileContentHash>
<FileVersion></FileVersion>
<Name>avrasm/templates/main.asm</Name>
<SelectString>Main file (.asm)</SelectString>
<SourcePath></SourcePath>
</d4p1:anyType>
</Files>
<PackName>ATmega_DFP</PackName>
<PackPath>C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.209/Atmel.ATmega_DFP.pdsc</PackPath>
<PackVersion>1.2.209</PackVersion>
<PresentInProject>true</PresentInProject>
<ReferenceConditionId>ATmega128</ReferenceConditionId>
<RteComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d4p1:string></d4p1:string>
</RteComponents>
<Status>Resolved</Status>
<VersionMode>Fixed</VersionMode>
<IsComponentInAtProject>true</IsComponentInAtProject>
</ProjectComponent>
</ProjectComponents>
</Store>

View File

@@ -0,0 +1,48 @@
:020000020000FC
:0200000045C0F9
:10008C000FEF0DBF00E10EBF47D0E4E0F1E0C0E0A0
:10009C00D1E070E2059109937A95E1F77CD009E102
:1000AC00102F1BD001D0FACF0F93AF927F93AF9349
:1000BC00BF93A0E0B1E00D9170E27A95AC900C93F7
:1000CC00A3950A2D7A95D1F7A0E0B1E00C93BF91DE
:1000DC00AF917F91AF900F9108951F932F933F9302
:1000EC0030EE2DEE2A95F1F73A95D9F71A95C1F71E
:1000FC003F912F911F91089520436F7277696E2065
:10010C0050657272656E2020202048656C6C6F20E3
:10011C00576F726C642120200F930FB70F931F93AE
:10012C0000E008BB0FEF07BB00E002BB00E001BB27
:10013C0000E00093620008E00093610000E50DB957
:10014C0001E00EB900E805BF02E400936D0000E881
:10015C0000936C0000E00BB908E10AB906E00093CB
:10016C00950000E00093900007E609B906E01AEF4D
:10017C00BFD00A95E1F708E397D008E095D001E0ED
:10018C0093D006E091D00CE08FD028D01F910F9126
:10019C000FBF0F91089502D011D008950F93EF93D4
:1001AC00FF932F933F93E0E0F1E030E86BD076D0F3
:1001BC003F912F91FF91EF910F9108950F93EF9332
:1001CC00FF932F933F93E0E1F1E030EC5BD066D0EE
:1001DC003F912F91FF91EF910F91089502D011D083
:1001EC0008950F933F932F93EF93FF9330E84AD0EA
:1001FC00E0E0F1E04CD0FF91EF912F913F910F9106
:10020C0008950F933F932F93EF93FF9330EC3AD0D5
:10021C00E0E1F1E03CD0FF91EF912F913F910F91F4
:10022C0008950F933F932F93283250F4313011F4EB
:10023C0030E803C0323021F430EC320F23D042D0FE
:10024C002F913F910F9108950F936F935F93BF93ED
:10025C00AF93043618F023E0139607C00A3018F059
:10026C0022E0129602C0119621E04AD000E3060F5C
:10027C000E93052F0030C9F7AF91BF915F916F912D
:10028C000F9108950F93032F0FD00F91089500E253
:10029C0020E1019317D02A95E1F7089520E101910F
:1002AC0011D02A95E1F708954F931F9340E013D096
:1002BC000F9302E01DEC1CD00A95E1F70F911F91F2
:1002CC004F9108954F931F9341E005D010E110D04A
:1002DC001F914F9108954FB912E00AD00FB912E057
:1002EC0007D018E01093620010E01093620008959C
:1002FC000F9309E40A95F1F71A95D9F70F91089520
:10030C000F92502F56955695500F5695500F569557
:10031C0056955695500F5695500F56955695569591
:10032C00500F5695500F5695569556955695652FD8
:10033C00660F660F650F660F062E602F60196A3008
:0C034C0018F053956A50FBCF0F900895F5
:00000001FF

View File

@@ -0,0 +1,933 @@
AVRASM ver. 2.2.7 C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm Tue Oct 23 20:38:27 2018
EQU SIGNATURE_000 0000001e
EQU SIGNATURE_001 00000097
EQU SIGNATURE_002 00000002
EQU UCSR1C 0000009d
EQU UDR1 0000009c
EQU UCSR1A 0000009b
EQU UCSR1B 0000009a
EQU UBRR1H 00000098
EQU UBRR1L 00000099
EQU UCSR0C 00000095
EQU UBRR0H 00000090
EQU TCCR3C 0000008c
EQU TCCR3A 0000008b
EQU TCCR3B 0000008a
EQU TCNT3L 00000088
EQU TCNT3H 00000089
EQU OCR3AL 00000086
EQU OCR3AH 00000087
EQU OCR3BL 00000084
EQU OCR3BH 00000085
EQU OCR3CL 00000082
EQU OCR3CH 00000083
EQU ICR3L 00000080
EQU ICR3H 00000081
EQU ETIMSK 0000007d
EQU ETIFR 0000007c
EQU TCCR1C 0000007a
EQU OCR1CL 00000078
EQU OCR1CH 00000079
EQU TWCR 00000074
EQU TWDR 00000073
EQU TWAR 00000072
EQU TWSR 00000071
EQU TWBR 00000070
EQU OSCCAL 0000006f
EQU XMCRA 0000006d
EQU XMCRB 0000006c
EQU EICRA 0000006a
EQU SPMCSR 00000068
EQU PORTG 00000065
EQU DDRG 00000064
EQU PING 00000063
EQU PORTF 00000062
EQU DDRF 00000061
EQU SREG 0000003f
EQU SPL 0000003d
EQU SPH 0000003e
EQU XDIV 0000003c
EQU RAMPZ 0000003b
EQU EICRB 0000003a
EQU EIMSK 00000039
EQU EIFR 00000038
EQU TIMSK 00000037
EQU TIFR 00000036
EQU MCUCR 00000035
EQU MCUCSR 00000034
EQU TCCR0 00000033
EQU TCNT0 00000032
EQU OCR0 00000031
EQU ASSR 00000030
EQU TCCR1A 0000002f
EQU TCCR1B 0000002e
EQU TCNT1L 0000002c
EQU TCNT1H 0000002d
EQU OCR1AL 0000002a
EQU OCR1AH 0000002b
EQU OCR1BL 00000028
EQU OCR1BH 00000029
EQU ICR1L 00000026
EQU ICR1H 00000027
EQU TCCR2 00000025
EQU TCNT2 00000024
EQU OCR2 00000023
EQU OCDR 00000022
EQU WDTCR 00000021
EQU SFIOR 00000020
EQU EEARL 0000001e
EQU EEARH 0000001f
EQU EEDR 0000001d
EQU EECR 0000001c
EQU PORTA 0000001b
EQU DDRA 0000001a
EQU PINA 00000019
EQU PORTB 00000018
EQU DDRB 00000017
EQU PINB 00000016
EQU PORTC 00000015
EQU DDRC 00000014
EQU PINC 00000013
EQU PORTD 00000012
EQU DDRD 00000011
EQU PIND 00000010
EQU SPDR 0000000f
EQU SPSR 0000000e
EQU SPCR 0000000d
EQU UDR0 0000000c
EQU UCSR0A 0000000b
EQU UCSR0B 0000000a
EQU UBRR0L 00000009
EQU ACSR 00000008
EQU ADMUX 00000007
EQU ADCSRA 00000006
EQU ADCH 00000005
EQU ADCL 00000004
EQU PORTE 00000003
EQU DDRE 00000002
EQU PINE 00000001
EQU PINF 00000000
EQU ACME 00000003
EQU ACIS0 00000000
EQU ACIS1 00000001
EQU ACIC 00000002
EQU ACIE 00000003
EQU ACI 00000004
EQU ACO 00000005
EQU ACBG 00000006
EQU ACD 00000007
EQU SPDR0 00000000
EQU SPDR1 00000001
EQU SPDR2 00000002
EQU SPDR3 00000003
EQU SPDR4 00000004
EQU SPDR5 00000005
EQU SPDR6 00000006
EQU SPDR7 00000007
EQU SPI2X 00000000
EQU WCOL 00000006
EQU SPIF 00000007
EQU SPR0 00000000
EQU SPR1 00000001
EQU CPHA 00000002
EQU CPOL 00000003
EQU MSTR 00000004
EQU DORD 00000005
EQU SPE 00000006
EQU SPIE 00000007
EQU I2BR 00000070
EQU TWBR0 00000000
EQU TWBR1 00000001
EQU TWBR2 00000002
EQU TWBR3 00000003
EQU TWBR4 00000004
EQU TWBR5 00000005
EQU TWBR6 00000006
EQU TWBR7 00000007
EQU I2CR 00000074
EQU TWIE 00000000
EQU I2IE 00000000
EQU TWEN 00000002
EQU I2EN 00000002
EQU ENI2C 00000002
EQU TWWC 00000003
EQU I2WC 00000003
EQU TWSTO 00000004
EQU I2STO 00000004
EQU TWSTA 00000005
EQU I2STA 00000005
EQU TWEA 00000006
EQU I2EA 00000006
EQU TWINT 00000007
EQU I2INT 00000007
EQU I2SR 00000071
EQU TWPS0 00000000
EQU TWS0 00000000
EQU I2GCE 00000000
EQU TWPS1 00000001
EQU TWS1 00000001
EQU TWS3 00000003
EQU I2S3 00000003
EQU TWS4 00000004
EQU I2S4 00000004
EQU TWS5 00000005
EQU I2S5 00000005
EQU TWS6 00000006
EQU I2S6 00000006
EQU TWS7 00000007
EQU I2S7 00000007
EQU I2DR 00000073
EQU TWD0 00000000
EQU TWD1 00000001
EQU TWD2 00000002
EQU TWD3 00000003
EQU TWD4 00000004
EQU TWD5 00000005
EQU TWD6 00000006
EQU TWD7 00000007
EQU I2AR 00000072
EQU TWGCE 00000000
EQU TWA0 00000001
EQU TWA1 00000002
EQU TWA2 00000003
EQU TWA3 00000004
EQU TWA4 00000005
EQU TWA5 00000006
EQU TWA6 00000007
EQU UDR00 00000000
EQU UDR01 00000001
EQU UDR02 00000002
EQU UDR03 00000003
EQU UDR04 00000004
EQU UDR05 00000005
EQU UDR06 00000006
EQU UDR07 00000007
EQU MPCM0 00000000
EQU U2X0 00000001
EQU UPE0 00000002
EQU DOR0 00000003
EQU FE0 00000004
EQU UDRE0 00000005
EQU TXC0 00000006
EQU RXC0 00000007
EQU TXB80 00000000
EQU RXB80 00000001
EQU UCSZ02 00000002
EQU UCSZ2 00000002
EQU TXEN0 00000003
EQU RXEN0 00000004
EQU UDRIE0 00000005
EQU TXCIE0 00000006
EQU RXCIE0 00000007
EQU UCPOL0 00000000
EQU UCSZ00 00000001
EQU UCSZ01 00000002
EQU USBS0 00000003
EQU UPM00 00000004
EQU UPM01 00000005
EQU UMSEL0 00000006
EQU UBRR8 00000000
EQU UBRR9 00000001
EQU UBRR10 00000002
EQU UBRR11 00000003
EQU UBRR0 00000000
EQU UBRR1 00000001
EQU UBRR2 00000002
EQU UBRR3 00000003
EQU UBRR4 00000004
EQU UBRR5 00000005
EQU UBRR6 00000006
EQU UBRR7 00000007
EQU UDR10 00000000
EQU UDR11 00000001
EQU UDR12 00000002
EQU UDR13 00000003
EQU UDR14 00000004
EQU UDR15 00000005
EQU UDR16 00000006
EQU UDR17 00000007
EQU MPCM1 00000000
EQU U2X1 00000001
EQU UPE1 00000002
EQU DOR1 00000003
EQU FE1 00000004
EQU UDRE1 00000005
EQU TXC1 00000006
EQU RXC1 00000007
EQU TXB81 00000000
EQU RXB81 00000001
EQU UCSZ12 00000002
EQU TXEN1 00000003
EQU RXEN1 00000004
EQU UDRIE1 00000005
EQU TXCIE1 00000006
EQU RXCIE1 00000007
EQU UCPOL1 00000000
EQU UCSZ10 00000001
EQU UCSZ11 00000002
EQU USBS1 00000003
EQU UPM10 00000004
EQU UPM11 00000005
EQU UMSEL1 00000006
EQU SREG_C 00000000
EQU SREG_Z 00000001
EQU SREG_N 00000002
EQU SREG_V 00000003
EQU SREG_S 00000004
EQU SREG_H 00000005
EQU SREG_T 00000006
EQU SREG_I 00000007
EQU IVCE 00000000
EQU IVSEL 00000001
EQU SM2 00000002
EQU SM0 00000003
EQU SM1 00000004
EQU SE 00000005
EQU SRW10 00000006
EQU SRE 00000007
EQU SRW11 00000001
EQU SRW00 00000002
EQU SRW01 00000003
EQU SRL0 00000004
EQU SRL1 00000005
EQU SRL2 00000006
EQU XMM0 00000000
EQU XMM1 00000001
EQU XMM2 00000002
EQU XMBK 00000007
EQU CAL0 00000000
EQU CAL1 00000001
EQU CAL2 00000002
EQU CAL3 00000003
EQU CAL4 00000004
EQU CAL5 00000005
EQU CAL6 00000006
EQU CAL7 00000007
EQU XDIV0 00000000
EQU XDIV1 00000001
EQU XDIV2 00000002
EQU XDIV3 00000003
EQU XDIV4 00000004
EQU XDIV5 00000005
EQU XDIV6 00000006
EQU XDIVEN 00000007
EQU PORF 00000000
EQU EXTRF 00000001
EQU BORF 00000002
EQU WDRF 00000003
EQU JTRF 00000004
EQU JTD 00000007
EQU RAMPZ0 00000000
EQU SPMCR 00000068
EQU SPMEN 00000000
EQU PGERS 00000001
EQU PGWRT 00000002
EQU BLBSET 00000003
EQU RWWSRE 00000004
EQU ASRE 00000004
EQU RWWSB 00000006
EQU ASB 00000006
EQU SPMIE 00000007
EQU OCDR0 00000000
EQU OCDR1 00000001
EQU OCDR2 00000002
EQU OCDR3 00000003
EQU OCDR4 00000004
EQU OCDR5 00000005
EQU OCDR6 00000006
EQU OCDR7 00000007
EQU IDRD 00000007
EQU PSR321 00000000
EQU PSR1 00000000
EQU PSR2 00000000
EQU PSR3 00000000
EQU PSR0 00000001
EQU PUD 00000002
EQU TSM 00000007
EQU ISC00 00000000
EQU ISC01 00000001
EQU ISC10 00000002
EQU ISC11 00000003
EQU ISC20 00000004
EQU ISC21 00000005
EQU ISC30 00000006
EQU ISC31 00000007
EQU ISC40 00000000
EQU ISC41 00000001
EQU ISC50 00000002
EQU ISC51 00000003
EQU ISC60 00000004
EQU ISC61 00000005
EQU ISC70 00000006
EQU ISC71 00000007
EQU GICR 00000039
EQU GIMSK 00000039
EQU INT0 00000000
EQU INT1 00000001
EQU INT2 00000002
EQU INT3 00000003
EQU INT4 00000004
EQU INT5 00000005
EQU INT6 00000006
EQU INT7 00000007
EQU GIFR 00000038
EQU INTF0 00000000
EQU INTF1 00000001
EQU INTF2 00000002
EQU INTF3 00000003
EQU INTF4 00000004
EQU INTF5 00000005
EQU INTF6 00000006
EQU INTF7 00000007
EQU EEDR0 00000000
EQU EEDR1 00000001
EQU EEDR2 00000002
EQU EEDR3 00000003
EQU EEDR4 00000004
EQU EEDR5 00000005
EQU EEDR6 00000006
EQU EEDR7 00000007
EQU EERE 00000000
EQU EEWE 00000001
EQU EEMWE 00000002
EQU EERIE 00000003
EQU PORTA0 00000000
EQU PA0 00000000
EQU PORTA1 00000001
EQU PA1 00000001
EQU PORTA2 00000002
EQU PA2 00000002
EQU PORTA3 00000003
EQU PA3 00000003
EQU PORTA4 00000004
EQU PA4 00000004
EQU PORTA5 00000005
EQU PA5 00000005
EQU PORTA6 00000006
EQU PA6 00000006
EQU PORTA7 00000007
EQU PA7 00000007
EQU DDA0 00000000
EQU DDA1 00000001
EQU DDA2 00000002
EQU DDA3 00000003
EQU DDA4 00000004
EQU DDA5 00000005
EQU DDA6 00000006
EQU DDA7 00000007
EQU PINA0 00000000
EQU PINA1 00000001
EQU PINA2 00000002
EQU PINA3 00000003
EQU PINA4 00000004
EQU PINA5 00000005
EQU PINA6 00000006
EQU PINA7 00000007
EQU PORTB0 00000000
EQU PB0 00000000
EQU PORTB1 00000001
EQU PB1 00000001
EQU PORTB2 00000002
EQU PB2 00000002
EQU PORTB3 00000003
EQU PB3 00000003
EQU PORTB4 00000004
EQU PB4 00000004
EQU PORTB5 00000005
EQU PB5 00000005
EQU PORTB6 00000006
EQU PB6 00000006
EQU PORTB7 00000007
EQU PB7 00000007
EQU DDB0 00000000
EQU DDB1 00000001
EQU DDB2 00000002
EQU DDB3 00000003
EQU DDB4 00000004
EQU DDB5 00000005
EQU DDB6 00000006
EQU DDB7 00000007
EQU PINB0 00000000
EQU PINB1 00000001
EQU PINB2 00000002
EQU PINB3 00000003
EQU PINB4 00000004
EQU PINB5 00000005
EQU PINB6 00000006
EQU PINB7 00000007
EQU PORTC0 00000000
EQU PC0 00000000
EQU PORTC1 00000001
EQU PC1 00000001
EQU PORTC2 00000002
EQU PC2 00000002
EQU PORTC3 00000003
EQU PC3 00000003
EQU PORTC4 00000004
EQU PC4 00000004
EQU PORTC5 00000005
EQU PC5 00000005
EQU PORTC6 00000006
EQU PC6 00000006
EQU PORTC7 00000007
EQU PC7 00000007
EQU DDC0 00000000
EQU DDC1 00000001
EQU DDC2 00000002
EQU DDC3 00000003
EQU DDC4 00000004
EQU DDC5 00000005
EQU DDC6 00000006
EQU DDC7 00000007
EQU PINC0 00000000
EQU PINC1 00000001
EQU PINC2 00000002
EQU PINC3 00000003
EQU PINC4 00000004
EQU PINC5 00000005
EQU PINC6 00000006
EQU PINC7 00000007
EQU PORTD0 00000000
EQU PD0 00000000
EQU PORTD1 00000001
EQU PD1 00000001
EQU PORTD2 00000002
EQU PD2 00000002
EQU PORTD3 00000003
EQU PD3 00000003
EQU PORTD4 00000004
EQU PD4 00000004
EQU PORTD5 00000005
EQU PD5 00000005
EQU PORTD6 00000006
EQU PD6 00000006
EQU PORTD7 00000007
EQU PD7 00000007
EQU DDD0 00000000
EQU DDD1 00000001
EQU DDD2 00000002
EQU DDD3 00000003
EQU DDD4 00000004
EQU DDD5 00000005
EQU DDD6 00000006
EQU DDD7 00000007
EQU PIND0 00000000
EQU PIND1 00000001
EQU PIND2 00000002
EQU PIND3 00000003
EQU PIND4 00000004
EQU PIND5 00000005
EQU PIND6 00000006
EQU PIND7 00000007
EQU PORTE0 00000000
EQU PE0 00000000
EQU PORTE1 00000001
EQU PE1 00000001
EQU PORTE2 00000002
EQU PE2 00000002
EQU PORTE3 00000003
EQU PE3 00000003
EQU PORTE4 00000004
EQU PE4 00000004
EQU PORTE5 00000005
EQU PE5 00000005
EQU PORTE6 00000006
EQU PE6 00000006
EQU PORTE7 00000007
EQU PE7 00000007
EQU DDE0 00000000
EQU DDE1 00000001
EQU DDE2 00000002
EQU DDE3 00000003
EQU DDE4 00000004
EQU DDE5 00000005
EQU DDE6 00000006
EQU DDE7 00000007
EQU PINE0 00000000
EQU PINE1 00000001
EQU PINE2 00000002
EQU PINE3 00000003
EQU PINE4 00000004
EQU PINE5 00000005
EQU PINE6 00000006
EQU PINE7 00000007
EQU PORTF0 00000000
EQU PF0 00000000
EQU PORTF1 00000001
EQU PF1 00000001
EQU PORTF2 00000002
EQU PF2 00000002
EQU PORTF3 00000003
EQU PF3 00000003
EQU PORTF4 00000004
EQU PF4 00000004
EQU PORTF5 00000005
EQU PF5 00000005
EQU PORTF6 00000006
EQU PF6 00000006
EQU PORTF7 00000007
EQU PF7 00000007
EQU DDF0 00000000
EQU DDF1 00000001
EQU DDF2 00000002
EQU DDF3 00000003
EQU DDF4 00000004
EQU DDF5 00000005
EQU DDF6 00000006
EQU DDF7 00000007
EQU PINF0 00000000
EQU PINF1 00000001
EQU PINF2 00000002
EQU PINF3 00000003
EQU PINF4 00000004
EQU PINF5 00000005
EQU PINF6 00000006
EQU PINF7 00000007
EQU PORTG0 00000000
EQU PG0 00000000
EQU PORTG1 00000001
EQU PG1 00000001
EQU PORTG2 00000002
EQU PG2 00000002
EQU PORTG3 00000003
EQU PG3 00000003
EQU PORTG4 00000004
EQU PG4 00000004
EQU DDG0 00000000
EQU DDG1 00000001
EQU DDG2 00000002
EQU DDG3 00000003
EQU DDG4 00000004
EQU PING0 00000000
EQU PING1 00000001
EQU PING2 00000002
EQU PING3 00000003
EQU PING4 00000004
EQU CS00 00000000
EQU CS01 00000001
EQU CS02 00000002
EQU WGM01 00000003
EQU CTC0 00000003
EQU COM00 00000004
EQU COM01 00000005
EQU WGM00 00000006
EQU PWM0 00000006
EQU FOC0 00000007
EQU TCNT0_0 00000000
EQU TCNT0_1 00000001
EQU TCNT0_2 00000002
EQU TCNT0_3 00000003
EQU TCNT0_4 00000004
EQU TCNT0_5 00000005
EQU TCNT0_6 00000006
EQU TCNT0_7 00000007
EQU OCR0_0 00000000
EQU OCR0_1 00000001
EQU OCR0_2 00000002
EQU OCR0_3 00000003
EQU OCR0_4 00000004
EQU OCR0_5 00000005
EQU OCR0_6 00000006
EQU OCR0_7 00000007
EQU TCR0UB 00000000
EQU OCR0UB 00000001
EQU TCN0UB 00000002
EQU AS0 00000003
EQU TOIE0 00000000
EQU OCIE0 00000001
EQU TOV0 00000000
EQU OCF0 00000001
EQU TOIE1 00000002
EQU OCIE1B 00000003
EQU OCIE1A 00000004
EQU TICIE1 00000005
EQU OCIE1C 00000000
EQU TOV1 00000002
EQU OCF1B 00000003
EQU OCF1A 00000004
EQU ICF1 00000005
EQU OCF1C 00000000
EQU WGM10 00000000
EQU PWM10 00000000
EQU WGM11 00000001
EQU PWM11 00000001
EQU COM1C0 00000002
EQU COM1C1 00000003
EQU COM1B0 00000004
EQU COM1B1 00000005
EQU COM1A0 00000006
EQU COM1A1 00000007
EQU CS10 00000000
EQU CS11 00000001
EQU CS12 00000002
EQU WGM12 00000003
EQU CTC10 00000003
EQU WGM13 00000004
EQU CTC11 00000004
EQU ICES1 00000006
EQU ICNC1 00000007
EQU FOC1C 00000005
EQU FOC1B 00000006
EQU FOC1A 00000007
EQU CS20 00000000
EQU CS21 00000001
EQU CS22 00000002
EQU WGM21 00000003
EQU CTC2 00000003
EQU COM20 00000004
EQU COM21 00000005
EQU WGM20 00000006
EQU PWM2 00000006
EQU FOC2 00000007
EQU TCNT2_0 00000000
EQU TCNT2_1 00000001
EQU TCNT2_2 00000002
EQU TCNT2_3 00000003
EQU TCNT2_4 00000004
EQU TCNT2_5 00000005
EQU TCNT2_6 00000006
EQU TCNT2_7 00000007
EQU OCR2_0 00000000
EQU OCR2_1 00000001
EQU OCR2_2 00000002
EQU OCR2_3 00000003
EQU OCR2_4 00000004
EQU OCR2_5 00000005
EQU OCR2_6 00000006
EQU OCR2_7 00000007
EQU TOIE2 00000006
EQU OCIE2 00000007
EQU TOV2 00000006
EQU OCF2 00000007
EQU OCIE3C 00000001
EQU TOIE3 00000002
EQU OCIE3B 00000003
EQU OCIE3A 00000004
EQU TICIE3 00000005
EQU OCF3C 00000001
EQU TOV3 00000002
EQU OCF3B 00000003
EQU OCF3A 00000004
EQU ICF3 00000005
EQU WGM30 00000000
EQU PWM30 00000000
EQU WGM31 00000001
EQU PWM31 00000001
EQU COM3C0 00000002
EQU COM3C1 00000003
EQU COM3B0 00000004
EQU COM3B1 00000005
EQU COM3A0 00000006
EQU COM3A1 00000007
EQU CS30 00000000
EQU CS31 00000001
EQU CS32 00000002
EQU WGM32 00000003
EQU CTC30 00000003
EQU WGM33 00000004
EQU CTC31 00000004
EQU ICES3 00000006
EQU ICNC3 00000007
EQU FOC3C 00000005
EQU FOC3B 00000006
EQU FOC3A 00000007
EQU TCN3L0 00000000
EQU TCN3L1 00000001
EQU TCN3L2 00000002
EQU TCN3L3 00000003
EQU TCN3L4 00000004
EQU TCN3L5 00000005
EQU TCN3L6 00000006
EQU TCN3L7 00000007
EQU WDTCSR 00000021
EQU WDP0 00000000
EQU WDP1 00000001
EQU WDP2 00000002
EQU WDE 00000003
EQU WDCE 00000004
EQU WDTOE 00000004
EQU MUX0 00000000
EQU MUX1 00000001
EQU MUX2 00000002
EQU MUX3 00000003
EQU MUX4 00000004
EQU ADLAR 00000005
EQU REFS0 00000006
EQU REFS1 00000007
EQU ADCSR 00000006
EQU ADPS0 00000000
EQU ADPS1 00000001
EQU ADPS2 00000002
EQU ADIE 00000003
EQU ADIF 00000004
EQU ADFR 00000005
EQU ADSC 00000006
EQU ADEN 00000007
EQU ADCH0 00000000
EQU ADCH1 00000001
EQU ADCH2 00000002
EQU ADCH3 00000003
EQU ADCH4 00000004
EQU ADCH5 00000005
EQU ADCH6 00000006
EQU ADCH7 00000007
EQU ADCL0 00000000
EQU ADCL1 00000001
EQU ADCL2 00000002
EQU ADCL3 00000003
EQU ADCL4 00000004
EQU ADCL5 00000005
EQU ADCL6 00000006
EQU ADCL7 00000007
EQU LB1 00000000
EQU LB2 00000001
EQU BLB01 00000002
EQU BLB02 00000003
EQU BLB11 00000004
EQU BLB12 00000005
EQU CKSEL0 00000000
EQU CKSEL1 00000001
EQU CKSEL2 00000002
EQU CKSEL3 00000003
EQU SUT0 00000004
EQU SUT1 00000005
EQU BODEN 00000006
EQU BODLEVEL 00000007
EQU BOOTRST 00000000
EQU BOOTSZ0 00000001
EQU BOOTSZ1 00000002
EQU EESAVE 00000003
EQU CKOPT 00000004
EQU SPIEN 00000005
EQU JTAGEN 00000006
EQU OCDEN 00000007
EQU WDTON 00000000
EQU M103C 00000001
DEF XH r27
DEF XL r26
DEF YH r29
DEF YL r28
DEF ZH r31
DEF ZL r30
EQU FLASHEND 0000ffff
EQU IOEND 000000ff
EQU SRAM_START 00000100
EQU SRAM_SIZE 00001000
EQU RAMEND 000010ff
EQU XRAMEND 0000ffff
EQU E2END 00000fff
EQU EEPROMEND 00000fff
EQU EEADRBITS 0000000c
EQU NRWW_START_ADDR 0000f000
EQU NRWW_STOP_ADDR 0000ffff
EQU RWW_START_ADDR 00000000
EQU RWW_STOP_ADDR 0000efff
EQU PAGESIZE 00000080
EQU FIRSTBOOTSTART 0000fe00
EQU SECONDBOOTSTART 0000fc00
EQU THIRDBOOTSTART 0000f800
EQU FOURTHBOOTSTART 0000f000
EQU SMALLBOOTSTART 0000fe00
EQU LARGEBOOTSTART 0000f000
EQU INT0addr 00000002
EQU INT1addr 00000004
EQU INT2addr 00000006
EQU INT3addr 00000008
EQU INT4addr 0000000a
EQU INT5addr 0000000c
EQU INT6addr 0000000e
EQU INT7addr 00000010
EQU OC2addr 00000012
EQU OVF2addr 00000014
EQU ICP1addr 00000016
EQU OC1Aaddr 00000018
EQU OC1Baddr 0000001a
EQU OVF1addr 0000001c
EQU OC0addr 0000001e
EQU OVF0addr 00000020
EQU SPIaddr 00000022
EQU URXC0addr 00000024
EQU UDRE0addr 00000026
EQU UTXC0addr 00000028
EQU ADCCaddr 0000002a
EQU ERDYaddr 0000002c
EQU ACIaddr 0000002e
EQU OC1Caddr 00000030
EQU ICP3addr 00000032
EQU OC3Aaddr 00000034
EQU OC3Baddr 00000036
EQU OC3Caddr 00000038
EQU OVF3addr 0000003a
EQU URXC1addr 0000003c
EQU UDRE1addr 0000003e
EQU UTXC1addr 00000040
EQU TWIaddr 00000042
EQU SPMRaddr 00000044
EQU INT_VECTORS_SIZE 00000046
DEF mpr r16
DEF mpr2 r10
DEF dataloopcountreg r23
EQU WTime 00000019
EQU datamemstart 00000100
EQU stringlen 00000020
CSEG INIT 00000046
CSEG LCDInit 00000092
CSEG STRING_BEG 00000082
CSEG INIT_MEMCOPYLOOP 00000050
CSEG MAIN 00000054
CSEG LCDWrite 000000d1
DEF wait r17
CSEG AVRWait 00000073
CSEG ROTATE_TEXT 0000005a
CSEG ROTATE_TEXT_LOOP 00000064
DEF count r18
DEF line r19
CSEG Loop 00000076
CSEG OLoop 00000077
CSEG ILoop 00000078
CSEG STRING_END 00000092
DEF type r20
DEF q r21
DEF r r22
EQU LCDLine1 00000080
EQU LCDLine2 000000c0
EQU LCDClear 00000001
EQU LCDHome 00000002
EQU LCDPulse 00000008
EQU LCDCmd 00000000
EQU LCDTxt 00000001
EQU LCDMaxCnt 00000010
EQU LCDLn1Addr 00000100
EQU LCDLn2Addr 00000110
CSEG LCDINIT_L1 000000bd
CSEG LCDWait 0000017e
CSEG LCDWriteCmd 0000015a
CSEG LCDClr 000000f4
CSEG LCDWrLn1 000000d4
CSEG LCDWrLn2 000000e4
CSEG LCDSetLine 00000148
CSEG LCDWriteLine 00000154
CSEG LCDClrLn1 000000f7
CSEG LCDClrLn2 00000107
CSEG LCDClrLine 0000014d
CSEG LCDWriteByte 00000117
CSEG LCDWriteByte_3 00000126
CSEG LCDWriteByte_1 00000120
CSEG LCDWriteByte_2 00000123
CSEG LCDWriteChar 00000168
CSEG Bin2ASCII 0000012a
CSEG B2A_1 00000134
CSEG B2A_3 0000013b
CSEG B2A_2 00000139
CSEG div10 00000186
CSEG LCDClrLine_1 0000014f
CSEG LCDWriteLine_1 00000155
CSEG LCDWriteData 00000171
CSEG LCDWC_L1 00000160
CSEG LCDW_L1 0000017f
CSEG LCDW_L2 00000180
CSEG div10_1 000001a5
CSEG div10_2 000001aa

View File

@@ -0,0 +1,69 @@
<ASSEMBLER_INFO>
<VERSION>2.2.7</VERSION>
<DEVICE>"ATmega128"</DEVICE>
<WORKING_DIR>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Debug</WORKING_DIR>
<INCLUDE_PATH>
<DIR>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\avrasm\inc</DIR>
<DIR>C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avrassembler\Include</DIR>
<DIR></DIR>
</INCLUDE_PATH>
<SOURCE_FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</SOURCE_FILE>
<INCLUDED_FILES>
<FILE>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\avrasm\inc\m128def.inc</FILE>
<FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE>
</INCLUDED_FILES>
<OBJECT_FILES>
<FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Debug\Corwin_Perren_Lab4_challengecode.obj</FILE>
</OBJECT_FILES>
<HEX_FILES>
<FILE>Corwin_Perren_Lab4_challengecode.hex</FILE>
</HEX_FILES>
<OUTPUT_FILES>
<FILE>Corwin_Perren_Lab4_challengecode.map</FILE>
<FILE>Corwin_Perren_Lab4_challengecode.lss</FILE>
</OUTPUT_FILES>
<LABELS>
<INIT><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>49</LINE></INIT>
<LCDInit><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>75</LINE></LCDInit>
<STRING_BEG><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>186</LINE></STRING_BEG>
<INIT_MEMCOPYLOOP><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>68</LINE></INIT_MEMCOPYLOOP>
<MAIN><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>85</LINE></MAIN>
<LCDWrite><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>170</LINE></LCDWrite>
<AVRWait><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>159</LINE></AVRWait>
<ROTATE_TEXT><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>106</LINE></ROTATE_TEXT>
<ROTATE_TEXT_LOOP><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>125</LINE></ROTATE_TEXT_LOOP>
<Loop><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>164</LINE></Loop>
<OLoop><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>165</LINE></OLoop>
<ILoop><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>166</LINE></ILoop>
<STRING_END><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode.asm</FILE><LINE>188</LINE></STRING_END>
<LCDINIT_L1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>139</LINE></LCDINIT_L1>
<LCDWait><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>492</LINE></LCDWait>
<LCDWriteCmd><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>436</LINE></LCDWriteCmd>
<LCDClr><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>230</LINE></LCDClr>
<LCDWrLn1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>180</LINE></LCDWrLn1>
<LCDWrLn2><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>205</LINE></LCDWrLn2>
<LCDSetLine><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>388</LINE></LCDSetLine>
<LCDWriteLine><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>423</LINE></LCDWriteLine>
<LCDClrLn1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>240</LINE></LCDClrLn1>
<LCDClrLn2><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>265</LINE></LCDClrLn2>
<LCDClrLine><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>404</LINE></LCDClrLine>
<LCDWriteByte><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>302</LINE></LCDWriteByte>
<LCDWriteByte_3><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>323</LINE></LCDWriteByte_3>
<LCDWriteByte_1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>313</LINE></LCDWriteByte_1>
<LCDWriteByte_2><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>318</LINE></LCDWriteByte_2>
<LCDWriteChar><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>457</LINE></LCDWriteChar>
<Bin2ASCII><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>339</LINE></Bin2ASCII>
<B2A_1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>352</LINE></B2A_1>
<B2A_3><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>360</LINE></B2A_3>
<B2A_2><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>357</LINE></B2A_2>
<div10><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>515</LINE></div10>
<LCDClrLine_1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>407</LINE></LCDClrLine_1>
<LCDWriteLine_1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>425</LINE></LCDWriteLine_1>
<LCDWriteData><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>472</LINE></LCDWriteData>
<LCDWC_L1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>443</LINE></LCDWC_L1>
<LCDW_L1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>493</LINE></LCDW_L1>
<LCDW_L2><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>494</LINE></LCDW_L2>
<div10_1><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>554</LINE></div10_1>
<div10_2><FILE>C:\Users\caperren\Github\ECE_375\Labs\Lab 4\Corwin_Perren_Lab4_challengecode\Corwin_Perren_Lab4_challengecode\LCDDriver.asm</FILE><LINE>560</LINE></div10_2>
</LABELS>
</ASSEMBLER_INFO>

View File

@@ -0,0 +1,561 @@
;***********************************************************
;*
;* LCDDriver.asm - V2.0
;*
;* Contains the neccessary functions to display text to a
;* 2 x 16 character LCD Display. Additional functions
;* include a conversion routine from an unsigned 8-bit
;* binary number to and ASCII text string.
;*
;* Version 2.0 - Added support for accessing the LCD
;* Display via the serial port. See version 1.0 for
;* accessing a memory mapped LCD display.
;*
;***********************************************************
;*
;* Author: David Zier
;* Date: March 17, 2003
;* Company: TekBots(TM), Oregon State University - EECS
;* Version: 2.0
;*
;***********************************************************
;* Rev Date Name Description
;*----------------------------------------------------------
;* - 8/20/02 Zier Initial Creation of Version 1.0
;* A 3/7/03 Zier V2.0 - Updated for USART LCD
;*
;*
;***********************************************************
;***********************************************************
;* Internal Register Definitions and Constants
;* NOTE: A register MUST be named 'mpr' in the Main Code
;* It is recomended to use register r16.
;* WARNING: Register r17-r22 are reserved and cannot be
;* renamed outside of the LCD Driver functions. Doing
;* so will damage the functionality of the LCD Driver
;***********************************************************
.def wait = r17 ; Wait Loop Register
.def count = r18 ; Character Counter
.def line = r19 ; Line Select Register
.def type = r20 ; LCD data type: Command or Text
.def q = r21 ; Quotient for div10
.def r = r22 ; Remander for div10
.equ LCDLine1 = $80 ; LCD Line 1 select command
.equ LCDLine2 = $c0 ; LCD Line 2 select command
.equ LCDClear = $01 ; LCD Clear Command
.equ LCDHome = $02 ; LCD Set Cursor Home Command
.equ LCDPulse = $08 ; LCD Pulse signal, used to simulate
; write signal
.equ LCDCmd = $00 ; Constant used to write a command
.equ LCDTxt = $01 ; Constant used to write a text character
.equ LCDMaxCnt = 16 ; Maximum number of characters per line
.equ LCDLn1Addr = $0100 ; Beginning address for Line 1 data
.equ LCDLn2Addr = $0110 ; Beginning address for Line 2 data
;-----------------------------------------------------------
;***********************************************************
;* Public LCD Driver Suboutines and Functions
;* These functions and subroutines can be called safely
;* from within any program
;***********************************************************
;-----------------------------------------------------------
;*******************************************************
;* SubRt: LCDInit
;* Desc: Initialize the Serial Port and the Hitachi
;* Display 8 Bit inc DD-RAM
;* Pointer with no features
;* - 2 LInes with 16 characters
;*******************************************************
LCDInit:
push mpr ; Save the state of machine
in mpr, SREG ; Save the SREG
push mpr ;
push wait ; Save wait
; Setup the Communication Ports
; Port B: Output
; Port D: Input w/ internal pullup resistors
; Port F: Output on Pin 3
ldi mpr, $00 ; Initialize Port B for outputs
out PORTB, mpr ; Port B outputs high
ldi mpr, $ff ; except for any overrides
out DDRB, mpr ;
ldi mpr, $00 ; Initialize Port D for inputs
out PORTD, mpr ; with Tri-State
ldi mpr, $00 ; except for any overrides
out DDRD, mpr ;
ldi mpr, $00 ; Initialize Port F Pin 3 to
sts PORTF, mpr ; output inorder to twiddle the
ldi mpr, (1<<DDF3) ; LCD interface
sts DDRF, mpr ; Must NOT override this port
; Setup the Serial Functionality
; SPI Type: Master
; SPI Clock Rate: 2*1000.000 kHz
; SPI Clock Phase: Cycle Half
; SPI Clock Polarity: Low
; SPI Data Order: MSB First
ldi mpr, (1<<SPE|1<<MSTR)
out SPCR, mpr ; Set Serial Port Control Register
ldi mpr, (1<<SPI2X)
out SPSR, mpr ; Set Serial Port Status Register
; Setup External SRAM configuration
; $0460 - $7FFF / $8000 - $FFFF
; Lower page wait state(s): None
; Uppoer page wait state(s): 2r/w
ldi mpr, (1<<SRE) ;
out MCUCR, mpr ; Initialize MCUCR
ldi mpr, (1<<SRL2|1<<SRW11)
sts XMCRA, mpr ; Initialize XMCRA
ldi mpr, (1<<XMBK) ;
sts XMCRB, mpr ; Initialize XMCRB
; Initialize USART0
; Communication Parameter: 8 bit, 1 stop, No Parity
; USART0 Rx: On
; USART0 Tx: On
; USART0 Mode: Asynchronous
; USART0 Baudrate: 9600
ldi mpr, $00 ;
out UCSR0A, mpr ; Init UCSR0A
ldi mpr, (1<<RXEN0|1<<TXEN0)
out UCSR0B, mpr ; Init UCSR0B
ldi mpr, (1<<UCSZ01|1<<UCSZ00)
sts UCSR0C, mpr ; Init UCSR0C
ldi mpr, $00 ;
sts UBRR0H, mpr ; Init UBRR0H
ldi mpr, $67 ;
out UBRR0L, mpr ; Init UBRR0L
; Initialize the LCD Display
ldi mpr, 6 ;
LCDINIT_L1:
ldi wait, 250 ; 15ms of Display
rcall LCDWait ; Bootup wait
dec mpr ;
brne LCDINIT_L1 ;
ldi mpr, $38 ; Display Mode set
rcall LCDWriteCmd ;
ldi mpr, $08 ; Display Off
rcall LCDWriteCmd ;
ldi mpr, $01 ; Display Clear
rcall LCDWriteCmd ;
ldi mpr, $06 ; Entry mode set
rcall LCDWriteCmd ;
ldi mpr, $0c ; Display on
rcall LCDWriteCmd ;
rcall LCDClr ; Clear display
pop wait ; Restore wait
pop mpr ; Restore SREG
out SREG, mpr ;
pop mpr ; Restore mpr
ret ; Return from subroutine
;*******************************************************
;* Func: LCDWrite
;* Desc: Generic Write Function that writes both lines
;* of text out to the LCD
;* - Line 1 data is in address space $0100-$010F
;* - Line 2 data is in address space $0110-$010F
;*******************************************************
LCDWrite:
rcall LCDWrLn1 ; Write Line 1
rcall LCDWrLn2 ; Write Line 2
ret ; Return from function
;*******************************************************
;* Func: LCDWrLn1
;* Desc: This function will write the first line of
;* data to the first line of the LCD Display
;*******************************************************
LCDWrLn1:
push mpr ; Save mpr
push ZL ; Save Z pointer
push ZH ;
push count ; Save the count register
push line ; Save the line register
ldi ZL, low(LCDLn1Addr)
ldi ZH, high(LCDLn1Addr)
ldi line, LCDLine1 ; Set LCD line to Line 1
rcall LCDSetLine ; Restart at the beginning of line 1
rcall LCDWriteLine ; Write the line of text
pop line
pop count ; Restore the counter
pop ZH ; Restore Z pointer
pop ZL ;
pop mpr ; Restore mpr
ret ; Return from function
;*******************************************************
;* Func: LCDWrLn2
;* Desc: This function will write the second line of
;* data to the second line of the LCD Display
;*******************************************************
LCDWrLn2:
push mpr ; Save mpr
push ZL ; Save Z pointer
push ZH ;
push count ; Save the count register
push line ; Save the line register
ldi ZL, low(LCDLn2Addr)
ldi ZH, high(LCDLn2Addr)
ldi line, LCDLine2 ; Set LCD line to Line 2
rcall LCDSetLine ; Restart at the beginning of line 2
rcall LCDWriteLine ; Write the line of text
pop line
pop count ; Restore the counter
pop ZH ; Restore Z pointer
pop ZL ;
pop mpr ; Restore mpr
ret ; Return from function
;*******************************************************
;* Func: LCDClr
;* Desc: Generic Clear Subroutine that clears both
;* lines of the LCD and Data Memory storage area
;*******************************************************
LCDClr:
rcall LCDClrLn1 ; Clear Line 1
rcall LCDClrLn2 ; Clear Line 2
ret ; Return from Subroutine
;*******************************************************
;* Func: LCDClrLn1
;* Desc: This subroutine will clear the first line of
;* the data and the first line of the LCD Display
;*******************************************************
LCDClrLn1:
push mpr ; Save mpr
push line ; Save line register
push count ; Save the count register
push ZL ; Save Z pointer
push ZH ;
ldi line, LCDline1 ; Set Access to Line 1 of LCD
rcall LCDSetLine ; Set Z pointer to address of line 1 data
ldi ZL, low(LCDLn1Addr)
ldi ZH, high(LCDLn1Addr)
rcall LCDClrLine ; Call the Clear Line function
pop ZH ; Restore Z pointer
pop ZL ;
pop count ; Restore the count register
pop line ; Restore line register
pop mpr ; Restore mpr
ret ; Return from Subroutine
;*******************************************************
;* Func: LCDClrLn2
;* Desc: This subroutine will clear the second line of
;* the data and the second line of the LCD Display
;*******************************************************
LCDClrLn2:
push mpr ; Save mpr
push line ; Save line register
push count ; Save the count register
push ZL ; Save Z pointer
push ZH ;
ldi line, LCDline2 ; Set Access to Line 2 of LCD
rcall LCDSetLine ; Set Z pointer to address of line 2 data
ldi ZL, low(LCDLn2Addr)
ldi ZH, high(LCDLn2Addr)
rcall LCDClrLine ; Call the Clear Line function
pop ZH ; Restore Z pointer
pop ZL ;
pop count ; Restore the count register
pop line ; Restore line register
pop mpr ; Restore mpr
ret ; Return from Subroutine
;*******************************************************
;* Func: LCDWriteByte
;* Desc: This is a complex and low level function that
;* allows any program to write any ASCII character
;* (Byte) anywhere in the LCD Display. There
;* are several things that need to be initialized
;* before this function is called:
;* count - Holds the index value of the line to where
;* the char is written, 0-15(39). i.e. if
;* count has the value of 3, then the char is
;* going to be written to the third element of
;* the line.
;* line - Holds the line number that the char is going
;* to be written to, (1 or 2).
;* mpr - Contains the value of the ASCII character to
;* be written (0-255)
;*********************************************************
LCDWriteByte:
push mpr ; Save the mpr
push line ; Save the line
push count ; Save the count
; Preform sanity checks on count and line
cpi count, 40 ; Make sure count is within range
brsh LCDWriteByte_3 ; Do nothing and exit function
cpi line, 1 ; If (line == 1)
brne LCDWriteByte_1 ;
ldi line, LCDLine1 ; Load line 1 base LCD Address
rjmp LCDWriteByte_2 ; Continue on with function
LCDWriteByte_1:
cpi line, 2 ; If (line == 2)
brne LCDWriteByte_3 ; Do nothing and exit function
ldi line, LCDLine2 ; Load line 2 base LCD Address
LCDWriteByte_2: ; Write char to LCD
add line, count ; Set the correct LCD address
rcall LCDSetLine ; Set the line address to LCD
rcall LCDWriteChar ; Write Char to LCD Display
LCDWriteByte_3: ; Exit Function
pop count ; Restore the count
pop line ; Restore the line
pop mpr ; Restore the mpr
ret ; Return from function
;*******************************************************
;* Func: Bin2ASCII
;* Desc: Converts a binary number into an ASCII
;* text string equivalent.
;* - The binary number needs to be in the mpr
;* - The Start Address of where the text will
;* be placed needs to be in the X Register
;* - The count of the characters created are
;* added to the count register
;*******************************************************
Bin2ASCII:
push mpr ; save mpr
push r ; save r
push q ; save q
push XH ; save X-pointer
push XL ;
; Determine the range of mpr
cpi mpr, 100 ; is mpr >= 100
brlo B2A_1 ; goto next check
ldi count, 3 ; Three chars are written
adiw XL, 3 ; Increment X 3 address spaces
rjmp B2A_3 ; Continue with program
B2A_1: cpi mpr, 10 ; is mpr >= 10
brlo B2A_2 ; Continue with program
ldi count, 2 ; Two chars are written
adiw XL, 2 ; Increment X 2 address spaces
rjmp B2A_3 ; Continue with program
B2A_2: adiw XL, 1 ; Increment X 1 address space
ldi count, 1 ; One char is written
B2A_3: ;Do-While statement that converts Binary to ASCII
rcall div10 ; Call the div10 function
ldi mpr, '0' ; Set the base ASCII integer value
add mpr, r ; Create the ASCII integer value
st -X, mpr ; Load ASCII value to memory
mov mpr, q ; Set mpr to quotiant value
cpi mpr, 0 ; does mpr == 0
brne B2A_3 ; do while (mpr != 0)
pop XL ; restore X-pointer
pop XH ;
pop q ; restore q
pop r ; restore r
pop mpr ; restore mpr
ret ; return from function
;-------------------------------------------------------
;*******************************************************
;* Private LCD Driver Functions and Subroutines
;* NOTE: It is not recommended to call these functions
;* or subroutines, only call the Public ones.
;*******************************************************
;-------------------------------------------------------
;*******************************************************
;* Func: LCDSetLine
;* Desc: Change line to be written to
;*******************************************************
LCDSetLine:
push mpr ; Save mpr
mov mpr,line ; Copy Command Data to mpr
rcall LCDWriteCmd ; Write the Command
pop mpr ; Restore the mpr
ret ; Return from function
;*******************************************************
;* Func: LCDClrLine
;* Desc: Manually clears a single line within an LCD
;* Display and Data Memory by writing 16
;* consecutive ASCII spaces $20 to both the LCD
;* and the memory. The line to be cleared must
;* first be set in the LCD and the Z pointer is
;* pointing the first element in Data Memory
;*******************************************************
LCDClrLine:
ldi mpr, ' ' ; The space char to be written
ldi count, LCDMaxCnt; The character count
LCDClrLine_1:
st Z+, mpr ; Clear data memory element
rcall LCDWriteChar ; Clear LCD memory element
dec count ; Decrement the count
brne LCDClrLine_1 ; Continue untill all elements are cleared
ret ; Return from function
;*******************************************************
;* Func: LCDWriteLine
;* Desc: Writes a line of text to the LCD Display.
;* This routine takes a data element pointed to
;* by the Z-pointer and copies it to the LCD
;* Display for the duration of the line. The
;* line the Z-pointer must be set prior to the
;* function call.
;*******************************************************
LCDWriteLine:
ldi count, LCDMaxCnt; The character count
LCDWriteLine_1:
ld mpr, Z+ ; Get the data element
rcall LCDWriteChar ; Write element to LCD Display
dec count ; Decrement the count
brne LCDWriteLine_1 ; Continue untill all elements are written
ret ; Return from function
;*******************************************************
;* Func: LCDWriteCmd
;* Desc: Write command that is in the mpr to LCD
;*******************************************************
LCDWriteCmd:
push type ; Save type register
push wait ; Save wait register
ldi type, LCDCmd ; Set type to Command data
rcall LCDWriteData ; Write data to LCD
push mpr ; Save mpr register
ldi mpr, 2 ; Wait approx. 4.1 ms
LCDWC_L1:
ldi wait, 205 ; Wait 2050 us
rcall LCDWait ;
dec mpr ; The wait loop cont.
brne LCDWC_L1 ;
pop mpr ; Restore mpr
pop wait ; Restore wait register
pop type ; Restore type register
ret ; Return from function
;*******************************************************
;* Func: LCDWriteChar
;* Desc: Write character data that is in the mpr
;*******************************************************
LCDWriteChar:
push type ; Save type register
push wait ; Save the wait register
ldi type, LCDTxt ; Set type to Text data
rcall LCDWriteData ; Write data to LCD
ldi wait, 16 ; Delay 160 us
rcall LCDWait ;
pop wait ; Restore wait register
pop type ; Restore type register
ret ; Return from function
;*******************************************************
;* Func: LCDWriteData
;* Desc: Write data or command to LCD
;*******************************************************
LCDWriteData:
out SPDR, type ; Send type to SP
ldi wait, 2 ; Wait 2 us
rcall LCDWait ; Call Wait function
out SPDR,mpr ; Send data to serial port
ldi wait, 2 ; Wait 2 us
rcall LCDWait ; Call Wait function
ldi wait, LCDPulse ; Use wait temporarially to
sts PORTF, wait ; to send write pulse to LCD
ldi wait, $00 ;
sts PORTF, wait ;
ret ; Return from function
;*******************************************************
;* Func: LCDWait
;* Desc: A wait loop that is 10 + 159*wait cycles or
;* roughly wait*10us. Just initialize wait
;* for the specific amount of time in 10us
;* intervals.
;*******************************************************
LCDWait:push mpr ; Save mpr
LCDW_L1:ldi mpr, $49 ; Load with a 10us value
LCDW_L2:dec mpr ; Inner Wait Loop
brne LCDW_L2
dec wait ; Outer Wait Loop
brne LCDW_L1
pop mpr ; Restore mpr
ret ; Return from Wait Function
;*******************************************************
;* Bin2ASCII routines that can be used as a psuedo-
;* printf function to convert an 8-bit binary
;* number into the unigned decimal ASCII text
;*******************************************************
;***********************************************************
;* Func: div10
;* Desc: Divides the value in the mpr by 10 and
;* puts the remander in the 'r' register and
;* and the quotiant in the 'q' register.
;* DO NOT modify this function, trust me, it does
;* divide by 10 :) ~DZ
;***********************************************************
div10:
push r0 ; Save register
; q = mpr / 10 = mpr * 0.000110011001101b
mov q, mpr ; q = mpr * 1.0b
lsr q ; q >> 2
lsr q ; q = mpr * 0.01b
add q, mpr ; q = (q + mpr) >> 1
lsr q ; q = mpr * 0.101b
add q, mpr ; q = (q + mpr) >> 3
lsr q
lsr q
lsr q ; q = mpr * 0.001101b
add q, mpr ; q = (q + mpr) >> 1
lsr q ; q = mpr * 0.1001101b
add q, mpr ; q = (q + mpr) >> 3
lsr q
lsr q
lsr q ; q = mpr * 0.0011001101b
add q, mpr ; q = (q + mpr) >> 1
lsr q ; q = mpr * 0.10011001101b
add q, mpr ; q = (q + mpr) >> 4
lsr q
lsr q
lsr q
lsr q ; q = mpr * 0.000110011001101b
; compute the remainder as r = i - 10 * q
; calculate r = q * 10 = q * 1010b
mov r, q ; r = q * 1
lsl r ; r << 2
lsl r ; r = q * 100b
add r, q ; r = (r + q) << 1
lsl r ; r = q * 1010b
mov r0, r ; r0 = 10 * q
mov r, mpr ; r = mpr
sub r, r0 ; r = mpr - 10 * q
; Fix any errors that occur
div10_1:cpi r, 10 ; Compare with 10
brlo div10_2 ; do nothing if r < 10
inc q ; fix qoutient
subi r, 10 ; fix remainder
rjmp div10_1 ; Continue until error is corrected
div10_2:pop r0 ; Restore registers
ret ; Return from function

Some files were not shown because too many files have changed in this diff Show More