From 960203b5976f3be1ad96d91281258f834ca4f730 Mon Sep 17 00:00:00 2001 From: Evan Powell Date: Tue, 8 Sep 2020 20:16:43 -0500 Subject: [PATCH 1/6] added the logic of handling player one's turn then switching to player two's turn (#2) --- src/services/GameState.service.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/services/GameState.service.js b/src/services/GameState.service.js index 572a635..388b73a 100644 --- a/src/services/GameState.service.js +++ b/src/services/GameState.service.js @@ -253,12 +253,27 @@ export class GameStateService { //wait // because the place_ship handles all the validation // all you need to do is make sure they have placed all the appropriate ships - // e.g. if ( this.get_ship_entities(this.current_player).length === this.n_boats ) { ... } + if ( this.get_ship_entities(this.current_player).length === this.n_boats ) { + this.current_player = Player.Two; + this.current_opponent = Player.One; + } + else{ + throw new InvalidAdvanceStateError("Player One has a problem with the number of boats selected"); + } } if (this.current_player === Player.Two) { //wait for now + if ( this.get_ship_entities(this.current_player).length === this.n_boats ) { + this.current_state = GameState.PlayerTurn; + this.current_player = Player.One; + this.current_opponent = Player.Two; + } + else{ + throw new InvalidAdvanceStateError("Player Two has a problem with the number of boats selected"); + } } } + } /** From d29b4484843fb32c8a95ec5f8f0fd07c292d5fdf Mon Sep 17 00:00:00 2001 From: garrettmills Date: Tue, 8 Sep 2020 20:23:49 -0500 Subject: [PATCH 2/6] Add helper methods for checking for victory (#2) --- src/services/GameState.service.js | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/services/GameState.service.js b/src/services/GameState.service.js index 572a635..19389e6 100644 --- a/src/services/GameState.service.js +++ b/src/services/GameState.service.js @@ -89,6 +89,12 @@ export class GameStateService { */ current_opponent = Player.Two + /** + * True if, during the current turn, the user has tried to fire a missile. + * @type {boolean} + */ + current_turn_had_missile_attempt = false + /** * Construct a new game service. Initialize any internal states. */ @@ -274,6 +280,12 @@ export class GameStateService { * @return {boolean} */ attempt_missile_fire([target_row_i, target_col_i]) { + if ( this.current_turn_had_missile_attempt ) { + throw new InvalidMissileFireAttemptError('Cannot fire more than once per turn.') + } else { + this.current_turn_had_missile_attempt = true + } + const target_cell = this._get_cell_state(this.current_opponent, target_row_i, target_col_i) if ( !isValidTargetCell(target_cell.render) ) throw new InvalidMissileFireAttemptError('Cannot fire on cell with state: ' + target_cell.render) @@ -472,6 +484,35 @@ export class GameStateService { return cells } + /** + * If there is a winner, this will return the Player that won. + * If no winner has been decided yet, will return undefined. + * @return {Player|undefined} + */ + get_winner() { + const [player_1, player_2] = this.players + + // Make sure to sink any fully-damaged ships + this._sink_damaged_ships(player_1) + const player_1_loses = this.get_ship_cells(player_1).every(cell => cell.render === GridCellState.Sunk) + if ( player_1_loses ) return player_2 + + // Make sure to sink any fully-damaged ships + this._sink_damaged_ships(player_2) + const player_2_loses = this.get_ship_cells(player_2).every(cell => cell.render === GridCellState.Sunk) + if ( player_2_loses ) return player_2 + } + + /** + * Returns the other player. + * @param {Player} player + * @return {Player} + */ + get_other_player(player) { + if ( player === Player.One ) return Player.Two + else if ( player === Player.Two ) return Player.One + } + /** * Get an array of ship entities for the given player. * @param {Player} player From ce030c346e1d6dc5f186d16787071173aec8d5d2 Mon Sep 17 00:00:00 2001 From: Evan Powell Date: Tue, 8 Sep 2020 20:35:06 -0500 Subject: [PATCH 3/6] added the logic for ensuring the player had fired a missle and the flow of the game in terms of the players' turns (#2) --- src/services/GameState.service.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/services/GameState.service.js b/src/services/GameState.service.js index 78e030d..f491215 100644 --- a/src/services/GameState.service.js +++ b/src/services/GameState.service.js @@ -278,8 +278,31 @@ export class GameStateService { throw new InvalidAdvanceStateError("Player Two has a problem with the number of boats selected"); } } + + + } + if (this.current_state === GameState.PlayerTurn && this.current_player === Player.One) { + + if (this.current_turn_had_missile_attempt === true) { + this.current_player = Player.Two; + this.current_opponent = Player.One; + } + else { + throw new InvalidAdvanceStateError("the player has not fired a missle"); + } + } + if (this.current_state === GameState.PlayerTurn && this.current_player === Player.Two) { + + if (this.current_turn_had_missile_attempt === true) { + this.current_player = Player.One; + this.current_opponent = Player.Two; + } + else { + throw new InvalidAdvanceStateError("the player has not fired a missle"); + } } + } /** From 152f1fa776d1010e1ce16c376b6d77f38f219dfb Mon Sep 17 00:00:00 2001 From: Evan Powell Date: Tue, 8 Sep 2020 20:42:07 -0500 Subject: [PATCH 4/6] added the logic for the gamestate if a player has won (#2) --- src/services/GameState.service.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/services/GameState.service.js b/src/services/GameState.service.js index f491215..d704a18 100644 --- a/src/services/GameState.service.js +++ b/src/services/GameState.service.js @@ -301,7 +301,13 @@ export class GameStateService { throw new InvalidAdvanceStateError("the player has not fired a missle"); } } - + + let winner = this.get_winner(); + if(winner) { + this.current_state = GameState.PlayerVictory; + this.current_player = winner; + } + } From bb8592cbb04dfd0e5622d429cf20da266290410d Mon Sep 17 00:00:00 2001 From: garrettmills Date: Tue, 8 Sep 2020 20:58:35 -0500 Subject: [PATCH 5/6] Add ability to listen for game state changes (#3) --- src/services/GameState.service.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/services/GameState.service.js b/src/services/GameState.service.js index d704a18..8f59efd 100644 --- a/src/services/GameState.service.js +++ b/src/services/GameState.service.js @@ -95,6 +95,12 @@ export class GameStateService { */ current_turn_had_missile_attempt = false + /** + * Array of functions that are called when the game state changes. + * @type {function[]} + */ + game_state_change_listeners = [] + /** * Construct a new game service. Initialize any internal states. */ @@ -224,7 +230,6 @@ export class GameStateService { return(this.get_player_score() / this.get_progress() ) } - /** * responsible for advancing the game state * will be consisting of @@ -243,7 +248,6 @@ export class GameStateService { * 8) player win * */ - //1 if (this.current_state === GameState.ChoosingNumberOfShips) { if (this.n_boats >= 1 && this.n_boats <= 5) { this.current_state = GameState.PlayerSetup; @@ -252,11 +256,9 @@ export class GameStateService { } else { throw new InvalidAdvanceStateError("Invalid Number of Boats"); } - } if (this.current_state === GameState.PlayerSetup) { if (this.current_player === Player.One) { - //wait // because the place_ship handles all the validation // all you need to do is make sure they have placed all the appropriate ships if ( this.get_ship_entities(this.current_player).length === this.n_boats ) { @@ -268,7 +270,6 @@ export class GameStateService { } } if (this.current_player === Player.Two) { - //wait for now if ( this.get_ship_entities(this.current_player).length === this.n_boats ) { this.current_state = GameState.PlayerTurn; this.current_player = Player.One; @@ -278,11 +279,8 @@ export class GameStateService { throw new InvalidAdvanceStateError("Player Two has a problem with the number of boats selected"); } } - - } if (this.current_state === GameState.PlayerTurn && this.current_player === Player.One) { - if (this.current_turn_had_missile_attempt === true) { this.current_player = Player.Two; this.current_opponent = Player.One; @@ -292,7 +290,6 @@ export class GameStateService { } } if (this.current_state === GameState.PlayerTurn && this.current_player === Player.Two) { - if (this.current_turn_had_missile_attempt === true) { this.current_player = Player.One; this.current_opponent = Player.Two; @@ -308,7 +305,7 @@ export class GameStateService { this.current_player = winner; } - + this.game_state_change_listeners.forEach(fn => fn(this.current_state)) } /** From e9cbd8cf093d30469d0e677d05f004036416d081 Mon Sep 17 00:00:00 2001 From: garrettmills Date: Tue, 8 Sep 2020 21:10:55 -0500 Subject: [PATCH 6/6] Add helper to get the current game state (#3) --- src/services/GameState.service.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/services/GameState.service.js b/src/services/GameState.service.js index 8f59efd..2720368 100644 --- a/src/services/GameState.service.js +++ b/src/services/GameState.service.js @@ -230,6 +230,14 @@ export class GameStateService { return(this.get_player_score() / this.get_progress() ) } + /** + * Get the current game state. + * @return {GameState} + */ + get_game_state() { + return clone(this.current_state) + } + /** * responsible for advancing the game state * will be consisting of