Skip to content

Commit

Permalink
Adds creditable hints (#334)
Browse files Browse the repository at this point in the history
* Add creditable hints and improve layout

* Centralize discount code into GetAllHints and HintWithState
  • Loading branch information
bruceleban authored and tabascq committed Mar 28, 2019
1 parent 56083e2 commit f27360f
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 38 deletions.
4 changes: 4 additions & 0 deletions ServerCore/Pages/Hints/Edit.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
<a asp-page="./Index">Cancel</a>
</div>

<div>
A negative hint cost is treated as the equivalent positive cost
and is credited to the cost of other hints.
</div>
<hr />
<div class="row">
<div class="col-md-4">
Expand Down
115 changes: 87 additions & 28 deletions ServerCore/Pages/Teams/Hints.cshtml
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
@page "/{eventId}/{eventRole}/Teams/{teamId}/Hints/{puzzleId}"
@model ServerCore.Pages.Teams.HintsModel

<style>
button:disabled {
color: #aaaaaa;
}
/*
* Strikeout style for hints
*/
.strike1 {
position: relative;
}
.strike1:before {
color: red;
position: absolute;
content: "";
left: 0;
top: 50%;
right: 0;
border-top: 1px solid;
border-color: inherit;
-webkit-transform: rotate(-35deg);
-moz-transform: rotate(-35deg);
-ms-transform: rotate(-35deg);
-o-transform: rotate(-35deg);
transform: rotate(-35deg);
}
.strike2:after {
color: red;
position: absolute;
content: "";
left: 0;
top: 50%;
right: 0;
border-top: 1px solid;
border-color: inherit;
-webkit-transform: rotate(35deg);
-moz-transform: rotate(35deg);
-ms-transform: rotate(35deg);
-o-transform: rotate(35deg);
transform: rotate(35deg);
}
</style>
@{
ViewData["Title"] = "Hints";
ViewData["AdminRoute"] = "/Puzzles/Index";
Expand All @@ -14,7 +56,16 @@
<a asp-page="/Teams/Play">Back to puzzle list</a>
</div>

You have @Model.Team.HintCoinCount hint ticket(s).
You have <b>
@if (Model.Team.HintCoinCount > 0)
{
@Model.Team.HintCoinCount
}
else
{
<text>no</text>
}
</b> hint tickets.

<table class="table">
<thead>
Expand All @@ -23,10 +74,7 @@ You have @Model.Team.HintCoinCount hint ticket(s).
@Html.DisplayNameFor(model => model.Hints[0].Hint.Description)
</th>
<th>
@Html.DisplayNameFor(model => model.Hints[0].Hint.Content)
</th>
<th>
@Html.DisplayNameFor(model => model.Hints[0].Hint.Cost)
<text>Hint</text>
</th>
<th></th>
<th></th>
Expand All @@ -44,41 +92,52 @@ You have @Model.Team.HintCoinCount hint ticket(s).
{
@Html.DisplayFor(modelItem => hint.Hint.Content)
}
</td>
<td>
@if (!hint.IsUnlocked)
else
{
if (hint.Hint.Cost == 0)
{
<text>FREE</text>
}
else
<b>Cost:</b>
if (hint.AdjustedCost < hint.BaseCost)
{
@Html.DisplayFor(modelItem => hint.Hint.Cost)
<span class="strike1 strike2">&nbsp;@hint.BaseCost&nbsp;</span>
}
}
</td>
<td>
@if (!hint.IsUnlocked)
{
<form method="post">
@if (Model.Team.HintCoinCount >= hint.Hint.Cost)
if (hint.AdjustedCost == 0)
{
<button type="submit" asp-route-hintId="@hint.Hint.Id" asp-route-teamId="@Model.Team.ID" asp-route-puzzleId="@Model.PuzzleID" asp-page-handler="Unlock" onclick="return confirm('Are you sure you want to spend @hint.Hint.Cost tickets to find out &quot;@hint.Hint.Description&quot;?')">Unlock</button>
<text>FREE</text>
}
else
{
<button type="submit" asp-page-handler="Unlock" disabled>Unlock</button>
@hint.AdjustedCost
}
</form>
}
</td>
<td>
@if (Model.Team.HintCoinCount < hint.Hint.Cost)

@if (!hint.IsUnlocked)
{
<div>@(hint.Hint.Cost - Model.Team.HintCoinCount) more ticket(s) required</div>
<form method="post" style="display:inline-block">
@if (Model.Team.HintCoinCount >= hint.AdjustedCost)
{
<button type="submit" asp-route-hintId="@hint.Hint.Id"
asp-route-teamId="@Model.Team.ID"
asp-route-puzzleId="@Model.PuzzleID"
asp-page-handler="Unlock"
onclick="return confirm('Are you sure you want to spend @hint.AdjustedCost tickets to find out &quot;@hint.Hint.Description&quot;?')"
style="margin-left: 5px; margin-right: 5px;">Unlock</button>
}
else
{
<button type="submit" disabled
style="margin-left: 5px; margin-right: 5px;">Unlock</button>
if (hint.AdjustedCost - Model.Team.HintCoinCount == 1)
{
<text>You need 1 more ticket to unlock.</text>
}
else
{
<text>You need @(hint.AdjustedCost - Model.Team.HintCoinCount) more tickets to unlock.</text>
}
}
</form>
}
</td>
<td></td>
</tr>
}
</tbody>
Expand Down
36 changes: 26 additions & 10 deletions ServerCore/Pages/Teams/Hints.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ public class HintWithState
{
public Hint Hint { get; set; }
public bool IsUnlocked { get; set; }
public int Discount { get; set; }

public int BaseCost { get { return Math.Abs(Hint.Cost); } }
public int AdjustedCost { get { return Math.Max(0, Math.Abs(Hint.Cost) + Discount); } }
}

public IList<HintWithState> Hints { get; set; }
Expand All @@ -47,17 +51,27 @@ public async Task<IActionResult> OnGetAsync(int puzzleId, int teamId)
return Page();
}

