diff options
author | Robby Zambito <Zambito101@gmail.com> | 2019-11-23 16:06:45 -0500 |
---|---|---|
committer | Robby Zambito <Zambito101@gmail.com> | 2019-11-23 16:06:45 -0500 |
commit | df8385cab91926226e8a134bf074d4f5de79ea62 (patch) | |
tree | f4efaf1c24e56389a560d4fcaef535207d3e280f |
Initial commit.
-rw-r--r-- | .gitignore | 112 | ||||
-rw-r--r-- | .idea/.gitignore | 2 | ||||
-rw-r--r-- | .idea/codeStyles/codeStyleConfig.xml | 5 | ||||
-rw-r--r-- | .idea/compiler.xml | 6 | ||||
-rw-r--r-- | .idea/misc.xml | 6 | ||||
-rw-r--r-- | .idea/modules.xml | 9 | ||||
-rw-r--r-- | .idea/modules/OthelloAI-build.iml | 114 | ||||
-rw-r--r-- | .idea/modules/OthelloAI.iml | 16 | ||||
-rw-r--r-- | .idea/sbt.xml | 19 | ||||
-rw-r--r-- | .idea/scala_compiler.xml | 6 | ||||
-rw-r--r-- | .idea/vcs.xml | 6 | ||||
-rw-r--r-- | build.sbt | 5 | ||||
-rw-r--r-- | project/build.properties | 1 | ||||
-rw-r--r-- | src/main/scala/me/robbyzambito/othello/Main.scala | 20 | ||||
-rw-r--r-- | src/main/scala/me/robbyzambito/othello/game/Board.scala | 54 | ||||
-rw-r--r-- | src/main/scala/me/robbyzambito/othello/game/Game.scala | 82 | ||||
-rw-r--r-- | src/main/scala/me/robbyzambito/othello/game/Move.scala | 21 | ||||
-rw-r--r-- | src/main/scala/me/robbyzambito/othello/game/Player.scala | 75 | ||||
-rw-r--r-- | src/main/scala/me/robbyzambito/othello/game/package.scala | 11 |
19 files changed, 570 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a088253 --- /dev/null +++ b/.gitignore @@ -0,0 +1,112 @@ +# Java + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + + +# Maven + +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser
\ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..5c98b42 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ +<component name="ProjectCodeStyleConfiguration"> + <state> + <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> + </state> +</component>
\ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..a0af1d1 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CompilerConfiguration"> + <bytecodeTargetLevel target="12" /> + </component> +</project>
\ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d259417 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectRootManager" version="2" languageLevel="JDK_12" default="false" project-jdk-name="12" project-jdk-type="JavaSDK"> + <output url="file://$PROJECT_DIR$/out" /> + </component> +</project>
\ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..02df858 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/modules/OthelloAI.iml" filepath="$PROJECT_DIR$/.idea/modules/OthelloAI.iml" /> + <module fileurl="file://$PROJECT_DIR$/.idea/modules/OthelloAI-build.iml" filepath="$PROJECT_DIR$/.idea/modules/OthelloAI-build.iml" /> + </modules> + </component> +</project>
\ No newline at end of file diff --git a/.idea/modules/OthelloAI-build.iml b/.idea/modules/OthelloAI-build.iml new file mode 100644 index 0000000..ac1178d --- /dev/null +++ b/.idea/modules/OthelloAI-build.iml @@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.id="OthelloAI-build" external.linked.project.path="$MODULE_DIR$/../../project" external.root.project.path="$MODULE_DIR$/../.." external.system.id="SBT" sbt.imports="_root_.sbt.Keys._, _root_.sbt.ScriptedPlugin.autoImport._, _root_.sbt._, _root_.sbt.nio.Keys._, _root_.sbt.plugins.IvyPlugin, _root_.sbt.plugins.JvmPlugin, _root_.sbt.plugins.CorePlugin, _root_.sbt.ScriptedPlugin, _root_.sbt.plugins.SbtPlugin, _root_.sbt.plugins.SemanticdbPlugin, _root_.sbt.plugins.JUnitXmlReportPlugin, _root_.sbt.plugins.Giter8TemplatePlugin, _root_.scala.xml.{TopScope=&gt;SUB:DOLLARscope}" sbt.resolvers="https://repo1.maven.org/maven2/|maven|public, file:/home/robby/.sbt/preloaded|maven|local-preloaded, /home/robby/.ivy2/cache|ivy|Local cache" type="SBT_MODULE" version="4"> + <component name="NewModuleRootManager"> + <output url="file://$MODULE_DIR$/../../project/target/idea-classes" /> + <output-test url="file://$MODULE_DIR$/../../project/target/idea-test-classes" /> + <exclude-output /> + <content url="file://$MODULE_DIR$/../../project"> + <sourceFolder url="file://$MODULE_DIR$/../../project" isTestSource="false" /> + <excludeFolder url="file://$MODULE_DIR$/../../project/project/target" /> + <excludeFolder url="file://$MODULE_DIR$/../../project/target" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module-library"> + <library name="sbt: sbt-and-plugins"> + <CLASSES> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/lib/jansi.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/lib/jline.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/lib/scala-compiler.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/lib/scala-library.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/lib/scala-reflect.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/lib/scala-xml_2.12.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/actions_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/caffeine-2.5.6.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/collections_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/command_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/compiler-bridge_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/compiler-interface-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/completion_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/config-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/core-macros_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/disruptor-3.4.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/fastparse-utils_2.12-0.4.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/fastparse_2.12-0.4.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/file-tree-views-2.1.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/gigahorse-core_2.12-0.5.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/gigahorse-okhttp_2.12-0.5.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/io_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/ipcsocket-1.0.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/ivy-2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/jawn-parser_2.12-0.10.4.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/jline-2.14.6.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/jna-4.5.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/jna-platform-4.5.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/jsch-0.1.54.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/launcher-interface-1.1.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/lenses_2.12-0.4.12.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/librarymanagement-core_2.12-1.3.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/librarymanagement-ivy_2.12-1.3.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/lm-coursier-shaded_2.12-2.0.0-RC3-4.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/log4j-api-2.11.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/log4j-core-2.11.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/log4j-slf4j-impl-2.11.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/logic_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/main-settings_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/main_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/okhttp-3.14.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/okhttp-urlconnection-3.7.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/okio-1.17.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/protobuf-java-3.7.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/protocol_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/reactive-streams-1.0.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/run_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/sbinary_2.12-0.5.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/sbt-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/scala-parser-combinators_2.12-1.1.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/scala-reflect-2.12.10.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/scala-xml_2.12-1.2.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/scalacache-caffeine_2.12-0.20.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/scalacache-core_2.12-0.20.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/scalapb-runtime_2.12-0.6.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/scripted-plugin_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/scripted-sbt-redux_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/shaded-scalajson_2.12-1.0.0-M4.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/sjson-new-core_2.12-0.8.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/sjson-new-murmurhash_2.12-0.8.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/sjson-new-scalajson_2.12-0.8.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/slf4j-api-1.7.26.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/sourcecode_2.12-0.1.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/ssl-config-core_2.12-0.4.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/task-system_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/tasks_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/template-resolver-0.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/test-agent-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/test-interface-1.0.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/testing_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/util-cache_2.12-1.3.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/util-control_2.12-1.3.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/util-interface-1.3.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/util-logging_2.12-1.3.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/util-position_2.12-1.3.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/util-relation_2.12-1.3.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/util-scripted_2.12-1.3.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/util-tracking_2.12-1.3.2.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc-apiinfo_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc-classfile_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc-classpath_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc-compile-core_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc-compile_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc-core_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc-lm-integration_2.12-1.3.3.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc-persist_2.12-1.3.1.jar!/" /> + <root url="jar://$USER_HOME$/.sbt/boot/scala-2.12.10/org.scala-sbt/sbt/1.3.3/zinc_2.12-1.3.1.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> + </orderEntry> + </component> + <component name="SbtModule"> + <option name="buildForURI" value="file:$MODULE_DIR$/../../" /> + <option name="imports" value="_root_.sbt.Keys._, _root_.sbt.ScriptedPlugin.autoImport._, _root_.sbt._, _root_.sbt.nio.Keys._, _root_.sbt.plugins.IvyPlugin, _root_.sbt.plugins.JvmPlugin, _root_.sbt.plugins.CorePlugin, _root_.sbt.ScriptedPlugin, _root_.sbt.plugins.SbtPlugin, _root_.sbt.plugins.SemanticdbPlugin, _root_.sbt.plugins.JUnitXmlReportPlugin, _root_.sbt.plugins.Giter8TemplatePlugin, _root_.scala.xml.{TopScope=>SUB:DOLLARscope}" /> + </component> +</module>
\ No newline at end of file diff --git a/.idea/modules/OthelloAI.iml b/.idea/modules/OthelloAI.iml new file mode 100644 index 0000000..71f3394 --- /dev/null +++ b/.idea/modules/OthelloAI.iml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.id="othelloai [file:/home/robby/IdeaProjects/OthelloAI/]" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="SBT" type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_12"> + <output url="file://$MODULE_DIR$/../../target/scala-2.13/classes" /> + <output-test url="file://$MODULE_DIR$/../../target/scala-2.13/test-classes" /> + <exclude-output /> + <content url="file://$MODULE_DIR$/../.."> + <sourceFolder url="file://$MODULE_DIR$/../../src/main/scala" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/../../src/test/scala" isTestSource="true" /> + <excludeFolder url="file://$MODULE_DIR$/../../target" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="library" name="sbt: org.scala-lang:scala-library:2.13.1:jar" level="project" /> + </component> +</module>
\ No newline at end of file diff --git a/.idea/sbt.xml b/.idea/sbt.xml new file mode 100644 index 0000000..1bf561c --- /dev/null +++ b/.idea/sbt.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ScalaSbtSettings"> + <option name="customVMEnabled" value="true" /> + <option name="customVMPath" value="/usr/lib/jvm/java-12-openjdk-amd64" /> + <option name="linkedExternalProjectsSettings"> + <SbtProjectSettings> + <option name="externalProjectPath" value="$PROJECT_DIR$" /> + <option name="modules"> + <set> + <option value="$PROJECT_DIR$" /> + <option value="$PROJECT_DIR$/project" /> + </set> + </option> + <option name="useQualifiedModuleNames" value="true" /> + </SbtProjectSettings> + </option> + </component> +</project>
\ No newline at end of file diff --git a/.idea/scala_compiler.xml b/.idea/scala_compiler.xml new file mode 100644 index 0000000..a26a233 --- /dev/null +++ b/.idea/scala_compiler.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ScalaCompilerConfiguration"> + <profile name="sbt 1" modules="OthelloAI" /> + </component> +</project>
\ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="$PROJECT_DIR$" vcs="Git" /> + </component> +</project>
\ No newline at end of file diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..733f818 --- /dev/null +++ b/build.sbt @@ -0,0 +1,5 @@ +name := "OthelloAI" + +version := "0.1" + +scalaVersion := "2.13.1" diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..010613d --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version = 1.3.3
\ No newline at end of file diff --git a/src/main/scala/me/robbyzambito/othello/Main.scala b/src/main/scala/me/robbyzambito/othello/Main.scala new file mode 100644 index 0000000..3ad491c --- /dev/null +++ b/src/main/scala/me/robbyzambito/othello/Main.scala @@ -0,0 +1,20 @@ +package me.robbyzambito.othello + +import me.robbyzambito.othello.game.Game + +import scala.annotation.tailrec + +object Main extends App { + + val game = Game() + + @tailrec + def gameLoop(game: Game): Unit = { + if (game.winner.isEmpty) { + gameLoop(game.takeTurn) + } + } + + gameLoop(game) + +} diff --git a/src/main/scala/me/robbyzambito/othello/game/Board.scala b/src/main/scala/me/robbyzambito/othello/game/Board.scala new file mode 100644 index 0000000..fa230d0 --- /dev/null +++ b/src/main/scala/me/robbyzambito/othello/game/Board.scala @@ -0,0 +1,54 @@ +package me.robbyzambito.othello.game + +/** + * Represents the total space for which the game is played in. + * + * Written by Robby Zambito + * Written on 11/20/2019 + * Targeting Scala 2.13.1 + */ +case class Board(positions: List[List[Position]]) { + /** + * Assigns <pre>(x, y)</pre> in the board to <pre>position</pre>. + * + * @param row location to update value. + * @param column location to update value. + * @param position The new position value. + * @return copy of the existing board with a new updated value. + */ + def updatePosition(row: Int, column: Int, position: Position): Board = + this.copy(positions = positions.updated(row, positions(row).updated(column, position))) + + override def toString: String = + positions.map(row => row.map { + case Position.EMPTY => "*" + case Position.WHITE => "w" + case Position.BLACK => "b" + }.mkString(" ")).mkString("\n") + +} + +object Board { + /** + * Creates an empty board. + * + * @return a new board with all positions empty. + */ + protected def apply(): Board = + new Board(List.fill(8)(List.fill(8)(Position.EMPTY))) + + /** + * Factory method to construct a new board with the state + * of a new game. + * + * @return a board with a starting game state. + */ + def init(): Board = { + val board = Board().updatePosition(3, 3, Position.WHITE) + .updatePosition(3, 4, Position.BLACK) + .updatePosition(4, 3, Position.BLACK) + .updatePosition(4, 4, Position.WHITE) + + board + } +} diff --git a/src/main/scala/me/robbyzambito/othello/game/Game.scala b/src/main/scala/me/robbyzambito/othello/game/Game.scala new file mode 100644 index 0000000..f3a2738 --- /dev/null +++ b/src/main/scala/me/robbyzambito/othello/game/Game.scala @@ -0,0 +1,82 @@ +package me.robbyzambito.othello.game + +import scala.io.StdIn + +/** + * Represents the state of the game. + * Reports the winner of the game when that state is reached. + * + * Written by Robby Zambito + * Written on 11/20/2019 + * Targeting Scala 2.13.1 + */ +case class Game(board: Board, + players: List[Player], + turnCount: Int = 0) { + + val currentPlayer: Player = players(turnCount % players.length) + val currentOpponent: Player = players(turnCount % players.length) + + /** + * Save the game state to a file to be loaded at a later date. + * + * @return true if the game was successfully saved, otherwise false. + */ + def save(): Boolean = ??? + + /** + * The winner of the game. Ties are not yet handled + * + * [[None]] if there has not been a winner yet. Otherwise return the [[Player]] which has won. + */ + lazy val winner: Option[Player] = { + if (currentPlayer.canMove(board) || (!currentPlayer.canMove(board) && currentOpponent.canMove(board))) + None + else { // No one can move + val whiteCount = board.positions.flatten.count(_ == Position.WHITE) + val blackCount = board.positions.flatten.count(_ == Position.BLACK) + + if (whiteCount > blackCount) + players.find(p => p.color == Position.WHITE) + else if (whiteCount < blackCount) + players.find(p => p.color == Position.BLACK) + else None + // throw new Error("Game tied") + } + } + + override def toString: String = { + s""" + |${board} + | + |${if (winner.isDefined) s"${winner.get} has won!" else ""} + |""".stripMargin + } + + /** + * Take a turn + * + * @return the game with the next turn state + */ + def takeTurn: Game = { + println(board) + println() + + def getPos: (Int, Int) = { + val rowCount = StdIn.readLine(s"Enter the row to move for ${currentPlayer}: ").toInt + val colCount = StdIn.readLine(s"Enter the col to move for ${currentPlayer}: ").toInt + (rowCount, colCount) + } + + val pos = Iterator.continually(getPos) + .dropWhile(!currentPlayer.possibleMoves(board).contains(_)) + .next() + + this.copy(board = board.updatePosition(pos._1, pos._2, currentPlayer.color), turnCount = turnCount + 1) + } + +} + +object Game { + def apply(): Game = new Game(Board.init(), List(Player(Position.WHITE), Player(Position.BLACK))) +}
\ No newline at end of file diff --git a/src/main/scala/me/robbyzambito/othello/game/Move.scala b/src/main/scala/me/robbyzambito/othello/game/Move.scala new file mode 100644 index 0000000..62ffa9c --- /dev/null +++ b/src/main/scala/me/robbyzambito/othello/game/Move.scala @@ -0,0 +1,21 @@ +package me.robbyzambito.othello.game + +/** + * A position and the positions which will be taken once the move has been made. + * + * @param rowCount The vertical position + * @param colCount The horizontal position + * @param takenPositions The positions which will be taken by the move. + */ +case class Move(rowCount: Int, colCount: Int, takenPositions: List[(Int, Int)]) { + + /** + * Apply this move to the board. Assumes the move is valid for the given player. + * + * @param board that the move is being made on. + * @param player which is making the move. + * @return The board with the move applied. + */ + def apply(board: Board, player: Player): Board = + takenPositions.foldLeft(board) { case (b, (r, c)) => b.updatePosition(r, c, player.color) } +} diff --git a/src/main/scala/me/robbyzambito/othello/game/Player.scala b/src/main/scala/me/robbyzambito/othello/game/Player.scala new file mode 100644 index 0000000..e67d1b0 --- /dev/null +++ b/src/main/scala/me/robbyzambito/othello/game/Player.scala @@ -0,0 +1,75 @@ +package me.robbyzambito.othello.game + +import me.robbyzambito.othello.game.Position.Position + +import scala.annotation.tailrec +import scala.util.Try + +/** + * Represents a party which is partaking in the game. + * Both the AI and the end user are instances of Player. + * + * Written by Robby Zambito + * Written on 11/20/2019 + * Targeting Scala 2.13.1 + */ +case class Player(color: Position) { + def canMove(board: Board): Boolean = + possibleMoves(board).nonEmpty + + def possibleMoves(board: Board): List[(Int, Int)] = { + val enemyPosition = if (color == Position.WHITE) Position.BLACK else Position.WHITE + + def possibleAcross(rowCount: Int, colCount: Int): Boolean = { + val row = board.positions(rowCount) + + @tailrec + def checkInDirection(pos: Int, step: Int, isPossible: Boolean = false): Boolean = { + if (pos == colCount && row(pos) != Position.EMPTY) + false + else if (isPossible && row(pos + step) == color) + true + else if (!isPossible && Try(row(pos + step)).getOrElse(Position.EMPTY) == enemyPosition) + checkInDirection(pos + step, step, isPossible = true) + else false + } + + // Check can move left or right + checkInDirection(colCount, 1) || checkInDirection(colCount, -1) + } + + def possibleVertical(rowCount: Int, colCount: Int): Boolean = { + val col = board.positions.indices.map(i => board.positions(i)(colCount)) + + @tailrec + def checkInDirection(pos: Int, step: Int, isPossible: Boolean = false): Boolean = { + if (pos == rowCount && col(pos) != Position.EMPTY) + false + else if (isPossible && col(pos + step) == color) + true + else if (!isPossible && Try(col(pos + step)).getOrElse(Position.EMPTY) == enemyPosition) + checkInDirection(pos + step, step, isPossible = true) + else false + } + + // Check can move left or right + checkInDirection(rowCount, 1) || checkInDirection(rowCount, -1) + } + + + (for (rowCount <- board.positions.indices) yield { + (for (colCount <- board.positions(rowCount).indices) yield { + if (possibleAcross(rowCount, colCount) || possibleVertical(rowCount, colCount)) + List((rowCount, colCount)) + else List() + }).flatten + }).flatten + .toList + } + + override def toString: String = color match { + case Position.WHITE => "White" + case Position.BLACK => "Black" + case _ => "Default" + } +} diff --git a/src/main/scala/me/robbyzambito/othello/game/package.scala b/src/main/scala/me/robbyzambito/othello/game/package.scala new file mode 100644 index 0000000..250da56 --- /dev/null +++ b/src/main/scala/me/robbyzambito/othello/game/package.scala @@ -0,0 +1,11 @@ +package me.robbyzambito.othello + +package object game { + + object Position extends Enumeration { + type Position = Value + val EMPTY, WHITE, BLACK = Value + } + + type Position = Position.Position +} |