Untitled

 avatar
unknown
java
2 years ago
5.7 kB
7
Indexable
package net.datastructures;

import java.util.*;
import java.util.PriorityQueue;

public class Ex1_2023 {
    public record Spell(String name, int damage, int cast, int cooldown, int duration, int factor) {
        public Spell(String name, int damage, int cast, int cooldown) {
            this(name, damage, cast, cooldown, 0, 1);
        }
    }

    class sortSpells implements Comparator<Spell>
    {
        @Override
        public int compare(Spell o1, Spell o2) {
            int factorWeight;
            int oFactorWeight;
            if (o1.factor == 1) {
                factorWeight = o1.damage / o1.cast;
            } else {
                factorWeight = Integer.MAX_VALUE - 1000000 + o1.factor;
            }
            if (o2.factor == 1) {
                oFactorWeight = o2.damage / o2.cast;
            } else {
                oFactorWeight = Integer.MAX_VALUE - 1000000 + o2.factor;
            }
            return  oFactorWeight - factorWeight;
        }
    }

    class SpellTimers {
        int durationTime;
        int coolDownTime;
        SpellTimers(int durationTimeInSystemMs, int cooldownTimeInSystemMs) {
            durationTime = durationTimeInSystemMs;
            coolDownTime = cooldownTimeInSystemMs;
        }

        public long getCoolDownTime() {
            return coolDownTime;
        }

        public long getDurationTime() {
            return durationTime;
        }

        public void setCoolDownTime(int coolDownTime) {
            this.coolDownTime = coolDownTime;
        }

        public void setDurationTime(int durationTime) {
            this.durationTime = durationTime;
        }
    }

    /*
        TODO use a linked sorted linked list
    */

    public int simulate(Spell[] spells, int time) {
        // set the cumilative damage to 0 and set the end time to the current time + time in ms;
        int damage = 0;
        int nextSpell = 0;


        // Put all currently used spells in a priority Queue
        List<Spell> spellQueue = new ArrayList<>();
        spellQueue.addAll(Arrays.asList(spells));
        Collections.sort(spellQueue,new sortSpells());

        HashMap<Spell, SpellTimers> coolDownTimers = new HashMap<>();
        for (int i = 0; i < spells.length; i++) {
            coolDownTimers.put(spells[i], new SpellTimers(0,0));
        }

        while (time > nextSpell) {

            int currentFactor = 1;


            for (Spell spell: spellQueue) {
                SpellTimers spTimer = coolDownTimers.get(spell);

                if (nextSpell < spTimer.getCoolDownTime()) {
                    continue;
                }

                // Is a buff
                if (spell.factor != 1) {
                    if (spTimer.getDurationTime() > nextSpell) {
                        currentFactor += spell.factor;
                        continue;
                    }
                    if (spTimer.getCoolDownTime() < nextSpell) {
                        currentFactor += spell.factor;
                        spTimer.setCoolDownTime(nextSpell + spell.cooldown);
                        spTimer.setDurationTime(nextSpell + spell.duration);
                        nextSpell = nextSpell + spell.cast;
                        continue;
                    }
                }
                // not a buff
                damage += spell.damage * currentFactor;
                System.out.println(nextSpell + "s: " + spell.name + " (" + spell.damage + " damage, tootal: " + damage + ")");
                nextSpell = nextSpell + spell.cast;
                spTimer.setCoolDownTime(nextSpell + spell.cooldown);
                spTimer.setDurationTime(nextSpell + spell.duration);
            }
        }

        return damage;
    }

    public static void main(String[] args) {
        Spell fireball = new Spell("Fireball", 10, 2, 0);
        Spell fire_blast = new Spell("Fire Blast", 10, 1, 5);
        Spell pyroblast = new Spell("Pyroblast", 40, 5, 20);
        Spell combustion = new Spell("Combustion", 0, 1, 40, 10, 2);
        Ex1_2023 e = new Ex1_2023();

        System.out.println(e.simulate(new Spell[] { fireball, fire_blast, pyroblast }, 10)); // 80
        // 0s: Fire Blast (10 damage, total: 10)
        // 1s: Pyroblast (40 damage, total: 50)
        // 6s: Fire Blast (10 damage, total: 60)
        // 7s: Fireball (10 damage, total: 70)
        // 9s: Fireball (10 damage, total: 80)

        System.out.println(e.simulate(new Spell[] { fireball, fire_blast, pyroblast }, 60)); // 410

        System.out.println(e.simulate(new Spell[] { fireball, fire_blast, pyroblast, combustion }, 60)); // 530
        // 0s: Fire Blast (10 damage, total: 10)
        // 1s: Pyroblast (40 damage, total: 50)
        // 6s: Fire Blast (10 damage, total: 60)
        // 7s: Fireball (10 damage, total: 70)
        // 9s: Fireball (10 damage, total: 80)
        // 11s: Fire Blast (10 damage, total: 90)
        // 12s: Fireball (10 damage, total: 100)
        // 14s: Fireball (10 damage, total: 110)
        // 16s: Fire Blast (10 damage, total: 120)
        // 17s: Fireball (10 damage, total: 130)
        // 19s: Fireball (10 damage, total: 140)
        // 21s: Fire Blast (10 damage, total: 150)
        // 22s: Pyroblast (40 damage, total: 190)
        // 27s: Fire Blast (10 damage, total: 200)
        // 28s: Fireball (10 damage, total: 210)
        // ...

        System.out.println(e.simulate(new Spell[] { fireball, fire_blast, pyroblast, combustion }, 600)); // 4880
    }
}
Editor is loading...