Added swapping in for fallen monsters and looping turns

This commit is contained in:
James Daly 2019-05-28 22:17:08 -04:00
parent 9e376c4e52
commit 8ff9bdd938
5 changed files with 59 additions and 15 deletions

View File

@ -15,18 +15,20 @@ case class Prop(url : Seq[String])
object Game { object Game {
def main(args : Array[String]): Unit = { def main(args : Array[String]): Unit = {
println(Element("Water").effect) println(Element("Water").effect)
println(Move.moves)
println(Form.forms)
println(Status("psn")) println(Status("psn"))
implicit val rng = new scala.util.Random() implicit val rng = new scala.util.Random()
val form1 = Form("Diabolo") val form1 = Form("Diabolo")
val form2 = Form("Chanilla") val form2 = Form("Chanilla")
val movepool1 = IndexedSeq(Move("Frost Breath")) val movepool1 = IndexedSeq(Move("Close Combat"))
val movepool2 = IndexedSeq(Move("Absorb")) val movepool2 = IndexedSeq(Move("Absorb"))
val party1 = new Party(null, new Monster(new StorageMon("Allied Mon", Gene.randomGene(null, form1), form1, Statistic.emptyEvs, movepool1)), IndexedSeq()) val p1 = TrainerID("Jaeda", Gender.Female, 0)
val party2 = new Party(null, new Monster(new StorageMon("Wild Mon", Gene.randomGene(null, form2), form2, Statistic.emptyEvs, movepool2)), IndexedSeq()) val p2 = TrainerID("Wild Monster", Gender.Male, 0)
val party1 = new Party(p1, new Monster(new StorageMon("Allied Mon", Gene.randomGene(null, form1), form1, Statistic.emptyEvs, movepool1)), IndexedSeq())
val party2 = new Party(p2, new Monster(new StorageMon("Wild Mon", Gene.randomGene(null, form2), form2, Statistic.emptyEvs, movepool2)), IndexedSeq(
new Monster(new StorageMon("Sideboard Mon", Gene.randomGene(null, form2), form2, Statistic.emptyEvs, movepool2))
))
val engine = new BattleEngine(party1, party2) val engine = new BattleEngine(party1, party2)
engine.playTurn() engine.play()
println(party1.lead.elements) println(party1.lead.elements)
} }
} }

View File

@ -8,16 +8,40 @@ import mon.util.Fraction
class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random) { class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random) {
def play() = {
while (player.canFight && enemy.canFight) {
playTurn()
}
}
def playTurn() = { def playTurn() = {
val playerMove = player.pollAction val playerMove = player.pollAction
val playerTarget = player.pollTarget(playerMove, player.lead, player, enemy) val playerTarget = player.pollTarget(playerMove, player.lead, enemy)
val enemyMove = enemy.pollAction val enemyMove = enemy.pollAction
val enemyTarget = enemy.pollTarget(enemyMove, enemy.lead, enemy, player) val enemyTarget = enemy.pollTarget(enemyMove, enemy.lead, player)
val actions = Seq(Action(player.lead, playerMove, playerTarget), Action(enemy.lead, enemyMove, enemyTarget)) val actions = Seq(Action(player.lead, playerMove, playerTarget), Action(enemy.lead, enemyMove, enemyTarget))
val queue = rng.shuffle(actions).sorted // Shuffle to randomize in the event of a tie val queue = rng.shuffle(actions).sorted // Shuffle to randomize in the event of a tie
queue.foreach(useMove) queue.foreach(useMove)
val eotQueue = Seq(player.lead, enemy.lead).sortBy(_(Speed)) val eotQueue = Seq(player.lead, enemy.lead).sortBy(_(Speed))
eotQueue.foreach(mon => mon.status.map(_.onResidual.map(_(mon)))) eotQueue.foreach(mon => mon.status.map(_.onResidual.map(_(mon))))
if (!player.lead.isAlive) {
if (player.canFight) {
val replace = player.pollReplacement(enemy)
player.swapIn(replace)
} else {
println(s"${player.trainer} has lost!")
}
}
if (!enemy.lead.isAlive) {
if (enemy.canFight) {
val replace = enemy.pollReplacement(player)
enemy.swapIn(replace)
} else {
println(s"${enemy.trainer} has lost!")
}
}
println(s"${player.lead}(${player.lead.hp}/${player.lead(Hp)})") println(s"${player.lead}(${player.lead.hp}/${player.lead(Hp)})")
println(s"${enemy.lead}(${enemy.lead.hp}/${enemy.lead(Hp)})") println(s"${enemy.lead}(${enemy.lead.hp}/${enemy.lead(Hp)})")
} }
@ -55,7 +79,6 @@ class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random
} }
applyBoosts(target, move.boosts) applyBoosts(target, move.boosts)
applyStatus(target, move.status) applyStatus(target, move.status)
// TODO : Secondary effects
if (move.selfEffect != null) { if (move.selfEffect != null) {
applyEffect(user, move.selfEffect) applyEffect(user, move.selfEffect)
} }

View File

@ -93,11 +93,15 @@ case class MoveToken(
} }
object Move { object Move {
val tokens = YamlHelper.extractSeq[MoveToken](Source.fromInputStream(Move.getClass.getResourceAsStream("data/moves.yaml"))) private var moves = Map[String, Move]()
val moves = tokens.map(_.instantiate()) val tokens = YamlHelper.extractSeq[MoveToken](Source.fromInputStream(Move.getClass.getResourceAsStream("data/moves.yaml"))).map(t => (t.name, t)).toMap
val byName = moves.map(m => (m.name, m)).toMap
def apply(s : String) = byName(s) def apply(name : String) : Move = {
if (!moves.contains(name)) {
moves = moves.updated(name, tokens(name).instantiate())
}
moves(name)
}
def compilePowCallback(code: String): (Monster, Monster) => Int = { def compilePowCallback(code: String): (Monster, Monster) => Int = {
if (code != null) { if (code != null) {

View File

@ -5,13 +5,27 @@ import scala.util.Random
import mon.battle.rngDice import mon.battle.rngDice
import mon.stat.Target._ import mon.stat.Target._
class Party(val trainer : TrainerID, var lead : Monster, val sideboard : IndexedSeq[Monster]) { class Party(val trainer : TrainerID, var lead : Monster, var sideboard : IndexedSeq[Monster]) {
def pollAction(implicit rng : Random) : Move = rng.pick(lead.base.moves) def pollAction(implicit rng : Random) : Move = rng.pick(lead.base.moves)
def pollTarget(move : Move, user : Monster, us : Party, them: Party)(implicit rng : Random) : Monster = { def pollTarget(move : Move, user : Monster, them: Party)(implicit rng : Random) : Monster = {
if (move.target == Self) { if (move.target == Self) {
user user
} else { } else {
them.lead them.lead
} }
} }
def pollReplacement(them : Party)(implicit rng : Random) : Monster = {
sideboard.filter(_.isAlive).head
}
def swapIn(mon : Monster) = {
val index = sideboard.indexOf(mon)
sideboard = sideboard.updated(index, lead)
lead = mon
}
def canFight : Boolean = {
lead.isAlive || sideboard.exists(_.isAlive)
}
} }

View File

@ -2,4 +2,5 @@ package mon.stat
case class TrainerID(name : String, gender : Gender, id : Long) { case class TrainerID(name : String, gender : Gender, id : Long) {
override def toString : String = name
} }