Browse Source

Initial commit.

recursive-to-for
Robby Zambito 7 months ago
commit
df8385cab9
19 changed files with 570 additions and 0 deletions
  1. +112
    -0
      .gitignore
  2. +2
    -0
      .idea/.gitignore
  3. +5
    -0
      .idea/codeStyles/codeStyleConfig.xml
  4. +6
    -0
      .idea/compiler.xml
  5. +6
    -0
      .idea/misc.xml
  6. +9
    -0
      .idea/modules.xml
  7. +114
    -0
      .idea/modules/OthelloAI-build.iml
  8. +16
    -0
      .idea/modules/OthelloAI.iml
  9. +19
    -0
      .idea/sbt.xml
  10. +6
    -0
      .idea/scala_compiler.xml
  11. +6
    -0
      .idea/vcs.xml
  12. +5
    -0
      build.sbt
  13. +1
    -0
      project/build.properties
  14. +20
    -0
      src/main/scala/me/robbyzambito/othello/Main.scala
  15. +54
    -0
      src/main/scala/me/robbyzambito/othello/game/Board.scala
  16. +82
    -0
      src/main/scala/me/robbyzambito/othello/game/Game.scala
  17. +21
    -0
      src/main/scala/me/robbyzambito/othello/game/Move.scala
  18. +75
    -0
      src/main/scala/me/robbyzambito/othello/game/Player.scala
  19. +11
    -0
      src/main/scala/me/robbyzambito/othello/game/package.scala

+ 112
- 0
.gitignore View File

@@ -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

+ 2
- 0
.idea/.gitignore View File

@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

+ 5
- 0
.idea/codeStyles/codeStyleConfig.xml View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

+ 6
- 0
.idea/compiler.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="12" />
</component>
</project>

+ 6
- 0
.idea/misc.xml View File

@@ -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>

+ 9
- 0
.idea/modules.xml View File

@@ -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>

+ 114
- 0
.idea/modules/OthelloAI-build.iml View File

@@ -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=&amp;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=&gt;SUB:DOLLARscope}" />
</component>
</module>

+ 16
- 0
.idea/modules/OthelloAI.iml View File

@@ -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>

+ 19
- 0
.idea/sbt.xml View File

@@ -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>

+ 6
- 0
.idea/scala_compiler.xml View File

@@ -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>

+ 6
- 0
.idea/vcs.xml View File

@@ -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>

+ 5
- 0
build.sbt View File

@@ -0,0 +1,5 @@
name := "OthelloAI"

version := "0.1"

scalaVersion := "2.13.1"

+ 1
- 0
project/build.properties View File

@@ -0,0 +1 @@
sbt.version = 1.3.3

+ 20
- 0
src/main/scala/me/robbyzambito/othello/Main.scala View File

@@ -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)

}

+ 54
- 0
src/main/scala/me/robbyzambito/othello/game/Board.scala View File

@@ -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
}
}

+ 82
- 0
src/main/scala/me/robbyzambito/othello/game/Game.scala View File

@@ -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)))
}

+ 21
- 0
src/main/scala/me/robbyzambito/othello/game/Move.scala View File

@@ -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) }
}

+ 75
- 0
src/main/scala/me/robbyzambito/othello/game/Player.scala View File

@@ -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"
}
}

+ 11
- 0
src/main/scala/me/robbyzambito/othello/game/package.scala View File

@@ -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
}

Loading…
Cancel
Save