Skip to content

#2363 Calculate player's recovery#2450

Open
wsbrenk wants to merge 39 commits into
ho-dev:masterfrom
wsbrenk:#2363
Open

#2363 Calculate player's recovery#2450
wsbrenk wants to merge 39 commits into
ho-dev:masterfrom
wsbrenk:#2363

Conversation

@wsbrenk

@wsbrenk wsbrenk commented May 31, 2026

Copy link
Copy Markdown
Collaborator
  1. changes proposed in this pull request:

  2. src/main/resources/release_notes.md ...

  • has been updated
  • does not require update

@wsbrenk
wsbrenk requested a review from sgcr May 31, 2026 14:52
Comment thread src/main/java/core/model/player/Injury.java Outdated
Comment thread src/main/java/core/model/player/Injury.java Outdated
Comment thread src/main/java/core/model/player/Injury.java Outdated
Comment thread src/main/java/core/model/player/Injury.java Outdated
Comment thread src/main/java/core/model/player/Injury.java Outdated
Comment thread src/main/java/core/model/player/Injury.java Outdated
return whenSlightlyInjured;
}

public boolean getIsInvalid() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isInvalid

* Date is null if player is healthy
*/
private HODateTime whenHealthy;
/**

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provide a blank line.

return getInjury().getTypeOfEstimate();
}

public Boolean isInvalid() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boolean

private static double calcMedicianFactor(int doctorLevel) {
double x1Factor = 0.2124;
double x0Factor = 1;
return (x1Factor * (double) doctorLevel + x0Factor) / (x0Factor + 5 * x1Factor);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(double) cast not necessary

private static double calcMedicianFactor(int doctorLevel) {
double x1Factor = 0.2124;
double x0Factor = 1;
return (x1Factor * (double) doctorLevel + x0Factor) / (x0Factor + 5 * x1Factor);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 should be a constant instead of magic number.

/**
* Health calculation based on Schum formula (<a href="https://www82.hattrick.org/Forum/Read.aspx?t=17404127&n=6&v=0&mr=0">...</a>)
*/
public class Injury {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class should be package private if the sole constructor is also package private.

*/
private boolean isInvalid = false;

public enum TypeOfEstimate {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When Injury is only the calculation and all values are delegated to Getters in Player then this enum should be a general public enum outside that implementation class. Maybe InjuryEstimationType

public enum TypeOfEstimate {
REALISTIC_ESTIMATE,
OPTIMISTIC_ESTIMATE,
PESSIMISTIC_ESTIMATE,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about "no injury"?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed I think - if not injured, the whenHealthy date is null, meaning that it is realistic that we don't need any recovery.

PESSIMISTIC_ESTIMATE,
}

private TypeOfEstimate typeOfEstimate = TypeOfEstimate.REALISTIC_ESTIMATE;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why that default?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the player isn’t injured, which is hopefully the most likely situation for most players, no calculations are done, which means it’s realistic that no recovery is needed.

return regainerFactor * calcAgeFactor(player.getAgeAtDate(dateTime).toDouble()) * calcMedicianFactor(doctorLevel);
}

private void calculateRecovery(Player player) {

@sgcr sgcr Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method is very long: Could it be separated in parts of different sub functions?

/**
* True if the player is an invalid (no recovery possible)
*/
private boolean isInvalid = false;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: chronicInvalid as a name because invalid is very general and could be a state of the class instance itself.

}
public List<FactorObject> getFaktorenFromDB() {
return load(FactorObject.class);
// if (!factors.isEmpty()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete code that is not used anymore.

import kotlin.test.assertEquals
import kotlin.test.assertIsNot

class InjuryTests {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All tests should be named with the name of the class with the postfix "Test" in singular.


class InjuryTests {
@Test
fun testInjury() {

@sgcr sgcr Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a test but it should cover the cases that could happen (each at least for one possible result).
So multiple tests or if possible better a parameterized test.

I can offer to write tests for that class if you wish. Then you have a template.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is in progress - I will push the draft, which doesn't run successfully until now.

It is still a lot to do because the injury calculation requires a lot of data from the ho model, which will be provided by the new implemented test persistance manager.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry. Didn't see that.

@Test
fun testInjury() {

val hoAdmin = HOVerwaltung.instance()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the instance of HOVerwaltung really necessary?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will see...

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The injury calculation uses HOVerwaltung.instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants