-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor Riichi point calculations #22
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please split the constant definitions and the actual work in two seperate branches. Also do not adapt the code to your own style choices. All you are doing is making the code messier by having multiple styles existing at once in the same code base.
imports/api/Constants.js
Outdated
NORTH: "north", | ||
|
||
MAHJONG_CLUB_LEAGUE: "Mahjong Club League", | ||
MANGAN: 2000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have good intentions here, but "MANGAN = 2000" is meaningless. You may as well have called the constant "Y2K" or "Andre minus 1000". At least call this something like MANGAN_BASE_POINTS or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure
imports/api/NewGameUtils.js
Outdated
else //if (round > 8) | ||
return "西";; | ||
break; | ||
case Constants.GAME_TYPE.HONG_KONG: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the style I use for switch/case. Case stays indented the same as switch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update my code to have the case be aligned with switch.
imports/api/NewGameUtils.js
Outdated
return "西"; | ||
else //if (round > 12) | ||
return "北"; | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you so keen on putting breaks in every case? I prefer to not include breaks in switch cases which are returned from. Looks cleaner and the break is never called anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wasn't me that had them to begin with lmao
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
o im dum
imports/api/NewGameUtils.js
Outdated
}; | ||
}, | ||
|
||
// Helper function to ensure all players are selected | ||
allPlayersSelected() { | ||
return (Session.get("current_east") != Constants.DEFAULT_EAST && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just the style I've been taught, but can formatting please be put in a seperate branch if you think it's important? Otherwise there's just a lot of clutter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this pull request seems unrelated to point calculation. Either rename the commit or change this to reflect what the commit is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the code changes I wanted to make in this ticket are relating to refactoring, hence the refactor name of the commit. Actually, no behaviour should be changed from this ticket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you done extensive testing of point submission? This is the most critically important part of the submission form so every possible input must work exactly correct or the entire system is broken.
import { Constants } from './Constants'; | ||
import { NewGameUtils } from './NewGameUtils'; | ||
|
||
export var PointCalculationUtils = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're going to do this, make it generic (include HK calculation too it's much more simple anyway)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to do it later, since this ticket is already quite large.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just worried about JPN and HKG code diverging too much when it should be converging.
imports/ui/JapaneseNewGame.js
Outdated
@@ -601,7 +601,7 @@ function save_game_to_database(hands_array) { | |||
}; | |||
|
|||
// Initialise ELO calculator to update player ELO | |||
var jpn_elo_calculator = new EloCalculator(2000, 5, [15000, 0, -5000, -10000], game, Constants.GAME_TYPE.JAPANESE); | |||
var jpn_elo_calculator = new EloCalculator(2000, 5, [15000, 0, -5000, -10000], game, Constants.GAME_TYPE.JAPANESE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this space
imports/api/PointCalculationUtils.js
Outdated
let winds = {}; | ||
winds[Constants.EAST] = winds[Constants.SOUTH] = winds[Constants.WEST] = winds[Constants.NORTH] = 0; | ||
|
||
let basicPoints; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some funky indentation here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix that in my next commit.
imports/api/PointCalculationUtils.js
Outdated
let manganPayout = multiplier * Constants.MANGAN; | ||
|
||
if (points < 5) { | ||
if (fu == 20 || (points == 1 && fu == 25)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super funky indentation. Use tabs for indentation and spaces for alignment please.
} | ||
else if (winnerWind == "south") { | ||
} | ||
} else if (winnerWind == Constants.SOUTH) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Force of habit, although keep in mind that all this change does is modify it so that the oneline if statement is encapsulated in curly braces instead of following in a logical line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an encompasing statement I happened to put on this line. I actually generally agree with wrapping single line conditional logic.
ee0dc55
to
22eb957
Compare
Some responses posted. Please refactor as well as there are now merge conflicts. |
22eb957
to
10006f6
Compare
10006f6
to
c03cf1b
Compare
87844b5
to
093651b
Compare
093651b
to
7f00868
Compare
imports/api/PointCalculationUtils.js
Outdated
winds[w] = (nonDealerPays * 3) + (currentBonus * 300) + (riichiSticks * 1000); | ||
} else { | ||
winds[w] = -(nonDealerPays + (currentBonus * 100)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotta correct this as an aside, lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review to continue once these changes are made.
}; | ||
|
||
Constants.WINDS = [Constants.EAST, Constants.SOUTH, Constants.WEST, Constants.NORTH]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this defined outside the Constants object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those values don't exist until the Constants object is defined. I added this line afterwards so I didn't have to be redundant.
imports/api/NewGameUtils.js
Outdated
Session.get("current_south") != Constants.DEFAULT_SOUTH && | ||
Session.get("current_west") != Constants.DEFAULT_WEST && | ||
Session.get("current_north") != Constants.DEFAULT_NORTH); | ||
Session.get("current_south") != Constants.DEFAULT_SOUTH && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align these blocks with spaces. For instance, this line should be two tabs followed by 8 spaces in order for the Session(...) code to align properly on all environments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did not address.
imports/api/NewGameUtils.js
Outdated
@@ -129,13 +123,13 @@ export var NewGameUtils = { | |||
let westRoundOver = Session.get("current_round") > 12; | |||
// End condition where game has reached the end of south round with at least one player above minimum | |||
let someoneAboveMinimum = Session.get("current_round") > 8 && | |||
this.someoneAboveMinimum(Constants.JPN_END_POINTS); | |||
this.someoneAboveMinimum(Constants.JPN_END_POINTS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above (RE: Spaces)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did not address.
imports/api/NewGameUtils.js
Outdated
Session.get("current_bonus") > 0 && | ||
this.getDirectionScore("north") >= Constants.JPN_END_POINTS && | ||
this.getFirstPlace() == "north"; | ||
Session.get("current_bonus") > 0 && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above (RE: Spaces)
imports/api/PointCalculationUtils.js
Outdated
|
||
export var PointCalculationUtils = { | ||
jpn: { | ||
dealin_delta, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps these should be renamed jpn_dealin_delta to more easily accomodate later addition of hkg
imports/api/PointCalculationUtils.js
Outdated
} | ||
}; | ||
|
||
function dealin_delta(points, fu, winnerWind, loserWind, riichiSticks) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it hurt to put comments in your code additions? It makes it faster for others to review, and easier for others to maintain. I think we should probably start including function headers as well just to make things easier to understand.
imports/api/PointCalculationUtils.js
Outdated
} else { basicPoints = manganValue(points); } | ||
|
||
let nonDealerPays = Math.ceil(basicPoints / 100 * (dealerWind == winnerWind ? 2 : 1)) * 100; | ||
let dealerPays = Math.ceil(basicPoints / 100 * 2) * 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should declare used variables at the beginning of the function.
imports/api/PointCalculationUtils.js
Outdated
} | ||
} else { basicPoints = manganValue(points) * multiplier }; | ||
|
||
let currentBonus = Number(Session.get("current_bonus")) * 300; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bonus amount should probably be defined in Constants.js
imports/api/PointCalculationUtils.js
Outdated
} else { basicPoints = manganValue(points) * multiplier }; | ||
|
||
let currentBonus = Number(Session.get("current_bonus")) * 300; | ||
winds[winnerWind] = basicPoints + currentBonus + (riichiSticks * 1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So should riichi amount
imports/api/PointCalculationUtils.js
Outdated
|
||
function mistake_delta(loser) { | ||
let winds = {}; | ||
winds[Constants.EAST] = winds[Constants.SOUTH] = winds[Constants.WEST] = winds[Constants.NORTH] = 4000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mistake points should probably be defined in Constants.js
imports/api/Constants.js
Outdated
RIICHI_POINTS: 1000, | ||
|
||
// Points paid for a mistake | ||
MISTAKE_POINTS: 12000, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please specify this is the Japanese chombo amount. The Hong Kong amount is different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well give the JPN_ prefix to bonus and Riichi too, since that is sort of the convention it seems.
imports/api/NewGameUtils.js
Outdated
Session.get("current_south") != Constants.DEFAULT_SOUTH && | ||
Session.get("current_west") != Constants.DEFAULT_WEST && | ||
Session.get("current_north") != Constants.DEFAULT_NORTH); | ||
Session.get("current_south") != Constants.DEFAULT_SOUTH && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did not address.
imports/api/NewGameUtils.js
Outdated
@@ -129,13 +123,13 @@ export var NewGameUtils = { | |||
let westRoundOver = Session.get("current_round") > 12; | |||
// End condition where game has reached the end of south round with at least one player above minimum | |||
let someoneAboveMinimum = Session.get("current_round") > 8 && | |||
this.someoneAboveMinimum(Constants.JPN_END_POINTS); | |||
this.someoneAboveMinimum(Constants.JPN_END_POINTS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did not address.
imports/api/NewGameUtils.js
Outdated
@@ -129,13 +123,12 @@ export var NewGameUtils = { | |||
let westRoundOver = Session.get("current_round") > 12; | |||
// End condition where game has reached the end of south round with at least one player above minimum | |||
let someoneAboveMinimum = Session.get("current_round") > 8 && | |||
this.someoneAboveMinimum(Constants.JPN_END_POINTS); | |||
this.someoneAboveMinimum(Constants.JPN_END_POINTS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So close, but this doesn't actually line up with the above line.
imports/api/NewGameUtils.js
Outdated
this.getDirectionScore("north") >= Constants.JPN_END_POINTS && | ||
this.getFirstPlace() == "north"; | ||
|
||
Session.get("current_bonus") > 0 && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
imports/api/PointCalculationUtils.js
Outdated
basicPoints = Math.ceil((fu * Math.pow(2, 2 + points)) * multiplier / 100) * 100; | ||
basicPoints = basicPoints < manganPayout ? basicPoints : manganPayout; | ||
} | ||
} else { basicPoints = manganValue(points) * multiplier }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're going to do this, the semicolon should be at the end of the line, not the end of the block. I would still make this and the other one like it a seperate line.
imports/api/PointCalculationUtils.js
Outdated
* | ||
* @return {Object} containing the point difference for each seat | ||
*/ | ||
function jpn_dealin_delta(points, fu, winnerWind, loserWind, riichiSticks) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're adding function headers, make sure to add @param entries
imports/api/PointCalculationUtils.js
Outdated
export var PointCalculationUtils = { | ||
jpn_dealin_delta, | ||
jpn_selfdraw_delta, | ||
jpn_mistake_delta |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, is it possible to keep the jpn object in PointCalculationUtils with members "dealin_delta = jpn_dealin_delta"? It seems you removed it this entry in favour of just the suffix.
imports/ui/JapaneseNewGame.js
Outdated
northDelta += dealin_delta(points, fu, "north", winnerWind, loserWind) + | ||
rewardRiichiSticks(riichiSum, "north", winnerWind); | ||
allDelta = PointCalculationUtils.jpn_dealin_delta(points, fu, winnerWind, loserWind, riichiSum); | ||
Session.set("free_riichi_sticks", 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This is redundant as it exists in PointCalculationUtils (I would remove it from there personally)
- This is located in a different location than in self_draw. Should be consistent.
|
||
// Check to see if you have to count basic points | ||
if (points < 5) { | ||
if (points == 1 && (fu == 20 || fu == 25)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also need to protect 2 point 25 selfdraw as that combination does not exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is prevented in NewGameUtils#noIllegalSelfDraw. This should be removed for issue #27.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So will this be removed or augmented with 2p25f? In between makes no sense
imports/api/PointCalculationUtils.js
Outdated
* Calculates the change in points as a result of a deal-in hand | ||
* Uses the formula from https://en.wikipedia.org/wiki/Japanese_Mahjong_scoring_rules | ||
* | ||
* @param {number} points - the total number of han + dora |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think param variable types need to be capitalized.
imports/ui/JapaneseNewGame.js
Outdated
@@ -1089,36 +1091,37 @@ function push_split_pao_hand(template) { | |||
Session.set("north_riichi_sum", Number(Session.get("north_riichi_sum")) + 1); | |||
} | |||
|
|||
var value = dealin_delta(points, fu, winnerWind, winnerWind); | |||
var value = PointCalculationUtils.jpn.dealin_delta(points, fu, winnerWind, loserWind, 0)[loserWind]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct? I'm worried this might not be fully tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is wrong. I use the value of loserWind instead of winnerWind. Good catch.
As an aside, this one is weird where I have to pass 0 in the riichi value because of the unique splitting rules :/
The code previously would always return 0, too, because you compared winnerWind with winnerWind. The code for the original dealin_delta was:
if (playerWind != winnerWind && playerWind != loserWind) return 0;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to put in constants where we spoke about.
|
||
// Check to see if you have to count basic points | ||
if (points < 5) { | ||
if (points == 1 && (fu == 20 || fu == 25)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So will this be removed or augmented with 2p25f? In between makes no sense
imports/api/Constants.js
Outdated
@@ -43,7 +55,21 @@ export const Constants = { | |||
SELF_DRAW: "selfdraw", | |||
NO_WIN: "nowin", | |||
RESTART: "restart", | |||
MISTAKE: "fuckup" | |||
MISTAKE: "fuckup", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might conflict now
@@ -790,7 +791,7 @@ function save_game_to_database(hands_array) { | |||
if (Number(Session.get("west_score")) >= Number(Session.get("north_score"))) position--; | |||
Players.update({_id: west_id}, {$inc: {japanesePositionSum: position}}); | |||
|
|||
switch (position) { | |||
switch (position) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's generally a lot of ruined indentation in this patch. Please fix. (Tabs for indentation, spaces for alignment)
@@ -1188,36 +1195,37 @@ function push_split_pao_hand(template) { | |||
Session.set("north_riichi_sum", Number(Session.get("north_riichi_sum")) + 1); | |||
} | |||
|
|||
var value = dealin_delta(points, fu, winnerWind, winnerWind); | |||
var value = PointCalculationUtils.jpn.dealin_delta(points, fu, winnerWind, loserWind, 0)[winnerWind]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's worth creating another PointCalculationUtils function for Pao situations.
Can you rebase so I can review this again? |
Now a duplicate of #64 |
Resolution for #16 and #8