diff --git a/Torpedo/Torpedo/AIPlayer.cs b/Torpedo/Torpedo/AIPlayer.cs new file mode 100644 index 0000000..6a3aa5b --- /dev/null +++ b/Torpedo/Torpedo/AIPlayer.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Torpedo +{ + public static class AIPlayer + { + private static Random rand = new Random(); + public static void PlaceShips() + { + while (Player.Player2.NextShip != -1) + { + int x = rand.Next(Game.GameSize.Width); + int y = rand.Next(Game.GameSize.Height); + bool vertical = rand.Next(2) == 0; + Ship ship = new Ship(x, y, Player.Player2.NextShip, (vertical ? ShipDirection.Vertical : ShipDirection.Horizontal), Player.Player2); + if (!Ship.CheckHasShip(ship)) + { + Player.Player2.Ships.Add(ship); + } + } + } + + public static void Attack() + { + //TODO + } + } +} diff --git a/Torpedo/Torpedo/EnemyGameRenderer.cs b/Torpedo/Torpedo/EnemyGameRenderer.cs index 7c5201f..747dac5 100644 --- a/Torpedo/Torpedo/EnemyGameRenderer.cs +++ b/Torpedo/Torpedo/EnemyGameRenderer.cs @@ -18,7 +18,7 @@ namespace Torpedo private static ReadOnlyDictionary FieldTypes = new ReadOnlyDictionary(new Dictionary() { - {FieldTypeEnemy.Targeted, Color.LightBlue}, + {FieldTypeEnemy.Missed, Color.LightBlue}, {FieldTypeEnemy.TargetHit, Color.Red}, {FieldTypeEnemy.EnemyShipDestroyed, Color.Black} }); @@ -31,25 +31,35 @@ namespace Torpedo public override void RenderShip(Ship ship) { //TODO: Képek az egyes hajótípusokhoz + bool destroyed = ship.DamagedParts.All(p => p); for (int i = 0; i < ship.Size; i++) { + FieldTypeEnemy ft = FieldTypeEnemy.Missed; + if (destroyed) + ft = FieldTypeEnemy.EnemyShipDestroyed; + else if (ship.DamagedParts[i]) + ft = FieldTypeEnemy.TargetHit; + if (ft == FieldTypeEnemy.Missed) //A Missed itt nem használható, ezért alapértelmezett értékként van használva + continue; //Nem rajzolja meg a sértetlen hajókat és hajórészeket + if (ship.Direction == ShipDirection.Horizontal) - UpdateField(ship.X + i, ship.Y, FieldTypeEnemy.Targeted); + UpdateField(ship.X + i, ship.Y, ft); else - UpdateField(ship.X, ship.Y + i, FieldTypeEnemy.Targeted); + UpdateField(ship.X, ship.Y + i, ft); } //TODO: Rárajzolni a képet a mezőkre } public override void RenderGameField() { - Player.Player2.Ships.ForEach(s => RenderShip(s)); + Player.CurrentEnemy.Ships.ForEach(s => RenderShip(s)); + Player.CurrentOwn.Shots.ForEach(s => UpdateField(s.X, s.Y, FieldTypeEnemy.Missed)); } } public enum FieldTypeEnemy { - Targeted, + Missed, TargetHit, EnemyShipDestroyed } diff --git a/Torpedo/Torpedo/Game.cs b/Torpedo/Torpedo/Game.cs index 994a5ec..90c4b1e 100644 --- a/Torpedo/Torpedo/Game.cs +++ b/Torpedo/Torpedo/Game.cs @@ -4,6 +4,7 @@ using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Forms; namespace Torpedo { @@ -14,10 +15,10 @@ namespace Torpedo /// public static Size GameSize { get; private set; } = new Size(10, 10); - /// + /*/// /// A jelenlegi játékos /// - public static Player CurrentPlayer = Player.Player1; + public static Player CurrentPlayer = Player.Player1;*/ private static GameType type = GameType.Singleplayer; /// @@ -42,10 +43,113 @@ namespace Torpedo /// public static event EventHandler GameTypeChange; + /// + /// A játék állapotának változásakor hívódik meg (Prepare, Battle) + /// + public static event EventHandler GameStateChange; + + private static GameState state = GameState.Prepare; /// /// A játék állapota /// - public static GameState State { get; set; } = GameState.Prepare; + public static GameState State + { + get + { + return state; + } + set + { + state = value; + if (GameStateChange != null) + GameStateChange(null, new GameStateChangeEventArgs(value)); + } + } + + public static void NextTurn() + { + if (State == GameState.Prepare) + { + if (Player.CurrentOwn == Player.Player1) + { + if (Type == GameType.Singleplayer) + { + Player.SwapPlayers(); + AIPlayer.PlaceShips(); + State = GameState.Battle; + Player.SwapPlayers(); + } + } + else if (Type == GameType.Multiplayer) + { + Player.SwapPlayers(); + State = GameState.Battle; + } + else + throw new InvalidOperationException("Az első játékos csak egyszer rakhat le hajókat."); + + if (Type == GameType.Multiplayer) + { + GameForm.Instance.SetPanelsVisible(false); + GameRenderer.Own.RenderLines(); + GameRenderer.Enemy.RenderLines(); + Timer t = new Timer(); + t.Interval = 2000; + t.Tick += delegate + { + t.Stop(); + Player.SwapPlayers(); + GameRenderer.Own.RenderGameField(); + GameRenderer.Enemy.RenderGameField(); + GameForm.Instance.SetPanelsVisible(true); + }; + t.Start(); + } + } + else + { + if (Player.CurrentEnemy.Ships.All(s => s.DamagedParts.All(d => d))) + { + MessageBox.Show("Győzelem!"); + GameForm.Instance.Reset(); + return; + } + if (Type == GameType.Singleplayer) + { + Player.SwapPlayers(); + if (Player.CurrentOwn == Player.Player2) + AIPlayer.PlaceShips(); + Player.SwapPlayers(); + } + else if (Type == GameType.Multiplayer) + { + Timer t = new Timer(); + t.Interval = 2000; + int c = 0; + GameForm.Instance.SetPanelsEnabled(false); + t.Tick += delegate + { + if (c >= 1) //Kétszer fut le + { + t.Stop(); + Player.SwapPlayers(); + GameRenderer.Own.RenderGameField(); + GameRenderer.Enemy.RenderGameField(); + GameForm.Instance.SetPanelsVisible(true); + GameForm.Instance.SetPanelsEnabled(true); + } + else + { + GameForm.Instance.SetPanelsVisible(false); + GameRenderer.Own.RenderLines(); + GameRenderer.Enemy.RenderLines(); + c++; + } + }; + t.Start(); + } + } + } static Game() { @@ -54,8 +158,7 @@ namespace Torpedo private static void Game_GameTypeChange(object sender, GameTypeChangeEventArgs e) { - State = GameState.Prepare; //TODO - CurrentPlayer = Player.Player1; + State = GameState.Prepare; } } diff --git a/Torpedo/Torpedo/GameForm.Designer.cs b/Torpedo/Torpedo/GameForm.Designer.cs index 51315e1..d402bb9 100644 --- a/Torpedo/Torpedo/GameForm.Designer.cs +++ b/Torpedo/Torpedo/GameForm.Designer.cs @@ -87,6 +87,7 @@ this.enemyPanel.Name = "enemyPanel"; this.enemyPanel.Size = new System.Drawing.Size(300, 300); this.enemyPanel.TabIndex = 1; + this.enemyPanel.Click += new System.EventHandler(this.enemyPanel_Click); this.enemyPanel.Paint += new System.Windows.Forms.PaintEventHandler(this.enemyPanel_Paint); // // shipSizeLabel diff --git a/Torpedo/Torpedo/GameForm.cs b/Torpedo/Torpedo/GameForm.cs index cfdc775..21922b9 100644 --- a/Torpedo/Torpedo/GameForm.cs +++ b/Torpedo/Torpedo/GameForm.cs @@ -23,14 +23,40 @@ namespace Torpedo Instance = this; Game.GameTypeChange += Game_GameTypeChange; Game.Type = GameType.Singleplayer; + Game.GameStateChange += Game_GameStateChange; + } + + public void SetPanelsEnabled(bool enabled) + { + ownPanel.Enabled = enabled; + enemyPanel.Enabled = enabled; + } + + public void SetPanelsVisible(bool visible) + { + ownPanel.Visible = visible; + enemyPanel.Visible = visible; + } + + public void Reset() + { + egyjátékosToolStripMenuItem.Enabled = true; + egyjátékosToolStripMenuItem.PerformClick(); + GameRenderer.Own.RenderGame(); + GameRenderer.Enemy.RenderGame(); } private void Game_GameTypeChange(object sender, GameTypeChangeEventArgs e) { egyjátékosToolStripMenuItem.Enabled = false; többjátékosToolStripMenuItem.Enabled = false; - if (Player.Player1.NextShip != -1) - shipSizeLabel.Text = "Következő hajó: " + Player.Player1.NextShip; + moveUpButton.Enabled = true; + moveDownButton.Enabled = true; + moveLeftButton.Enabled = true; + moveRightButton.Enabled = true; + rotateButton.Enabled = true; + if (Player.CurrentOwn.NextShip != -1) + shipSizeLabel.Text = "Következő hajó: " + Player.CurrentOwn.NextShip; else shipSizeLabel.Text = ""; switch(e.NewValue) @@ -67,20 +93,23 @@ namespace Torpedo { if (Game.State != GameState.Prepare) return; - if (Player.Player1.NextShip == -1) + if (Player.CurrentOwn.NextShip == -1) return; Point clickedfield = GameRenderer.Own.PixelsToFields(ownPanel.PointToClient(Cursor.Position)); - Ship ship = new Ship(clickedfield.X, clickedfield.Y, Game.CurrentPlayer.NextShip, ShipDirection.Horizontal, false); + Ship ship = new Ship(clickedfield.X, clickedfield.Y, Player.CurrentOwn.NextShip, ShipDirection.Horizontal, Player.CurrentOwn); if (Ship.CheckHasShip(ship)) return; - Game.CurrentPlayer.Ships.Add(ship); + Player.CurrentOwn.Ships.Add(ship); GameRenderer.Own.RenderShip(ship); lastship = ship; - //TODO - if (Player.Player1.NextShip != -1) - shipSizeLabel.Text = "Következő hajó: " + Player.Player1.NextShip; + if (Player.CurrentOwn.NextShip != -1) + shipSizeLabel.Text = "Következő hajó: " + Player.CurrentOwn.NextShip; else + { shipSizeLabel.Text = ""; + lastship = null; + Game.NextTurn(); + } } private void MoveShip(object sender, EventArgs e) @@ -105,5 +134,35 @@ namespace Torpedo lastship.Rotate(); } } + + private void enemyPanel_Click(object sender, EventArgs e) + { + if (Game.State != GameState.Battle) + return; + Point clickedfield = GameRenderer.Enemy.PixelsToFields(enemyPanel.PointToClient(Cursor.Position)); + Ship ship = Ship.GetShipAtField(Player.CurrentEnemy, clickedfield.X, clickedfield.Y); + if (ship == null) + { + Player.CurrentOwn.Shots.Add(clickedfield); + } + else + { + if (ship.Direction == ShipDirection.Horizontal) + ship.DamagedParts[clickedfield.X - ship.X] = true; + else + ship.DamagedParts[clickedfield.Y - ship.Y] = true; + } + GameRenderer.Enemy.RenderGameField(); + Game.NextTurn(); + } + + private void Game_GameStateChange(object sender, GameStateChangeEventArgs e) + { + moveUpButton.Enabled = false; + moveDownButton.Enabled = false; + moveLeftButton.Enabled = false; + moveRightButton.Enabled = false; + rotateButton.Enabled = false; + } } } diff --git a/Torpedo/Torpedo/GameRenderer.cs b/Torpedo/Torpedo/GameRenderer.cs index 0a6a497..118ac04 100644 --- a/Torpedo/Torpedo/GameRenderer.cs +++ b/Torpedo/Torpedo/GameRenderer.cs @@ -31,7 +31,7 @@ namespace Torpedo RenderLines(); RenderGameField(); } - private void RenderLines() + public void RenderLines() { using (Graphics gr = Parent.CreateGraphics()) { diff --git a/Torpedo/Torpedo/GameStateChangeEventArgs.cs b/Torpedo/Torpedo/GameStateChangeEventArgs.cs new file mode 100644 index 0000000..deb0da2 --- /dev/null +++ b/Torpedo/Torpedo/GameStateChangeEventArgs.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Torpedo +{ + public class GameStateChangeEventArgs : EventArgs + { + public GameState NewState; + public GameStateChangeEventArgs(GameState newstate) + { + NewState = newstate; + } + } +} diff --git a/Torpedo/Torpedo/OwnGameRenderer.cs b/Torpedo/Torpedo/OwnGameRenderer.cs index 69ca9af..96fce66 100644 --- a/Torpedo/Torpedo/OwnGameRenderer.cs +++ b/Torpedo/Torpedo/OwnGameRenderer.cs @@ -42,7 +42,7 @@ namespace Torpedo public override void RenderGameField() { - Player.Player1.Ships.ForEach(s => RenderShip(s)); //TODO + Player.CurrentOwn.Ships.ForEach(s => RenderShip(s)); } } diff --git a/Torpedo/Torpedo/Player.cs b/Torpedo/Torpedo/Player.cs index 65146c3..f063ec6 100644 --- a/Torpedo/Torpedo/Player.cs +++ b/Torpedo/Torpedo/Player.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -11,9 +12,9 @@ namespace Torpedo /// /// Az első játékos /// - public static Player Player1 { get; set; } + public static Player Player1 { get; set; } = new Player(); - private static Player p2; + private static Player p2 = new Player(); /// /// A második játékos /// @@ -29,6 +30,34 @@ namespace Torpedo } } + private static bool swapped = false; + /// + /// Az aktuális játékos + /// + public static Player CurrentOwn + { + get + { + return (swapped ? Player2 : Player1); + } + } + + /// + /// Az aktuális ellenfél + /// + public static Player CurrentEnemy + { + get + { + return (swapped ? Player1 : Player2); + } + } + + public static void SwapPlayers() + { + swapped = !swapped; + } + static Player() { Game.GameTypeChange += Game_GameTypeChange_Global; @@ -38,6 +67,7 @@ namespace Torpedo { Player1 = new Player(); Player2 = new Player(); + swapped = false; } /// @@ -73,5 +103,7 @@ namespace Torpedo return -1; } } + + public List Shots = new List(); } } diff --git a/Torpedo/Torpedo/Ship.cs b/Torpedo/Torpedo/Ship.cs index 5d92eb5..74ed9e2 100644 --- a/Torpedo/Torpedo/Ship.cs +++ b/Torpedo/Torpedo/Ship.cs @@ -25,15 +25,22 @@ namespace Torpedo } public ShipDirection Direction { get; set; } public bool[] DamagedParts; - public bool Enemy; + public Player Owner; + public bool Enemy + { + get + { + return Owner == Player.CurrentEnemy; + } + } - public Ship(int x, int y, int size, ShipDirection direction, bool enemy) + public Ship(int x, int y, int size, ShipDirection direction, Player owner) { X = x; Y = y; Size = size; //A DamagedParts-ot is inicializálja Direction = direction; - Enemy = enemy; + Owner = owner; } /// @@ -97,7 +104,7 @@ namespace Torpedo { if (dircheck) { - Ship ship2 = GetShipAtField(ship.Enemy, ship.X + dx + i, ship.Y + dy); + Ship ship2 = GetShipAtField(ship.Owner, ship.X + dx + i, ship.Y + dy); if (ship2 != null && ship2 != ship) { hasship = true; @@ -106,7 +113,7 @@ namespace Torpedo } else { - Ship ship2 = GetShipAtField(ship.Enemy, ship.X + dx, ship.Y + dy + i); + Ship ship2 = GetShipAtField(ship.Owner, ship.X + dx, ship.Y + dy + i); if (ship2 != null && ship2 != ship) { hasship = true; @@ -117,13 +124,8 @@ namespace Torpedo return hasship; } - public static Ship GetShipAtField(bool enemy, int x, int y) + public static Ship GetShipAtField(Player player, int x, int y) { - Player player = null; - if (enemy) - player = Player.Player2; - else - player = Player.Player1; return player.Ships.SingleOrDefault(s => { if (s.Direction != ShipDirection.Horizontal) diff --git a/Torpedo/Torpedo/Torpedo.csproj b/Torpedo/Torpedo/Torpedo.csproj index a3e5c12..4d79f76 100644 --- a/Torpedo/Torpedo/Torpedo.csproj +++ b/Torpedo/Torpedo/Torpedo.csproj @@ -50,6 +50,7 @@ + Form @@ -59,6 +60,7 @@ +