Добавьте файлы проекта.

This commit is contained in:
107 2025-04-16 10:24:33 +07:00
parent 419186f710
commit 92c18b985a
18 changed files with 770 additions and 0 deletions

18
Components/App.razor Normal file
View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<link href="css/app.css" rel="stylesheet" />
<!-- Если имя вашего проекта другое, ссылка на app.css может отличаться -->
<link href="BlazorBlackjack.styles.css" rel="stylesheet" /> <!-- Эта строка важна для изолированных стилей -->
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>

View File

@ -0,0 +1,9 @@
@inherits LayoutComponentBase
@Body
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>

View File

@ -0,0 +1,18 @@
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}

View File

@ -0,0 +1,264 @@
@* --- НАЧАЛО КОДА ДЛЯ BlackjackGame.razor --- *@
@page "/blackjack"
@using БлэкДжек.Components @* <--- ВОТ ЭТУ СТРОКУ НУЖНО ПРОВЕРИТЬ/ЗАМЕНИТЬ *@
@implements IDisposable
<h3>Blackjack</h3>
@* Область для сообщений игры *@
@if (!string.IsNullOrEmpty(GameMessage))
{
<div class="alert @(IsGameOver && PlayerScore <= 21 && (DealerScore > 21 || PlayerScore > DealerScore) ? "alert-success" : "alert-info")" role="alert">
@GameMessage
</div>
}
@* Основной блок игры, отображается после нажатия "Начать" *@
@if (IsGameStarted)
{
<div>
<h4>Дилер (@(IsPlayerTurn ? "?" : DealerScore.ToString()))</h4>
<div class="hand">
@foreach (var card in DealerHand)
{
@* Условие для скрытия первой карты дилера во время хода игрока *@
<div class="card @GetCardColor(card)">
@((DealerHand.IndexOf(card) == 0 && IsPlayerTurn) ? "???" : card.Display)
</div>
}
</div>
</div>
<hr />
<div>
<h4>Игрок (@PlayerScore)</h4>
<div class="hand">
@foreach (var card in PlayerHand)
{
<div class="card @GetCardColor(card)">
@card.Display
</div>
}
</div>
</div>
<hr />
@* Кнопки действий *@
<div class="actions">
<button class="btn btn-primary" @onclick="PlayerHit" disabled="@(!IsPlayerTurn || IsGameOver)">Взять карту (Hit)</button>
<button class="btn btn-secondary" @onclick="PlayerStand" disabled="@(!IsPlayerTurn || IsGameOver)">Стоп (Stand)</button>
<button class="btn btn-warning" @onclick="StartGame">Новая игра</button>
</div>
}
else
{
@* Кнопка для старта игры, видна только до начала *@
<button class="btn btn-success btn-lg" @onclick="StartGame">Начать игру</button>
}
@* Блок с C# кодом *@
@code {
// --- Поля состояния игры ---
private Deck GameDeck;
private List<Card> PlayerHand = new List<Card>(); // Инициализируем, чтобы избежать null reference до старта
private List<Card> DealerHand = new List<Card>(); // Инициализируем
// --- Вычисляемые свойства для счета ---
private int PlayerScore => CalculateScore(PlayerHand);
private int DealerScore => CalculateScore(DealerHand);
// --- Флаги состояния игры ---
private bool IsPlayerTurn;
private bool IsGameOver;
private bool IsGameStarted; // Показывает, была ли нажата кнопка "Начать игру"
private string GameMessage = string.Empty; // Инициализируем пустой строкой
// --- Инициализация компонента ---
protected override void OnInitialized()
{
// Игра не начинается автоматически при загрузке страницы
IsGameStarted = false;
}
// --- Метод начала новой игры ---
private void StartGame()
{
GameDeck = new Deck();
GameDeck.Shuffle();
PlayerHand = new List<Card>();
DealerHand = new List<Card>();
IsGameOver = false;
IsPlayerTurn = true;
GameMessage = "Ваш ход. Взять карту или стоп?";
IsGameStarted = true; // Показываем игровое поле
// Раздаем по 2 карты
PlayerHand.Add(GameDeck.DealCard());
DealerHand.Add(GameDeck.DealCard()); // Первая карта дилера
PlayerHand.Add(GameDeck.DealCard());
DealerHand.Add(GameDeck.DealCard()); // Вторая карта дилера
// Проверка на блэкджек у игрока или дилера сразу после раздачи
if (PlayerScore == 21 && DealerHand.Count == 2) // У игрока блэкджек
{
if (DealerScore == 21) // У дилера тоже блэкджек
{
RevealDealerCardAndEndGame("Ничья! У обоих Блэкджек!");
}
else // Только у игрока блэкджек
{
RevealDealerCardAndEndGame("Блэкджек! Вы выиграли!");
}
}
else if (DealerScore == 21 && DealerHand.Count == 2) // Только у дилера блэкджек (проверяем после игрока)
{
RevealDealerCardAndEndGame("Блэкджек у дилера! Вы проиграли.");
}
// Если ни у кого нет блэкджека, игра продолжается с сообщением "Ваш ход..."
StateHasChanged(); // Обновляем UI, чтобы показать начальное состояние
}
// --- Действие игрока: Взять карту (Hit) ---
private void PlayerHit()
{
if (!IsPlayerTurn || IsGameOver) return; // Нельзя брать карту не в свой ход или если игра окончена
PlayerHand.Add(GameDeck.DealCard());
if (PlayerScore > 21)
{
EndGame("Перебор! Вы проиграли.");
}
else if (PlayerScore == 21)
{
// Если игрок набрал ровно 21, его ход автоматически завершается
PlayerStand();
}
// Если меньше 21, игрок может брать еще
StateHasChanged(); // Обновляем UI после взятия карты
}
// --- Действие игрока: Стоп (Stand) ---
private void PlayerStand()
{
if (!IsPlayerTurn || IsGameOver) return; // Нельзя остановиться не в свой ход или если игра окончена
IsPlayerTurn = false; // Передаем ход дилеру
GameMessage = "Дилер ходит...";
StateHasChanged(); // Обновим сообщение и откроем карту дилера
// Можно добавить небольшую задержку перед ходом дилера для наглядности
// await Task.Delay(500); // Если раскомментировать, метод должен быть async Task
DealerTurn(); // Начинаем ход дилера
}
// --- Логика хода Дилера ---
// Простая синхронная версия. Для пауз нужен async/await и Task.Delay
private void DealerTurn()
{
// Дилер берет карты, пока его счет меньше 17
while (DealerScore < 17)
{
// В реальном приложении можно добавить паузу здесь
// await Task.Delay(800);
DealerHand.Add(GameDeck.DealCard());
// StateHasChanged(); // Обновлять UI после каждой карты дилера, если есть пауза
}
// После того, как дилер закончил брать карты, определяем победителя
DetermineWinner();
StateHasChanged(); // Показать финальный результат
}
// --- Подсчет очков для руки ---
private int CalculateScore(List<Card> hand)
{
if (hand == null || hand.Count == 0) return 0;
int score = 0;
int aceCount = 0;
foreach (var card in hand)
{
score += card.Value;
if (card.Rank == "A")
{
aceCount++;
}
}
// Корректировка значения Тузов (с 11 на 1 при переборе)
while (score > 21 && aceCount > 0)
{
score -= 10; // Считаем Туз как 1 вместо 11
aceCount--;
}
return score;
}
// --- Определение победителя ---
private void DetermineWinner()
{
// Убедимся, что карта дилера видна (IsPlayerTurn уже false)
if (PlayerScore > 21)
{
// Это условие уже должно было быть обработано в PlayerHit, но на всякий случай
EndGame("Перебор! Вы проиграли.");
}
else if (DealerScore > 21)
{
EndGame("У дилера перебор! Вы выиграли!");
}
else if (PlayerScore > DealerScore)
{
EndGame("Вы выиграли!");
}
else if (DealerScore > PlayerScore)
{
EndGame("Дилер выиграл!");
}
else // Очки равны
{
EndGame("Ничья (Push)!");
}
}
// --- Метод для завершения игры и установки сообщения ---
private void RevealDealerCardAndEndGame(string message)
{
IsPlayerTurn = false; // Убедимся, что карта дилера видна
EndGame(message);
}
private void EndGame(string message)
{
IsGameOver = true;
IsPlayerTurn = false; // Больше никто не ходит
GameMessage = message;
// StateHasChanged(); // Обычно вызывается в методе, который вызвал EndGame
}
// --- Вспомогательный метод для определения цвета карты ---
private string GetCardColor(Card card)
{
return (card.Suit == "♥" || card.Suit == "♦") ? "card-red" : "card-black";
}
// --- Реализация IDisposable (пока пустая, но может пригодиться) ---
public void Dispose()
{
// Здесь можно остановить таймеры или отписаться от событий, если они будут добавлены
}
}
@* --- КОНЕЦ КОДА ДЛЯ BlackjackGame.razor --- *@

