Skip to content

Instantly share code, notes, and snippets.

@stphung
Created November 7, 2012 22:03
Show Gist options
  • Save stphung/4034805 to your computer and use it in GitHub Desktop.
Save stphung/4034805 to your computer and use it in GitHub Desktop.
Raid Scheduler
object Role extends Enumeration {
type Role = Value
val Tank = Value("Tank")
val Heal = Value("Heal")
val Damage = Value("Damage")
}
import Role._
case class Character(name: String, roles: List[Role], score: Double)
/**
* A composition defines a mixture of tank, healer, and damage characters.
*/
trait Composition {
def tankCount: Int
def healCount: Int
def damageCount: Int
}
/**
* A standard ten man composition.
*/
class StandardTenManComposition extends Composition {
def tankCount = 2
def healCount = 3
def damageCount = 5
}
/**
* A raid is a mapping of characters to roles to perform.
*/
case class Raid(tank: List[Character], heal: List[Character], damage: List[Character])
/**
* A raid factory creates a raid from a list of characters and a composition.
*/
trait RaidFactory {
def create(candidates: List[Character], composition: Composition): Option[Raid]
}
/**
* A raid factory which greedily selects tank, heal, and damage in that order.
*/
class GreedyRaidFactory {
def create(candidates: List[Character], composition: Composition): Option[Raid] = {
/**
* Returns in score ascending order, candidates which can assume a given role excluding the characters in the diff list.
*/
def roles(role: Role, diff: List[Character]) = (candidates.filterNot(diff.contains)).filter(_.roles.contains(role)).sortWith(_.score < _.score)
val tank = roles(Tank, Nil)
val heal = roles(Heal, tank)
val damage = roles(Damage, tank ::: heal)
try {
Some(Raid(tank.take(composition.tankCount), heal.take(composition.healCount), damage.take(composition.damageCount)))
} catch {
case thrown => None
}
}
}
/**
* Entrypoint
*/
object Main {
private def readCharacter(input: String): Character = {
val data = input.split(":")
val name = data(0).trim
val score = data(1).toDouble
val roles = createRoleList(data(2))
Character(name, roles, score)
}
private def createRoleList(role: String): List[Role] = {
val tank = if (role.contains("T")) List(Tank) else Nil
val heal = if (role.contains("H")) List(Heal) else Nil
val damage = if (role.contains("D")) List(Damage) else Nil
tank ::: heal ::: damage
}
def main(args: Array[String]): Unit = {
val lines = scala.io.Source.fromFile("Attendance.txt").getLines.toList
val characters = lines.last.split(",").map(readCharacter(_)).toList
val raidFactory = new GreedyRaidFactory
raidFactory.create(characters, new StandardTenManComposition) match {
case Some(raid) => {
println("attending tanks")
raid.tank.foreach(println)
println
println("attending healers")
raid.heal.foreach(println)
println
println("attending dps")
raid.damage.foreach(println)
}
case None => {
println("could not form a raid!")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment