Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Linq;
- using System.Windows.Forms;
- namespace SeaWedFri
- {
- public partial class Form1 : Form
- {
- private const int cellSize = 30;
- private int[,] playerField = new int[10, 10];
- private int[,] botField = new int[10, 10];
- private Button[,] playerButtons = new Button[10, 10];
- private Button[,] botButtons = new Button[10, 10];
- private Random random = new Random();
- private bool isHorizontal = true;
- public Form1()
- {
- InitializeComponent();
- InitializeGame();
- }
- private void InitializeGame()
- {
- CreateField(playerPanel, true);
- CreateField(botPanel, false);
- }
- private void CreateField(Panel panel, bool isPlayer)
- {
- panel.Controls.Clear();
- for (int x = 0; x < 10; x++)
- {
- for (int y = 0; y < 10; y++)
- {
- Button cell = new Button
- {
- Size = new Size(cellSize, cellSize),
- Location = new Point(x * cellSize, y * cellSize),
- Tag = new Point(x, y),
- BackColor = Color.LightBlue,
- Enabled = isPlayer // Отключаем возможность клика по клеткам бота до начала игры
- };
- if (!isPlayer)
- {
- cell.Click += PlayerCell_Click;
- }
- panel.Controls.Add(cell);
- if (isPlayer)
- {
- playerButtons[x, y] = cell;
- }
- else
- {
- botButtons[x, y] = cell;
- }
- }
- }
- }
- private void ship_MouseDown(object sender, MouseEventArgs e)
- {
- Button ship = sender as Button;
- ship.DoDragDrop(ship, DragDropEffects.Move);
- }
- private void playerPanel_DragEnter(object sender, DragEventArgs e)
- {
- if (e.Data.GetDataPresent(typeof(Button)))
- e.Effect = DragDropEffects.Move;
- }
- private void playerPanel_DragDrop(object sender, DragEventArgs e)
- {
- Button ship = (Button)e.Data.GetData(typeof(Button));
- Point dropLocation = playerPanel.PointToClient(new Point(e.X, e.Y));
- int x = dropLocation.X / cellSize;
- int y = dropLocation.Y / cellSize;
- int length = int.Parse(ship.Text);
- bool horizontal = isHorizontal;
- if (CanPlaceShip(playerField, x, y, length, horizontal))
- {
- PlaceShip(playerField, x, y, length, horizontal, true);
- // Скрываем или отключаем кнопку корабля после размещения
- ship.Enabled = false;
- ship.Visible = false;
- logListBox.Items.Add($"Вы разместили корабль длиной {length} по координатам ({x}, {y}) {(horizontal ? "горизонтально" : "вертикально")}.");
- }
- else
- {
- MessageBox.Show("Невозможно разместить корабль здесь! Требуется отступ в одну клетку.");
- }
- }
- private bool CanPlaceShip(int[,] field, int x, int y, int length, bool horizontal)
- {
- if (horizontal)
- {
- if (x + length > 10) return false;
- }
- else
- {
- if (y + length > 10) return false;
- }
- for (int i = -1; i <= length; i++)
- {
- for (int j = -1; j <= 1; j++)
- {
- int xi = x + (horizontal ? i : j);
- int yj = y + (horizontal ? j : i);
- if (xi >= 0 && xi < 10 && yj >= 0 && yj < 10)
- {
- if (field[xi, yj] != 0) return false;
- }
- }
- }
- return true;
- }
- private void PlaceShip(int[,] field, int x, int y, int length, bool horizontal, bool isPlayer)
- {
- if (horizontal)
- {
- for (int i = 0; i < length; i++)
- {
- field[x + i, y] = 1;
- if (isPlayer)
- {
- playerButtons[x + i, y].BackColor = Color.Green;
- }
- }
- }
- else
- {
- for (int i = 0; i < length; i++)
- {
- field[x, y + i] = 1;
- if (isPlayer)
- {
- playerButtons[x, y + i].BackColor = Color.Green;
- }
- }
- }
- }
- private void PlaceBotShips()
- {
- int[] shipLengths = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
- foreach (int length in shipLengths)
- {
- bool placed = false;
- while (!placed)
- {
- int x = random.Next(10);
- int y = random.Next(10);
- bool horizontal = random.Next(2) == 0;
- if (CanPlaceShip(botField, x, y, length, horizontal))
- {
- PlaceShip(botField, x, y, length, horizontal, false); // isPlayer = false
- placed = true;
- }
- }
- }
- }
- private void startGameButton_Click(object sender, EventArgs e)
- {
- // Проверяем, что все корабли размещены
- if (AreAllShipsPlaced())
- {
- PlaceBotShips();
- MessageBox.Show("Игра началась! Ход игрока.", "Морской бой");
- // Разрешаем клики по клеткам бота
- foreach (var button in botButtons)
- {
- button.Enabled = true;
- }
- }
- else
- {
- MessageBox.Show("Пожалуйста, разместите все свои корабли перед началом игры.");
- }
- }
- private bool AreAllShipsPlaced()
- {
- foreach (var control in Controls.OfType<Button>())
- {
- if (control.Name.StartsWith("ship") && control.Enabled)
- {
- return false;
- }
- }
- return true;
- }
- private void PlayerCell_Click(object sender, EventArgs e)
- {
- Button cell = sender as Button;
- Point coordinates = (Point)cell.Tag;
- int x = coordinates.X;
- int y = coordinates.Y;
- if (botField[x, y] == 2 || botField[x, y] == 3)
- {
- MessageBox.Show("Вы уже стреляли сюда!");
- return;
- }
- if (Shoot(x, y, botField))
- {
- cell.BackColor = Color.Red;
- logListBox.Items.Add($"Вы попали по координатам ({x}, {y})!");
- if (IsShipDestroyed(botField, x, y))
- {
- MarkDestroyedShip(botField, botButtons, x, y);
- logListBox.Items.Add("Вы уничтожили корабль!");
- }
- if (CheckWin(botField))
- {
- MessageBox.Show("Игрок выиграл!");
- logListBox.Items.Add("Игрок выиграл!");
- ResetGame();
- }
- }
- else
- {
- cell.BackColor = Color.Blue;
- logListBox.Items.Add($"Вы промахнулись по координатам ({x}, {y}).");
- BotTurn();
- }
- }
- private bool Shoot(int x, int y, int[,] field)
- {
- if (field[x, y] == 1)
- {
- field[x, y] = 2;
- return true;
- }
- else if (field[x, y] == 0)
- {
- field[x, y] = 3;
- return false;
- }
- return false;
- }
- private void BotTurn()
- {
- int x, y;
- do
- {
- x = random.Next(10);
- y = random.Next(10);
- }
- while (playerField[x, y] == 2 || playerField[x, y] == 3);
- if (Shoot(x, y, playerField))
- {
- Button btn = GetButtonAt(true, x, y);
- if (btn != null)
- {
- btn.BackColor = Color.Red;
- }
- logListBox.Items.Add($"Бот попал по вашим координатам ({x}, {y})!");
- if (IsShipDestroyed(playerField, x, y))
- {
- MarkDestroyedShip(playerField, playerButtons, x, y);
- logListBox.Items.Add("Ваш корабль уничтожен!");
- }
- if (CheckWin(playerField))
- {
- MessageBox.Show("Бот выиграл!");
- logListBox.Items.Add("Бот выиграл!");
- ResetGame();
- }
- else
- {
- BotTurn();
- }
- }
- else
- {
- Button btn = GetButtonAt(true, x, y);
- if (btn != null)
- {
- btn.BackColor = Color.Blue;
- }
- logListBox.Items.Add($"Бот промахнулся по координатам ({x}, {y}).");
- }
- }
- private Button GetButtonAt(bool isPlayer, int x, int y)
- {
- if (isPlayer)
- {
- return playerButtons[x, y];
- }
- else
- {
- return botButtons[x, y];
- }
- }
- private bool CheckWin(int[,] field)
- {
- for (int x = 0; x < 10; x++)
- {
- for (int y = 0; y < 10; y++)
- {
- if (field[x, y] == 1)
- {
- return false;
- }
- }
- }
- return true;
- }
- private void ResetGame()
- {
- playerPanel.Controls.Clear();
- botPanel.Controls.Clear();
- logListBox.Items.Clear();
- playerField = new int[10, 10];
- botField = new int[10, 10];
- playerButtons = new Button[10, 10];
- botButtons = new Button[10, 10];
- InitializeGame();
- // Сбрасываем корабли
- foreach (var control in Controls.OfType<Button>())
- {
- if (control.Name.StartsWith("ship"))
- {
- control.Enabled = true;
- control.Visible = true;
- control.BackColor = SystemColors.Control;
- }
- }
- }
- private bool IsShipDestroyed(int[,] field, int x, int y)
- {
- Queue<Point> queue = new Queue<Point>();
- List<Point> shipCells = new List<Point>();
- queue.Enqueue(new Point(x, y));
- while (queue.Count > 0)
- {
- Point p = queue.Dequeue();
- if (!shipCells.Contains(p))
- {
- shipCells.Add(p);
- int[] dx = { -1, 1, 0, 0 };
- int[] dy = { 0, 0, -1, 1 };
- for (int dir = 0; dir < 4; dir++)
- {
- int nx = p.X + dx[dir];
- int ny = p.Y + dy[dir];
- if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10)
- {
- if (field[nx, ny] == 2)
- {
- queue.Enqueue(new Point(nx, ny));
- }
- else if (field[nx, ny] == 1)
- {
- return false;
- }
- }
- }
- }
- }
- return true;
- }
- private void MarkDestroyedShip(int[,] field, Button[,] buttons, int x, int y)
- {
- Color destroyedColor = Color.DarkRed;
- Queue<Point> queue = new Queue<Point>();
- List<Point> shipCells = new List<Point>();
- queue.Enqueue(new Point(x, y));
- while (queue.Count > 0)
- {
- Point p = queue.Dequeue();
- if (!shipCells.Contains(p))
- {
- shipCells.Add(p);
- Button btn = buttons[p.X, p.Y];
- if (btn != null)
- {
- btn.BackColor = destroyedColor;
- }
- int[] dx = { -1, 1, 0, 0 };
- int[] dy = { 0, 0, -1, 1 };
- for (int dir = 0; dir < 4; dir++)
- {
- int nx = p.X + dx[dir];
- int ny = p.Y + dy[dir];
- if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && field[nx, ny] == 2)
- {
- field[nx, ny] = -1; // Помечаем как обработанный
- queue.Enqueue(new Point(nx, ny));
- }
- }
- }
- }
- }
- private void rotateButton_Click(object sender, EventArgs e)
- {
- isHorizontal = !isHorizontal;
- rotateButton.Text = isHorizontal ? "Горизонтально" : "Вертикально";
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement