274 lines
10 KiB
Plaintext
274 lines
10 KiB
Plaintext
@inject AudioService Audio
|
|
|
|
<div class="boss-container">
|
|
<!-- Horný panel súboja -->
|
|
<div class="card p-4 rounded-4 shadow-sm mb-4 border-0 text-white"
|
|
style="background: linear-gradient(135deg, #475569, #0f172a);">
|
|
<div class="d-flex flex-wrap justify-content-between align-items-center gap-3">
|
|
<!-- Hráč -->
|
|
<div class="d-flex align-items-center gap-3">
|
|
<div class="fs-1 bg-primary rounded-circle p-2 px-3 shadow">🛡️</div>
|
|
<div>
|
|
<h5 class="fw-bold m-0">Strážca Ypsilonu</h5>
|
|
<div class="d-flex gap-1 fs-5 mt-1">
|
|
@for (int i = 0; i < 3; i++)
|
|
{
|
|
<span>@(i < playerHp ? "❤️" : "🖤")</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="text-center">
|
|
<span class="badge bg-danger fs-5 px-4 py-2 rounded-pill shadow animate-pulse">
|
|
⚡ FINÁLNY SÚBOJ: PROVINCIA @Category.Letter ⚡
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Škriatok Mäkkýš -->
|
|
<div class="d-flex align-items-center gap-3 text-end">
|
|
<div>
|
|
<h5 class="fw-bold m-0 text-warning">Škriatok Mäkkýš</h5>
|
|
<div class="progress mt-1 shadow-sm" style="width: 140px; height: 16px; background-color: rgba(255,255,255,0.2);">
|
|
<div class="progress-bar bg-danger" style="width: @(bossHp * 20)%;"></div>
|
|
</div>
|
|
</div>
|
|
<div class="fs-1 bg-danger rounded-circle p-2 px-3 shadow">🧙♂️</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@if (!isBossDefeated && playerHp > 0)
|
|
{
|
|
var q = questions[currentQIndex];
|
|
<div class="card p-4 rounded-4 shadow-sm text-center bg-white border-0">
|
|
<div class="mb-4">
|
|
<span class="badge bg-secondary px-3 py-1 rounded-pill mb-2">Otázka @(currentQIndex + 1) z @questions.Count</span>
|
|
<h3 class="fw-bold text-dark mt-2">@q.QuestionText</h3>
|
|
</div>
|
|
|
|
<div class="row g-3 justify-content-center">
|
|
@foreach (var opt in q.Options)
|
|
{
|
|
<div class="col-12 col-md-6">
|
|
<button class="btn btn-lg w-100 p-4 rounded-4 shadow-sm text-center fw-bold transition-transform hover-scale
|
|
@(isAnswered ? (opt == q.CorrectOption ? "btn-success" : (opt == selectedOption ? "btn-danger" : "btn-light")) : "btn-light border-2")"
|
|
style="font-size: 1.25rem;"
|
|
disabled="@isAnswered"
|
|
@onclick="() => CheckAnswer(opt)">
|
|
@opt
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@if (isAnswered)
|
|
{
|
|
<div class="mt-4 p-3 rounded-4 @(isCorrect ? "bg-success bg-opacity-10 text-success" : "bg-danger bg-opacity-10 text-danger")">
|
|
<h5 class="fw-bold m-0">@(isCorrect ? "💥 Zásah! Škriatok stratil život!" : "🛡️ Jáj! Škriatok ťa prekabátil!")</h5>
|
|
<p class="m-0 mt-1">@q.Explanation</p>
|
|
|
|
<button class="btn btn-lg @(isCorrect ? "btn-success" : "btn-primary") rounded-pill px-5 shadow mt-3"
|
|
@onclick="NextQuestion">
|
|
Ďalej ➡️
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
else if (isBossDefeated)
|
|
{
|
|
<!-- Víťazstvo nad bossom -->
|
|
<div class="card p-5 rounded-4 shadow text-center bg-white border-0">
|
|
<span class="fs-1">👑</span>
|
|
<h1 class="fw-bold text-success mt-2">Škriatok Mäkkýš bol porazený!</h1>
|
|
<p class="fs-5 text-muted">
|
|
Oslobodil si provinciu <strong>@Category.Title</strong> a získal Zlatú Pečať!
|
|
</p>
|
|
|
|
<div class="my-4 p-4 rounded-4 bg-warning bg-opacity-25 d-inline-block">
|
|
<span class="fs-1">🎖️</span>
|
|
<h3 class="fw-bold text-dark m-0">Zlatá Pečať Ypsilonu (@Category.Letter)</h3>
|
|
</div>
|
|
|
|
<div class="mt-3">
|
|
<button class="btn btn-lg btn-success rounded-pill px-5 shadow" @onclick="FinishBoss">
|
|
Návrat na mapu kráľovstva 🗺️
|
|
</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<!-- Prehra hráča -->
|
|
<div class="card p-5 rounded-4 shadow text-center bg-white border-0">
|
|
<span class="fs-1">💔</span>
|
|
<h2 class="fw-bold text-danger mt-2">Škriatok Mäkkýš ťa tentoraz premohol!</h2>
|
|
<p class="fs-5 text-muted">
|
|
Nevadí! Zopakuj si vláčik slov a hádanky a skús vyzvať škriatka znova.
|
|
</p>
|
|
|
|
<div class="mt-4">
|
|
<button class="btn btn-lg btn-primary rounded-pill px-5 shadow" @onclick="RestartBoss">
|
|
🔄 Skúsiť znova
|
|
</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter] public LetterCategory Category { get; set; } = new();
|
|
[Parameter] public EventCallback<bool> OnDefeated { get; set; }
|
|
|
|
private class BossQuestion
|
|
{
|
|
public string QuestionText { get; set; } = string.Empty;
|
|
public List<string> Options { get; set; } = new();
|
|
public string CorrectOption { get; set; } = string.Empty;
|
|
public string Explanation { get; set; } = string.Empty;
|
|
}
|
|
|
|
private int playerHp = 3;
|
|
private int bossHp = 5;
|
|
private int currentQIndex = 0;
|
|
private bool isBossDefeated = false;
|
|
private bool isAnswered = false;
|
|
private bool isCorrect = false;
|
|
private string? selectedOption = null;
|
|
private List<BossQuestion> questions = new();
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
RestartBoss();
|
|
}
|
|
|
|
private void RestartBoss()
|
|
{
|
|
playerHp = 3;
|
|
bossHp = 5;
|
|
currentQIndex = 0;
|
|
isBossDefeated = false;
|
|
isAnswered = false;
|
|
selectedOption = null;
|
|
BuildQuestions();
|
|
}
|
|
|
|
private void BuildQuestions()
|
|
{
|
|
questions.Clear();
|
|
var rnd = new Random();
|
|
var words = Category.Words.OrderBy(_ => rnd.Next()).ToList();
|
|
|
|
// 1. Doplň chýbajúce slovo v reťazci
|
|
if (Category.Words.Count >= 3)
|
|
{
|
|
var w1 = Category.Words[0].Word;
|
|
var w2 = Category.Words[1].Word;
|
|
var w3 = Category.Words[2].Word;
|
|
questions.Add(new BossQuestion
|
|
{
|
|
QuestionText = $"Ktoré slovo nasleduje za sebou: „{w1}“, „{w2}“, [ ??? ] ?",
|
|
Options = new List<string> { w3, words.Last().Word, "bicykel" }.OrderBy(_ => rnd.Next()).ToList(),
|
|
CorrectOption = w3,
|
|
Explanation = $"Presne tak! Rad pokračuje slovom '{w3}'."
|
|
});
|
|
}
|
|
|
|
// 2. Chyť votrelca
|
|
var alien = Category.AlienPool.FirstOrDefault(a => a.IsAlien)?.Word ?? "bicykel";
|
|
var validW = words.First().Word;
|
|
var validW2 = words.Skip(1).First().Word;
|
|
questions.Add(new BossQuestion
|
|
{
|
|
QuestionText = "Ktoré z týchto slov je votrelec a NIE JE vybrané slovo?",
|
|
Options = new List<string> { alien, validW, validW2 }.OrderBy(_ => rnd.Next()).ToList(),
|
|
CorrectOption = alien,
|
|
Explanation = $"Výborne! Slovo '{alien}' nepatrí medzi vybrané slová."
|
|
});
|
|
|
|
// 3. Význam slova
|
|
var targetWord = words.FirstOrDefault(w => w.IsArchaicOrDifficult) ?? words.First();
|
|
var otherWord = words.FirstOrDefault(w => w.Word != targetWord.Word) ?? words.Last();
|
|
questions.Add(new BossQuestion
|
|
{
|
|
QuestionText = $"Čo znamená vybrané slovo „{targetWord.Word}“?",
|
|
Options = new List<string> { targetWord.Meaning, otherWord.Meaning, "Žlté auto na preteky" }.OrderBy(_ => rnd.Next()).ToList(),
|
|
CorrectOption = targetWord.Meaning,
|
|
Explanation = $"Správne! {targetWord.Word} znamená: {targetWord.Meaning}."
|
|
});
|
|
|
|
// 4. Doplnenie do vety
|
|
var sentenceWord = words.Skip(2).FirstOrDefault() ?? words.First();
|
|
var sentence = sentenceWord.ExampleSentence.Replace(sentenceWord.Word, "______", StringComparison.OrdinalIgnoreCase);
|
|
questions.Add(new BossQuestion
|
|
{
|
|
QuestionText = $"Doplň správne slovo do vety: „{sentence}“",
|
|
Options = new List<string> { sentenceWord.Word, words.Last().Word, "slnko" }.OrderBy(_ => rnd.Next()).ToList(),
|
|
CorrectOption = sentenceWord.Word,
|
|
Explanation = $"Skvelá pamäť! Patrí tam slovo '{sentenceWord.Word}'."
|
|
});
|
|
|
|
// 5. Finálna otázka
|
|
var lastWord = words.Last();
|
|
questions.Add(new BossQuestion
|
|
{
|
|
QuestionText = $"Aké písmeno po {Category.Letter} sa píše v slove „{lastWord.Word}“?",
|
|
Options = new List<string> { "Tvrdé Y/Ý", "Mäkké I/Í", "Dvojhláska Ô" }.OrderBy(_ => rnd.Next()).ToList(),
|
|
CorrectOption = "Tvrdé Y/Ý",
|
|
Explanation = $"Presne tak! Vybrané slová sa vždy píšu s tvrdým Y/Ý."
|
|
});
|
|
}
|
|
|
|
private async Task CheckAnswer(string opt)
|
|
{
|
|
isAnswered = true;
|
|
selectedOption = opt;
|
|
var q = questions[currentQIndex];
|
|
|
|
if (opt == q.CorrectOption)
|
|
{
|
|
isCorrect = true;
|
|
bossHp--;
|
|
await Audio.PlaySuccessAsync();
|
|
}
|
|
else
|
|
{
|
|
isCorrect = false;
|
|
playerHp--;
|
|
await Audio.PlayWrongAsync();
|
|
}
|
|
}
|
|
|
|
private async Task NextQuestion()
|
|
{
|
|
isAnswered = false;
|
|
selectedOption = null;
|
|
|
|
if (bossHp <= 0)
|
|
{
|
|
isBossDefeated = true;
|
|
await Audio.PlayFanfareAsync();
|
|
return;
|
|
}
|
|
|
|
if (playerHp <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentQIndex++;
|
|
if (currentQIndex >= questions.Count)
|
|
{
|
|
// Ak prešiel všetky otázky a prežil, boss padol
|
|
isBossDefeated = true;
|
|
await Audio.PlayFanfareAsync();
|
|
}
|
|
}
|
|
|
|
private async Task FinishBoss()
|
|
{
|
|
await OnDefeated.InvokeAsync(true);
|
|
}
|
|
}
|