mirror of
https://github.com/Noratrieb/ClickerGameSwing.git
synced 2026-01-14 15:45:04 +01:00
BigDecimal switch
This commit is contained in:
parent
31a219b3e2
commit
94a169b421
6 changed files with 144 additions and 65 deletions
|
|
@ -1,20 +1,22 @@
|
|||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ClickerModel {
|
||||
|
||||
private double nicolas;
|
||||
private BigDecimal nicolas;
|
||||
private final ArrayList<UpgradePanel> upgradePanels;
|
||||
|
||||
|
||||
public ClickerModel() {
|
||||
upgradePanels = new ArrayList<>();
|
||||
nicolas = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
public double getNicolas() {
|
||||
public BigDecimal getNicolas() {
|
||||
return nicolas;
|
||||
}
|
||||
|
||||
public void setNicolas(double nicolas) {
|
||||
public void setNicolas(BigDecimal nicolas) {
|
||||
this.nicolas = nicolas;
|
||||
}
|
||||
|
||||
|
|
@ -26,11 +28,27 @@ public class ClickerModel {
|
|||
upgradePanels.forEach(UpgradePanel::refresh);
|
||||
}
|
||||
|
||||
public double getNPS() {
|
||||
double nps = 0;
|
||||
public BigDecimal getNPS() {
|
||||
BigDecimal nps = BigDecimal.ZERO;
|
||||
for(UpgradePanel p : upgradePanels){
|
||||
nps += p.getNPS();
|
||||
nps = nps.add(p.getNPS());
|
||||
}
|
||||
return nps;
|
||||
}
|
||||
|
||||
public void addNicolas(long value) {
|
||||
addNicolas(BigDecimal.valueOf(value));
|
||||
}
|
||||
|
||||
public void addNicolas(BigDecimal value){
|
||||
nicolas = nicolas.add(value);
|
||||
}
|
||||
|
||||
public void removeNicolas(BigDecimal amount) {
|
||||
nicolas = nicolas.subtract(amount);
|
||||
}
|
||||
|
||||
public ArrayList<UpgradePanel> getUpgradePanels() {
|
||||
return upgradePanels;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
import javax.swing.*;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ClickerPresenter {
|
||||
|
||||
public static final int TARGET_FPS = 30;
|
||||
|
||||
public static final int MAX_UPGRADE_FACTOR = 100000;
|
||||
|
||||
private final ClickerView clickerView;
|
||||
private final ClickerModel clickerModel;
|
||||
|
||||
private double upgradeFactor = 1;
|
||||
private int upgradeFactor = 1;
|
||||
|
||||
LargeFormatter formatter = new LargeFormatter();
|
||||
|
||||
|
|
@ -25,7 +28,7 @@ public class ClickerPresenter {
|
|||
|
||||
addPanel(new UpgradePanel("Debugger", 1, 1, 1000000000, this));
|
||||
|
||||
|
||||
clickerModel.getUpgradePanels().forEach(UpgradePanel::recalculateUpgradeButtonText);
|
||||
Timer loop = new Timer(1000 / TARGET_FPS, e -> refresh());
|
||||
loop.start();
|
||||
}
|
||||
|
|
@ -37,7 +40,7 @@ public class ClickerPresenter {
|
|||
|
||||
|
||||
public void nicolasButtonClick() {
|
||||
clickerModel.setNicolas(clickerModel.getNicolas() + 1);
|
||||
clickerModel.addNicolas(1);
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
|
|
@ -46,27 +49,32 @@ public class ClickerPresenter {
|
|||
clickerModel.refresh();
|
||||
}
|
||||
|
||||
public void removeNicolas(double amount) {
|
||||
clickerModel.setNicolas(clickerModel.getNicolas() - amount);
|
||||
public void removeNicolas(BigDecimal amount) {
|
||||
clickerModel.removeNicolas(amount);
|
||||
}
|
||||
|
||||
public double getNicolas() {
|
||||
public BigDecimal getNicolas() {
|
||||
return clickerModel.getNicolas();
|
||||
}
|
||||
|
||||
public void addNicolas(double gain) {
|
||||
clickerModel.setNicolas(clickerModel.getNicolas() + gain);
|
||||
public void addNicolas(long value) {
|
||||
addNicolas(BigDecimal.valueOf(value));
|
||||
}
|
||||
|
||||
public void addNicolas(BigDecimal gain) {
|
||||
clickerModel.addNicolas(gain);
|
||||
}
|
||||
|
||||
public String changeFactor() {
|
||||
upgradeFactor *= 10;
|
||||
if (upgradeFactor > 1000) {
|
||||
if (upgradeFactor > MAX_UPGRADE_FACTOR) {
|
||||
upgradeFactor = 1;
|
||||
}
|
||||
return String.format("%,.0fx", upgradeFactor);
|
||||
clickerModel.getUpgradePanels().forEach(UpgradePanel::recalculateUpgradeButtonText);
|
||||
return String.format("%,dx", upgradeFactor);
|
||||
}
|
||||
|
||||
public double getUpgradeFactor() {
|
||||
public int getUpgradeFactor() {
|
||||
return upgradeFactor;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
import java.math.BigDecimal;
|
||||
|
||||
public class LargeFormatter {
|
||||
|
||||
private static final String[] suffixes = {"", "k", "M", "B", "T", "q", "Q", "s", "S", "O", "N"};
|
||||
//private static final String[] suffixes = {"", "k"}; //for large number testing
|
||||
|
||||
private static final BigDecimal _999 = BigDecimal.valueOf(999);
|
||||
private static final BigDecimal THOUSAND = BigDecimal.valueOf(100);
|
||||
private static final BigDecimal TEN = BigDecimal.TEN;
|
||||
|
||||
//input: 10 230 000 -> 10.23M
|
||||
public String formatBigNumber(double number) {
|
||||
public String formatDouble(double number) {
|
||||
int suffixSize = 0;
|
||||
boolean scientific = false;
|
||||
|
||||
while (number > 999) {
|
||||
|
||||
if(suffixSize == suffixes.length - 1){
|
||||
if (suffixSize == suffixes.length - 1) {
|
||||
scientific = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -19,15 +25,50 @@ public class LargeFormatter {
|
|||
number /= 1000;
|
||||
}
|
||||
|
||||
if(scientific){
|
||||
if (scientific) {
|
||||
int exp = 3 * suffixSize;
|
||||
while(number >= 10){
|
||||
while (number >= 10) {
|
||||
exp++;
|
||||
number /= 10;
|
||||
}
|
||||
return String.format("%.2fE%d", number, exp);
|
||||
} else {
|
||||
if(Math.floor(number) == number){
|
||||
if (Math.floor(number) == number) {
|
||||
return String.format("%.0f%s", number, suffixes[suffixSize]);
|
||||
} else {
|
||||
return String.format("%.2f%s", number, suffixes[suffixSize]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String formatBigNumber(BigDecimal number) {
|
||||
if(number == null){
|
||||
System.err.println("NUMBER IS NULL ");
|
||||
return "";
|
||||
}
|
||||
int suffixSize = 0;
|
||||
boolean scientific = false;
|
||||
|
||||
while (number.compareTo(_999) > 0) {
|
||||
|
||||
if (suffixSize == suffixes.length - 1) {
|
||||
scientific = true;
|
||||
break;
|
||||
}
|
||||
|
||||
suffixSize++;
|
||||
number = number.divide(THOUSAND);
|
||||
}
|
||||
|
||||
if (scientific) {
|
||||
int exp = 3 * suffixSize;
|
||||
while (number.compareTo(TEN) >= 0) {
|
||||
exp++;
|
||||
number = number.divide(TEN);
|
||||
}
|
||||
return String.format("%.2fE%d", number, exp);
|
||||
} else {
|
||||
if (false) { //TODO implement better solution
|
||||
return String.format("%.0f%s", number, suffixes[suffixSize]);
|
||||
} else {
|
||||
return String.format("%.2f%s", number, suffixes[suffixSize]);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import javax.swing.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
public class UpgradePanel extends JPanel {
|
||||
|
||||
|
|
@ -11,11 +13,11 @@ public class UpgradePanel extends JPanel {
|
|||
|
||||
private String name;
|
||||
|
||||
private final double costMultiplier;
|
||||
private final BigDecimal costMultiplier;
|
||||
private final double baseGain;
|
||||
|
||||
private double cost;
|
||||
private double gain = 0;
|
||||
private BigDecimal cost;
|
||||
private BigDecimal gain = BigDecimal.ZERO;
|
||||
private int level;
|
||||
|
||||
private long lastAddedTimeStamp = 0;
|
||||
|
|
@ -24,12 +26,14 @@ public class UpgradePanel extends JPanel {
|
|||
private final ClickerPresenter presenter;
|
||||
private final LargeFormatter lf = new LargeFormatter();
|
||||
|
||||
private String upgradeButtonText = "";
|
||||
|
||||
public UpgradePanel(String name, double baseCost, double costMultiplier, double baseGain, ClickerPresenter presenter) {
|
||||
add(mainPanel);
|
||||
|
||||
this.name = name;
|
||||
this.cost = baseCost;
|
||||
this.costMultiplier = costMultiplier;
|
||||
this.cost = new BigDecimal(baseCost);
|
||||
this.costMultiplier = BigDecimal.valueOf(costMultiplier);
|
||||
this.baseGain = baseGain;
|
||||
this.presenter = presenter;
|
||||
|
||||
|
|
@ -38,62 +42,70 @@ public class UpgradePanel extends JPanel {
|
|||
upgradeButton.addActionListener(e -> upgrade(presenter.getUpgradeFactor()));
|
||||
}
|
||||
|
||||
public void upgrade(double amount) {
|
||||
public void upgrade(int amount) {
|
||||
|
||||
presenter.removeNicolas(calculateExp(cost, costMultiplier, amount));
|
||||
gain += baseGain * amount;
|
||||
gain = gain.add(new BigDecimal(baseGain * amount));
|
||||
level += amount;
|
||||
|
||||
cost *= Math.pow(costMultiplier, amount);
|
||||
cost = cost.multiply(costMultiplier.pow(amount));
|
||||
|
||||
recalculateUpgradeButtonText();
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
upgradeButton.setEnabled(presenter.getNicolas() >= calculateExp(cost, costMultiplier, presenter.getUpgradeFactor()));
|
||||
upgradeButton.setEnabled(presenter.getNicolas().compareTo(calculateExp(cost, costMultiplier, presenter.getUpgradeFactor())) >= 0);
|
||||
|
||||
//should nicolas be added?
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long lastAddDeltaTime = currentTime - lastAddedTimeStamp;
|
||||
double timePerNicolas = 1 / gain * 1000;
|
||||
if (gain.compareTo(BigDecimal.ZERO) > 0) {
|
||||
//should nicolas be added?
|
||||
double lastAddDeltaTime = currentTime - lastAddedTimeStamp;
|
||||
double inverseLastAddDeltaTime = 1 / (lastAddDeltaTime / 1000);
|
||||
|
||||
if (timePerNicolas < lastAddDeltaTime) {
|
||||
//add nicolas
|
||||
long frameDeltaTime = currentTime - lastFrameTimeStamp;
|
||||
//gain=2 tpn=0.5 ladt=1000 laps=1
|
||||
if (gain.compareTo(BigDecimal.valueOf(inverseLastAddDeltaTime)) > 0) {
|
||||
double frameDeltaTime = currentTime - lastFrameTimeStamp;
|
||||
BigDecimal inverseFrameDeltaTime = BigDecimal.valueOf(1 / (frameDeltaTime / 1000));
|
||||
lastAddedTimeStamp = currentTime;
|
||||
|
||||
System.out.printf("tpn=%.2f ladt=%d Δt=%d", timePerNicolas, lastAddDeltaTime, frameDeltaTime);
|
||||
lastAddedTimeStamp = currentTime;
|
||||
|
||||
|
||||
if (timePerNicolas < frameDeltaTime) {
|
||||
double missedNicolas = frameDeltaTime / timePerNicolas;
|
||||
System.out.printf(" FN mn=%.2f gain=%.2f add=%.2f", missedNicolas, gain, missedNicolas);
|
||||
presenter.addNicolas(missedNicolas);
|
||||
} else {
|
||||
presenter.addNicolas(1);
|
||||
if (gain.compareTo(inverseFrameDeltaTime) > 0) {
|
||||
//normal: dt/tpn inverse: gain/idt
|
||||
System.out.println(inverseFrameDeltaTime + " " + gain);
|
||||
BigDecimal missedNicolas = gain.divide(inverseFrameDeltaTime, 0, RoundingMode.HALF_UP); /*frameDeltaTime / timePerNicolas*/
|
||||
System.out.println(missedNicolas);
|
||||
presenter.addNicolas(missedNicolas);
|
||||
} else {
|
||||
presenter.addNicolas(1);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.print("\n");
|
||||
}
|
||||
|
||||
lastFrameTimeStamp = currentTime;
|
||||
|
||||
levelLabel.setText("Level: " + level);
|
||||
gainLabel.setText(lf.formatBigNumber(gain) + " Nicolas");
|
||||
|
||||
upgradeButton.setText(String.format("%,.0fx Upgrade: %s Nicolas",
|
||||
presenter.getUpgradeFactor(), lf.formatBigNumber(calculateExp(cost, costMultiplier, presenter.getUpgradeFactor()))));
|
||||
upgradeButton.setText(upgradeButtonText);
|
||||
}
|
||||
|
||||
private double calculateExp(double c, double fac, double amount) {
|
||||
private BigDecimal calculateExp(BigDecimal c, BigDecimal fac, long amount) {
|
||||
//x10 cost = c + c*x + c*x*x + c*x*x*x... = c * x^1 + c*x^2 + c*x^3 + c*x^4 + c*x^5... =
|
||||
// c * (x^0 + x^1 + x^2 + x^3...)
|
||||
//new cost = c * x^amount
|
||||
double result = 0;
|
||||
BigDecimal result = BigDecimal.ZERO;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
result += Math.pow(fac, i);
|
||||
result = result.add(fac.pow(i));
|
||||
|
||||
}
|
||||
return result * c;
|
||||
return result.multiply(c);
|
||||
}
|
||||
|
||||
public double getNPS() {
|
||||
public BigDecimal getNPS() {
|
||||
return gain;
|
||||
}
|
||||
|
||||
public void recalculateUpgradeButtonText() {
|
||||
upgradeButtonText = String.format("%,dx Upgrade: %s Nicolas",
|
||||
presenter.getUpgradeFactor(), lf.formatBigNumber(calculateExp(cost, costMultiplier, presenter.getUpgradeFactor())));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,34 +16,34 @@ class LargeFormatterLargeTest {
|
|||
void normal(){
|
||||
double n = 100000;
|
||||
String s = "100k";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
|
||||
@Test
|
||||
void smallestSci(){
|
||||
double n = 1000000;
|
||||
String s = "1.00E6";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
|
||||
@Test
|
||||
void biggerSci(){
|
||||
double n = 10000000;
|
||||
String s = "1.00E7";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
|
||||
@Test
|
||||
void decimalSci(){
|
||||
double n = 16900000;
|
||||
String s = "1.69E7";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
|
||||
@Test
|
||||
void pointNine(){
|
||||
double n = 9780000;
|
||||
String s = "9.78E6";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
}
|
||||
|
|
@ -16,27 +16,27 @@ class LargeFormatterTest {
|
|||
void tinyNumberTest(){
|
||||
double n = 0.1;
|
||||
String s = "0.10";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
|
||||
@Test
|
||||
void smallNumberTest(){
|
||||
double n = 10;
|
||||
String s = "10";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
|
||||
@Test
|
||||
void kTest(){
|
||||
double n = 1000;
|
||||
String s = "1k";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
|
||||
@Test
|
||||
void mTest(){
|
||||
double n = 10230000;
|
||||
String s = "10.23M";
|
||||
assertEquals(s, lf.formatBigNumber(n));
|
||||
assertEquals(s, lf.formatDouble(n));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue