diff options
Diffstat (limited to 'app/views/puzzles')
-rw-r--r-- | app/views/puzzles/_handle_puzzle.html.erb | 76 | ||||
-rw-r--r-- | app/views/puzzles/_submission.html.haml | 9 | ||||
-rw-r--r-- | app/views/puzzles/about.html.haml | 53 | ||||
-rw-r--r-- | app/views/puzzles/index.html.haml | 26 | ||||
-rw-r--r-- | app/views/puzzles/show.html.haml | 41 | ||||
-rw-r--r-- | app/views/puzzles/solve.js.erb | 5 |
6 files changed, 210 insertions, 0 deletions
diff --git a/app/views/puzzles/_handle_puzzle.html.erb b/app/views/puzzles/_handle_puzzle.html.erb new file mode 100644 index 0000000..f0e3227 --- /dev/null +++ b/app/views/puzzles/_handle_puzzle.html.erb | |||
@@ -0,0 +1,76 @@ | |||
1 | <script type="text/javascript"> | ||
2 | var totalSeconds = 0 | ||
3 | var startTime = 0 | ||
4 | var timerInterval | ||
5 | |||
6 | function pad(val) { | ||
7 | var valString = val + "" | ||
8 | if (valString.length < 2) | ||
9 | { | ||
10 | return "0" + valString | ||
11 | } else { | ||
12 | return valString | ||
13 | } | ||
14 | } | ||
15 | function setTime() { | ||
16 | totalSeconds = Math.floor((Date.now() - startTime) / 1000) | ||
17 | $("#seconds").text(pad(totalSeconds%60)) | ||
18 | $("#minutes").text(pad(parseInt(totalSeconds/60))) | ||
19 | } | ||
20 | |||
21 | window.onload = function() { | ||
22 | <% if @playable or @puzzle.latest? %> | ||
23 | $("#sens").val(window.settings.sensitivity) | ||
24 | $("#sens").on("change", function() { | ||
25 | window.settings.sensitivity = this.value | ||
26 | }) | ||
27 | $("#volume").val(parseFloat(window.settings.volume)) | ||
28 | $("#volume").on("change", function() { | ||
29 | window.settings.volume = this.value | ||
30 | }) | ||
31 | <% end %> | ||
32 | |||
33 | <% if @playable %> | ||
34 | <% if @already_started %> | ||
35 | var puzzle = window.deserializePuzzle("<%= @puzzle.data %>") | ||
36 | draw(puzzle) | ||
37 | <% else %> | ||
38 | $("#activation-button button").on("click", function() { | ||
39 | var puzzle = window.deserializePuzzle("<%= @puzzle.data %>") | ||
40 | draw(puzzle) | ||
41 | |||
42 | $("#activation-button").hide() | ||
43 | |||
44 | startTime = Date.now() | ||
45 | timerInterval = setInterval(setTime, 1000); | ||
46 | |||
47 | $.ajax({ | ||
48 | type: "POST", | ||
49 | url: "<%= start_puzzle_path(@puzzle, format: :js) %>" | ||
50 | }) | ||
51 | }) | ||
52 | <% end %> | ||
53 | <% else %> | ||
54 | var puzzle = window.deserializePuzzle("<%= @puzzle.data %>") | ||
55 | draw(puzzle) | ||
56 | drawPath(puzzle, JSON.parse("<%= escape_javascript(sanitize @solution) %>")) | ||
57 | <% unless @puzzle.latest? %> | ||
58 | window.trace = function() {} | ||
59 | <% end %> | ||
60 | <% end %> | ||
61 | } | ||
62 | |||
63 | <% if @playable %> | ||
64 | window.TRACE_COMPLETION_FUNC = function(puzzle, rawPath) { | ||
65 | clearInterval(timerInterval) | ||
66 | setTime() | ||
67 | |||
68 | $.ajax({ | ||
69 | type: "POST", | ||
70 | url: "<%= solve_puzzle_path(@puzzle, format: :js) %>", | ||
71 | data: { solved: JSON.stringify(rawPath) <% unless @already_started %> , time: totalSeconds <% end %> } | ||
72 | }) | ||
73 | } | ||
74 | |||
75 | <% end %> | ||
76 | </script> | ||
diff --git a/app/views/puzzles/_submission.html.haml b/app/views/puzzles/_submission.html.haml new file mode 100644 index 0000000..a3d0740 --- /dev/null +++ b/app/views/puzzles/_submission.html.haml | |||
@@ -0,0 +1,9 @@ | |||
1 | %h3 Congrats! | ||
2 | %p Would you like to submit your time? | ||
3 | = form_with url: submit_puzzle_path(@puzzle) do |form| | ||
4 | - unless @time.nil? | ||
5 | = form.hidden_field :time, value: @time | ||
6 | %p | ||
7 | = form.label :name, "Name:" | ||
8 | = form.text_field :name | ||
9 | %p= form.submit "Submit" | ||
diff --git a/app/views/puzzles/about.html.haml b/app/views/puzzles/about.html.haml new file mode 100644 index 0000000..f1f7aa0 --- /dev/null +++ b/app/views/puzzles/about.html.haml | |||
@@ -0,0 +1,53 @@ | |||
1 | %p.summary <strong>Wittle</strong> gives you daily randomly-generated puzzles in the style of those from the 2016 indie game, <a href="http://the-witness.net">The Witness</a>. There are three difficulties of puzzles to choose from: | ||
2 | %h2#current-date= @normal_puzzle.created_at.localtime.strftime("%B %-d, %Y") | ||
3 | %nav#choose-difficulty | ||
4 | #normal-link | ||
5 | = link_to "Normal", @normal_puzzle | ||
6 | - if @normal_solved | ||
7 | %p.puzzle-status Solved! | ||
8 | - elsif @normal_started | ||
9 | %p.puzzle-status Started | ||
10 | #hard-link | ||
11 | = link_to "Hard", @hard_puzzle | ||
12 | - if @hard_solved | ||
13 | %p.puzzle-status Solved! | ||
14 | - elsif @hard_started | ||
15 | %p.puzzle-status Started | ||
16 | #expert-link | ||
17 | = link_to "Expert", @expert_puzzle | ||
18 | - if @expert_solved | ||
19 | %p.puzzle-status Solved! | ||
20 | - elsif @expert_started | ||
21 | %p.puzzle-status Started | ||
22 | #new-puzzles | ||
23 | - if @normal_puzzle.created_at.localtime.to_date != DateTime.now.localtime.to_date | ||
24 | New puzzles are being generated... | ||
25 | - else | ||
26 | Time until new puzzles: <span id="hours">00</span>:<span id="minutes">00</span>:<span id="seconds">00</span> | ||
27 | :javascript | ||
28 | function pad(val) { | ||
29 | var valString = val + "" | ||
30 | if (valString.length < 2) | ||
31 | { | ||
32 | return "0" + valString | ||
33 | } else { | ||
34 | return valString | ||
35 | } | ||
36 | } | ||
37 | function setTime() { | ||
38 | --totalSeconds | ||
39 | if (totalSeconds == 0) | ||
40 | { | ||
41 | $("#new-puzzles").text("Refresh the page for today's puzzles!") | ||
42 | clearInterval(timerInterval) | ||
43 | } else { | ||
44 | $("#seconds").text(pad(totalSeconds%60)) | ||
45 | $("#minutes").text(pad(parseInt(totalSeconds/60)%60)) | ||
46 | $("#hours").text(pad(parseInt(parseInt(totalSeconds/60)/60))) | ||
47 | } | ||
48 | } | ||
49 | var totalSeconds = #{(Time.now.tomorrow.beginning_of_day - Time.now).to_i + 1} | ||
50 | setTime() | ||
51 | var timerInterval = setInterval(setTime, 1000); | ||
52 | %p.summary Wittle was created by <a href="https://www.fourisland.com/">Hatkirby</a>, with major help from <a href="https://github.com/sigma144/witness-randomizer">Sigma144</a> (who wrote the puzzle generation code) and <a href="https://github.com/jbzdarkid/jbzdarkid.github.io">jbzdarkid</a> (who wrote the puzzle solving web interface). The source code is available <a href="https://code.fourisland.com/wittle">here</a>. If you encounter any bugs, or have feedback regarding puzzle difficulty level, feel free to contact me! I am <code>hatkirby</code> on Discord, and you can also find me in the <a href="https://discord.gg/0nJwyUyYIfTEgSz0">Witness Speedrunning server</a>. | ||
53 | %p.summary There is an <a href="#{ archive_path }">archive of past puzzles</a> for those interested. | ||
diff --git a/app/views/puzzles/index.html.haml b/app/views/puzzles/index.html.haml new file mode 100644 index 0000000..fe497e4 --- /dev/null +++ b/app/views/puzzles/index.html.haml | |||
@@ -0,0 +1,26 @@ | |||
1 | .breadcrumb= link_to "← Back to home page", root_path | ||
2 | %h1 Archive | ||
3 | %table#archive | ||
4 | %tr | ||
5 | %th | ||
6 | %th Normal | ||
7 | %th Hard | ||
8 | %th Expert | ||
9 | - @puzzles.each do |date, dps| | ||
10 | %tr{ class: cycle("even", "odd") } | ||
11 | %td= date.strftime("%B %-d, %Y") | ||
12 | %td | ||
13 | - if dps.has_key? "normal" | ||
14 | %ul | ||
15 | - dps["normal"].each do |puzzle| | ||
16 | %li= link_to "\##{puzzle.id}", puzzle | ||
17 | %td | ||
18 | - if dps.has_key? "hard" | ||
19 | %ul | ||
20 | - dps["hard"].each do |puzzle| | ||
21 | %li= link_to "\##{puzzle.id}", puzzle | ||
22 | %td | ||
23 | - if dps.has_key? "expert" | ||
24 | %ul | ||
25 | - dps["expert"].each do |puzzle| | ||
26 | %li= link_to "\##{puzzle.id}", puzzle | ||
diff --git a/app/views/puzzles/show.html.haml b/app/views/puzzles/show.html.haml new file mode 100644 index 0000000..47db8f2 --- /dev/null +++ b/app/views/puzzles/show.html.haml | |||
@@ -0,0 +1,41 @@ | |||
1 | .breadcrumb= link_to "← Back to home page", root_path | ||
2 | %h1 Wittle ##{@puzzle.id} | ||
3 | .puzzle-description #{@puzzle.category.capitalize} - #{@puzzle.created_at.localtime.strftime("%B %-d, %Y")} | ||
4 | #puzzle-container{ style: "display: flex; justify-content: center; align-items: center" } | ||
5 | %svg#puzzle{ style: "pointer-events: auto"} | ||
6 | #submission-form | ||
7 | - if @playable | ||
8 | - unless @already_started | ||
9 | #activation-button | ||
10 | %button{ type: "button" } Reveal Puzzle | ||
11 | #timer | ||
12 | %label#minutes 00 | ||
13 | %label#colon : | ||
14 | %label#seconds 00 | ||
15 | - if @playable or @puzzle.latest? | ||
16 | %details#trace-settings | ||
17 | %summary Settings | ||
18 | .things | ||
19 | %label{ for: "sens" } Mouse Speed 2D | ||
20 | %input#sens{ type: "range", min: "0.1", max: "1.3", step: "0.1" } | ||
21 | %label{ for: "volume" } Volume | ||
22 | %input#volume{ type: "range", min: "0", max: "0.24", step: "0.02" } | ||
23 | - unless @playable | ||
24 | #scores | ||
25 | #by-time | ||
26 | %h2 Fastest Solves | ||
27 | %table | ||
28 | - @puzzle.scores.where("seconds_taken IS NOT NULL").order(seconds_taken: :asc, created_at: :asc).limit(100).each_with_index do |score, i| | ||
29 | %tr | ||
30 | %td #{(i + 1)}. | ||
31 | %td= score.name | ||
32 | %td.score-field= humanize_interval(score.seconds_taken) | ||
33 | #by-when | ||
34 | %h2 Completion Order | ||
35 | %table | ||
36 | - @puzzle.scores.order(created_at: :asc).limit(100).each_with_index do |score, i| | ||
37 | %tr | ||
38 | %td #{(i + 1)}. | ||
39 | %td= score.name | ||
40 | %td.score-field= score.created_at.getlocal().strftime("%-I:%M:%S%P") | ||
41 | = render partial: "handle_puzzle" | ||
diff --git a/app/views/puzzles/solve.js.erb b/app/views/puzzles/solve.js.erb new file mode 100644 index 0000000..2aa22e9 --- /dev/null +++ b/app/views/puzzles/solve.js.erb | |||
@@ -0,0 +1,5 @@ | |||
1 | $("#submission-form").html('<%= escape_javascript(render partial: "submission") %>'); | ||
2 | $("#submission-form #name").val(window.settings.player_name) | ||
3 | $("#submission-form #name").on("change", function() { | ||
4 | window.settings.player_name = this.value | ||
5 | }) | ||