View File

@ -0,0 +1,169 @@
/* 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; /* Увеличим отступы */
}

View File

@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}

View File

@ -0,0 +1,7 @@
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.

6
Components/Routes.razor Normal file
View File

@ -0,0 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

10
Components/_Imports.razor Normal file
View File

@ -0,0 +1,10 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using БлэкДжек
@using БлэкДжек.Components

22
Models/Card.cs Normal file
View File

@ -0,0 +1,22 @@
namespace БлэкДжек.Components // Замените BlazorBlackjack на имя вашего проекта
{
public class Card
{
public string Suit { get; set; } // Масть (♥, ♦, ♣, ♠)
public string Rank { get; set; } // Ранг (2, 3, ..., 10, J, Q, K, A)
public int Value { get; set; } // Значение (J,Q,K = 10, A = 11 или 1)
// Для удобного отображения
public string Display => $"{Rank}{Suit}";
// Можно добавить свойство для пути к изображению карты, если хотите графику
// public string ImagePath => $"images/cards/{Rank.ToLower()}{SuitChar}.png";
// private char SuitChar => Suit switch { "♥" => 'h', "♦" => 'd', "♣" => 'c', "♠" => 's', _ => ' ' };
public Card(string suit, string rank, int value)
{
Suit = suit;
Rank = rank;
Value = value;
}
}
}

