Skip to content

Instantly share code, notes, and snippets.

@stevenhao
Created April 12, 2016 19:48
Show Gist options
  • Save stevenhao/3794023b7a668e97c42f3b3655879720 to your computer and use it in GitHub Desktop.
Save stevenhao/3794023b7a668e97c42f3b3655879720 to your computer and use it in GitHub Desktop.
<html>
<head>
<script src="jquery.min.js"></script>
<link rel="stylesheet" href="bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script>
var xmlns = "http://www.w3.org/2000/svg";
window.$$ = function(tag) {
var el = document.createElementNS(xmlns, tag);
return $(el);
}
$.attrHooks['viewbox'] = {
set: function(elem, value, name) {
elem.setAttributeNS(null, 'viewBox', value + '');
return value;
}
};
$.attrHooks['class'] = {
set: function(elem, value, name) {
elem.setAttributeNS(null, 'class', value + '');
return value;
}
};
</script>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Bbbb</a> </div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav" hidden>
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul>
<form class="navbar-form navbar-left" role="search" hidden> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form>
<ul class="nav navbar-nav navbar-right" hidden> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<style>
.card {
cursor: pointer;
}
.card.small {
width:100px;
height:50px;
}
.card:hover rect.card-back{
filter:url(#blur);
/*opacity:0.7;*/
}
.selected rect.card-back {
stroke:orange;
stroke-width:15;
/*filter:url(#borderFilter);*/
}
.card-back {
fill: white;
width: 200;
height: 100;
}
.stripe {
width:1;
height:.5;
opacity:0.8;
}
.shape {
stroke-width:2;
}
.green {
stroke: green;
}
.purple {
stroke: #5A1398;
}
.red {
stroke: red;
}
.open {
fill:white;
}
.green.solid {
fill:green;
}
.red.solid {
fill:red;
}
.purple.solid {
fill:#5A1398;
}
.green.striped {
fill:url(#green-stripe);
}
.purple.striped {
fill:url(#purple-stripe);
}
.red.striped {
fill:url(#red-stripe);
}
</style>
<svg style="height:0">
<defs>
<filter id="blur" >
<feGaussianBlur stdDeviation="15"> </feGaussianBlur>
</filter>
<pattern id="green-stripe" x="0" y="0" width="1" height="1" patternUnits="userSpaceOnUse">
<rect class="stripe" fill="green"></rect>
</pattern>
<pattern id="purple-stripe" x="0" y="0" width="1" height="1" patternUnits="userSpaceOnUse">
<rect class="stripe" fill="purple"></rect>
</pattern>
<pattern id="red-stripe" x="0" y="0" width="1" height="1" patternUnits="userSpaceOnUse">
<rect class="stripe" fill="red"></rect>
</pattern>
</defs>
</svg>
<div class="container">
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">These are your cards</h3>
</div>
<div class="panel-body">
<div style="position:relative;margin: 0 auto; width:50em;height:25em;background-color:gray" id="your-cards">
</div> <!-- the dimension needs to be 2x1 -->
</div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">These are my cards</h3>
</div>
<div class="panel-body">
<button id="check-set">Check Set</button>
<button id="restart">Restart</button>
</div>
</div>
</div>
</div>
<script>
</script>
<script>
function rep(val, n) {
var ret = [];
for(var i = 0; i < n; ++i) {
ret.push(val);
}
return ret;
}
var paths = {
"diamond": "l15,30 l15,-30 l-15,-30 Z",
"oval": "l0,20 c0,15 30,15 30,0 l0,-40 c0,-15 -30,-15 -30,0 Z",
"squiggle": "c-2.1570791838747962,6.544283122053847 -4.314158367749604,13.088566244107705 -2.4489795918367347,19.183673469387756 c1.8651787759128697,6.09510722528005 7.752615511613418,11.741038553786302 15.10204081632653,13.061224489795919 c7.3494253047131135,1.3201859360096166 16.16083917843869,-1.6853735204773788 17.142857142857142,-6.530612244897959 c0.9820179644184557,-4.84523872442058 -5.865359980470161,-11.530156716774757 -6.530612244897959,-18.775510204081634 c-0.6652522644277984,-7.24535348730687 4.851621151605291,-15.05114246956644 4.489795918367347,-22.857142857142858 c-0.36182523323794397,-7.806000387576418 -6.602349115746922,-15.612212180469674 -13.877551020408163,-18.367346938775512 c-7.275201904661242,-2.755134758305836 -15.585081831474726,-0.45919248202425283 -17.142857142857142,3.673469387755102 c-1.5577753113824173,4.132661869779355 3.6365539926662547,10.10204333305649 5.3061224489795915,15.510204081632653 c1.669568456313337,5.408160748576165 -0.18562393510863756,10.255100782451347 -2.0408163265306123,15.10204081632653 ",
}
var placements = {1: "85,50", 2: "60,50", 3: "35,50"};
var colors = ["red", "purple", "green"], shadings = ["open", "striped", "solid"], shapes = ["oval", "diamond", "squiggle"], counts = [1, 2, 3];
var $el = $("#your-cards");
makeCard = function(count, color, shading, shape) {
var pth = "M" + placements[count] + " " + rep(paths[shape], count).join('m50,0 ');
var svgElem = $$('svg');
svgElem.addClass("card").attr("viewbox", "0 0 200 100");
var rect = $$('rect');
rect.addClass("card-back").appendTo(svgElem);
var path = $$('path');
path.addClass('shape').addClass(color).addClass(shading).attr("d", pth).appendTo(svgElem);
return svgElem;
}
shuffle = function(deck) {
for (var i = 0; i < deck.length; ++i) {
var tmp = deck[i]
var j = Math.floor(Math.random() * i);
deck[i] = deck[j];
deck[j] = tmp;
}
return deck;
}
makeDeck = function() {
var deck = []
for(var i = 0; i < 81; ++i) {
var cur = i;
var a = cur % 3; cur = (cur - a) / 3;
var b = cur % 3; cur = (cur - b) / 3;
var c = cur % 3; cur = (cur - c) / 3;
var d = cur;
deck.push({count: a, color: b, shading: c, shape: d});
}
return shuffle(deck);
}
deal12 = function(deck) {
var cards = []
for (var i = 0; i < 12; ++i) {
cards[i] = deck.pop();
}
return cards
}
var deck = makeDeck();
var cards = deal12(deck)
selected = [];
render = function() {
$el.empty();
for(var r = 0; r < 3; ++r) {
for(var c = 0; c < 4; ++c) {
var i = r * 4 + c;
var count = counts[cards[i].count], color = colors[cards[i].color], shading = shadings[cards[i].shading], shape = shapes[cards[i].shape];
var svgElem = makeCard(count, color, shading, shape).css({position: "absolute", left: 4 + c * 24 + "%", top: 10 + r * 30 + "%", width: "20%", height: "20%"});
svgElem.appendTo($el);
svgElem.attr('pos', i);
}
}
$('.card').mousedown(function(e) {
e.preventDefault();
});
$('.card').click(function(e) {
$(this).toggleClass("selected");
var pos = parseInt($(this).attr('pos'));
if ($(this).hasClass('selected')) {
selected.push(pos);
}
})
}
render();
isSet = function(arr) {
if (arr.length != 3) {
return false;
}
var dimen = ['count', 'color', 'shading', 'shape'];
for (d of dimen) {
var x = cards[arr[0]][d], y = cards[arr[1]][d], z = cards[arr[2]][d];
var isOkay = function(a, b, c) {
if (a == b && b == c) {
return true;
}
if (a != b && b != c && c != a) {
return true;
}
return false;
}
if (!isOkay(x, y, z)) {
return false;
}
}
return true;
}
help = function() {
for (var i = 0; i < 12; ++i) {
for (var j = i + 1; j < 12; ++j) {
for (var k = j + 1; k < 12; ++k) {
if (isSet([i, j, k])) {
$($el.children()[i]).addClass('selected')
$($el.children()[j]).addClass('selected')
$($el.children()[k]).addClass('selected')
return 'found'
}
}
}
}
deck = shuffle(deck.concat(cards))
cards = deal12(deck)
render()
return 'not found'
}
startTime = Date.now()
pad2 = function(x) {
x = "" + x;
while (x.length < 2) {
x = "0" + x;
}
return x;
}
$('#check-set').click(function() {
// console.log($el.children());
var selectedCards = [];
for (var i = 0; i < 12; i++) {
var $ch = $($el.children()[i]);
if ($ch.hasClass('selected')) {
selectedCards.push(i)
}
}
var diff = new Date(Date.now() - startTime)
console.log(""+pad2(diff.getMinutes())+":"+pad2(diff.getSeconds()))
if (isSet(selectedCards)) {
console.log("yay")
var cardEls = $el.children();
for (var i of selectedCards) {
cards[i] = deck.pop();
}
render();
} else {
console.log("boo hoo")
}
})
$('#restart').click(function() {
deck = makeDeck()
cards = deal12(deck)
startTime = Date.now()
render()
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment