Created
November 7, 2012 22:03
-
-
Save stphung/4034805 to your computer and use it in GitHub Desktop.
Raid Scheduler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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