Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions public/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ function rand(x) {
return Math.floor(Math.random() * x);
}

function shuffle(lst) {
function shuffle(lst, seed=null) {
var randf = seed == null? rand: seeded_prng(seed);
for (var i = 0; i < lst.length; ++i) {
var tmp = lst[i]
var j = rand(i);
var j = randf(i);
lst[i] = lst[j];
lst[j] = tmp;
}
Expand All @@ -71,3 +72,36 @@ $.attrHooks['class'] = {
return value;
}
};


// blatantly stolen from https://stackoverflow.com/a/47593316
function xmur3(str) {
for(var i = 0, h = 1779033703 ^ str.length; i < str.length; i++)
h = Math.imul(h ^ str.charCodeAt(i), 3432918353),
h = h << 13 | h >>> 19;
return function() {
h = Math.imul(h ^ h >>> 16, 2246822507);
h = Math.imul(h ^ h >>> 13, 3266489909);
return (h ^= h >>> 16) >>> 0;
}
}

function sfc32(a, b, c, d) {
return function(x) {
a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0;
var t = (a + b) | 0;
a = b ^ b >>> 9;
b = c + (c << 3) | 0;
c = (c << 21 | c >>> 11);
d = d + 1 | 0;
t = t + d | 0;
c = c + t | 0;
var temp = (t >>> 0) / 4294967296;
return Math.floor(temp * x);
}
}

function seeded_prng(seed) {
var seeder = xmur3(seed);
return sfc32(seeder(), seeder(), seeder(), seeder());
}
1 change: 1 addition & 0 deletions public/hiddenset.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
animationTime: 400
}

root.initialSeed = window.location.hash.substr(1) || null
root.variant = Variants.hiddenset
root.Controller.start()
</script>
Expand Down
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
animationTime: 400
}

root.initialSeed = window.location.hash.substr(1) || null
root.variant = Variants.set
root.Controller.start()
</script>
Expand Down
12 changes: 10 additions & 2 deletions public/model.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ root.Model = do ->
startTime = null
endTime = null
phase = null
seed = null

getClockTime = ->
seconds = Math.floor((endTime - startTime) / 1000)
Expand All @@ -16,7 +17,7 @@ root.Model = do ->
deselectAll = -> selected.slice().forEach(deselect)

newGame = ->
deck = variant.makeDeck()
deck = variant.makeDeck(seed)
cards = variant.deal(deck)
selected = []
startTime = Date.now()
Expand All @@ -28,18 +29,24 @@ root.Model = do ->
View.setLabels(phase)

restart = ->
seed = (rand(0x1000000)).toString(16)
View.showSeed(seed)
if phase == 'gameover'
View.gameOverDone()
setTimeout(newGame, 1000)
else
newGame()

loadGame = ->
seed = if initialSeed? then initialSeed else null
gameid = variant.name
print 'loading', gameid
if typeof(Storage) isnt 'undefined' and localStorage.getItem(gameid)?
game = JSON.parse(localStorage.getItem(gameid))
if (game? and game.cards? and game.deck? and game.startTime? and game.selected? and game.phase?)
if seed != null and seed != game.seed
return false
seed = game.seed
cards = game.cards
deck = game.deck
startTime = game.startTime
Expand All @@ -59,14 +66,15 @@ root.Model = do ->
View.addCards(cards)
View.layoutCards()
View.setLabels(phase)
View.showSeed(seed)
return true
return false

saveGame = ->
gameid = variant.name
if typeof(Storage) isnt 'undefined'
gameString = JSON.stringify {
cards: cards, deck: deck, startTime: startTime, phase: phase,
cards: cards, deck: deck, startTime: startTime, phase: phase, seed: seed,
selected: [], # do we want to preserve selected cards?
endTime: endTime, # may be null
}
Expand Down
1 change: 1 addition & 0 deletions public/powerset.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
if not View.isAnimating()
if cnt in allowedDimensions
currentDimensions = cnt
root.initialSeed = window.location.hash.substr(1) || null
root.variant = Variants.powersetWithDimension(currentDimensions)
root.Controller.start()
setDimension(6)
Expand Down
1 change: 1 addition & 0 deletions public/superset.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
animationTime: 400
}

root.initialSeed = window.location.hash.substr(1) || null
root.variant = Variants.superset
root.Controller.start()
</script>
Expand Down
12 changes: 6 additions & 6 deletions public/variants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function makeStandardDeck() {
function makeStandardDeck(seed) {
var deck = []
for(var i = 0; i < 81; ++i) {
var cur = i;
Expand All @@ -8,7 +8,7 @@ function makeStandardDeck() {
var z = cur;
deck.push({type: '3^4', count: a, color: b, shading: c, shape: z});
}
return shuffle(deck);
return shuffle(deck, seed);
}

function isNotNull(set) {
Expand Down Expand Up @@ -133,8 +133,8 @@ superset = {

hiddenset = {
name: 'Set',
makeDeck: function() {
var ret = makeStandardDeck();
makeDeck: function(seed) {
var ret = makeStandardDeck(seed);
ret[0].hidden = true;
return ret;
},
Expand Down Expand Up @@ -191,12 +191,12 @@ function findPowerSet(cards, previous) {
function powersetWithDimension(dim) {
return {
name: 'Power Set ' + dim,
makeDeck: function() {
makeDeck: function(seed) {
var deck = [];
for (var i = 1; i < (1 << dim); ++i) {
deck.push({type: '2^' + dim, value: i});
}
return shuffle(deck);
return shuffle(deck, seed);
},
deal: deal,
isSet: isPowerSet,
Expand Down
4 changes: 4 additions & 0 deletions public/view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ root.View = do ->
$cards.forEach ($card) -> $card.remove()
$cards = []

showSeed = (seed) ->
window.location.hash = seed

return {
select: (i) ->
$cards[i].addClass('selected')
Expand All @@ -259,6 +262,7 @@ root.View = do ->
gameOver: gameOver
gameOverDone: gameOverDone
clear: clear
showSeed: showSeed

setTheme: (theme) -> $body.removeClass('light dark').addClass(theme)
toggleFullScreen: toggleFullScreen
Expand Down