All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.robocode.tankroyale.server.rules.math.kt Maven / Gradle / Ivy

package dev.robocode.tankroyale.server.rules

import kotlin.math.abs
import kotlin.math.sign

/**
 * Returns value clamped to the inclusive range of min and max.
 *
 * @param value is the value to be clamped.
 * @param min   is the lower bound of the result.
 * @param max   is the upper bound of the result.
 * @return is the clamped value.
 */
fun clamp(value: Double, min: Double, max: Double): Double {
    return min.coerceAtLeast(max.coerceAtMost(value))
}

/**
 * Calculates new bot speed.
 * @param currentSpeed is the current speed.
 * @param targetSpeed is the target speed.
 * @return is the calculated new speed of the bot.
 */
fun calcNewBotSpeed(currentSpeed: Double, targetSpeed: Double): Double {
    if (currentSpeed < 0.0)
        return -calcNewBotSpeed(-currentSpeed, -targetSpeed) // to avoid redundancy

    return when {
        currentSpeed > 0 -> {
            if (currentSpeed.sign == targetSpeed.sign) {
                val diff = targetSpeed - currentSpeed
                if (diff >= 0) {
                    val acceleration = diff.coerceAtMost(ACCELERATION)
                    (currentSpeed + acceleration).coerceAtMost(MAX_FORWARD_SPEED)
                } else {
                    val acceleration = diff.coerceAtLeast(DECELERATION)
                    (currentSpeed + acceleration).coerceAtLeast(MAX_BACKWARD_SPEED)
                }
            } else { // crossing the speed of 0
                if (targetSpeed == 0.0) {
                    0.0
                } else {
                    val decelerationTime = currentSpeed / -DECELERATION
                    (1 - decelerationTime) * -ACCELERATION
                }
            }
        }
        else -> { // currentSpeed == 0
            val diff = targetSpeed - currentSpeed
            val acceleration = abs(diff).coerceAtMost(ACCELERATION)
            if (diff >= 0) {
                (currentSpeed + acceleration).coerceAtMost(MAX_FORWARD_SPEED)
            } else {
                (currentSpeed - acceleration).coerceAtLeast(MAX_BACKWARD_SPEED)
            }
        }
    }
}

/**
 * Limits the driving turn rate.
 * @param turnRate is the driving turn rate to limit
 * @param speed is the speed
 * @return limited driving turn rate.
 */
fun limitTurnRate(turnRate: Double, speed: Double): Double {
    val maxTurnRate = calcMaxTurnRate(speed)
    return clamp(turnRate, -maxTurnRate, maxTurnRate)
}

/**
 * Limits the gun turn rate.
 * @param gunTurnRate is the gun turn rate to limit
 * @return limited gun turn rate.
 */
fun limitGunTurnRate(gunTurnRate: Double): Double = clamp(gunTurnRate, -MAX_GUN_TURN_RATE, MAX_GUN_TURN_RATE)

/**
 * Limits the radar turn rate.
 * @param radarTurnRate is the radar turn rate to limit
 * @return limited radar turn rate.
 */
fun limitRadarTurnRate(radarTurnRate: Double): Double =
    clamp(radarTurnRate, -MAX_RADAR_TURN_RATE, MAX_RADAR_TURN_RATE)

/**
 * Calculates the maximum driving turn rate for a specific speed.
 * @param speed is the speed that limits the driving turn rate.
 * @return maximum turn rate.
 */
fun calcMaxTurnRate(speed: Double): Double = MAX_TURN_RATE - 0.75 * abs(clampSpeed(speed))

/**
 * Calculates wall damage.
 * @param speed is the speed of the bot hitting the wall.
 * @return wall damage.
 */
fun calcWallDamage(speed: Double): Double = (abs(clampSpeed(speed)) / 2 - 1).coerceAtLeast(0.0)

/**
 * Calculates bullet speed.
 * @param firepower is the firepower used for firing the bullet.
 * @return bullet speed.
 */
fun calcBulletSpeed(firepower: Double): Double = 20 - 3 * clampFirepower(firepower)

/**
 * Calculates bullet damage.
 * @param firepower is the firepower used for firing the bullet.
 * @return bullet damage.
 */
fun calcBulletDamage(firepower: Double): Double {
    var damage = 4 * clampFirepower(firepower)
    if (firepower > 1) {
        damage += 2 * (firepower - 1)
    }
    return damage
}

/**
 * Calculate gun heat after having fired the gun.
 * @param firepower is the firepower used for firing the bullet.
 * @return gun heat.
 */
fun calcGunHeat(firepower: Double): Double = 1 + clampFirepower(firepower) / 5

fun clampSpeed(speed: Double) = clamp(speed, MAX_BACKWARD_SPEED, MAX_FORWARD_SPEED)

fun clampFirepower(firepower: Double) = clamp(firepower, MIN_FIREPOWER, MAX_FIREPOWER)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy