Skip to content

Commit

Permalink
Merge pull request #100 from EntelectChallenge/feature/fix-version-nu…
Browse files Browse the repository at this point in the history
…mbering

Fix version numbering
  • Loading branch information
PetrusOrion committed Jun 22, 2018
2 parents e17b2a6 + 6c34131 commit a75191d
Show file tree
Hide file tree
Showing 20 changed files with 360 additions and 15 deletions.
2 changes: 1 addition & 1 deletion game-runner/game-runner-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"verbose-mode": true,
"max-runtime-ms": 2000,
"player-a": "../starter-bots/java",
"player-b": "../starter-bots/java",
"player-b": "../reference-bot/java",
"is-tournament-mode": false
}
8 changes: 0 additions & 8 deletions starter-pack/config.json

This file was deleted.

4 changes: 2 additions & 2 deletions starter-pack/game-runner-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"game-config-file-location": "./game-config.properties",
"verbose-mode": true,
"max-runtime-ms": 2000,
"player-a": "./starter-bots/javascript",
"player-b": "./starter-bots/javascript",
"player-a": "./starter-bots/java",
"player-b": "./reference-bot/java",
"is-tournament-mode": false
}
4 changes: 2 additions & 2 deletions starter-pack/makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
default:
java -jar tower-defence-runner-1.2.0.jar
java -jar tower-defence-runner-2.0.0.jar

run:
java -jar tower-defence-runner-1.2.0.jar
java -jar tower-defence-runner-2.0.0.jar
2 changes: 1 addition & 1 deletion starter-pack/run.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
java -jar tower-defence-runner-1.2.0.jar
java -jar tower-defence-runner-2.0.0.jar
pause
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public enum BuildingType
Attack = 1,
[JsonProperty("ENERGY")]
[EnumMember(Value = "ENERGY")]
Energy = 2
Energy = 2,
[JsonProperty("TESLA")]
[EnumMember(Value = "TESLA")]
Tesla = 4
}
}
59 changes: 59 additions & 0 deletions starter-pack/starter-bots/scala/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# 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/dictionaries

# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml

# Gradle:
.idea/**/gradle.xml
.idea/**/libraries

# CMake
cmake-build-debug/
cmake-build-release/

# Mongo Explorer plugin:
.idea/**/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# 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
\.idea/

*.iml

target/*
*/target/*

*/command.txt
*/state.json
*/textMap.txt
8 changes: 8 additions & 0 deletions starter-pack/starter-bots/scala/bot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"author": "John Doe",
"email": "[email protected]",
"nickName": "Odersky",
"botLocation": "/target/scala-2.12",
"botFileName": "Entelect-Scala-Bot-assembly-0.1.jar",
"botLanguage": "scala"
}
13 changes: 13 additions & 0 deletions starter-pack/starter-bots/scala/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name := "Entelect-Scala-Bot"

version := "0.1"

scalaVersion := "2.12.2"

val json4sNative = "org.json4s" %% "json4s-native" % "3.5.4"

libraryDependencies ++= {
Seq(
json4sNative
)
}
1 change: 1 addition & 0 deletions starter-pack/starter-bots/scala/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.0.4
1 change: 1 addition & 0 deletions starter-pack/starter-bots/scala/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.internal.DslEntry
Binary file not shown.
21 changes: 21 additions & 0 deletions starter-pack/starter-bots/scala/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Scala Sample Bot

A simple starter bot using Functional Scala.

## Dependencies

The bot requires `sbt` for dependency management, as well as the Java runtime environment to be run.

## Running

The game runner will compile using the `sbt assmbly` command. For example:

```
sbt assembly
```

This generates the jar file, which can be run using the java runtime environment, example:

