private probVector combineBaseAndWaveValues(probVector baseProb, probVector waveProb, double lowestBaseProb) { return(new probVector( calculateProb(baseProb.dynProb, waveProb.dynProb, lowestBaseProb), calculateProb(baseProb.watProb, waveProb.watProb, lowestBaseProb), calculateProb(baseProb.rpsProb, waveProb.rpsProb, lowestBaseProb) )); }
public void add(probVector p2) { this.dynProb += p2.dynProb; this.watProb += p2.watProb; this.rpsProb += p2.rpsProb; normalise(); }
public Weapon GetNextWeaponChoice() { int approxWinsLeft = Math.Max(2000 - 2 * Math.Max(myWins, enemyWins) - currentDrawStreak, 1); var L = GetNumTimeSituationRepeats(); double d = NumberOfDrawsOneThirdDyn(approxWinsLeft, myDynamiteCounter); //Approx number Of Consecutive Draws Whereby dynamite can be thrown one third of the time. double v = CalculateDynamiteValue(d); double ed = NumberOfDrawsOneThirdDyn(approxWinsLeft, enemyDynamiteCounter); //Approx number Of Consecutive Draws Whereby dynamite can be thrown one third of the time. double ev = CalculateDynamiteValue(ed); ev = Math.Max(1.5, ev); double pW = Math.Max((1 - 1 * ev / (currentDrawStreak + 1)) / 3.0, 0);//I don't understand why does 0.8 work better than 1. SOMETHING WRONG!!!!!!!!!!!!!!!!!!!!! double pD = 0; double pRps = 0; if (currentDrawStreak > v) { pD = 0.33; } else if (currentDrawStreak == Math.Floor(v)) { var a = (double)approxWinsLeft / (Math.Pow(3.0, currentDrawStreak + 1)); //ApproxNumTimesSituationPlusOneDrawWillRepeat var b = 0.33 * a; //For whatever reason this works fine var c = Math.Max(100 - myDynamiteCounter - b, 0); pD = c / L; pD = Math.Min(pD, 0.33); } else { pD = 0; } pRps = 1 - pD - pW; //var mem = memory.GetMemory(currentDrawStreak, ev); //var mem = waveMemory.GetMemory(currentDrawStreak, ev); var prediction = masterMemory.GetMemoryValues(currentDrawStreak, ev); var values = prediction.probVector; pD = Math.Max(0, pD); pW = Math.Max(0, pW); pRps = Math.Max(0, pRps); values = values.Normalise(); var baseValues = new probVector(pD, pW, pRps).Normalise(); var lowestBaseProb = baseValues.dynProb > baseValues.watProb ? baseValues.watProb : baseValues.dynProb; if (lowestBaseProb > 0.34) { throw new Exception(); } var memoryZone = masterMemory.GetMemoryZone(currentDrawStreak, ed); const double lowScore = 3.0; const double medScore = 3.5; const double highScore = 4.0; if (prediction.score > highScore) { var p = combineBaseAndWaveValues(baseValues, values, lowestBaseProb); pD = p.dynProb; pW = p.watProb; pRps = p.rpsProb; } else if (prediction.score > medScore) { var p = combineBaseAndWaveValues(baseValues, values, lowestBaseProb); pD = 0.25 * baseValues.dynProb + 0.75 * p.dynProb; pW = 0.25 * baseValues.watProb + 0.75 * p.watProb; pRps = 0.25 * baseValues.rpsProb + 0.75 * p.rpsProb; } else if (prediction.score > lowScore) { var p = combineBaseAndWaveValues(baseValues, values, lowestBaseProb); pD = 0.75 * baseValues.dynProb + 0.25 * p.dynProb; pW = 0.75 * baseValues.watProb + 0.25 * p.watProb; pRps = +0.75 * baseValues.rpsProb + 0.25 * p.rpsProb; } if (approxWinsLeft > 100) { pW = 0.99 * pW; } //Scaling if (approxWinsLeft > 100) { pD = 0.99 * pD; } //Keep dynamite as a threat. if (100 - myDynamiteCounter == 1 && approxWinsLeft - currentDrawStreak > 1) { pD = 0.1 * pD; } double totalValue = pD + pW + pRps; if (currentDrawStreak < Math.Floor(d)) { pD = 0; } if (currentDrawStreak == 0 && pW != 0) { pW = 0; } pD = pD / totalValue; pW = pW / totalValue; pRps = pRps / totalValue; var weaponChoice = rand.NextDouble(); if (weaponChoice < pW) { return(Weapon.WaterBallon); } if (weaponChoice < pW + pD) { return(Weapon.Dynamite); } return((Weapon)rand.Next(3));// returns rock, paper, scissors randomly. }