package approach.domain import org.w3c.dom.* import approach.domain.KromaiaFormat.WeaponType.* import approach.encoding.Format import approach.simulation.Configuration import approach.simulation.ConfigurationSlice import approach.simulation.Individual class KromaiaFormat(val name: String, private val model: Document?) : Format { lateinit var configuration: Configuration lateinit var vi: ConfigurationSlice lateinit var me: ConfigurationSlice lateinit var bu: ConfigurationSlice lateinit var ho: ConfigurationSlice lateinit var la: ConfigurationSlice lateinit var hu: ConfigurationSlice private lateinit var li: ConfigurationSlice private lateinit var be: ConfigurationSlice override fun apply(): Format { this.vi = getVital() this.me = getMelee() this.bu = getBullet() this.ho = getHoming() this.la = getLaser() this.hu = getHull() this.li = getLink() this.be = getBehavior() this.configuration = "$vi$me$bu$ho$la$hu$li$be" return this } constructor(name: String, configuration: Configuration) : this(name, null) { this.vi = configuration.substring(VI_RANGE) this.me = configuration.substring(ME_RANGE) this.bu = configuration.substring(BU_RANGE) this.ho = configuration.substring(HO_RANGE) this.la = configuration.substring(LA_RANGE) this.hu = configuration.substring(HU_RANGE) this.li = configuration.substring(LI_RANGE) this.be = configuration.substring(BE_RANGE) this.configuration = configuration } /** * Vi (Vital) - Weak points. */ private fun getVital(): ConfigurationSlice { val hulls: NodeList = model!!.getElementsByTagName("Hull") val positions = mutableListOf() for (i in 0 until hulls.length) { val hull: Node = hulls.item(i) if (hull.nodeType == Node.ELEMENT_NODE) { val hullVitalData: NodeList = (hull as Element).getElementsByTagName("HullVitalData") if (hullVitalData.item(0) != null) { positions.add(i) } } } return padding("0", "1", positions, MAX_LENGTH) } enum class WeaponType { MELEE, BULLET, HOMING, LASER } /** * Me (Melee) - Contact weapons. */ private fun getMelee(): ConfigurationSlice { val weapons: NodeList = model!!.getElementsByTagName("Weapon") val positions = mutableListOf() for (i in 0 until weapons.length) { val weapon: Node = weapons.item(i) if (weapon.nodeType == Node.ELEMENT_NODE) { val weaponType = weapon.attributes.getNamedItem("WeaponType").textContent.toInt() if (weaponType in WEAPON_TYPE[MELEE]!!) { positions.add(i) } } } return padding("0", "1", positions, MAX_LENGTH) } /** * Bu (Bullet) - Bullet weapons. */ private fun getBullet(): ConfigurationSlice { val weapons: NodeList = model!!.getElementsByTagName("Weapon") val positions = mutableListOf() for (i in 0 until weapons.length) { val weapon: Node = weapons.item(i) if (weapon.nodeType == Node.ELEMENT_NODE) { val weaponType = weapon.attributes.getNamedItem("WeaponType").textContent.toInt() if (weaponType in WEAPON_TYPE[BULLET]!!) { positions.add(i) } } } return padding("0", "1", positions, MAX_LENGTH) } /** * Ho (Homing) - Guided missile weapons. */ private fun getHoming(): ConfigurationSlice { val weapons: NodeList = model!!.getElementsByTagName("Weapon") val positions = mutableListOf() for (i in 0 until weapons.length) { val weapon: Node = weapons.item(i) if (weapon.nodeType == Node.ELEMENT_NODE) { val weaponProjectileData: NodeList = (weapon as Element).getElementsByTagName("WeaponProjectileData") if (weaponProjectileData.item(0) != null) { val projectileType = weaponProjectileData.item(0).attributes.getNamedItem("ProjectileType").textContent.toInt() if (projectileType in WEAPON_TYPE[HOMING]!!) { positions.add(i) } } } } return padding("0", "1", positions, MAX_LENGTH) } /** * La (Laser) - Laser weapons. */ private fun getLaser(): ConfigurationSlice { val weapons: NodeList = model!!.getElementsByTagName("Weapon") val positions = mutableListOf() for (i in 0 until weapons.length) { val weapon: Node = weapons.item(i) if (weapon.nodeType == Node.ELEMENT_NODE) { val weaponType = weapon.attributes.getNamedItem("WeaponType").textContent.toInt() if (weaponType in WEAPON_TYPE[LASER]!!) { positions.add(i) } } } return padding("0", "1", positions, MAX_LENGTH) } /** * Hu (Hull) - Hulls enabled. */ private fun getHull(): ConfigurationSlice { // Get val hulls: NodeList = model!!.getElementsByTagName("Hull") return padding("0", "1", hulls.length, MAX_LENGTH) } /** * Li (Link) - Parents of hulls, via link (-1 ("-") and range of hulls enabled). */ private fun getLink(): ConfigurationSlice { // FIXME return "-".repeat(MAX_LENGTH) } /** * Be (Behavior) - Hulls leading behavior (movement, mainly). */ private fun getBehavior(): ConfigurationSlice { // FIXME return "0".repeat(MAX_LENGTH) } companion object { val WEAPON_TYPE = mapOf( MELEE to listOf(3), BULLET to listOf(0), HOMING to listOf(6, 102), LASER to listOf(6) ) val VI_RANGE: IntRange = 0 * Individual.CONFIGURATION_ROW_LENGTH until (0 + 1) * Individual.CONFIGURATION_ROW_LENGTH val ME_RANGE: IntRange = 1 * Individual.CONFIGURATION_ROW_LENGTH until (1 + 1) * Individual.CONFIGURATION_ROW_LENGTH val BU_RANGE: IntRange = 2 * Individual.CONFIGURATION_ROW_LENGTH until (2 + 1) * Individual.CONFIGURATION_ROW_LENGTH val HO_RANGE: IntRange = 3 * Individual.CONFIGURATION_ROW_LENGTH until (3 + 1) * Individual.CONFIGURATION_ROW_LENGTH val LA_RANGE: IntRange = 4 * Individual.CONFIGURATION_ROW_LENGTH until (4 + 1) * Individual.CONFIGURATION_ROW_LENGTH val HU_RANGE: IntRange = 5 * Individual.CONFIGURATION_ROW_LENGTH until (5 + 1) * Individual.CONFIGURATION_ROW_LENGTH val LI_RANGE: IntRange = 6 * Individual.CONFIGURATION_ROW_LENGTH until (6 + 1) * Individual.CONFIGURATION_ROW_LENGTH val BE_RANGE: IntRange = 7 * Individual.CONFIGURATION_ROW_LENGTH until (7 + 1) * Individual.CONFIGURATION_ROW_LENGTH const val MAX_LENGTH = Individual.CONFIGURATION_ROW_LENGTH fun padding(default: String, replace: String, repeat: Int, length: Int): String { return if (repeat >= length) { replace.repeat(length) } else if (repeat in 1 until length) { val str = default.repeat(length).toCharArray() for (i in 0 until repeat) { str[i] = replace.single() } String(str) } else { default.repeat(length) } } fun padding(default: String, replace: String, positions: List, length: Int): String { return if (positions.size >= length) { replace.repeat(length) } else if (positions.size in 1 until length) { val str = default.repeat(length).toCharArray() for (i in positions) { str[i] = replace.single() } String(str) } else { default.repeat(length) } } } }