changes
@@ -107,6 +107,58 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- PAUSE & STEP-BY-STEP EXPLANATION MODAL (WHEN ANSWER IS INCORRECT) -->
|
||||||
|
@if (ShowExplanationModal && ExplanationProblem != null)
|
||||||
|
{
|
||||||
|
<div class="explanation-modal-overlay anim-fade-in">
|
||||||
|
<div class="explanation-parchment-box anim-victory-modal-pop">
|
||||||
|
<div class="explanation-header">
|
||||||
|
<span class="explanation-owl-icon">🦉</span>
|
||||||
|
<span class="explanation-badge">📖 MÚDRA ROZPRÁVKOVÁ RADA</span>
|
||||||
|
<h2 class="explanation-title">Pozor na chybičku!</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="explanation-body">
|
||||||
|
<!-- QUESTION & ANSWERS COMPARISON ROW -->
|
||||||
|
<div class="explanation-equation-card">
|
||||||
|
<div class="equation-question-row">
|
||||||
|
<span class="equation-label">Príklad:</span>
|
||||||
|
<span class="equation-text">@ExplanationProblem.QuestionText</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="equation-answers-row">
|
||||||
|
<div class="answer-box user-answer">
|
||||||
|
<span class="ans-label">Tvoja odpoveď:</span>
|
||||||
|
<span class="ans-val">@(string.IsNullOrWhiteSpace(ExplanationUserAnswer) ? "Čas vypršal ⏱️" : ExplanationUserAnswer) ❌</span>
|
||||||
|
</div>
|
||||||
|
<div class="answer-box correct-answer">
|
||||||
|
<span class="ans-label">Správny výsledok:</span>
|
||||||
|
<span class="ans-val">@ExplanationProblem.CorrectAnswer ✅</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- STEP BY STEP EXPLANATION -->
|
||||||
|
<div class="explanation-step-card">
|
||||||
|
<div class="step-card-header">
|
||||||
|
<span class="sparkle-icon">💡</span>
|
||||||
|
<strong>Ako na to (Postup výpočtu):</strong>
|
||||||
|
</div>
|
||||||
|
<p class="step-explanation-text">
|
||||||
|
@ExplanationProblem.Explanation
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="explanation-actions">
|
||||||
|
<button class="btn-grand-celebration btn-explanation-continue" @onclick="DismissExplanation">
|
||||||
|
@(IsExplanationFromDefense ? "🛡️ ROZUMIEM, POKRAČOVAŤ ➜" : "⚔️ ROZUMIEM, IDEME NA OBRANU! ➜")
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<!-- FULLSCREEN VICTORY / DEFEAT CELEBRATION OVERLAY -->
|
<!-- FULLSCREEN VICTORY / DEFEAT CELEBRATION OVERLAY -->
|
||||||
@if (State.IsBattleOver)
|
@if (State.IsBattleOver)
|
||||||
{
|
{
|
||||||
@@ -213,6 +265,11 @@
|
|||||||
private System.Threading.Timer? _timer;
|
private System.Threading.Timer? _timer;
|
||||||
private double RemainingTimeSeconds { get; set; } = 6.0;
|
private double RemainingTimeSeconds { get; set; } = 6.0;
|
||||||
|
|
||||||
|
private bool ShowExplanationModal { get; set; } = false;
|
||||||
|
private bool IsExplanationFromDefense { get; set; } = false;
|
||||||
|
private string ExplanationUserAnswer { get; set; } = string.Empty;
|
||||||
|
private MathProblem? ExplanationProblem { get; set; }
|
||||||
|
|
||||||
private Level? NextLevel => DataLoader.GetNextLevel(PlayerGrade, CurrentLevel.Id);
|
private Level? NextLevel => DataLoader.GetNextLevel(PlayerGrade, CurrentLevel.Id);
|
||||||
private string? _loadedLevelId;
|
private string? _loadedLevelId;
|
||||||
|
|
||||||
@@ -241,6 +298,8 @@
|
|||||||
|
|
||||||
private void StartBattle()
|
private void StartBattle()
|
||||||
{
|
{
|
||||||
|
ShowExplanationModal = false;
|
||||||
|
ExplanationProblem = null;
|
||||||
BattleEngine.StartBattle(Hero, CurrentLevel, Config);
|
BattleEngine.StartBattle(Hero, CurrentLevel, Config);
|
||||||
CurrentInput = string.Empty;
|
CurrentInput = string.Empty;
|
||||||
StartTimer();
|
StartTimer();
|
||||||
@@ -249,58 +308,162 @@
|
|||||||
private void StartTimer()
|
private void StartTimer()
|
||||||
{
|
{
|
||||||
_timer?.Dispose();
|
_timer?.Dispose();
|
||||||
|
State.ProblemStartTime = DateTime.UtcNow;
|
||||||
RemainingTimeSeconds = State.IsDefensePhase ? Config.Battle.DefenseTestDurationSeconds : Config.Battle.StandardTimeSeconds;
|
RemainingTimeSeconds = State.IsDefensePhase ? Config.Battle.DefenseTestDurationSeconds : Config.Battle.StandardTimeSeconds;
|
||||||
_timer = new System.Threading.Timer(async _ =>
|
_timer = new System.Threading.Timer(async _ =>
|
||||||
{
|
{
|
||||||
|
if (ShowExplanationModal || State.IsBattleOver) return;
|
||||||
|
|
||||||
var elapsed = (DateTime.UtcNow - State.ProblemStartTime).TotalSeconds;
|
var elapsed = (DateTime.UtcNow - State.ProblemStartTime).TotalSeconds;
|
||||||
double limit = State.IsDefensePhase ? Config.Battle.DefenseTestDurationSeconds : Config.Battle.StandardTimeSeconds;
|
double limit = State.IsDefensePhase ? Config.Battle.DefenseTestDurationSeconds : Config.Battle.StandardTimeSeconds;
|
||||||
RemainingTimeSeconds = Math.Max(0, limit - elapsed);
|
RemainingTimeSeconds = Math.Max(0, limit - elapsed);
|
||||||
|
|
||||||
|
if (RemainingTimeSeconds <= 0)
|
||||||
|
{
|
||||||
|
_timer?.Dispose();
|
||||||
|
await InvokeAsync(async () =>
|
||||||
|
{
|
||||||
|
if (State.IsDefensePhase)
|
||||||
|
{
|
||||||
|
var prob = State.CurrentProblem;
|
||||||
|
var result = await BattleEngine.SubmitDefenseAnswerAsync("");
|
||||||
|
ExplanationProblem = prob;
|
||||||
|
ExplanationUserAnswer = "Čas vypršal ⏱️";
|
||||||
|
IsExplanationFromDefense = true;
|
||||||
|
ShowExplanationModal = true;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var prob = State.CurrentProblem;
|
||||||
|
var result = await BattleEngine.SubmitAnswerAsync("");
|
||||||
|
ExplanationProblem = prob;
|
||||||
|
ExplanationUserAnswer = "Čas vypršal ⏱️";
|
||||||
|
IsExplanationFromDefense = false;
|
||||||
|
ShowExplanationModal = true;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
}, null, 100, 100);
|
}, null, 100, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleInputSubmit(string input)
|
private async Task HandleInputSubmit(string input)
|
||||||
{
|
{
|
||||||
if (State.IsBattleOver) return;
|
if (State.IsBattleOver || ShowExplanationModal) return;
|
||||||
|
|
||||||
if (State.IsDefensePhase)
|
if (State.IsDefensePhase)
|
||||||
{
|
{
|
||||||
await BattleEngine.SubmitDefenseAnswerAsync(input);
|
var problemBeforeSubmit = State.CurrentProblem;
|
||||||
|
var result = await BattleEngine.SubmitDefenseAnswerAsync(input);
|
||||||
|
CurrentInput = string.Empty;
|
||||||
|
|
||||||
|
if (result is CombatResultType.DefenseFailed or CombatResultType.Defeat)
|
||||||
|
{
|
||||||
|
_timer?.Dispose();
|
||||||
|
ExplanationProblem = problemBeforeSubmit;
|
||||||
|
ExplanationUserAnswer = input;
|
||||||
|
IsExplanationFromDefense = true;
|
||||||
|
ShowExplanationModal = true;
|
||||||
|
StateHasChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await BattleEngine.SubmitAnswerAsync(input);
|
var problemBeforeSubmit = State.CurrentProblem;
|
||||||
|
var result = await BattleEngine.SubmitAnswerAsync(input);
|
||||||
|
CurrentInput = string.Empty;
|
||||||
|
|
||||||
|
if (result == CombatResultType.PlayerMissed)
|
||||||
|
{
|
||||||
|
_timer?.Dispose();
|
||||||
|
ExplanationProblem = problemBeforeSubmit;
|
||||||
|
ExplanationUserAnswer = input;
|
||||||
|
IsExplanationFromDefense = false;
|
||||||
|
ShowExplanationModal = true;
|
||||||
|
StateHasChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentInput = string.Empty;
|
|
||||||
await ProcessPostTurn();
|
await ProcessPostTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleChoiceSelected(string choice)
|
private async Task HandleChoiceSelected(string choice)
|
||||||
{
|
{
|
||||||
if (State.IsBattleOver) return;
|
if (State.IsBattleOver || ShowExplanationModal) return;
|
||||||
|
|
||||||
if (State.IsDefensePhase)
|
if (State.IsDefensePhase)
|
||||||
{
|
{
|
||||||
await BattleEngine.SubmitDefenseAnswerAsync(choice);
|
var problemBeforeSubmit = State.CurrentProblem;
|
||||||
|
var result = await BattleEngine.SubmitDefenseAnswerAsync(choice);
|
||||||
|
|
||||||
|
if (result is CombatResultType.DefenseFailed or CombatResultType.Defeat)
|
||||||
|
{
|
||||||
|
_timer?.Dispose();
|
||||||
|
ExplanationProblem = problemBeforeSubmit;
|
||||||
|
ExplanationUserAnswer = choice;
|
||||||
|
IsExplanationFromDefense = true;
|
||||||
|
ShowExplanationModal = true;
|
||||||
|
StateHasChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await BattleEngine.SubmitAnswerAsync(choice);
|
var problemBeforeSubmit = State.CurrentProblem;
|
||||||
|
var result = await BattleEngine.SubmitAnswerAsync(choice);
|
||||||
|
|
||||||
|
if (result == CombatResultType.PlayerMissed)
|
||||||
|
{
|
||||||
|
_timer?.Dispose();
|
||||||
|
ExplanationProblem = problemBeforeSubmit;
|
||||||
|
ExplanationUserAnswer = choice;
|
||||||
|
IsExplanationFromDefense = false;
|
||||||
|
ShowExplanationModal = true;
|
||||||
|
StateHasChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await ProcessPostTurn();
|
await ProcessPostTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task DismissExplanation()
|
||||||
|
{
|
||||||
|
ShowExplanationModal = false;
|
||||||
|
|
||||||
|
if (IsExplanationFromDefense)
|
||||||
|
{
|
||||||
|
if (State.IsBattleOver)
|
||||||
|
{
|
||||||
|
StateHasChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleEngine.NextProblem();
|
||||||
|
StartTimer();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Start fresh timer for the defense phase problem
|
||||||
|
StartTimer();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ProcessPostTurn()
|
private async Task ProcessPostTurn()
|
||||||
{
|
{
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|
||||||
if (!State.IsBattleOver)
|
if (!State.IsBattleOver)
|
||||||
{
|
{
|
||||||
// Short delay to display attack/hurt animation before next question
|
await Task.Delay(900);
|
||||||
await Task.Delay(1000);
|
|
||||||
if (!State.IsDefensePhase)
|
if (!State.IsDefensePhase)
|
||||||
{
|
{
|
||||||
BattleEngine.NextProblem();
|
BattleEngine.NextProblem();
|
||||||
@@ -370,8 +533,10 @@
|
|||||||
|
|
||||||
private string GetTimerColorClass()
|
private string GetTimerColorClass()
|
||||||
{
|
{
|
||||||
if (RemainingTimeSeconds > 3.0) return "timer-green";
|
double limit = State.IsDefensePhase ? Config.Battle.DefenseTestDurationSeconds : Config.Battle.StandardTimeSeconds;
|
||||||
if (RemainingTimeSeconds > 1.5) return "timer-yellow";
|
double ratio = limit > 0 ? (RemainingTimeSeconds / limit) : 0;
|
||||||
|
if (ratio > 0.45) return "timer-green";
|
||||||
|
if (ratio > 0.20) return "timer-yellow";
|
||||||
return "timer-red";
|
return "timer-red";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +565,15 @@
|
|||||||
|
|
||||||
private async Task HandleKeyDown(KeyboardEventArgs e)
|
private async Task HandleKeyDown(KeyboardEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (ShowExplanationModal)
|
||||||
|
{
|
||||||
|
if (e.Key is "Enter" or " " or "Escape")
|
||||||
|
{
|
||||||
|
await DismissExplanation();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (State.IsBattleOver)
|
if (State.IsBattleOver)
|
||||||
{
|
{
|
||||||
if (e.Key == "Enter")
|
if (e.Key == "Enter")
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ public class GameConfig
|
|||||||
|
|
||||||
public class BattleConfig
|
public class BattleConfig
|
||||||
{
|
{
|
||||||
public double CriticalTimeSeconds { get; set; } = 3.0;
|
public double CriticalTimeSeconds { get; set; } = 4.0;
|
||||||
public double StandardTimeSeconds { get; set; } = 6.0;
|
public double StandardTimeSeconds { get; set; } = 10.0;
|
||||||
public double CriticalDamageMultiplier { get; set; } = 1.5;
|
public double CriticalDamageMultiplier { get; set; } = 1.5;
|
||||||
public double WeakDamageMultiplier { get; set; } = 0.5;
|
public double WeakDamageMultiplier { get; set; } = 0.5;
|
||||||
public double DefenseTestDurationSeconds { get; set; } = 5.0;
|
public double DefenseTestDurationSeconds { get; set; } = 16.0;
|
||||||
public int DefaultPlayerHp { get; set; } = 5;
|
public int DefaultPlayerHp { get; set; } = 5;
|
||||||
public int ComboStreakBonusDmg { get; set; } = 1;
|
public int ComboStreakBonusDmg { get; set; } = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public class MathProblem
|
|||||||
public string Operation { get; set; } = "+";
|
public string Operation { get; set; } = "+";
|
||||||
public string DisplayB { get; set; } = string.Empty;
|
public string DisplayB { get; set; } = string.Empty;
|
||||||
public string CorrectAnswer { get; set; } = string.Empty;
|
public string CorrectAnswer { get; set; } = string.Empty;
|
||||||
|
public string Explanation { get; set; } = string.Empty;
|
||||||
public List<string> Choices { get; set; } = new();
|
public List<string> Choices { get; set; } = new();
|
||||||
public string InputType { get; set; } = "DirectInput";
|
public string InputType { get; set; } = "DirectInput";
|
||||||
public bool IsDefenseTest { get; set; } = false;
|
public bool IsDefenseTest { get; set; } = false;
|
||||||
|
|||||||
@@ -51,24 +51,60 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<!-- FAIRYTALE LEVEL TRANSITION SCREEN -->
|
<!-- FAIRYTALE LEVEL TRANSITION SCREEN -->
|
||||||
@if (IsTransitioning)
|
@if (IsTransitioning && PendingLevel != null)
|
||||||
{
|
{
|
||||||
var hero = DataLoader.GetHero(Profile.SelectedHeroId) ?? DataLoader.Heroes.FirstOrDefault();
|
var hero = DataLoader.GetHero(Profile.SelectedHeroId) ?? DataLoader.Heroes.FirstOrDefault();
|
||||||
var heroAvatar = hero != null ? $"{hero.AssetFolder}_idle_p1.png" : "assets/images/heroes/knight_idle_p1.png";
|
var heroAvatar = hero != null ? $"{hero.AssetFolder}_idle_p1.png" : "assets/images/heroes/knight_idle_p1.png";
|
||||||
|
var enemyAvatar = $"{PendingLevel.Enemy.AssetFolder}_idle_p1.png";
|
||||||
|
var heroDisplayName = !string.IsNullOrWhiteSpace(Profile.Name) ? Profile.Name : (hero?.Name ?? "Hrdina");
|
||||||
|
|
||||||
<div class="transition-screen-overlay anim-fade-in">
|
<div class="transition-screen-overlay anim-fade-in">
|
||||||
<div class="transition-parchment-box anim-victory-modal-pop">
|
<div class="transition-parchment-box anim-victory-modal-pop">
|
||||||
<div class="transition-hero-marching">
|
<div class="transition-header">
|
||||||
<img src="@heroAvatar"
|
<span class="transition-badge">@(PendingLevel.IsBoss ? "👑 BOSS LEVEL" : "⚔️ NOVÁ VÝZVA")</span>
|
||||||
class="marching-hero-img anim-hero-march"
|
<h2 class="transition-title">@PendingLevel.Name</h2>
|
||||||
alt="Hrdina na ceste" />
|
|
||||||
</div>
|
</div>
|
||||||
<h2 class="transition-title">🗺️ Vstupuješ do novej oblasti...</h2>
|
|
||||||
<p class="transition-target">📍 @TransitionTargetText</p>
|
<div class="transition-faceoff-stage">
|
||||||
<div class="transition-sparkles">
|
<div class="faceoff-card hero-side">
|
||||||
<span class="sparkle">✨</span>
|
<div class="faceoff-avatar-pedestal">
|
||||||
<span class="sparkle">⭐</span>
|
<img src="@heroAvatar"
|
||||||
<span class="sparkle">✨</span>
|
class="faceoff-avatar-img anim-hero-march"
|
||||||
|
alt="@heroDisplayName" />
|
||||||
|
</div>
|
||||||
|
<span class="faceoff-name">@heroDisplayName</span>
|
||||||
|
<span class="faceoff-role">Udatný Počtár</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="faceoff-vs-pill">
|
||||||
|
<span class="vs-text">VS</span>
|
||||||
|
<span class="vs-swords">⚔️</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="faceoff-card enemy-side">
|
||||||
|
<div class="faceoff-avatar-pedestal">
|
||||||
|
<img src="@enemyAvatar"
|
||||||
|
class="faceoff-avatar-img anim-enemy-idle"
|
||||||
|
alt="@PendingLevel.Enemy.Name" />
|
||||||
|
</div>
|
||||||
|
<span class="faceoff-name">@PendingLevel.Enemy.Name</span>
|
||||||
|
<span class="faceoff-hp-badge">❤️ @PendingLevel.Enemy.MaxHp HP</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="transition-details-card">
|
||||||
|
<p class="transition-math-info">
|
||||||
|
🧠 <strong>Úloha:</strong> @(PendingLevel.IsBoss ? "Záverečná skúška vedomostí!" : "Vyrieš matematické príklady a poraz protivníka!")
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="transition-action-buttons">
|
||||||
|
<button class="btn-grand-celebration btn-transition-start" @onclick="ConfirmAndStartPendingLevel">
|
||||||
|
⚔️ VSTÚPIŤ DO BOJA ➜
|
||||||
|
</button>
|
||||||
|
<button class="btn-secondary-celebration" @onclick="CancelPendingLevel">
|
||||||
|
🗺️ Späť na mapu
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -89,9 +125,9 @@
|
|||||||
private ScreenType CurrentScreen { get; set; } = ScreenType.Loading;
|
private ScreenType CurrentScreen { get; set; } = ScreenType.Loading;
|
||||||
private PlayerProfile Profile { get; set; } = new();
|
private PlayerProfile Profile { get; set; } = new();
|
||||||
private Level? SelectedLevel { get; set; }
|
private Level? SelectedLevel { get; set; }
|
||||||
|
private Level? PendingLevel { get; set; }
|
||||||
|
|
||||||
private bool IsTransitioning { get; set; } = false;
|
private bool IsTransitioning { get; set; } = false;
|
||||||
private string TransitionTargetText { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
@@ -121,19 +157,32 @@
|
|||||||
await Storage.SaveProfileAsync(Profile);
|
await Storage.SaveProfileAsync(Profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleLevelSelected(Level level)
|
private void HandleLevelSelected(Level level)
|
||||||
{
|
{
|
||||||
TransitionTargetText = $"{level.Name} (Protivník: {level.Enemy.Name})";
|
PendingLevel = level;
|
||||||
IsTransitioning = true;
|
IsTransitioning = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
await Task.Delay(850);
|
private void ConfirmAndStartPendingLevel()
|
||||||
|
{
|
||||||
SelectedLevel = level;
|
if (PendingLevel != null)
|
||||||
|
{
|
||||||
|
SelectedLevel = PendingLevel;
|
||||||
|
PendingLevel = null;
|
||||||
CurrentScreen = ScreenType.Battle;
|
CurrentScreen = ScreenType.Battle;
|
||||||
IsTransitioning = false;
|
IsTransitioning = false;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelPendingLevel()
|
||||||
|
{
|
||||||
|
PendingLevel = null;
|
||||||
|
IsTransitioning = false;
|
||||||
|
CurrentScreen = ScreenType.WorldMap;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task HandleLevelCompleted(Level completedLevel)
|
private async Task HandleLevelCompleted(Level completedLevel)
|
||||||
{
|
{
|
||||||
@@ -150,7 +199,7 @@
|
|||||||
await Storage.SaveProfileAsync(Profile);
|
await Storage.SaveProfileAsync(Profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
await HandleLevelSelected(nextLevel);
|
HandleLevelSelected(nextLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnlockNextLevel(Level completedLevel)
|
private void UnlockNextLevel(Level completedLevel)
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = b.ToString(),
|
DisplayB = b.ToString(),
|
||||||
CorrectAnswer = sum.ToString(),
|
CorrectAnswer = sum.ToString(),
|
||||||
QuestionText = $"{a} + {b} = ?",
|
QuestionText = $"{a} + {b} = ?",
|
||||||
|
Explanation = GetAdditionExplanation(a, b, sum),
|
||||||
InputType = config.InputType
|
InputType = config.InputType
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -118,6 +119,36 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
return problem;
|
return problem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetAdditionExplanation(int a, int b, int sum)
|
||||||
|
{
|
||||||
|
if (sum <= 10)
|
||||||
|
{
|
||||||
|
return $"Sčítanie: k číslu {a} pridáme {b} a dostaneme {sum}.";
|
||||||
|
}
|
||||||
|
if (a < 10 && b < 10 && sum > 10)
|
||||||
|
{
|
||||||
|
int toTen = 10 - a;
|
||||||
|
int rem = b - toTen;
|
||||||
|
return $"Tip: Rozlož si druhé číslo {b} na {toTen} a {rem}. Najprv doplň do desiatky ({a} + {toTen} = 10) a potom pripočítaj zvyšok (10 + {rem} = {sum})!";
|
||||||
|
}
|
||||||
|
if (a >= 10 && b < 10)
|
||||||
|
{
|
||||||
|
int unitsA = a % 10;
|
||||||
|
if (unitsA + b < 10)
|
||||||
|
{
|
||||||
|
return $"Sčítaj jednotky: {unitsA} + {b} = {unitsA + b}. Desiatky ({a / 10 * 10}) opíšeme: výsledok je {sum}.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int toNextTen = 10 - unitsA;
|
||||||
|
int rem = b - toNextTen;
|
||||||
|
int nextTen = ((a / 10) + 1) * 10;
|
||||||
|
return $"Doplň do celej desiatky: {a} + {toNextTen} = {nextTen}, a potom pripočítaj zvyšných {rem}: {nextTen} + {rem} = {sum}!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $"Sčítanie: {a} + {b} = {sum}.";
|
||||||
|
}
|
||||||
|
|
||||||
private MathProblem GenerateSubtraction(MathConfig config, int hpPhase)
|
private MathProblem GenerateSubtraction(MathConfig config, int hpPhase)
|
||||||
{
|
{
|
||||||
// Phase 4: Possibility of 3-term mixed chain
|
// Phase 4: Possibility of 3-term mixed chain
|
||||||
@@ -135,6 +166,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = "",
|
DisplayB = "",
|
||||||
CorrectAnswer = res3.ToString(),
|
CorrectAnswer = res3.ToString(),
|
||||||
QuestionText = $"{a3} - {b3} + {c3} = ?",
|
QuestionText = $"{a3} - {b3} + {c3} = ?",
|
||||||
|
Explanation = $"Počítaj postupne zľava doprava: najprv {a3} - {b3} = {a3 - b3}, a potom {a3 - b3} + {c3} = {res3}.",
|
||||||
InputType = config.InputType
|
InputType = config.InputType
|
||||||
};
|
};
|
||||||
if (config.InputType == "MultipleChoice")
|
if (config.InputType == "MultipleChoice")
|
||||||
@@ -184,6 +216,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = b.ToString(),
|
DisplayB = b.ToString(),
|
||||||
CorrectAnswer = diff.ToString(),
|
CorrectAnswer = diff.ToString(),
|
||||||
QuestionText = $"{a} - {b} = ?",
|
QuestionText = $"{a} - {b} = ?",
|
||||||
|
Explanation = GetSubtractionExplanation(a, b, diff),
|
||||||
InputType = config.InputType
|
InputType = config.InputType
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -195,6 +228,42 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
return problem;
|
return problem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetSubtractionExplanation(int a, int b, int diff)
|
||||||
|
{
|
||||||
|
if (a <= 10)
|
||||||
|
{
|
||||||
|
return $"Odčítanie: od čísla {a} uberieme {b} a zostane nám {diff}.";
|
||||||
|
}
|
||||||
|
if (a > 10 && a <= 20 && b < 10)
|
||||||
|
{
|
||||||
|
int toTen = a - 10;
|
||||||
|
if (b <= toTen)
|
||||||
|
{
|
||||||
|
return $"Odčítaj jednotky: {toTen} - {b} = {toTen - b}. K desiatke pridáme {toTen - b} a máme {diff}.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int rem = b - toTen;
|
||||||
|
return $"Tip: Rozlož si {b} na {toTen} a {rem}. Najprv odčítaj po desiatku ({a} - {toTen} = 10) a potom uber zvyšok (10 - {rem} = {diff})!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a > 20 && b < 10)
|
||||||
|
{
|
||||||
|
int unitsA = a % 10;
|
||||||
|
if (unitsA >= b)
|
||||||
|
{
|
||||||
|
return $"Odčítaj jednotky: {unitsA} - {b} = {unitsA - b}. Desiatky ({a / 10 * 10}) zostávajú: výsledok je {diff}.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int rem = b - unitsA;
|
||||||
|
int prevTen = (a / 10) * 10;
|
||||||
|
return $"Odčítaj najprv {unitsA} do desiatky ({a} - {unitsA} = {prevTen}) a potom odčítaj zvyšných {rem} ({prevTen} - {rem} = {diff})!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $"Odčítanie: {a} - {b} = {diff}.";
|
||||||
|
}
|
||||||
|
|
||||||
private MathProblem GenerateMultiplication(MathConfig config, int hpPhase)
|
private MathProblem GenerateMultiplication(MathConfig config, int hpPhase)
|
||||||
{
|
{
|
||||||
var factors = config.Factors != null && config.Factors.Count > 0
|
var factors = config.Factors != null && config.Factors.Count > 0
|
||||||
@@ -232,6 +301,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = factorB.ToString(),
|
DisplayB = factorB.ToString(),
|
||||||
CorrectAnswer = product.ToString(),
|
CorrectAnswer = product.ToString(),
|
||||||
QuestionText = $"{factorA} × {factorB} = ?",
|
QuestionText = $"{factorA} × {factorB} = ?",
|
||||||
|
Explanation = $"Násobenie: {factorA} × {factorB} znamená {factorB}-krát sčítať číslo {factorA}. Výsledok je {product}.",
|
||||||
InputType = config.InputType
|
InputType = config.InputType
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -280,6 +350,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = divisor.ToString(),
|
DisplayB = divisor.ToString(),
|
||||||
CorrectAnswer = result.ToString(),
|
CorrectAnswer = result.ToString(),
|
||||||
QuestionText = $"{dividend} ÷ {divisor} = ?",
|
QuestionText = $"{dividend} ÷ {divisor} = ?",
|
||||||
|
Explanation = $"Delenie: pýtame sa, koľkokrát sa {divisor} zmestí do {dividend}. Keďže {divisor} × {result} = {dividend}, výsledok je {result}!",
|
||||||
InputType = config.InputType
|
InputType = config.InputType
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -321,6 +392,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
string comp = leftVal < rightVal ? "<" : (leftVal > rightVal ? ">" : "=");
|
string comp = leftVal < rightVal ? "<" : (leftVal > rightVal ? ">" : "=");
|
||||||
|
string compWord = leftVal < rightVal ? "menšie ako" : (leftVal > rightVal ? "väčšie ako" : "rovné");
|
||||||
|
|
||||||
return new MathProblem
|
return new MathProblem
|
||||||
{
|
{
|
||||||
@@ -329,6 +401,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = rightStr,
|
DisplayB = rightStr,
|
||||||
CorrectAnswer = comp,
|
CorrectAnswer = comp,
|
||||||
QuestionText = $"{leftStr} ? {rightStr}",
|
QuestionText = $"{leftStr} ? {rightStr}",
|
||||||
|
Explanation = $"Vypočítajme obe strany: ( {leftStr} = {leftVal} ) a ( {rightStr} = {rightVal} ). Keďže {leftVal} je {compWord} {rightVal}, správny znak je {comp}.",
|
||||||
InputType = "MultipleChoice",
|
InputType = "MultipleChoice",
|
||||||
Choices = new List<string> { "<", "=", ">" }
|
Choices = new List<string> { "<", "=", ">" }
|
||||||
};
|
};
|
||||||
@@ -343,6 +416,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
string answer = x < y ? "<" : (x > y ? ">" : "=");
|
string answer = x < y ? "<" : (x > y ? ">" : "=");
|
||||||
|
string word = x < y ? "menšie ako" : (x > y ? "väčšie ako" : "rovné");
|
||||||
|
|
||||||
return new MathProblem
|
return new MathProblem
|
||||||
{
|
{
|
||||||
@@ -351,6 +425,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = y.ToString(),
|
DisplayB = y.ToString(),
|
||||||
CorrectAnswer = answer,
|
CorrectAnswer = answer,
|
||||||
QuestionText = $"{x} ? {y}",
|
QuestionText = $"{x} ? {y}",
|
||||||
|
Explanation = $"Porovnanie: Číslo {x} je {word} číslu {y}, preto platí {x} {answer} {y}.",
|
||||||
InputType = "MultipleChoice",
|
InputType = "MultipleChoice",
|
||||||
Choices = new List<string> { "<", "=", ">" }
|
Choices = new List<string> { "<", "=", ">" }
|
||||||
};
|
};
|
||||||
@@ -392,11 +467,10 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
|
|
||||||
private MathProblem GenerateChallengingComparisonDefense(MathConfig config)
|
private MathProblem GenerateChallengingComparisonDefense(MathConfig config)
|
||||||
{
|
{
|
||||||
// Compare expressions: (a + b) ? (c - d)
|
|
||||||
int valLeft, valRight;
|
int valLeft, valRight;
|
||||||
string exprLeft, exprRight;
|
string exprLeft, exprRight;
|
||||||
|
|
||||||
if (config.MaxA > 100) // Grade 3 large numbers
|
if (config.MaxA > 100)
|
||||||
{
|
{
|
||||||
int a = _rand.Next(10, 50) * 10;
|
int a = _rand.Next(10, 50) * 10;
|
||||||
int b = _rand.Next(5, 30) * 10;
|
int b = _rand.Next(5, 30) * 10;
|
||||||
@@ -408,7 +482,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
valRight = c - d;
|
valRight = c - d;
|
||||||
exprRight = $"{c} - {d}";
|
exprRight = $"{c} - {d}";
|
||||||
}
|
}
|
||||||
else if (config.MaxSum > 20 || config.MaxA > 20) // Grade 2
|
else if (config.MaxSum > 20 || config.MaxA > 20)
|
||||||
{
|
{
|
||||||
int a = _rand.Next(10, 45);
|
int a = _rand.Next(10, 45);
|
||||||
int b = _rand.Next(5, 30);
|
int b = _rand.Next(5, 30);
|
||||||
@@ -420,7 +494,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
valRight = c - d;
|
valRight = c - d;
|
||||||
exprRight = $"{c} - {d}";
|
exprRight = $"{c} - {d}";
|
||||||
}
|
}
|
||||||
else // Grade 1
|
else
|
||||||
{
|
{
|
||||||
int a = _rand.Next(2, 9);
|
int a = _rand.Next(2, 9);
|
||||||
int b = _rand.Next(2, 9);
|
int b = _rand.Next(2, 9);
|
||||||
@@ -433,7 +507,6 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
exprRight = $"{c} - {d}";
|
exprRight = $"{c} - {d}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sometimes create equal expressions
|
|
||||||
if (_rand.Next(3) == 0)
|
if (_rand.Next(3) == 0)
|
||||||
{
|
{
|
||||||
valRight = valLeft;
|
valRight = valLeft;
|
||||||
@@ -442,6 +515,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
string answer = valLeft < valRight ? "<" : (valLeft > valRight ? ">" : "=");
|
string answer = valLeft < valRight ? "<" : (valLeft > valRight ? ">" : "=");
|
||||||
|
string compWord = valLeft < valRight ? "menšie ako" : (valLeft > valRight ? "väčšie ako" : "rovné");
|
||||||
|
|
||||||
return new MathProblem
|
return new MathProblem
|
||||||
{
|
{
|
||||||
@@ -450,6 +524,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = exprRight,
|
DisplayB = exprRight,
|
||||||
CorrectAnswer = answer,
|
CorrectAnswer = answer,
|
||||||
QuestionText = $"Porovnaj výrazy:\n( {exprLeft} ) ? ( {exprRight} )",
|
QuestionText = $"Porovnaj výrazy:\n( {exprLeft} ) ? ( {exprRight} )",
|
||||||
|
Explanation = $"Ľavá strana: {exprLeft} = {valLeft}. Pravá strana: {exprRight} = {valRight}. Keďže {valLeft} je {compWord} {valRight}, správny znak je {answer}.",
|
||||||
InputType = "MultipleChoice",
|
InputType = "MultipleChoice",
|
||||||
Choices = new List<string> { "<", "=", ">" },
|
Choices = new List<string> { "<", "=", ">" },
|
||||||
IsDefenseTest = true
|
IsDefenseTest = true
|
||||||
@@ -461,8 +536,9 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
bool isAdd = _rand.Next(2) == 0;
|
bool isAdd = _rand.Next(2) == 0;
|
||||||
int missing, known, result;
|
int missing, known, result;
|
||||||
string equation;
|
string equation;
|
||||||
|
string explanation;
|
||||||
|
|
||||||
if (config.MaxSum > 100 || config.MaxA > 100) // Grade 3
|
if (config.MaxSum > 100 || config.MaxA > 100)
|
||||||
{
|
{
|
||||||
known = _rand.Next(10, 50) * 10;
|
known = _rand.Next(10, 50) * 10;
|
||||||
missing = _rand.Next(10, 40) * 10;
|
missing = _rand.Next(10, 40) * 10;
|
||||||
@@ -470,15 +546,17 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
{
|
{
|
||||||
result = known + missing;
|
result = known + missing;
|
||||||
equation = _rand.Next(2) == 0 ? $"{known} + ❓ = {result}" : $"❓ + {known} = {result}";
|
equation = _rand.Next(2) == 0 ? $"{known} + ❓ = {result}" : $"❓ + {known} = {result}";
|
||||||
|
explanation = $"Neznáme číslo nájdeme odčítaním: {result} - {known} = {missing}.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = known;
|
result = known;
|
||||||
int total = known + missing;
|
int total = known + missing;
|
||||||
equation = $"{total} - ❓ = {result}";
|
equation = $"{total} - ❓ = {result}";
|
||||||
|
explanation = $"Neznáme číslo zistíme odčítaním výsledku od celku: {total} - {result} = {missing}.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (config.MaxSum > 20 || config.MaxA > 20) // Grade 2
|
else if (config.MaxSum > 20 || config.MaxA > 20)
|
||||||
{
|
{
|
||||||
known = _rand.Next(12, 50);
|
known = _rand.Next(12, 50);
|
||||||
missing = _rand.Next(8, 35);
|
missing = _rand.Next(8, 35);
|
||||||
@@ -486,15 +564,17 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
{
|
{
|
||||||
result = known + missing;
|
result = known + missing;
|
||||||
equation = _rand.Next(2) == 0 ? $"{known} + ❓ = {result}" : $"❓ + {known} = {result}";
|
equation = _rand.Next(2) == 0 ? $"{known} + ❓ = {result}" : $"❓ + {known} = {result}";
|
||||||
|
explanation = $"Neznáme číslo nájdeme odčítaním: {result} - {known} = {missing}.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = known;
|
result = known;
|
||||||
int total = known + missing;
|
int total = known + missing;
|
||||||
equation = $"{total} - ❓ = {result}";
|
equation = $"{total} - ❓ = {result}";
|
||||||
|
explanation = $"Neznáme číslo zistíme odčítaním výsledku od celku: {total} - {result} = {missing}.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Grade 1
|
else
|
||||||
{
|
{
|
||||||
known = _rand.Next(3, 10);
|
known = _rand.Next(3, 10);
|
||||||
missing = _rand.Next(3, 10);
|
missing = _rand.Next(3, 10);
|
||||||
@@ -502,12 +582,14 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
{
|
{
|
||||||
result = known + missing;
|
result = known + missing;
|
||||||
equation = _rand.Next(2) == 0 ? $"{known} + ❓ = {result}" : $"❓ + {known} = {result}";
|
equation = _rand.Next(2) == 0 ? $"{known} + ❓ = {result}" : $"❓ + {known} = {result}";
|
||||||
|
explanation = $"Neznáme číslo nájdeme odčítaním: {result} - {known} = {missing}.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = known;
|
result = known;
|
||||||
int total = known + missing;
|
int total = known + missing;
|
||||||
equation = $"{total} - ❓ = {result}";
|
equation = $"{total} - ❓ = {result}";
|
||||||
|
explanation = $"Neznáme číslo zistíme odčítaním: {total} - {result} = {missing}.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,6 +600,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = "",
|
DisplayB = "",
|
||||||
CorrectAnswer = missing.ToString(),
|
CorrectAnswer = missing.ToString(),
|
||||||
QuestionText = $"Doplň chýbajúce číslo ❓:\n{equation}",
|
QuestionText = $"Doplň chýbajúce číslo ❓:\n{equation}",
|
||||||
|
Explanation = explanation,
|
||||||
InputType = "MultipleChoice",
|
InputType = "MultipleChoice",
|
||||||
Choices = GenerateNumericChoices(missing, 1, 1000),
|
Choices = GenerateNumericChoices(missing, 1, 1000),
|
||||||
IsDefenseTest = true
|
IsDefenseTest = true
|
||||||
@@ -529,7 +612,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
int a, b, c, result;
|
int a, b, c, result;
|
||||||
string expr;
|
string expr;
|
||||||
|
|
||||||
if (config.MaxSum > 100 || config.MaxA > 100) // Grade 3
|
if (config.MaxSum > 100 || config.MaxA > 100)
|
||||||
{
|
{
|
||||||
a = _rand.Next(15, 45) * 10;
|
a = _rand.Next(15, 45) * 10;
|
||||||
b = _rand.Next(10, 30) * 10;
|
b = _rand.Next(10, 30) * 10;
|
||||||
@@ -537,7 +620,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
result = a + b - c;
|
result = a + b - c;
|
||||||
expr = $"{a} + {b} - {c}";
|
expr = $"{a} + {b} - {c}";
|
||||||
}
|
}
|
||||||
else if (config.MaxSum > 20 || config.MaxA > 20) // Grade 2
|
else if (config.MaxSum > 20 || config.MaxA > 20)
|
||||||
{
|
{
|
||||||
a = _rand.Next(15, 50);
|
a = _rand.Next(15, 50);
|
||||||
b = _rand.Next(10, 30);
|
b = _rand.Next(10, 30);
|
||||||
@@ -545,7 +628,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
result = a + b - c;
|
result = a + b - c;
|
||||||
expr = $"{a} + {b} - {c}";
|
expr = $"{a} + {b} - {c}";
|
||||||
}
|
}
|
||||||
else // Grade 1
|
else
|
||||||
{
|
{
|
||||||
a = _rand.Next(4, 9);
|
a = _rand.Next(4, 9);
|
||||||
b = _rand.Next(3, 8);
|
b = _rand.Next(3, 8);
|
||||||
@@ -561,6 +644,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = "",
|
DisplayB = "",
|
||||||
CorrectAnswer = result.ToString(),
|
CorrectAnswer = result.ToString(),
|
||||||
QuestionText = $"Vypočítaj trojčlenný reťazec:\n{expr} = ?",
|
QuestionText = $"Vypočítaj trojčlenný reťazec:\n{expr} = ?",
|
||||||
|
Explanation = $"Počítaj po krokoch zľava doprava: najprv {a} + {b} = {a + b}, a potom {a + b} - {c} = {result}.",
|
||||||
InputType = "MultipleChoice",
|
InputType = "MultipleChoice",
|
||||||
Choices = GenerateNumericChoices(result, 0, 1000),
|
Choices = GenerateNumericChoices(result, 0, 1000),
|
||||||
IsDefenseTest = true
|
IsDefenseTest = true
|
||||||
@@ -585,6 +669,9 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
string equation = isDiv
|
string equation = isDiv
|
||||||
? $"{product} ÷ ❓ = {factorA}"
|
? $"{product} ÷ ❓ = {factorA}"
|
||||||
: (_rand.Next(2) == 0 ? $"{factorA} × ❓ = {product}" : $"❓ × {factorA} = {product}");
|
: (_rand.Next(2) == 0 ? $"{factorA} × ❓ = {product}" : $"❓ × {factorA} = {product}");
|
||||||
|
string explanation = isDiv
|
||||||
|
? $"Neznámeho deliteľa nájdeme delením: {product} ÷ {factorA} = {missing}."
|
||||||
|
: $"Neznámeho činiteľa nájdeme delením: {product} ÷ {factorA} = {missing}.";
|
||||||
|
|
||||||
return new MathProblem
|
return new MathProblem
|
||||||
{
|
{
|
||||||
@@ -593,6 +680,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = "",
|
DisplayB = "",
|
||||||
CorrectAnswer = missing.ToString(),
|
CorrectAnswer = missing.ToString(),
|
||||||
QuestionText = $"Nájdi neznáme číslo ❓:\n{equation}",
|
QuestionText = $"Nájdi neznáme číslo ❓:\n{equation}",
|
||||||
|
Explanation = explanation,
|
||||||
InputType = "MultipleChoice",
|
InputType = "MultipleChoice",
|
||||||
Choices = GenerateNumericChoices(missing, 1, 10),
|
Choices = GenerateNumericChoices(missing, 1, 10),
|
||||||
IsDefenseTest = true
|
IsDefenseTest = true
|
||||||
@@ -617,6 +705,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = "",
|
DisplayB = "",
|
||||||
CorrectAnswer = result.ToString(),
|
CorrectAnswer = result.ToString(),
|
||||||
QuestionText = $"Kombinovaný výpočet (najprv násob!):\n{expr} = ?",
|
QuestionText = $"Kombinovaný výpočet (najprv násob!):\n{expr} = ?",
|
||||||
|
Explanation = $"Násobenie má vždy prednosť! Najprv: {f1} × {f2} = {prod}, a potom: {prod} {(isSub ? "-" : "+")} {add} = {result}.",
|
||||||
InputType = "MultipleChoice",
|
InputType = "MultipleChoice",
|
||||||
Choices = GenerateNumericChoices(result, 1, 100),
|
Choices = GenerateNumericChoices(result, 1, 100),
|
||||||
IsDefenseTest = true
|
IsDefenseTest = true
|
||||||
@@ -627,6 +716,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
{
|
{
|
||||||
bool isCorrect = _rand.Next(2) == 0;
|
bool isCorrect = _rand.Next(2) == 0;
|
||||||
string equation;
|
string equation;
|
||||||
|
string explanation;
|
||||||
|
|
||||||
if (isMult)
|
if (isMult)
|
||||||
{
|
{
|
||||||
@@ -636,6 +726,9 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
int displayed = isCorrect ? prod : (prod + (_rand.Next(2) == 0 ? _rand.Next(1, 4) : -_rand.Next(1, 4)));
|
int displayed = isCorrect ? prod : (prod + (_rand.Next(2) == 0 ? _rand.Next(1, 4) : -_rand.Next(1, 4)));
|
||||||
if (displayed <= 0) displayed = prod + 2;
|
if (displayed <= 0) displayed = prod + 2;
|
||||||
equation = $"{a} × {b} = {displayed}";
|
equation = $"{a} × {b} = {displayed}";
|
||||||
|
explanation = isCorrect
|
||||||
|
? $"Rovnica {equation} je správna, pretože {a} × {b} sa skutočne rovná {prod}."
|
||||||
|
: $"Rovnica {equation} je nesprávna! Správny výsledok {a} × {b} je {prod} (nie {displayed}).";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -646,6 +739,9 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
int displayed = isCorrect ? sum : (sum + offset);
|
int displayed = isCorrect ? sum : (sum + offset);
|
||||||
if (displayed <= 0) displayed = sum + 2;
|
if (displayed <= 0) displayed = sum + 2;
|
||||||
equation = $"{a} + {b} = {displayed}";
|
equation = $"{a} + {b} = {displayed}";
|
||||||
|
explanation = isCorrect
|
||||||
|
? $"Rovnica {equation} je správna, pretože {a} + {b} sa skutočne rovná {sum}."
|
||||||
|
: $"Rovnica {equation} je nesprávna! Správny výsledok {a} + {b} je {sum} (nie {displayed}).";
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MathProblem
|
return new MathProblem
|
||||||
@@ -655,6 +751,7 @@ public class MathProblemGenerator : IMathProblemGenerator
|
|||||||
DisplayB = "",
|
DisplayB = "",
|
||||||
CorrectAnswer = isCorrect ? "ÁNO" : "NIE",
|
CorrectAnswer = isCorrect ? "ÁNO" : "NIE",
|
||||||
QuestionText = $"Je táto rovnica správna?\n{equation}",
|
QuestionText = $"Je táto rovnica správna?\n{equation}",
|
||||||
|
Explanation = explanation,
|
||||||
InputType = "MultipleChoice",
|
InputType = "MultipleChoice",
|
||||||
Choices = new List<string> { "ÁNO", "NIE" },
|
Choices = new List<string> { "ÁNO", "NIE" },
|
||||||
IsDefenseTest = true
|
IsDefenseTest = true
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 994 KiB |
|
After Width: | Height: | Size: 999 KiB |
|
After Width: | Height: | Size: 1007 KiB |
|
After Width: | Height: | Size: 991 KiB |
|
After Width: | Height: | Size: 837 KiB |
|
After Width: | Height: | Size: 841 KiB |
|
After Width: | Height: | Size: 848 KiB |
|
After Width: | Height: | Size: 835 KiB |
|
After Width: | Height: | Size: 802 KiB |
|
After Width: | Height: | Size: 805 KiB |
|
After Width: | Height: | Size: 810 KiB |
|
After Width: | Height: | Size: 797 KiB |
|
After Width: | Height: | Size: 895 KiB |
|
After Width: | Height: | Size: 901 KiB |
|
After Width: | Height: | Size: 915 KiB |
|
After Width: | Height: | Size: 903 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 959 KiB |
|
After Width: | Height: | Size: 968 KiB |
|
After Width: | Height: | Size: 966 KiB |
|
After Width: | Height: | Size: 914 KiB |
|
After Width: | Height: | Size: 822 KiB |
|
After Width: | Height: | Size: 829 KiB |
|
After Width: | Height: | Size: 826 KiB |
|
After Width: | Height: | Size: 784 KiB |
|
After Width: | Height: | Size: 766 KiB |
|
After Width: | Height: | Size: 771 KiB |
|
After Width: | Height: | Size: 770 KiB |
|
After Width: | Height: | Size: 730 KiB |
|
After Width: | Height: | Size: 851 KiB |
|
After Width: | Height: | Size: 861 KiB |
|
After Width: | Height: | Size: 870 KiB |
|
After Width: | Height: | Size: 844 KiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |