Csata mód működőképes, az AI le tud rakni hajókat

git-tfs-id: [https://sznp.visualstudio.com/DefaultCollection/]$/Torpedo;C13
This commit is contained in:
Norbi Peti 2016-03-16 19:08:39 +00:00
parent d413d77a63
commit d6fe86e650
11 changed files with 291 additions and 33 deletions

View file

@ -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
}
}
}

View file

@ -18,7 +18,7 @@ namespace Torpedo
private static ReadOnlyDictionary<FieldTypeEnemy, Color> FieldTypes = new ReadOnlyDictionary<FieldTypeEnemy, Color>(new Dictionary<FieldTypeEnemy, Color>()
{
{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
}

View file

@ -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
/// </summary>
public static Size GameSize { get; private set; } = new Size(10, 10);
/// <summary>
/*/// <summary>
/// A jelenlegi játékos
/// </summary>
public static Player CurrentPlayer = Player.Player1;
public static Player CurrentPlayer = Player.Player1;*/
private static GameType type = GameType.Singleplayer;
/// <summary>
@ -42,10 +43,113 @@ namespace Torpedo
/// </summary>
public static event EventHandler<GameTypeChangeEventArgs> GameTypeChange;
/// <summary>
/// A játék állapotának változásakor hívódik meg (Prepare, Battle)
/// </summary>
public static event EventHandler<GameStateChangeEventArgs> GameStateChange;
private static GameState state = GameState.Prepare;
/// <summary>
/// A játék állapota
/// </summary>
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;
}
}

View file

@ -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

View file

@ -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;
}
}
}

View file

@ -31,7 +31,7 @@ namespace Torpedo
RenderLines();
RenderGameField();
}
private void RenderLines()
public void RenderLines()
{
using (Graphics gr = Parent.CreateGraphics())
{

View file

@ -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;
}
}
}

View file

@ -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));
}
}

View file

@ -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
/// <summary>
/// <para>Az első játékos</para>
/// </summary>
public static Player Player1 { get; set; }
public static Player Player1 { get; set; } = new Player();
private static Player p2;
private static Player p2 = new Player();
/// <summary>
/// <para>A második játékos</para>
/// </summary>
@ -29,6 +30,34 @@ namespace Torpedo
}
}
private static bool swapped = false;
/// <summary>
/// Az aktuális játékos
/// </summary>
public static Player CurrentOwn
{
get
{
return (swapped ? Player2 : Player1);
}
}
/// <summary>
/// Az aktuális ellenfél
/// </summary>
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;
}
/// <summary>
@ -73,5 +103,7 @@ namespace Torpedo
return -1;
}
}
public List<Point> Shots = new List<Point>();
}
}

View file

@ -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;
}
/// <summary>
@ -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)

View file

@ -50,6 +50,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AIPlayer.cs" />
<Compile Include="EnemyGameRenderer.cs" />
<Compile Include="GameForm.cs">
<SubType>Form</SubType>
@ -59,6 +60,7 @@
</Compile>
<Compile Include="Game.cs" />
<Compile Include="GameRenderer.cs" />
<Compile Include="GameStateChangeEventArgs.cs" />
<Compile Include="GameTypeChangeEventArgs.cs" />
<Compile Include="OwnGameRenderer.cs" />
<Compile Include="Player.cs" />