private async Task<IList<HintWithState>> GetAllHints(int puzzleId, int teamId)
{
Hints = await (from Hint hint in _context.Hints
join HintStatePerTeam state in _context.HintStatePerTeam on hint.Id equals state.HintID
where state.TeamID == teamId && hint.Puzzle.ID == puzzleId
orderby hint.DisplayOrder, hint.Description
select new HintWithState { Hint = hint, IsUnlocked = state.IsUnlocked }).ToListAsync();

int discount = Hints.Min(hws => (hws.IsUnlocked && hws.Hint.Cost < 0) ? hws.Hint.Cost : 0);
foreach (HintWithState hint in Hints) {
hint.Discount = discount;
}
return Hints;
}

private async Task PopulateUI(int puzzleId, int teamId)
{
PuzzleName = await (from Puzzle in _context.Puzzles
where Puzzle.ID == puzzleId
select Puzzle.Name).FirstOrDefaultAsync();
Hints = await
(from Hint hint in _context.Hints
join HintStatePerTeam state in _context.HintStatePerTeam on hint.Id equals state.HintID
where state.TeamID == teamId && hint.Puzzle.ID == puzzleId
orderby hint.DisplayOrder, hint.Description
select new HintWithState { Hint = hint, IsUnlocked = state.IsUnlocked }).ToListAsync();
Hints = await GetAllHints(puzzleId, teamId);
}

public async Task<IActionResult> OnPostUnlockAsync(int hintID, int puzzleId, int teamId)
Expand Down Expand Up @@ -88,15 +102,17 @@ public async Task<IActionResult> OnPostUnlockAsync(int hintID, int puzzleId, int

if (!state.IsUnlocked)
{
int cost = hint.Cost;
if (Team.HintCoinCount < cost)
Hints = await GetAllHints(puzzleId, teamId);
HintWithState hintToUnlock = Hints.SingleOrDefault(hws => hws.Hint.Id == hintID);

if (Team.HintCoinCount < hintToUnlock.AdjustedCost)
{
return NotFound();
}

state.UnlockTime = DateTime.UtcNow;
Team.HintCoinCount -= cost;
Team.HintCoinsUsed += cost;
Team.HintCoinCount -= hintToUnlock.AdjustedCost;
Team.HintCoinsUsed += hintToUnlock.AdjustedCost;
await _context.SaveChangesAsync();
}

Expand Down

0 comments on commit f27360f

Please sign in to comment.