From 7d53578bb4dfc9b7d9da60f61504e9ff13e7a5e6 Mon Sep 17 00:00:00 2001 From: Kevin Chow Date: Thu, 21 Mar 2019 14:21:52 -0700 Subject: [PATCH] Generalized game sheets to a reusable template Created game-sheet directory in UI folder Sheet can be used for other purposes --- imports/ui/game-sheet/GameSheet.html | 140 ++++++++++ imports/ui/game-sheet/GameSheet.js | 260 ++++++++++++++++++ .../ui/record-game/RecordHongKongGame.html | 97 +------ imports/ui/record-game/RecordHongKongGame.js | 114 ++------ .../ui/record-game/RecordJapaneseGame.html | 108 +------- imports/ui/record-game/RecordJapaneseGame.js | 139 +--------- 6 files changed, 434 insertions(+), 424 deletions(-) create mode 100644 imports/ui/game-sheet/GameSheet.html create mode 100644 imports/ui/game-sheet/GameSheet.js diff --git a/imports/ui/game-sheet/GameSheet.html b/imports/ui/game-sheet/GameSheet.html new file mode 100644 index 0000000..b37a630 --- /dev/null +++ b/imports/ui/game-sheet/GameSheet.html @@ -0,0 +1,140 @@ + + + + + diff --git a/imports/ui/game-sheet/GameSheet.js b/imports/ui/game-sheet/GameSheet.js new file mode 100644 index 0000000..32bba67 --- /dev/null +++ b/imports/ui/game-sheet/GameSheet.js @@ -0,0 +1,260 @@ +import Players from '../../api/Players'; + +import Constants from '../../api/Constants'; +import EloCalculator from '../../api/EloCalculator'; +import GameRecordUtils from '../../api/utils/GameRecordUtils'; + +import './GameSheet.html' + +/** + * Retreives the appropriate start points for a game + * @param[in] style The game style to get the start points for + * + * @returns {Number} The starting points for a mahjong game + */ +function _getStartPoints(style) { + switch (style) { + case Constants.GAME_TYPE.HONG_KONG: + return Constants.HKG_START_POINTS; + case Constants.GAME_TYPE.JAPANESE: + return Constants.JPN_START_POINTS; + } +}; + +/** + * Template predicate to determine if game is Hong Kong style + * @param[in] style The game style + * + * @returns {Boolean} Whether the game is Hong Kong style + */ +function _isHongKong(style) { + return style === Constants.GAME_TYPE.HONG_KONG; +}; + +/** + * Template predicate to determine if game is Japanese style + * @param[in] style The game style + * + * @returns {Boolean} Whether the game is Japanese style + */ +function _isJapanese(style) { + return style === Constants.GAME_TYPE.JAPANESE; +}; + +Template.GameSheet.helpers({ + /** + * Provide number of information columns for a hand for a style + * @param[in] style The style to determine the information columns for + * + * @returns {Number} A number of information columns + */ + getInfoColumnWidth(style) { + switch (style) { + case Constants.GAME_TYPE.HONG_KONG: + return 2; + case Constants.GAME_TYPE.JAPANESE: + return 4; + } + }, + /** + * Template predicate to determine if game is Hong Kong style + * @param[in] style The game style + * + * @returns {Boolean} Whether the game is Hong Kong style + */ + isHongKong: _isHongKong, + /** + * Template predicate to determine if game is Japanese style + * @param[in] style The game style + * + * @returns {Boolean} Whether the game is Japanese style + */ + isJapanese: _isJapanese, + /** + * Retreives the appropriate start points for a game + * @param[in] style The game style + * + * @returns {Number} The starting points for a mahjong game + */ + getStartPoints: _getStartPoints, + /** + * Retrieve the pre-game ELO for a player for a certain style + * @param[in] player The player to retreive ELO for + * @param[in] style The game style + * + * @returns An ELO truncated to 2 decimal points + */ + getElo(player, style) { + switch (player) { + case Constants.DEFAULT_EAST: + case Constants.DEFAULT_SOUTH: + case Constants.DEFAULT_WEST: + case Constants.DEFAULT_NORTH: + return "?"; + default: + switch (style) { + case Constants.GAME_TYPE.HONG_KONG: + return Players.findOne({hongKongLeagueName: player}).hongKongElo.toFixed(2); + case Constants.GAME_TYPE.JAPANESE: + return Players.findOne({japaneseLeagueName: player}).japaneseElo.toFixed(2); + } + }; + }, + /** + * Retrieve the current gain or loss for a player + * @param[in] direction The seat to get plus minus for + * @param[in] style The game style + * + * @returns The gain or loss of a player + */ + getPlayerDelta(direction, style) { + return (GameRecordUtils.getDirectionScore(direction) - _getStartPoints(style)); + }, + /** + * Retreive the current score for a player + * @param[in] direction The seat to get the current score for + * @param[in] style The game style + * + * @returns The current score of a player + */ + getPlayerScore(direction) { + return GameRecordUtils.getDirectionScore(direction); + }, + /** + * Retreive the final score for a player + * @param[in] direction The seat to get the final score for + * @param[in] style The game style + * + * @returns The final score of a player + */ + getPlayerScoreFinal(direction, style) { + let retval = GameRecordUtils.getDirectionScore(direction); + + if (style === Constants.GAME_TYPE.JAPANESE) { + let winScore = Math.max(Number(Session.get("east_score")), + Number(Session.get("south_score")), + Number(Session.get("west_score")), + Number(Session.get("north_score"))); + + + if (winScore == Session.get("east_score")) { + if (direction == Constants.EAST) + retval += Constants.JPN_RIICHI_POINTS * Number(Session.get("free_riichi_sticks")); + } else if (winScore == Session.get("south_score")) { + if (direction == Constants.SOUTH) + retval += Constants.JPN_RIICHI_POINTS * Number(Session.get("free_riichi_sticks")); + } else if (winScore == Session.get("west_score")) { + if (direction == Constants.WEST) + retval += Constants.JPN_RIICHI_POINTS * Number(Session.get("free_riichi_sticks")); + } else if (winScore == Session.get("north_score")) { + if (direction == Constants.NORTH) + retval += Constants.JPN_RIICHI_POINTS * Number(Session.get("free_riichi_sticks")); + } + } + + return retval; + }, + /** + * @param[in] round The round to display the wind for + * @param[in] style The game style + * + * @returns a string of the round wind + */ + displayRoundWind(round, style) { + return GameRecordUtils.displayRoundWind(round, style); + }, + /** + * @param[in] round The round to display the number for + * @param[in] style The game style + * + * @returns the current round number for Hong Kong style + */ + displayRoundNumber(round, style) { + return GameRecordUtils.handNumberToRoundNumber(round, style); + }, + /** + * Show what a player's Elo change will look like if game is ended now + * @param[in] direction The seat to get the ELO for + * @param[in] style The game style + * + * @returns An expected ELO change + */ + getExpectedEloChange(direction, style) { + + let eastPlayer = Session.get("current_east"); + let southPlayer = Session.get("current_south"); + let westPlayer = Session.get("current_west"); + let northPlayer = Session.get("current_north"); + + if (eastPlayer == Constants.DEFAULT_EAST || + southPlayer == Constants.DEFAULT_SOUTH || + westPlayer == Constants.DEFAULT_WEST || + northPlayer == Constants.DEFAULT_NORTH) { + return "N/A"; + } + + let game = { + timestamp: Date.now(), + east_player: eastPlayer, + south_player: southPlayer, + west_player: westPlayer, + north_player: northPlayer, + east_score: (Number(Session.get("east_score"))), + south_score: (Number(Session.get("south_score"))), + west_score: (Number(Session.get("west_score"))), + north_score: (Number(Session.get("north_score"))), + all_hands: Template.instance().data.game.hands, + }; + + let scoreAdjustment; + + switch (style) { + case Constants.GAME_TYPE.HONG_KONG: + scoreAdjustment = Constants.HKG_SCORE_ADJUSTMENT; + case Constants.GAME_TYPE.JAPANESE: + scoreAdjustment = Constants.JPN_SCORE_ADJUSTMENT; + } + + let gameEloCalculator = new EloCalculator(Constants.ELO_CALCULATOR_N, + Constants.ELO_CALCULATOR_EXP, + scoreAdjustment, + game, + style); + + switch (direction) { + case Constants.EAST: return gameEloCalculator.eloChange(eastPlayer).toFixed(2); + case Constants.SOUTH: return gameEloCalculator.eloChange(southPlayer).toFixed(2); + case Constants.WEST: return gameEloCalculator.eloChange(westPlayer).toFixed(2); + case Constants.NORTH: return gameEloCalculator.eloChange(northPlayer).toFixed(2); + }; + }, +}); + + +Template.RenderHand.helpers({ + isHongKong: _isHongKong, + isJapanese: _isJapanese, + isDealin(hand_type) { + return hand_type == Constants.DEAL_IN; + }, + isSelfdraw(hand_type) { + return hand_type == Constants.SELF_DRAW; + }, + isNowin(hand_type) { + return hand_type == Constants.NO_WIN; + }, + isRestart(hand_type) { + return hand_type == Constants.RESTART; + }, + isMistake(hand_type) { + return hand_type == Constants.MISTAKE; + }, + // Return a string of the round wind for Hong Kong style + displayRoundWind(round, style) { + return GameRecordUtils.displayRoundWind(round, style); + }, + // Return the current round number for Hong Kong style + displayRoundNumber(round, style) { + return GameRecordUtils.handNumberToRoundNumber(round, style); + }, +}); diff --git a/imports/ui/record-game/RecordHongKongGame.html b/imports/ui/record-game/RecordHongKongGame.html index 7b2d38f..0dd8765 100644 --- a/imports/ui/record-game/RecordHongKongGame.html +++ b/imports/ui/record-game/RecordHongKongGame.html @@ -73,61 +73,7 @@

Hong Kong Mahjong Game Sheet

- - - - - - - - - - - - - - - - - - {{#each hands}} - {{> render_hand}} - {{/each}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{get_east}} ({{get_hk_elo get_east}}){{get_south}} ({{get_hk_elo get_south}}){{get_west}} ({{get_hk_elo get_west}}){{get_north}} ({{get_hk_elo get_north}})
RoundBonusPoints{{HKG_START_POINTS}}{{HKG_START_POINTS}}{{HKG_START_POINTS}}{{HKG_START_POINTS}}
- {{displayRoundWind get_round}} {{displayRoundNumber get_round}} - B {{get_bonus}}
Transaction total:{{get_player_delta EAST}}{{get_player_delta SOUTH}}{{get_player_delta WEST}}{{get_player_delta NORTH}}
Current score:{{get_player_score EAST}}{{get_player_score SOUTH}}{{get_player_score WEST}}{{get_player_score NORTH}}
End score:{{get_player_score_final EAST}}{{get_player_score_final SOUTH}}{{get_player_score_final WEST}}{{get_player_score_final NORTH}}
ELO change:{{get_expected_elo_change EAST}}{{get_expected_elo_change SOUTH}}{{get_expected_elo_change WEST}}{{get_expected_elo_change NORTH}}
+ {{ > GameSheet game=getGame }} @@ -135,47 +81,6 @@

Hong Kong Mahjong Game Sheet

- - diff --git a/imports/ui/record-game/RecordHongKongGame.js b/imports/ui/record-game/RecordHongKongGame.js index 8c5c650..c8f886c 100644 --- a/imports/ui/record-game/RecordHongKongGame.js +++ b/imports/ui/record-game/RecordHongKongGame.js @@ -5,6 +5,7 @@ import { HongKongHands } from '../../api/GameDatabases'; import Constants from '../../api/Constants'; import EloCalculator from '../../api/EloCalculator'; import GameRecordUtils from '../../api/utils/GameRecordUtils'; +import '../game-sheet/GameSheet'; import './RecordHongKongGame.html'; @@ -25,103 +26,22 @@ Template.RecordHongKongGame.helpers({ hands() { return Template.instance().hands.get(); }, - get_player_delta(direction) { - return (GameRecordUtils.getDirectionScore(direction) - Constants.HKG_START_POINTS); - }, - get_player_score(direction) { - return GameRecordUtils.getDirectionScore(direction); - }, - get_player_score_final(direction) { - return GameRecordUtils.getDirectionScore(direction); - }, - // Show what a player's Elo change will look like if game is ended now - get_expected_elo_change(direction) { - - let eastPlayer = Session.get("current_east"); - let southPlayer = Session.get("current_south"); - let westPlayer = Session.get("current_west"); - let northPlayer = Session.get("current_north"); - - if (eastPlayer == Constants.DEFAULT_EAST || - southPlayer == Constants.DEFAULT_SOUTH || - westPlayer == Constants.DEFAULT_WEST || - northPlayer == Constants.DEFAULT_NORTH) { - return "N/A"; - } - - let game = { - timestamp: Date.now(), - east_player: eastPlayer, - south_player: southPlayer, - west_player: westPlayer, - north_player: northPlayer, - east_score: (Number(Session.get("east_score"))), - south_score: (Number(Session.get("south_score"))), - west_score: (Number(Session.get("west_score"))), - north_score: (Number(Session.get("north_score"))), - all_hands: Template.instance().hands.get(), - }; - - let hkEloCalculator = new EloCalculator(Constants.ELO_CALCULATOR_N, - Constants.ELO_CALCULATOR_EXP, - Constants.HKG_SCORE_ADJUSTMENT, - game, - Constants.GAME_TYPE.HONG_KONG); - - switch (direction) { - case Constants.EAST: return hkEloCalculator.eloChange(eastPlayer).toFixed(2); - case Constants.SOUTH: return hkEloCalculator.eloChange(southPlayer).toFixed(2); - case Constants.WEST: return hkEloCalculator.eloChange(westPlayer).toFixed(2); - case Constants.NORTH: return hkEloCalculator.eloChange(northPlayer).toFixed(2); - }; - }, - get_hk_elo(player) { - switch (player) { - case Constants.DEFAULT_EAST: - case Constants.DEFAULT_SOUTH: - case Constants.DEFAULT_WEST: - case Constants.DEFAULT_NORTH: - return "?"; - default: - return Players.findOne({hongKongLeagueName: player}).hongKongElo.toFixed(2); - }; - }, - // Return a string of the round wind for Hong Kong style - displayRoundWind(round) { - return GameRecordUtils.displayRoundWind(round, Constants.GAME_TYPE.HONG_KONG); - }, - // Return the current round number for Hong Kong style - displayRoundNumber(round) { - return GameRecordUtils.handNumberToRoundNumber(round, - Constants.GAME_TYPE.HONG_KONG); - }, -}); - -Template.render_hand.helpers({ - is_dealin(hand_type) { - return hand_type == Constants.DEAL_IN; - }, - is_selfdraw(hand_type) { - return hand_type == Constants.SELF_DRAW; - }, - is_nowin(hand_type) { - return hand_type == Constants.NO_WIN; - }, - is_restart(hand_type) { - return hand_type == Constants.RESTART; - }, - is_mistake(hand_type) { - return hand_type == Constants.MISTAKE; - }, - // Return a string of the round wind for Hong Kong style - displayRoundWind(round) { - return GameRecordUtils.displayRoundWind(round, Constants.GAME_TYPE.HONG_KONG); - }, - // Return the current round number for Hong Kong style - displayRoundNumber(round) { - return GameRecordUtils.handNumberToRoundNumber(round, - Constants.GAME_TYPE.HONG_KONG); - }, + /** + * Returns a game object to display + * + * @returns a formatted game object + */ + getGame() { + return { + style: Constants.GAME_TYPE.HONG_KONG, + players: [Session.get("current_east"), + Session.get("current_south"), + Session.get("current_west"), + Session.get("current_north")], + + hands: Template.instance().hands.get() + }; + } }); // Helper for point selection dropdown diff --git a/imports/ui/record-game/RecordJapaneseGame.html b/imports/ui/record-game/RecordJapaneseGame.html index d6e55ea..56b273b 100644 --- a/imports/ui/record-game/RecordJapaneseGame.html +++ b/imports/ui/record-game/RecordJapaneseGame.html @@ -70,61 +70,7 @@

Riichi Japanese Mahjong Game Sheet

- - - - - - - - - - - - - - - - - - - {{#each hands}} - {{> jpn_render_hand}} - {{/each}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{get_east}} ({{get_jpn_elo get_east}}){{get_south}} ({{get_jpn_elo get_south}}){{get_west}} ({{get_jpn_elo get_west}}){{get_north}} ({{get_jpn_elo get_north}})
RoundPFD{{JPN_START_POINTS}}{{JPN_START_POINTS}}{{JPN_START_POINTS}}{{JPN_START_POINTS}}
- {{displayRoundWind get_round}} {{displayRoundNumber get_round}} B{{get_bonus}} -
Transaction total:{{get_player_delta EAST}}{{get_player_delta SOUTH}}{{get_player_delta WEST}}{{get_player_delta NORTH}}
Current score:{{get_player_score EAST}}{{get_player_score SOUTH}}{{get_player_score WEST}}{{get_player_score NORTH}}
End score:{{get_player_score_final EAST}}{{get_player_score_final SOUTH}}{{get_player_score_final WEST}}{{get_player_score_final NORTH}}
ELO change:{{get_expected_elo_change EAST}}{{get_expected_elo_change SOUTH}}{{get_expected_elo_change WEST}}{{get_expected_elo_change NORTH}}
+ {{ > GameSheet game=getGame }} @@ -132,58 +78,6 @@

Riichi Japanese Mahjong Game Sheet

- - diff --git a/imports/ui/record-game/RecordJapaneseGame.js b/imports/ui/record-game/RecordJapaneseGame.js index ee46dda..28911e5 100644 --- a/imports/ui/record-game/RecordJapaneseGame.js +++ b/imports/ui/record-game/RecordJapaneseGame.js @@ -5,6 +5,7 @@ import { JapaneseHands } from '../../api/GameDatabases'; import Constants from '../../api/Constants'; import EloCalculator from '../../api/EloCalculator'; import GameRecordUtils from '../../api/utils/GameRecordUtils'; +import '../game-sheet/GameSheet'; import { HandScoreCalculator } from '../../api/HandScoreCalculator'; import './RecordJapaneseGame.html'; @@ -100,133 +101,23 @@ Template.RecordJapaneseGame.helpers({ hands() { return Template.instance().hands.get(); }, - // Show what a player's +/- is - get_player_delta(direction) { - return (GameRecordUtils.getDirectionScore(direction) - Constants.JPN_START_POINTS); - }, - // Show what a player's current score is - get_player_score(direction) { - return GameRecordUtils.getDirectionScore(direction); - }, - // Show what a player's score will look like if game is ended now - get_player_score_final(direction) { - retval = GameRecordUtils.getDirectionScore(direction); - - var winScore = Math.max(Number(Session.get("east_score")), - Number(Session.get("south_score")), - Number(Session.get("west_score")), - Number(Session.get("north_score"))); - - if (winScore == Session.get("east_score")) { - if (direction == Constants.EAST) - retval += Constants.JPN_RIICHI_POINTS * Number(Session.get("free_riichi_sticks")); - } else if (winScore == Session.get("south_score")) { - if (direction == Constants.SOUTH) - retval += Constants.JPN_RIICHI_POINTS * Number(Session.get("free_riichi_sticks")); - } else if (winScore == Session.get("west_score")) { - if (direction == Constants.WEST) - retval += Constants.JPN_RIICHI_POINTS * Number(Session.get("free_riichi_sticks")); - } else if (winScore == Session.get("north_score")) { - if (direction == Constants.NORTH) - retval += Constants.JPN_RIICHI_POINTS * Number(Session.get("free_riichi_sticks")); - } - - - return retval; - }, - // Show what a player's Elo change will look like if game is ended now - get_expected_elo_change(direction) { - - let eastPlayer = Session.get("current_east"); - let southPlayer = Session.get("current_south"); - let westPlayer = Session.get("current_west"); - let northPlayer = Session.get("current_north"); - - if (eastPlayer == Constants.DEFAULT_EAST || - southPlayer == Constants.DEFAULT_SOUTH || - westPlayer == Constants.DEFAULT_WEST || - northPlayer == Constants.DEFAULT_NORTH) { - return "N/A"; - } - - let game = { - timestamp: Date.now(), - east_player: eastPlayer, - south_player: southPlayer, - west_player: westPlayer, - north_player: northPlayer, - east_score: (Number(Session.get("east_score"))), - south_score: (Number(Session.get("south_score"))), - west_score: (Number(Session.get("west_score"))), - north_score: (Number(Session.get("north_score"))), - all_hands: Template.instance().hands.get(), - }; - - let jpnEloCalculator = new EloCalculator(Constants.ELO_CALCULATOR_N, - Constants.ELO_CALCULATOR_EXP, - Constants.JPN_SCORE_ADJUSTMENT, - game, - Constants.GAME_TYPE.JAPANESE); - - switch (direction) { - case Constants.EAST: return jpnEloCalculator.eloChange(eastPlayer).toFixed(2); - case Constants.SOUTH: return jpnEloCalculator.eloChange(southPlayer).toFixed(2); - case Constants.WEST: return jpnEloCalculator.eloChange(westPlayer).toFixed(2); - case Constants.NORTH: return jpnEloCalculator.eloChange(northPlayer).toFixed(2); - }; - }, - // Show a player's ELO - get_jpn_elo(player) { - switch (player) { - case Constants.DEFAULT_EAST: - case Constants.DEFAULT_SOUTH: - case Constants.DEFAULT_WEST: - case Constants.DEFAULT_NORTH: - return "?"; - default: - return Players.findOne({japaneseLeagueName: player}).japaneseElo.toFixed(2); - }; - }, - // Return a string of the round wind for Japanese style - displayRoundWind(round) { - return GameRecordUtils.displayRoundWind(round, Constants.GAME_TYPE.JAPANESE); - }, - // Return the current round number for Japanese style - displayRoundNumber(round) { - return GameRecordUtils.handNumberToRoundNumber(round, - Constants.GAME_TYPE.JAPANESE); + /** + * Returns a game object to display + * + * @returns a formatted game object + */ + getGame() { + return { + style: Constants.GAME_TYPE.JAPANESE, + players: [Session.get("current_east"), + Session.get("current_south"), + Session.get("current_west"), + Session.get("current_north")], + hands: Template.instance().hands.get() + }; }, }); -// GUI helpers for rendering hands -Template.jpn_render_hand.helpers({ - // Boolean expressions to help with rendering hands - is_dealin(hand_type) { - return hand_type == Constants.DEAL_IN; - }, - is_selfdraw(hand_type) { - return hand_type == Constants.SELF_DRAW; - }, - is_nowin(hand_type) { - return hand_type == Constants.NO_WIN; - }, - is_restart(hand_type) { - return hand_type == Constants.RESTART; - }, - is_mistake(hand_type) { - return hand_type == Constants.MISTAKE; - }, - // Return a string of the round wind for Japanese style - displayRoundWind(round) { - return GameRecordUtils.displayRoundWind(round, Constants.GAME_TYPE.JAPANESE); - }, - // Return the current round number for Japanese style - displayRoundNumber(round) { - return GameRecordUtils.handNumberToRoundNumber(round, - Constants.GAME_TYPE.JAPANESE); - }, -}) - // Helpers for point selection dropdown Template.jpn_points.helpers({ /**