Загрузка данных
using System;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Media;
namespace MorskoyBoy
{
public partial class MainWindow : Window
{
// Состояния клеток: 0 - водичка, 1 - кораблик, 2 - промах (бульк), 3 - подбит (бум)
int[,] pole_1 = new int[10, 10];
int[,] pole_2 = new int[10, 10];
Button[,] knopki_1 = new Button[10, 10];
Button[,] knopki_2 = new Button[10, 10];
bool igra_s_kompom = true;
int chey_hod = 1; // 1 или 2
bool igra_okonchena = false;
// Переменные для супер-удара 3x3
int zaryad_1 = 0;
int zaryad_2 = 0;
bool rezhim_babaha = false;
Random великий_рандом = new Random();
public MainWindow()
{
InitializeComponent();
sozdat_knopochki();
}
// --- ВХОД И НАВИГАЦИЯ ---
private void vhod_protiv_kompa(object? sender, RoutedEventArgs e)
{
igra_s_kompom = true;
Imya_Vtorogo.Text = "Поле Злого Компа";
vhod();
}
private void vhod_na_dvoih(object? sender, RoutedEventArgs e)
{
igra_s_kompom = false;
Imya_Vtorogo.Text = "Поле Игрока 2";
vhod();
}
private void vhod()
{
GlavnoeMenu.IsVisible = false;
OknoIgry.IsVisible = true;
zapustit_novuyu_igru();
}
private void vyhod_v_menu(object? sender, RoutedEventArgs e)
{
OknoIgry.IsVisible = false;
GlavnoeMenu.IsVisible = true;
}
private void perezapusk_igry(object? sender, RoutedEventArgs e)
{
zapustit_novuyu_igru();
}
// --- ПОДГОТОВКА ПОЛЯ И КОРАБЛИКОВ ---
private void sozdat_knopochki()
{
for (int r = 0; r < 10; r++)
{
for (int c = 0; c < 10; c++)
{
int stroka = r;
int stolbec = c;
// Кнопки первого поля (по ним стреляет Игрок 2)
Button k1 = new Button
{
Margin = new Avalonia.Thickness(1),
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center,
VerticalContentAlignment = Avalonia.Layout.VerticalAlignment.Center,
FontWeight = FontWeight.Bold
};
k1.Click += (s, e) => tyk_po_kletke(1, stroka, stolbec);
knopki_1[r, c] = k1;
Setka_1.Children.Add(k1);
// Кнопки второго поля (по ним стреляет Игрок 1)
Button k2 = new Button
{
Margin = new Avalonia.Thickness(1),
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center,
VerticalContentAlignment = Avalonia.Layout.VerticalAlignment.Center,
FontWeight = FontWeight.Bold
};
k2.Click += (s, e) => tyk_po_kletke(2, stroka, stolbec);
knopki_2[r, c] = k2;
Setka_2.Children.Add(k2);
}
}
}
private void zapustit_novuyu_igru()
{
chey_hod = 1;
zaryad_1 = 0;
zaryad_2 = 0;
rezhim_babaha = false;
igra_okonchena = false;
nasypat_korablikov(pole_1);
nasypat_korablikov(pole_2);
obnovit_kartinku();
}
private void nasypat_korablikov(int[,] pole)
{
Array.Clear(pole, 0, pole.Length);
int[] razmery = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
foreach (int razmer in razmery)
{
bool postavil = false;
while (!postavil)
{
int r = великий_рандом.Next(10);
int c = великий_рандом.Next(10);
bool gorizontalno = великий_рандом.Next(2) == 0;
if (mozhno_li_prisunut(pole, r, c, razmer, gorizontalno))
{
for (int i = 0; i < razmer; i++)
{
int nr = gorizontalno ? r : r + i;
int nc = gorizontalno ? c + i : c;
pole[nr, nc] = 1;
}
postavil = true;
}
}
}
}
private bool mozhno_li_prisunut(int[,] pole, int r, int c, int razmer, bool gorizontalno)
{
for (int i = 0; i < razmer; i++)
{
int nr = gorizontalno ? r : r + i;
int nc = gorizontalno ? c + i : c;
if (nr >= 10 || nc >= 10) return false;
// Проверяем саму клетку и соседей вокруг неё
for (int dr = -1; dr <= 1; dr++)
{
for (int dc = -1; dc <= 1; dc++)
{
int sr = nr + dr;
int sc = nc + dc;
if (sr >= 0 && sr < 10 && sc >= 0 && sc < 10)
{
if (pole[sr, sc] != 0) return false;
}
}
}
}
return true;
}
// --- СТРЕЛЬБА И СУПЕР-УДАР ---
private void aktivirovat_babah(object? sender, RoutedEventArgs e)
{
rezhim_babaha = !rezhim_babaha;
obnovit_kartinku();
}
private void tyk_po_kletke(int nomer_polya, int r, int c)
{
if (igra_okonchena) return;
// Игрок 1 бьет только по полю 2, а Игрок 2 — только по полю 1
if (chey_hod == 1 && nomer_polya != 2) return;
if (chey_hod == 2 && (nomer_polya != 1 || igra_s_kompom)) return;
int[,] cel_pole = (nomer_polya == 1) ? pole_1 : pole_2;
// Если обычный выстрел в уже стреляную клетку — не засчитываем ход
if (!rezhim_babaha && (cel_pole[r, c] == 2 || cel_pole[r, c] == 3))
{
Tekst_Statusa.Text = "Эй, сюда уже пуляли! Выбери другую клетку";
return;
}
if (rezhim_babaha)
{
// Разносим квадрат 3x3
babahnut_3x3(cel_pole, r, c);
if (chey_hod == 1) zaryad_1 = 0;
else zaryad_2 = 0;
rezhim_babaha = false;
}
else
{
// Обычный выстрел в 1 клетку
pif_paf(cel_pole, r, c);
if (chey_hod == 1 && zaryad_1 < 5) zaryad_1++;
if (chey_hod == 2 && zaryad_2 < 5) zaryad_2++;
}
if (proverit_pobedu()) return;
// Передаем ход
chey_hod = (chey_hod == 1) ? 2 : 1;
// Если играем против компа, он сразу делает ответный ход
if (igra_s_kompom && chey_hod == 2)
{
hod_zlogo_kompa();
if (proverit_pobedu()) return;
chey_hod = 1;
}
obnovit_kartinku();
}
private void pif_paf(int[,] pole, int r, int c)
{
if (r < 0 || r >= 10 || c < 0 || c >= 10) return;
if (pole[r, c] == 0) pole[r, c] = 2; // Бульк (мимо)
else if (pole[r, c] == 1) pole[r, c] = 3; // Бум (попал)
}
private void babahnut_3x3(int[,] pole, int center_r, int center_c)
{
for (int dr = -1; dr <= 1; dr++)
{
for (int dc = -1; dc <= 1; dc++)
{
pif_paf(pole, center_r + dr, center_c + dc);
}
}
}
private void hod_zlogo_kompa()
{
// Если комп накопил 5 ходов, он тоже радостно кидает бомбу 3x3!
if (zaryad_2 >= 5)
{
int br = великий_рандом.Next(1, 9);
int bc = великий_рандом.Next(1, 9);
babahnut_3x3(pole_1, br, bc);
zaryad_2 = 0;
return;
}
// Иначе ищет нестреляную клетку
while (true)
{
int r = великий_рандом.Next(10);
int c = великий_рандом.Next(10);
if (pole_1[r, c] == 0 || pole_1[r, c] == 1)
{
pif_paf(pole_1, r, c);
if (zaryad_2 < 5) zaryad_2++;
break;
}
}
}
// --- ПРОВЕРКА ПОБЕДЫ И ОТРИСОВКА ---
private bool proverit_pobedu()
{
bool zhiv_1 = est_li_zhivye(pole_1);
bool zhiv_2 = est_li_zhivye(pole_2);
if (!zhiv_2)
{
igra_okonchena = true;
obnovit_kartinku();
Tekst_Statusa.Text = "🏆 ИГРОК 1 РАЗНЁС ВСЕХ В ЩЕПКИ!";
return true;
}
if (!zhiv_1)
{
igra_okonchena = true;
obnovit_kartinku();
Tekst_Statusa.Text = igra_s_kompom ? "🤖 КОМПЬЮТЕР ПОБЕДИЛ!" : "🏆 ИГРОК 2 ПОБЕДИЛ!";
return true;
}
return false;
}
private bool est_li_zhivye(int[,] pole)
{
for (int r = 0; r < 10; r++)
for (int c = 0; c < 10; c++)
if (pole[r, c] == 1) return true;
return false;
}
private void obnovit_kartinku()
{
for (int r = 0; r < 10; r++)
{
for (int c = 0; c < 10; c++)
{
// В игре с компом показываем корабли Игрока 1, а в игре на двоих прячем оба поля
nastroit_knopku(knopki_1[r, c], pole_1[r, c], pokazyvat_korabli: igra_s_kompom || igra_okonchena);
nastroit_knopku(knopki_2[r, c], pole_2[r, c], pokazyvat_korabli: igra_okonchena);
}
}
if (igra_okonchena)
{
Knopka_Bomba.IsEnabled = false;
return;
}
Tekst_Statusa.Text = (chey_hod == 1)
? "👉 Ходит Игрок 1 (стреляй по правому полю)"
: "👈 Ходит Игрок 2 (стреляй по левому полю)";
int tekushiy_zaryad = (chey_hod == 1) ? zaryad_1 : zaryad_2;
Knopka_Bomba.IsEnabled = (tekushiy_zaryad >= 5);
if (rezhim_babaha)
{
Knopka_Bomba.Content = "🔥 ПРИЦЕЛ 3x3 АКТИВЕН! (Нажми для отмены)";
Knopka_Bomba.Background = SolidColorBrush.Parse("#FFA801");
}
else if (tekushiy_zaryad >= 5)
{
Knopka_Bomba.Content = "💣 ЦАРЬ-БОМБА 3x3 ГОТОВА! (Жми сюда)";
Knopka_Bomba.Background = SolidColorBrush.Parse("#FF3F34");
}
else
{
Knopka_Bomba.Content = $"💣 Царь-Бомба 3x3 (Копим ход: {tekushiy_zaryad}/5)";
Knopka_Bomba.Background = SolidColorBrush.Parse("#485460");
}
}
private void nastroit_knopku(Button knopka, int sostoyanie, bool pokazyvat_korabli)
{
if (sostoyanie == 0) // Водичка
{
knopka.Background = SolidColorBrush.Parse("#2C3A47");
knopka.Content = "";
}
else if (sostoyanie == 1) // Живой кораблик
{
knopka.Background = pokazyvat_korabli ? SolidColorBrush.Parse("#05C46B") : SolidColorBrush.Parse("#2C3A47");
knopka.Content = pokazyvat_korabli ? "🚢" : "";
}
else if (sostoyanie == 2) // Мимо
{
knopka.Background = SolidColorBrush.Parse("#57606F");
knopka.Content = "•";
knopka.Foreground = Brushes.White;
}
else if (sostoyanie == 3) // Подбит
{
knopka.Background = SolidColorBrush.Parse("#FF3F34");
knopka.Content = "✖";
knopka.Foreground = Brushes.White;
}
}
}
}