// '' <summary> // '' Shoot will swap between players and check if a player has been killed. // '' It also allows the current player to hit on the enemygrid. // '' </summary> // '' <param name="row">the row fired upon</param> // '' <param name="col">the column fired upon</param> // '' <returns>The result of the attack</returns> public AttackResult Shoot(int row, int col) { AttackResult newAttack; int otherPlayer = ((_playerIndex + 1) % 2); newAttack = Player.Shoot(row, col); // Will exit the game when all players ships are destroyed if (_players(otherPlayer).IsDestroyed) { newAttack = new AttackResult(ResultOfAttack.GameOver, newAttack.Ship, newAttack.Text, row, col); } AttackCompleted(this, newAttack); // change player if the last hit was a miss if ((newAttack.Value == ResultOfAttack.Miss)) { _playerIndex = otherPlayer; } return(newAttack); }
/// <summary> /// ProcessShot is able to process each shot that is made and call the right methods belonging /// to that shot. For example, if its a miss = do nothing, if it's a hit = process that hit location /// </summary> /// <param name="row">the row that was shot at</param> /// <param name="col">the column that was shot at</param> /// <param name="result">the result from that hit</param> protected override void ProcessShot(int row, int col, AttackResult result) { if (result.Value == ResultOfAttack.Miss) { _CurrentTarget = null; } else if (result.Value == ResultOfAttack.Hit) { ProcessHit(row, col); } else if (result.Value == ResultOfAttack.Destroyed) { ProcessDestroy(row, col, result.Ship); } else if (result.Value == ResultOfAttack.ShotAlready) { throw (new ApplicationException("Error in AI")); } if (_Targets.Count == 0) { _CurrentState = AIStates.Searching; } }
/// <summary> /// The last shot had the following result. Child classes can use this /// to prepare for the next shot. /// </summary> /// <param name="result">The result of the shot</param> /// <param name="row">the row shot</param> /// <param name="col">the column shot</param> protected abstract void ProcessShot(int row, int col, AttackResult result);
/// <summary> /// Listens for attacks to be completed. /// </summary> /// <param name="sender">the game</param> /// <param name="result">the result of the attack</param> /// <remarks> /// Displays a message, plays sound and redraws the screen /// </remarks> private static void AttackCompleted(object sender, AttackResult result) { bool isHuman; isHuman = _theGame.Player == HumanPlayer; if (isHuman) { UtilityFunctions.Message = "You " + result.ToString(); } else { UtilityFunctions.Message = "The AI " + result.ToString(); } switch (result.Value) { case var @case when @case == ResultOfAttack.Destroyed: { PlayHitSequence(result.Row, result.Column, isHuman); Audio.PlaySoundEffect(GameResources.GameSound("Sink")); break; } case var case1 when case1 == ResultOfAttack.GameOver: { PlayHitSequence(result.Row, result.Column, isHuman); Audio.PlaySoundEffect(GameResources.GameSound("Sink")); while (Audio.SoundEffectPlaying(GameResources.GameSound("Sink"))) { SwinGame.Delay(10); SwinGame.RefreshScreen(); } if (HumanPlayer.IsDestroyed) { Audio.PlaySoundEffect(GameResources.GameSound("Lose")); } else { Audio.PlaySoundEffect(GameResources.GameSound("Winner")); } break; } case var case2 when case2 == ResultOfAttack.Hit: { PlayHitSequence(result.Row, result.Column, isHuman); break; } case var case3 when case3 == ResultOfAttack.Miss: { PlayMissSequence(result.Row, result.Column, isHuman); break; } case var case4 when case4 == ResultOfAttack.ShotAlready: { Audio.PlaySoundEffect(GameResources.GameSound("Error")); break; } } }
// Note: The only buttons that can be clicked are those that are in the // enemy's grid private void btn_Click(object sender, RoutedEventArgs e) { Button btn = sender as Button; if (btn == null) { return; } Location loc = (Location)btn.Tag; Image img = new Image(); img.Height = btn.Height; img.Width = btn.Width; Image cimg = new Image(); cimg.Height = btn.Height; cimg.Width = btn.Width; SoundPlayer player = new SoundPlayer(); if (gameRunning) { // Update model to reflect player's attack AttackResult playerAttackResult = ctrl.AttackComputer(loc); if (playerAttackResult == AttackResult.Miss) { txtFeedback.Text = "you missed"; img.Source = new BitmapImage(new Uri("Assets/miss.jpg", UriKind.Relative)); player.SoundLocation = "Assets/miss.wav"; } else if (playerAttackResult == AttackResult.Hit) { txtFeedback.Text = "Wooh! You hit a ship!!"; img.Source = new BitmapImage(new Uri("Assets/hit.png", UriKind.Relative)); player.SoundLocation = "Assets/hit.wav"; } else if (playerAttackResult == AttackResult.Sink) { txtFeedback.Text = "You managed to sink a ship, good job."; img.Source = new BitmapImage(new Uri("Assets/hit.png", UriKind.Relative)); player.SoundLocation = "Assets/sink.wav"; } if (playerAttackResult != AttackResult.repeat) //ignore instead of throwing exception { btn.Content = img; player.Load(); player.Play(); } if (ctrl.IsGameOver()) { player.SoundLocation = "Assets/win.wav"; player.Load(); player.Play(); gameRunning = false; EndGame("You"); } } if (gameRunning) { // Determine computer's response ComputerAttackResult computerAttackResult = ctrl.AttackPlayer(); if (computerAttackResult.Result == AttackResult.Miss) { cimg.Source = new BitmapImage(new Uri("Assets/miss.jpg", UriKind.Relative)); } else if (computerAttackResult.Result == AttackResult.Hit) { cimg.Source = new BitmapImage(new Uri("Assets/hit.png", UriKind.Relative)); } else if (computerAttackResult.Result == AttackResult.Sink) { cimg.Source = new BitmapImage(new Uri("Assets/hit.png", UriKind.Relative)); } for (int i = 0; i < playerGridButtons.Count; i++) { if ((playerGridButtons[i].Tag as Location).Column == computerAttackResult.Col && (playerGridButtons[i].Tag as Location).Row == computerAttackResult.Row) { playerGridButtons[i].Content = cimg; break; } } if (ctrl.IsGameOver()) { player.SoundLocation = "Assets/lose.wav"; player.Load(); player.Play(); gameRunning = false; EndGame("The computer"); } } }
/// <summary> /// Gets the AI to attack. /// </summary> /// <remarks> /// Checks the attack result once the attack is complete. /// </remarks> private static void AIAttack() { AttackResult result = _theGame.Player.Attack(); CheckAttackResult(result); }
/// <summary> /// Gets the player to attack the indicated row and column. /// </summary> /// <param name="row">the row to attack</param> /// <param name="col">the column to attack</param> /// <remarks> /// Checks the attack result once the attack is complete /// </remarks> public static void Attack(int row, int col) { AttackResult result = _theGame.Shoot(row, col); CheckAttackResult(result); }