66
Models/Deck.cs Normal file
View File

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace БлэкДжек.Components // Замените BlazorBlackjack на имя вашего проекта
{
public class Deck
{
public List<Card> Cards { get; private set; }
public Deck()
{
InitializeDeck();
}
private void InitializeDeck()
{
Cards = new List<Card>();
string[] suits = { "♥", "♦", "♣", "♠" };
string[] ranks = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };
foreach (var suit in suits)
{
foreach (var rank in ranks)
{
int value = 0;
if (int.TryParse(rank, out int numValue))
{
value = numValue;
}
else if (rank == "J" || rank == "Q" || rank == "K")
{
value = 10;
}
else if (rank == "A")
{
value = 11; // Туз по умолчанию 11
}
Cards.Add(new Card(suit, rank, value));
}
}
}
public void Shuffle()
{
Random rng = new Random();
Cards = Cards.OrderBy(c => rng.Next()).ToList();
}
public Card DealCard()
{
if (Cards.Count == 0)
{
// Можно пересоздать и перемешать колоду, если она закончилась
// InitializeDeck();
// Shuffle();
// Или просто вернуть null/выбросить исключение
return null;
}
Card card = Cards[0];
Cards.RemoveAt(0);
return card;
}
}
}

27
Program.cs Normal file
View File

@ -0,0 +1,27 @@
using БлэкДжек.Components;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();

View File

@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:10828",
"sslPort": 44355
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5097",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7115;http://localhost:5097",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

9
appsettings.json Normal file
View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

29
wwwroot/app.css Normal file
View File

@ -0,0 +1,29 @@
h1:focus {
outline: none;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid #e50000;
}
.validation-message {
color: #e50000;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
.darker-border-checkbox.form-check-input {
border-color: #929292;
}

9
БлэкДжек.csproj Normal file
View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

25
БлэкДжек.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35828.75 d17.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "БлэкДжек", "БлэкДжек.csproj", "{11339889-A9DE-4748-A250-599F6D56EDA1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{11339889-A9DE-4748-A250-599F6D56EDA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11339889-A9DE-4748-A250-599F6D56EDA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11339889-A9DE-4748-A250-599F6D56EDA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11339889-A9DE-4748-A250-599F6D56EDA1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {816006BE-33DE-493A-8068-5FFC09509947}
EndGlobalSection
EndGlobal