diff --git a/Components/App.razor b/Components/App.razor index 19aa0af..c391745 100644 --- a/Components/App.razor +++ b/Components/App.razor @@ -1,13 +1,18 @@ - - +@using Microsoft.AspNetCore.Components.Routing + + + + + + - - + + diff --git a/Components/Pages/BlackjackGame.razor b/Components/Pages/BlackjackGame.razor index 680d3c9..5c41b38 100644 --- a/Components/Pages/BlackjackGame.razor +++ b/Components/Pages/BlackjackGame.razor @@ -1,72 +1,128 @@ -@* --- НАЧАЛО КОДА ДЛЯ BlackjackGame.razor --- *@ - -@page "/blackjack" -@using БлэкДжек.Components @* <--- ВОТ ЭТУ СТРОКУ НУЖНО ПРОВЕРИТЬ/ЗАМЕНИТЬ *@ +@page "/blackjack" +@using БлэкДжек.Components @implements IDisposable -

Blackjack

- -@* Область для сообщений игры *@ -@if (!string.IsNullOrEmpty(GameMessage)) -{ - -} - -@* Основной блок игры, отображается после нажатия "Начать" *@ -@if (IsGameStarted) -{ -
-

Дилер (@(IsPlayerTurn ? "?" : DealerScore.ToString()))

-
- @foreach (var card in DealerHand) - { - @* Условие для скрытия первой карты дилера во время хода игрока *@ -
- @((DealerHand.IndexOf(card) == 0 && IsPlayerTurn) ? "???" : card.Display) -
- } +
+
+
+

Blackjack

+
-
-
+ @* Область для сообщений игры *@ + @if (!string.IsNullOrEmpty(GameMessage)) + { + + } -
-

Игрок (@PlayerScore)

-
- @foreach (var card in PlayerHand) - { -
- @card.Display + @* Основной блок игры, отображается после нажатия "Начать" *@ + @if (IsGameStarted) + { +
+
+
+
+

Дилер @(IsPlayerTurn ? "?" : DealerScore.ToString())

+
+
+
+ @foreach (var card in DealerHand) + { +
+ @if (DealerHand.IndexOf(card) == 0 && IsPlayerTurn) + { +
+
+
+ } + else + { +
+
+
@card.Rank
+
@card.Suit
+
+
@card.Suit
+
+
@card.Rank
+
@card.Suit
+
+
+ } +
+ } +
+
- } -
+ +
+
+
+
+
+
+ +
+
+
+

Игрок @PlayerScore

+
+
+
+ @foreach (var card in PlayerHand) + { +
+
+
+
@card.Rank
+
@card.Suit
+
+
@card.Suit
+
+
@card.Rank
+
@card.Suit
+
+
+
+ } +
+
+
+ + @* Кнопки действий *@ +
+ + + +
+
+ } + else + { +
+ + +
+ }
+
-
- - @* Кнопки действий *@ -
- - - -
-} -else -{ - @* Кнопка для старта игры, видна только до начала *@ - -} - - - -@* Блок с C# кодом *@ @code { // --- Поля состояния игры --- private Deck GameDeck; - private List PlayerHand = new List(); // Инициализируем, чтобы избежать null reference до старта - private List DealerHand = new List(); // Инициализируем + private List PlayerHand = new List(); + private List DealerHand = new List(); // --- Вычисляемые свойства для счета --- private int PlayerScore => CalculateScore(PlayerHand); @@ -75,13 +131,12 @@ else // --- Флаги состояния игры --- private bool IsPlayerTurn; private bool IsGameOver; - private bool IsGameStarted; // Показывает, была ли нажата кнопка "Начать игру" - private string GameMessage = string.Empty; // Инициализируем пустой строкой + private bool IsGameStarted; + private string GameMessage = string.Empty; // --- Инициализация компонента --- protected override void OnInitialized() { - // Игра не начинается автоматически при загрузке страницы IsGameStarted = false; } @@ -97,40 +152,38 @@ else IsGameOver = false; IsPlayerTurn = true; GameMessage = "Ваш ход. Взять карту или стоп?"; - IsGameStarted = true; // Показываем игровое поле + IsGameStarted = true; // Раздаем по 2 карты PlayerHand.Add(GameDeck.DealCard()); - DealerHand.Add(GameDeck.DealCard()); // Первая карта дилера + DealerHand.Add(GameDeck.DealCard()); PlayerHand.Add(GameDeck.DealCard()); - DealerHand.Add(GameDeck.DealCard()); // Вторая карта дилера + DealerHand.Add(GameDeck.DealCard()); - // Проверка на блэкджек у игрока или дилера сразу после раздачи - if (PlayerScore == 21 && DealerHand.Count == 2) // У игрока блэкджек + // Проверка на блэкджек + if (PlayerScore == 21 && DealerHand.Count == 2) { - if (DealerScore == 21) // У дилера тоже блэкджек + if (DealerScore == 21) { RevealDealerCardAndEndGame("Ничья! У обоих Блэкджек!"); } - else // Только у игрока блэкджек + else { RevealDealerCardAndEndGame("Блэкджек! Вы выиграли!"); } } - else if (DealerScore == 21 && DealerHand.Count == 2) // Только у дилера блэкджек (проверяем после игрока) + else if (DealerScore == 21 && DealerHand.Count == 2) { RevealDealerCardAndEndGame("Блэкджек у дилера! Вы проиграли."); } - // Если ни у кого нет блэкджека, игра продолжается с сообщением "Ваш ход..." - StateHasChanged(); // Обновляем UI, чтобы показать начальное состояние + StateHasChanged(); } - // --- Действие игрока: Взять карту (Hit) --- private void PlayerHit() { - if (!IsPlayerTurn || IsGameOver) return; // Нельзя брать карту не в свой ход или если игра окончена + if (!IsPlayerTurn || IsGameOver) return; PlayerHand.Add(GameDeck.DealCard()); @@ -140,45 +193,34 @@ else } else if (PlayerScore == 21) { - // Если игрок набрал ровно 21, его ход автоматически завершается PlayerStand(); } - // Если меньше 21, игрок может брать еще - StateHasChanged(); // Обновляем UI после взятия карты + StateHasChanged(); } // --- Действие игрока: Стоп (Stand) --- private void PlayerStand() { - if (!IsPlayerTurn || IsGameOver) return; // Нельзя остановиться не в свой ход или если игра окончена + if (!IsPlayerTurn || IsGameOver) return; - IsPlayerTurn = false; // Передаем ход дилеру + IsPlayerTurn = false; GameMessage = "Дилер ходит..."; - StateHasChanged(); // Обновим сообщение и откроем карту дилера + StateHasChanged(); - // Можно добавить небольшую задержку перед ходом дилера для наглядности - // await Task.Delay(500); // Если раскомментировать, метод должен быть async Task - DealerTurn(); // Начинаем ход дилера + DealerTurn(); } - // --- Логика хода Дилера --- - // Простая синхронная версия. Для пауз нужен async/await и Task.Delay private void DealerTurn() { - // Дилер берет карты, пока его счет меньше 17 while (DealerScore < 17) { - // В реальном приложении можно добавить паузу здесь - // await Task.Delay(800); DealerHand.Add(GameDeck.DealCard()); - // StateHasChanged(); // Обновлять UI после каждой карты дилера, если есть пауза } - // После того, как дилер закончил брать карты, определяем победителя DetermineWinner(); - StateHasChanged(); // Показать финальный результат + StateHasChanged(); } // --- Подсчет очков для руки --- @@ -197,10 +239,10 @@ else } } - // Корректировка значения Тузов (с 11 на 1 при переборе) + // Корректировка значения Тузов while (score > 21 && aceCount > 0) { - score -= 10; // Считаем Туз как 1 вместо 11 + score -= 10; aceCount--; } return score; @@ -209,10 +251,8 @@ else // --- Определение победителя --- private void DetermineWinner() { - // Убедимся, что карта дилера видна (IsPlayerTurn уже false) if (PlayerScore > 21) { - // Это условие уже должно было быть обработано в PlayerHit, но на всякий случай EndGame("Перебор! Вы проиграли."); } else if (DealerScore > 21) @@ -236,16 +276,15 @@ else // --- Метод для завершения игры и установки сообщения --- private void RevealDealerCardAndEndGame(string message) { - IsPlayerTurn = false; // Убедимся, что карта дилера видна + IsPlayerTurn = false; EndGame(message); } private void EndGame(string message) { IsGameOver = true; - IsPlayerTurn = false; // Больше никто не ходит + IsPlayerTurn = false; GameMessage = message; - // StateHasChanged(); // Обычно вызывается в методе, который вызвал EndGame } // --- Вспомогательный метод для определения цвета карты --- @@ -254,11 +293,9 @@ else return (card.Suit == "♥" || card.Suit == "♦") ? "card-red" : "card-black"; } - // --- Реализация IDisposable (пока пустая, но может пригодиться) --- + // --- Реализация IDisposable --- public void Dispose() { - // Здесь можно остановить таймеры или отписаться от событий, если они будут добавлены + // Реализация IDisposable } } - -@* --- КОНЕЦ КОДА ДЛЯ BlackjackGame.razor --- *@ \ No newline at end of file diff --git a/Components/Pages/BlackjackGame.razor.css b/Components/Pages/BlackjackGame.razor.css new file mode 100644 index 0000000..bfe00b4 --- /dev/null +++ b/Components/Pages/BlackjackGame.razor.css @@ -0,0 +1,592 @@ +:root { + /* Обновленная цветовая палитра - более яркие и контрастные цвета */ + --casino-green: #2a9d8f; + --casino-dark-green: #226f66; + --felt-green: #40a886; + --wood-brown: #b76e40; + --gold: #ffbe0b; + --light-gold: #ffe066; + --dark-gold: #e29400; + --red: #ff5e5b; + --black: #2b2b2b; + --white: #ffffff; + --gray: #7d8597; + --light-gray: #f1f3f5; + --blue: #3a86ff; + /* Улучшенные тени и эффекты - без затемнений */ + --card-shadow: 0 6px 12px rgba(0, 0, 0, 0.2); + --button-shadow: 0 6px 0 var(--dark-gold); + --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); + --text-shadow: none; +} + +/* Основной фон казино - убрано затемнение */ +.casino-background { + background-image: url('_content/БлэкДжек/images/casino-bg.jpg'); + background-size: cover; + background-position: center; + min-height: 100vh; + padding: 2rem; + box-sizing: border-box; + display: flex; + justify-content: center; + align-items: center; + font-family: 'Poppins', 'Montserrat', sans-serif; + color: var(--white); +} + +/* Основной контейнер игры */ +.blackjack-container { + width: 100%; + max-width: 1000px; + background: linear-gradient(145deg, var(--casino-green), var(--casino-dark-green)); + border-radius: 24px; + box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3); + padding: 2.5rem; + position: relative; + overflow: hidden; + border: 8px solid var(--wood-brown); +} + +/* Декоративный элемент с фишками */ +.chip-stack { + background-image: url('_content/БлэкДжек/images/chips-stack.png'); + background-size: contain; + background-repeat: no-repeat; + width: 90px; + height: 90px; + position: absolute; + right: 2rem; + top: 2rem; + filter: drop-shadow(0 5px 10px rgba(0, 0, 0, 0.2)); +} + +/* Заголовок игры */ +.game-header { + display: flex; + justify-content: center; + align-items: center; + position: relative; + margin-bottom: 2.5rem; +} + +.game-title { + color: var(--light-gold); + text-transform: uppercase; + text-align: center; + font-size: 3.2rem; + margin: 0; + letter-spacing: 4px; + font-weight: 800; + position: relative; +} + + .game-title::after { + content: ''; + position: absolute; + bottom: -12px; + left: 50%; + transform: translateX(-50%); + width: 70%; + height: 4px; + background: linear-gradient(90deg, transparent, var(--gold), transparent); + } + +/* Область сообщений - улучшена читаемость */ +.message-box { + background-color: #ffffff; + border-left: 6px solid var(--gold); + padding: 1.2rem; + margin: 1.2rem auto 2.2rem; + color: var(--black); + border-radius: 10px; + box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2); + text-align: center; + max-width: 85%; + transition: var(--transition); +} + +.message-win { + border-left: 6px solid #4caf50; + background-color: #e8f5e9; + color: #2e7d32; +} + +.message-lose { + border-left: 6px solid var(--red); + background-color: #ffebee; + color: #c62828; +} + +.message-info { + border-left: 6px solid var(--blue); + background-color: #e1f5fe; + color: #0277bd; +} + +.message-content { + font-size: 1.3rem; + font-weight: 600; + letter-spacing: 0.5px; +} + +/* Область игры */ +.game-area { + background-color: var(--felt-green); + border-radius: 20px; + padding: 2.2rem; + box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.3); + position: relative; + border: 4px solid var(--casino-dark-green); +} + +/* Стили секций игроков */ +.player-section { + margin-bottom: 2.4rem; + position: relative; +} + +.player-info { + display: flex; + align-items: center; + gap: 1.2rem; + margin-bottom: 1.2rem; +} + +.player-avatar { + width: 55px; + height: 55px; + border-radius: 50%; + background-position: center; + background-size: cover; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + border: 3px solid var(--gold); +} + +.dealer-avatar { + background-image: url('_content/БлэкДжек/images/dealer-avatar.png'); +} + +.player-avatar-user { + background-image: url('_content/БлэкДжек/images/player-avatar.png'); +} + +.player-title { + color: var(--white); + font-size: 1.7rem; + margin: 0; + font-weight: 600; + letter-spacing: 0.5px; +} + +.score-badge { + background: #ffffff; + padding: 0.3rem 0.8rem; + border-radius: 50px; + font-size: 1.2rem; + margin-left: 0.8rem; + color: var(--black); + border: 2px solid var(--dark-gold); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.2); +} + +.table-felt { + background-color: var(--felt-green); + padding: 1.2rem; + border-radius: 16px; + box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3); +} + +/* Карты в руке */ +.hand { + display: flex; + flex-wrap: wrap; + min-height: 170px; + gap: 0.8rem; + padding: 0.8rem; + position: relative; + justify-content: center; +} + +.dealer-hand::before { + content: ''; + position: absolute; + top: -12px; + left: 50%; + transform: translateX(-50%); + width: 75%; + height: 3px; + background: linear-gradient(90deg, transparent, var(--gold), transparent); +} + +/* Разделитель между дилером и игроком */ +.table-divider { + display: flex; + justify-content: center; + gap: 15px; + margin: 2rem 0; + position: relative; +} + + .table-divider::before { + content: ''; + position: absolute; + top: 50%; + left: 5%; + right: 5%; + height: 2px; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent); + } + +/* Игральные фишки */ +.chip { + width: 40px; + height: 40px; + border-radius: 50%; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + position: relative; + z-index: 1; + transition: transform 0.3s ease; +} + + .chip:hover { + transform: translateY(-3px); + } + +.red-chip { + background: radial-gradient(circle at 30% 30%, #ff8a8a 0%, var(--red) 60%); + border: 3px dashed #ffc7c7; +} + +.blue-chip { + background: radial-gradient(circle at 30% 30%, #94d0ff 0%, var(--blue) 60%); + border: 3px dashed #c5e5ff; +} + +.green-chip { + background: radial-gradient(circle at 30% 30%, #89e89c 0%, #3cac4c 60%); + border: 3px dashed #d2f9db; +} + +.black-chip { + background: radial-gradient(circle at 30% 30%, #a6aaaf 0%, var(--black) 60%); + border: 3px dashed #e2e6eb; +} + +/* Стили для контейнера карты */ +.card-container { + position: relative; + transform-style: preserve-3d; + transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); + margin: 0.3rem; +} + + .card-container.card-hidden { + transform: rotateY(0deg); + } + +/* Игральная карта */ +.playing-card { + width: 110px; + height: 154px; + background-color: var(--white); + border-radius: 10px; + box-shadow: var(--card-shadow); + position: relative; + display: flex; + justify-content: center; + align-items: center; + transform-style: preserve-3d; + backface-visibility: hidden; + border: 1px solid rgba(0, 0, 0, 0.15); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.card-container:hover .playing-card { + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3); + transform: translateY(-5px); +} + +.card-back { + background-color: #3f51b5; + transform: rotateY(0deg); + position: relative; + background: linear-gradient(145deg, #5c6bc0, #3949ab); +} + +.card-back-design { + width: 85%; + height: 85%; + background-image: url('_content/БлэкДжек/images/card-back.png'); + background-size: contain; + background-repeat: no-repeat; + background-position: center; +} + +.card-red { + color: #e53935; +} + +.card-black { + color: #212121; +} + +/* Уголки карты */ +.card-corner { + position: absolute; + display: flex; + flex-direction: column; + align-items: center; + line-height: 1; +} + +.top-left { + top: 8px; + left: 8px; +} + +.bottom-right { + bottom: 8px; + right: 8px; + transform: rotate(180deg); +} + +.card-rank { + font-size: 1.5rem; + font-weight: bold; +} + +.card-suit { + font-size: 1.3rem; +} + +.card-center-suit { + font-size: 3.2rem; + filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.1)); +} + +/* Кнопки действий */ +.action-buttons { + display: flex; + justify-content: center; + gap: 2rem; + margin-top: 2.5rem; + flex-wrap: wrap; +} + +/* 3D кнопки */ +.btn-3d { + position: relative; + padding: 14px 28px; + background: linear-gradient(to bottom, var(--gold), var(--dark-gold)); + color: var(--black); + border: none; + border-radius: 50px; + font-size: 1.1rem; + font-weight: 700; + text-transform: uppercase; + box-shadow: var(--button-shadow), 0 10px 20px rgba(0, 0, 0, 0.2); + transition: all 0.25s; + cursor: pointer; + outline: none; + min-width: 160px; + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + letter-spacing: 1px; +} + + .btn-3d:hover { + background: linear-gradient(to bottom, var(--light-gold), var(--gold)); + transform: translateY(-3px); + box-shadow: 0 9px 0 var(--dark-gold), 0 14px 25px rgba(0, 0, 0, 0.2); + } + + .btn-3d:active { + transform: translateY(3px); + box-shadow: 0 3px 0 var(--dark-gold), 0 5px 10px rgba(0, 0, 0, 0.1); + } + + .btn-3d:disabled { + background: linear-gradient(to bottom, var(--gray), #939cad); + color: var(--light-gray); + cursor: not-allowed; + box-shadow: 0 6px 0 #636b7c, 0 10px 20px rgba(0, 0, 0, 0.1); + opacity: 0.8; + } + +.btn-hit { + background: linear-gradient(to bottom, #76cf79, #48a04c); + box-shadow: 0 6px 0 #3e8942, 0 10px 20px rgba(0, 0, 0, 0.2); + color: white; +} + + .btn-hit:hover { + background: linear-gradient(to bottom, #91d994, #53b557); + box-shadow: 0 9px 0 #3e8942, 0 14px 25px rgba(0, 0, 0, 0.2); + } + + .btn-hit:active { + box-shadow: 0 3px 0 #3e8942, 0 5px 10px rgba(0, 0, 0, 0.1); + } + +.btn-stand { + background: linear-gradient(to bottom, #ff7875, #d63d38); + box-shadow: 0 6px 0 #c62828, 0 10px 20px rgba(0, 0, 0, 0.2); + color: white; +} + + .btn-stand:hover { + background: linear-gradient(to bottom, #ff9793, #e34744); + box-shadow: 0 9px 0 #c62828, 0 14px 25px rgba(0, 0, 0, 0.2); + } + + .btn-stand:active { + box-shadow: 0 3px 0 #c62828, 0 5px 10px rgba(0, 0, 0, 0.1); + } + +.btn-new-game { + background: linear-gradient(to bottom, #7986cb, #495cc9); + color: var(--white); + box-shadow: 0 6px 0 #3949ab, 0 10px 20px rgba(0, 0, 0, 0.2); +} + + .btn-new-game:hover { + background: linear-gradient(to bottom, #9aa5d6, #5969d2); + box-shadow: 0 9px 0 #3949ab, 0 14px 25px rgba(0, 0, 0, 0.2); + } + + .btn-new-game:active { + box-shadow: 0 3px 0 #3949ab, 0 5px 10px rgba(0, 0, 0, 0.1); + } + +.btn-icon { + display: inline-block; + width: 24px; + height: 24px; + background-size: contain; + background-repeat: no-repeat; + filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2)); +} + +.hit-icon { + background-image: url('_content/БлэкДжек/images/hit-icon.svg'); +} + +.stand-icon { + background-image: url('_content/БлэкДжек/images/stand-icon.svg'); +} + +.new-game-icon { + background-image: url('_content/БлэкДжек/images/new-game-icon.svg'); +} + +/* Начальный экран */ +.start-screen { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 4rem 1rem; +} + +.game-logo { + width: 350px; + height: 230px; + background-image: url('_content/БлэкДжек/images/blackjack-logo.png'); + background-size: contain; + background-position: center; + background-repeat: no-repeat; + margin-bottom: 4rem; + filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.3)); + transition: transform 0.5s ease; +} + + .game-logo:hover { + transform: scale(1.05); + } + +.btn-start { + font-size: 1.5rem; + padding: 18px 45px; + min-width: 220px; + box-shadow: 0 8px 0 var(--dark-gold), 0 15px 25px rgba(0, 0, 0, 0.2); +} + + .btn-start:hover { + transform: translateY(-4px); + box-shadow: 0 12px 0 var(--dark-gold), 0 20px 35px rgba(0, 0, 0, 0.2); + } + +/* Адаптивные стили */ +@media (max-width: 768px) { + .blackjack-container { + padding: 1.5rem; + } + + .game-title { + font-size: 2.2rem; + } + + .playing-card { + width: 90px; + height: 126px; + } + + .card-rank { + font-size: 1.3rem; + } + + .card-center-suit { + font-size: 2.6rem; + } + + .action-buttons { + gap: 1.2rem; + } + + .btn-3d { + padding: 12px 20px; + min-width: 140px; + font-size: 1rem; + } +} + +@media (max-width: 480px) { + .playing-card { + width: 70px; + height: 98px; + } + + .card-rank { + font-size: 1.1rem; + } + + .card-suit { + font-size: 1rem; + } + + .card-center-suit { + font-size: 2.2rem; + } + + .action-buttons { + flex-direction: column; + align-items: center; + gap: 1rem; + } + + .btn-3d { + width: 100%; + max-width: 220px; + } + + .game-area { + padding: 1.5rem; + } + + .message-content { + font-size: 1.1rem; + } +} diff --git a/Components/Pages/BlackjackGame.razor.razor b/Components/Pages/BlackjackGame.razor.razor deleted file mode 100644 index 8e276a2..0000000 --- a/Components/Pages/BlackjackGame.razor.razor +++ /dev/null @@ -1,169 +0,0 @@ -/* BlackjackGame.razor.css - Стили для компонента Blackjack */ - -/* Общие стили для секций игрока и дилера */ -h4 { - margin-bottom: 0.8rem; /* Немного больше отступа снизу */ - font-weight: 600; /* Немного жирнее */ - color: #e0e0e0; /* Светлый цвет для темного фона (если будете добавлять) */ - text-shadow: 1px 1px 2px rgba(0,0,0,0.5); /* Легкая тень для читаемости */ -} - -/* Контейнер для карт (рука) */ -.hand { - display: flex; - flex-wrap: wrap; /* Карты будут переноситься, если не помещаются */ - gap: 10px; /* Пространство между картами */ - min-height: 95px; /* Минимальная высота, чтобы контейнер не схлопывался без карт */ - margin-bottom: 1.5rem; /* Отступ под рукой */ - padding: 8px; - background-color: rgba(0, 0, 0, 0.1); /* Легкий фон для области карт */ - border-radius: 8px; - border: 1px solid rgba(255, 255, 255, 0.1); /* Тонкая светлая рамка */ -} - -/* Стиль для отдельной карты */ -.card { - background-color: #fff; /* Белый фон карты */ - border: 1px solid #ababab; /* Серая рамка */ - border-radius: 6px; /* Скругленные углы */ - padding: 15px 10px; /* Внутренние отступы (больше по вертикали) */ - min-width: 65px; /* Минимальная ширина карты */ - text-align: center; - font-size: 1.5em; /* Размер шрифта ранга/масти */ - font-weight: bold; - box-shadow: 3px 3px 7px rgba(0, 0, 0, 0.25); /* Тень для объема */ - display: inline-block; - position: relative; - user-select: none; /* Запретить выделение текста на карте */ - transition: transform 0.1s ease-in-out; /* Плавность при наведении (если добавим) */ -} - -/* Если захотите эффект при наведении */ -/* -.card:hover { - transform: translateY(-3px); -} -*/ - -/* Стиль для скрытой карты дилера ("???") */ -/* Мы не можем легко стилизовать сам текст "???", но можем стилизовать */ -/* первую карту в руке дилера, пока ход игрока. */ -/* Однако, текущая логика просто выводит текст "???" в .card */ -/* Давайте просто сделаем текст "?" серым, если бы мы обернули его в span */ -/* Если вы изменили Razor, как обсуждалось ранее: */ -/* -.hidden-card-content { - color: #9e9e9e; - font-style: italic; - font-size: 0.9em; -} -*/ -/* В текущем варианте специальный стиль для "???" не применяется, она будет в стандартной карте */ - -/* Цвета для мастей */ -.card-red { - color: #D32F2F; /* Насыщенный красный */ -} - -.card-black { - color: #212121; /* Глубокий черный */ -} - -/* Контейнер для кнопок действий */ -.actions { - display: flex; - flex-wrap: wrap; - gap: 12px; /* Расстояние между кнопками */ - margin-top: 1.5rem; /* Отступ сверху */ -} - -/* Стиль для кнопок */ -.actions button, -.btn-lg { /* Стиль для кнопки "Начать игру" */ - padding: 10px 20px; /* Увеличим кнопки */ - font-size: 1em; - cursor: pointer; - border-radius: 5px; - border: none; /* Убираем стандартную рамку Bootstrap */ - transition: background-color 0.2s ease, transform 0.1s ease; /* Плавные переходы */ - box-shadow: 0 2px 5px rgba(0,0,0,0.2); /* Легкая тень для кнопок */ -} - -/* Улучшенные стили для кнопок Bootstrap (можно настроить под себя) */ -.actions .btn-primary { /* Взять карту */ - background-color: #1976D2; /* Синий */ - color: white; -} -.actions .btn-primary:hover:not(:disabled) { - background-color: #1565C0; - transform: translateY(-1px); -} - -.actions .btn-secondary { /* Стоп */ - background-color: #6c757d; /* Серый */ - color: white; -} -.actions .btn-secondary:hover:not(:disabled) { - background-color: #5a6268; - transform: translateY(-1px); -} - -.actions .btn-warning { /* Новая игра */ - background-color: #FFA000; /* Оранжевый */ - color: #212121; /* Темный текст на оранжевом */ -} -.actions .btn-warning:hover:not(:disabled) { - background-color: #FF8F00; - transform: translateY(-1px); -} - -/* Кнопка "Начать игру" */ -.btn-success.btn-lg { - background-color: #388E3C; /* Зеленый */ - color: white; - font-size: 1.2em; /* Крупнее */ - padding: 12px 25px; -} -.btn-success.btn-lg:hover:not(:disabled) { - background-color: #2E7D32; - transform: translateY(-1px); -} - - -/* Стиль для отключенных кнопок */ -.actions button:disabled { - cursor: not-allowed; - opacity: 0.5; /* Сделать полупрозрачными */ - box-shadow: none; /* Убрать тень у неактивных */ -} - -/* Сообщения игры */ -.alert { - margin-top: 1rem; - margin-bottom: 1.5rem; - padding: 1rem; - border-radius: 6px; - font-weight: 500; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} - -/* Успешное сообщение (выигрыш) */ -.alert-success { - background-color: #E8F5E9; /* Светло-зеленый фон */ - color: #2E7D32; /* Темно-зеленый текст */ - border: 1px solid #A5D6A7; /* Зеленая рамка */ -} - -/* Информационное сообщение (ход игры, ничья, проигрыш) */ -.alert-info { - background-color: #E3F2FD; /* Светло-голубой фон */ - color: #1565C0; /* Темно-синий текст */ - border: 1px solid #90CAF9; /* Голубая рамка */ -} - -/* Разделитель */ -hr { - border: none; /* Убираем стандартную линию */ - border-top: 1px solid rgba(255, 255, 255, 0.2); /* Светлая полупрозрачная линия */ - margin: 2rem 0; /* Увеличим отступы */ -} \ No newline at end of file diff --git a/Components/Routes.razor b/Components/Routes.razor index f756e19..8e65da2 100644 --- a/Components/Routes.razor +++ b/Components/Routes.razor @@ -1,6 +1,19 @@ - +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Routing + + - - + @if (routeData.PageType.Name == "Index" || string.IsNullOrEmpty(routeData.PageType.Name)) + { + + } + else + { + + } + + Не найдено +

Извините, страница не найдена.

+
diff --git a/Program.cs b/Program.cs index 4047a8a..50c10ee 100644 --- a/Program.cs +++ b/Program.cs @@ -2,11 +2,14 @@ using БлэкДжек.Components; var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHttpContextAccessor(); + // Add services to the container. builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); var app = builder.Build(); +app.UseStaticFiles(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) diff --git a/wwwroot/app.css b/wwwroot/css/app.css similarity index 92% rename from wwwroot/app.css rename to wwwroot/css/app.css index e398853..786f690 100644 --- a/wwwroot/app.css +++ b/wwwroot/css/app.css @@ -1,3 +1,6 @@ +/* wwwroot/css/app.css CSS */ +@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap'); + h1:focus { outline: none; } diff --git a/БлэкДжек.sln b/БлэкДжек.sln index af9f629..8ba4d47 100644 --- a/БлэкДжек.sln +++ b/БлэкДжек.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.13.35828.75 d17.13 +VisualStudioVersion = 17.13.35828.75 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "БлэкДжек", "БлэкДжек.csproj", "{11339889-A9DE-4748-A250-599F6D56EDA1}" EndProject