romaji

Heartbeat

Nov 7th, 2018
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.46 KB | None | 0 0
  1. package mu.nu.nullpo.game.subsystem.mode;
  2.  
  3. import java.util.Random;
  4. import mu.nu.nullpo.game.component.SpeedParam;
  5.  
  6. /** @author Romaji Milton Amulo.*/
  7. // This class is needed for Arrthmia modes.
  8.  
  9. public class Heartbeat {
  10.     /** allow cutting into Lock Delay?*/
  11.     public boolean panicMode;
  12.    
  13.     /** midpoint of ARE probability curve*/
  14.     public int meanARE;
  15.    
  16.     /** default lock delay. Always the lock delay if panicMode is disabled.*/
  17.     public int lockDelay;
  18.    
  19.     /** randomness width. so ARE is [meanARE-delta,meanARE+delta] */
  20.     public int delta;
  21.    
  22.     /** minimum length of a streak. */
  23.     public int streakMin;
  24.    
  25.     /** chance in the middle of a streak, of suddenly switching length (1.0 is every possible chance) */
  26.     public double spikeProbability;
  27.    
  28.     /** chance a spike could be "mini". that is to the same side as current streak */
  29.     public double miniSpike;
  30.    
  31.     /** how many drops since a streak starts or finished that another spike can't happen */
  32.     public int gracePeriod;
  33.    
  34.     /** chance that a streak longer than streakMin will continue. setting to 1.0 will make the current streak not end,
  35.      * unless you set ContractionType to a value other than NONE
  36.      */
  37.     public double streakDecay;
  38.    
  39.     /**Chooses the kind of streak contraction to use
  40.      * None: Doesn't do any Contraction
  41.      * Harmonic: reduces the effective streakDecay in a way reminiscent of the Harmonic series, with harmonicScale = 1 being exactly it
  42.      * Exponential: uses the exponentialScale to reduce the effective streakDecay
  43.      * @author RomajiMiltonAmulo
  44.      *
  45.      */
  46.     public enum ContractionType {NONE,HARMONIC,EXPONENTIAL};
  47.    
  48.     public ContractionType currentContraction;
  49.     public double harmonicScale;
  50.     public double exponentialScale;
  51.    
  52.     /** recompute all values when delta changes, or only after a streak or spike change? */
  53.     public boolean instantDeltaChangeRecompute;
  54.    
  55.     /** Probability that a streak change will do a spike first */
  56.     public double spikeIntoChange;
  57.    
  58.     private int[] current;
  59.     private int cIndex; //current index of element to take
  60.    
  61.     private int oldDelta;
  62.    
  63.     private int[] alt;
  64.    
  65.     private int dropsSinceMinStreakLength;
  66.     private int remainingGrace;
  67.     private double contractionValue;//used for both exponent and harmonic. Please don't switch while contraction is happening
  68.    
  69.     private enum Status {STREAK,SPIKE,MINI,SWITCH};
  70.     private Status currentStatus;
  71.    
  72.    
  73.     /** creates a new heartbeat, with default settings
  74.      * @param RNG randomness to establish settings
  75.      */
  76.     public Heartbeat(Random RNG) {
  77.         reset(RNG);
  78.     }
  79.    
  80.     /** creates a new Heartbeat with settings from Clone
  81.      * @param clone heartbeat cloned from
  82.      * @param RNG randomness to establish settings
  83.      */
  84.     public Heartbeat(Heartbeat clone, Random RNG) {
  85.         copy(clone);
  86.         reshuffle(RNG);
  87.     }
  88.  
  89.     /** returns to default values. Will also re-roll highs and lows.
  90.      * @param RNG randomness to establish settings
  91.      */
  92.     public void reset(Random RNG) {
  93.         panicMode = false;
  94.         meanARE = 24;
  95.         lockDelay = 30;
  96.        
  97.         delta = 10;
  98.         streakMin = 3;
  99.         spikeProbability = 0.2;
  100.         miniSpike = 0;
  101.         gracePeriod = 2;
  102.        
  103.         streakDecay = 0.5;
  104.         currentContraction = ContractionType.NONE;
  105.         harmonicScale = 0.0; //does nothing at present
  106.         exponentialScale = 1.0; //once again, doesn't do anything
  107.        
  108.         instantDeltaChangeRecompute = false;
  109.         oldDelta = 10;
  110.        
  111.         spikeIntoChange = 0.4;
  112.        
  113.         reshuffle(RNG);
  114.     }
  115.     /** sets external settings to those of the clone. Hides changes to delta, doesn't reshuffle.
  116.      * @param clone Heartbeat copied
  117.      */
  118.     public void copy(Heartbeat clone) {
  119.         panicMode = clone.panicMode;
  120.         meanARE = clone.meanARE;
  121.         lockDelay = clone.lockDelay;
  122.        
  123.         delta = clone.delta;
  124.         streakMin = clone.streakMin;
  125.         spikeProbability = clone.spikeProbability;
  126.         miniSpike = clone.miniSpike;
  127.         gracePeriod = clone.gracePeriod;
  128.        
  129.         streakDecay = clone.streakDecay;
  130.         currentContraction = clone.currentContraction;
  131.         harmonicScale = clone.harmonicScale;
  132.         exponentialScale = clone.exponentialScale;
  133.        
  134.         instantDeltaChangeRecompute = clone.instantDeltaChangeRecompute;
  135.         oldDelta = delta;
  136.        
  137.         spikeIntoChange = clone.spikeIntoChange;
  138.        
  139.     }
  140.     /** Changes delta and oldDelta. Warning, doing this while the Heartbeat is in use can cause issues.
  141.      * @param newDelta the new delta
  142.      */
  143.     public void stealthChangeDelta(int newDelta) {
  144.         delta = newDelta;
  145.         oldDelta = newDelta;
  146.        
  147.     }
  148.     /** Doesn't alter settings but refreshes the values.
  149.      * @param RNG
  150.      */
  151.     public void reshuffle(Random RNG) {
  152.         current = new int[2];
  153.         current[0] = -1*(1+RNG.nextInt(delta));
  154.         current[1] = 1+RNG.nextInt(delta);
  155.        
  156.         cIndex = RNG.nextInt(2);
  157.        
  158.         alt = new int[2];
  159.         alt[0] = -1*(1+RNG.nextInt(delta));
  160.         alt[1] = 1+RNG.nextInt(delta);
  161.        
  162.         dropsSinceMinStreakLength = -streakMin;
  163.         remainingGrace = gracePeriod;
  164.        
  165.         currentStatus = Status.STREAK;
  166.         contractionValue = 1.0;
  167.     }
  168.    
  169.     /** In an Arrythmia gamemode, call this immediately after locking the piece.
  170.      * updates the speed parameter using the Heartbeat settings.
  171.      * @param oldSpeed your speed parameter from the engine.
  172.      * @param RNG your Engine's randomness
  173.      * @return a new speed parameter to feed into the engine, for the next piece.
  174.      */
  175.     public SpeedParam updateSpeed(SpeedParam oldSpeed, Random RNG) {
  176.         SpeedParam ret = new SpeedParam(oldSpeed); //copy current parameter for modifying and returning
  177.        
  178.         if (delta!=oldDelta) { //did delta change since last update?
  179.             if(instantDeltaChangeRecompute) { //do I recompute current whenever delta changes?
  180.                 current[0] = -1*(1+RNG.nextInt(delta));
  181.                 current[1] = 1+RNG.nextInt(delta);
  182.             }
  183.             alt[0] = -1*(1+RNG.nextInt(delta)); //always recompute the alt.
  184.             alt[1] = 1+RNG.nextInt(delta);
  185.             oldDelta = delta; //now the change has been recorded
  186.         }
  187.         int newARE = meanARE; //find out what ARE you're in for.
  188.         switch(currentStatus) {
  189.         case STREAK:
  190.             newARE += current[cIndex];
  191.             dropsSinceMinStreakLength++;
  192.             if (dropsSinceMinStreakLength >0) {
  193.                 double effectiveStreakDecay = streakDecay;
  194.                 switch(currentContraction) {
  195.                 case NONE:
  196.                     break;
  197.                 case HARMONIC:
  198.                     contractionValue += harmonicScale;
  199.                     effectiveStreakDecay /= contractionValue;
  200.                     break;
  201.                 case EXPONENTIAL:
  202.                     contractionValue *= exponentialScale;
  203.                     effectiveStreakDecay *= contractionValue;
  204.                 }
  205.                 if(RNG.nextDouble()>effectiveStreakDecay) { //if the generated value is bigger than computed value, end the streak
  206.                     dropsSinceMinStreakLength = -streakMin; //reset everything
  207.                     contractionValue = 1.0;
  208.                     remainingGrace = gracePeriod;
  209.                    
  210.                     current[cIndex]= (2*cIndex -1)*(1+RNG.nextInt(delta)); //reshuffle the current value for later.
  211.                    
  212.                     cIndex= 1-cIndex; //flip the sides
  213.                    
  214.                     if(RNG.nextDouble()<spikeIntoChange) { // roll to see if using a spike change
  215.                         currentStatus = Status.SWITCH;
  216.                     }
  217.                     break; //in all cases, ignore possibility of a spike,
  218.                 }
  219.             }
  220.             remainingGrace--;
  221.             if(remainingGrace <=0) { //if the grace period is over, try for a spike
  222.                 if(RNG.nextDouble() < spikeProbability) {
  223.                     remainingGrace = gracePeriod;
  224.                     if(RNG.nextDouble() < miniSpike) { // is this spike mini?
  225.                         currentStatus = Status.MINI;
  226.                     } else { //in the likely chance it isn't, go for normal spike.
  227.                         currentStatus = Status.SPIKE;
  228.                     }
  229.                 }
  230.             }
  231.             break;
  232.         case SPIKE:
  233.             newARE += alt[1-cIndex];//for the spike, use an alt of the opposite sign
  234.             alt[1-cIndex] = (1- 2*cIndex)*(1+RNG.nextInt(delta)); //reset the alt for next time.
  235.             currentStatus = Status.STREAK; // go back to continuing the streak.
  236.             break;
  237.         case MINI:
  238.         case SWITCH: //these are the same, but different names to reflect the difference in arrival method.
  239.             newARE += alt[cIndex]; //unlike normally, don't go for opposite.
  240.             alt[cIndex]= (2*cIndex -1)*(1+RNG.nextInt(delta)); //reset the alt for next time.
  241.             currentStatus = Status.STREAK; // go back to continuing/starting the streak.
  242.             break;
  243.         }
  244.         if (newARE < 0) { //ARE can't actually be literally negative.
  245.             //set the real ARE to zero, but keep the newARE for later use (such as panic mode
  246.             ret.are=0;
  247.             ret.areLine=0;
  248.         } else {
  249.             //otherwise, setting it to the var is fine.
  250.             ret.are=newARE;
  251.             ret.areLine=newARE;
  252.         }
  253.         if (panicMode) { //mess with lock delay??
  254.             if(newARE < 0) {
  255.                 ret.lockDelay = this.lockDelay - newARE;
  256.                 if(ret.lockDelay < 0) {
  257.                     ret.lockDelay = 0; //just in case
  258.                 }
  259.             } else {
  260.                 ret.lockDelay = this.lockDelay;//otherwise, reset
  261.             }
  262.         }
  263.        
  264.         return ret;
  265.     }
  266.  
  267. }
Advertisement
Add Comment
Please, Sign In to add comment