```
java -jar Entelect-Scala-Bot-assembly-0.1.jar
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package za.co.sample

import java.io.FileWriter

import scala.io.Source
import org.json4s._
import org.json4s.native.JsonMethods._
import za.co.sample.models.Models.State


object Parser{
implicit val formats = DefaultFormats

def readFile(fileName: String): String = {
Source.fromFile(fileName)("UTF-8").getLines().mkString
}

def readJsonParse4s(fileName: String): State = {
val json = parse(fileName)
json.extract[State]
}

def writeToFile(fileName:String, data:String): Unit =
using (new FileWriter(fileName)) {
fileWriter => fileWriter.write(data)
}

/**
* Used for reading/writing to database, files, etc.
* Code From the book "Beginning Scala"
* http://www.amazon.com/Beginning-Scala-David-Pollak/dp/1430219890
*/
def using[A <: {def close(): Unit}, B](param: A)(f: A => B): B =
try { f(param) } finally { param.close() }
}
146 changes: 146 additions & 0 deletions starter-pack/starter-bots/scala/src/main/scala/za/co/sample/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package za.co.sample

import za.co.sample.models.Models.{Cell, GameDetails, Player, State}

import scala.util.Random

object Main extends App{
// override def main(args: Array[String]): Unit = {
val stateFile = "state.json"
val commandFile = "command.txt"
implicit val NOTHING_COMMAND = ""

val stateRaw = Parser.readFile(stateFile)
val state: State = Parser.readJsonParse4s(stateRaw)

implicit val gameDetails = state.gameDetails

implicit val gameMap = state.gameMap

implicit val mapHeight = gameDetails.mapHeight
implicit val mapWidth = gameDetails.mapWidth

val playerA = state.players.filter(_.playerType == "A").head
val playerB = state.players.filter(_.playerType == "B").head

implicit val expensiveBuildingCost = List(gameDetails.buildingsStats.ATTACK.price, gameDetails.buildingsStats.DEFENSE.price, gameDetails.buildingsStats.ENERGY.price).max

val action = {
if(isUnderAttack(playerA, playerB) && canAffordBuilding("DEFENSE", playerA))
placeDefendingBuilding(playerA, playerB)
else if (playerA.energy > expensiveBuildingCost)
placeRandomBuilding(playerA)
else
doNothingCommand
}

Parser.writeToFile(commandFile, action)
// }

/**
* Chooses a random unoccupied spot in row to place a defending building.
*
* @return String
*/
def placeDefendingBuilding(playerA: Player, playerB: Player)(implicit gameMap: List[List[Cell]]): String = {
val gettingAttackedInRow = gameMap.filter(row => {
val attacking = row.exists(cell => cell.cellOwner == playerB.playerType && cell.buildings.exists(building => building.buildingType == "A" || building.buildingType == "a"))
val defending = row.exists(cell => cell.cellOwner == playerA.playerType && cell.buildings.exists(building => building.buildingType == "d" || building.buildingType == "D"))
attacking && !defending
})//.head.head.y

println(gameMap.filter(row => row.exists(cell => cell.cellOwner == playerB.playerType)))

// println(gameMap.filter(row => row.exists(cell => cell.cellOwner == playerB.playerType && cell.buildings.exists(building => building.buildingType == "A" || building.buildingType == "a"))))
// println(gameMap.flatMap(row => row.filter(cell => cell.buildings.exists(building => building.buildingType == "A" || building.buildingType == "a"))))
// gameMap.foreach(row => {
// row.foreach(cell => print(s" $cell "))
// println("")
// })
gameMap.foreach(row => {
row.foreach(cell => print(s" ${
if (cell.buildings.nonEmpty)
cell.buildings.head.buildingType
else
"NONE"
} "
)
)
println("")
})
// println(gameMap.exists(row => row.exists(cell => /*cell.cellOwner == playerB.playerType*/cell.buildings.filter(building => building.buildingType == "A" || building.buildingType == "a"))))
println(gettingAttackedInRow)

val cells = gameMap.flatMap(row => row.filter(cell => cell.cellOwner == playerA.playerType && cell.buildings.isEmpty && cell.y == gettingAttackedInRow))
val chosenCell = cells(Random.nextInt(cells.size))
s"${chosenCell.x},${chosenCell.y},0"
}

/**
* Chooses a random unoccupied cell owned by Player A, and place a random building.
*
* @return String
*/
def placeRandomBuilding(playerA: Player)(implicit gameMap: List[List[Cell]]): String = {
val unoccupiedCells = gameMap.flatMap(row => row.filter(cell => cell.cellOwner == playerA.playerType && cell.buildings.isEmpty))
println(unoccupiedCells)
val chosenCell = unoccupiedCells(Random.nextInt(unoccupiedCells.size))
println(chosenCell)
s"${chosenCell.x},${chosenCell.y},${Random.nextInt(2)}"
}

/**
* Check if Player A is under attack by Player B and whether Player A has no defending buildings in that row.
*
* @return Boolean
*/
def isUnderAttack(playerA: Player, playerB: Player)(implicit gameMap: List[List[Cell]]): Boolean = {
val gettingAttackedInRow = gameMap.filter(row => {
val attacking = row.filter(cell => cell.cellOwner == playerB.playerType && cell.buildings.exists(_.buildingType == "ATTACK"))
val defending = row.filter(cell => cell.cellOwner == playerA.playerType && cell.buildings.exists(_.buildingType == "DEFENSE"))
attacking.zip(defending).exists(cells => (cells._1.x, cells._1.y) == (cells._2.x, cells._2.y))
})

//
//
// println("+++++++++++++++++++++")
//
// gameMap.map(row => row.filter(cell => cell.cellOwner == playerA.playerType && cell.buildings.exists(_.buildingType == "DEFENSE"))).foreach(row => {
// row.foreach(cell => print(s" ${
// if(cell.buildings.nonEmpty)
// cell.buildings.head.buildingType
// else
// "NONE"
// }"))
// })
// println(gameMap.exists(row => row.exists(cell => cell.buildings.exists(_.buildingType == "ATTACK"))))
// println(ga)

gettingAttackedInRow.nonEmpty
}


/**
* Checks if a building type is affordable.
*
* @param buildingType
* @return Boolean
*/
def canAffordBuilding(buildingType: String, playerA: Player)(implicit gameDetails: GameDetails): Boolean = {
buildingType match {
case "DEFENSE" => gameDetails.buildingPrices.DEFENSE < playerA.energy
case "ATTACK" => gameDetails.buildingPrices.ATTACK < playerA.energy
case "ENERGY" => gameDetails.buildingPrices.ENERGY < playerA.energy
}
}

/**
* Do nothing.
*
* @return NOTHING
*/
def doNothingCommand(implicit NOTHING_COMMAND: String): String = {
NOTHING_COMMAND
}

}
Loading

0 comments on commit a75191d

Please sign in to comment.