Skip to content

Instantly share code, notes, and snippets.

@dankronstal
Last active February 5, 2016 22:04
Show Gist options
  • Save dankronstal/8942abc8ba85cb6e620b to your computer and use it in GitHub Desktop.
Save dankronstal/8942abc8ba85cb6e620b to your computer and use it in GitHub Desktop.
Play Hexers!

extending my previous play with hexagonal layouts to make a "checkers-like" game. Instructions are in the sidebar.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
*{
font-family: courier;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.hexagon {
fill: none;
stroke: #000;
stroke-width: .5px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/d3.hexbin.v0.min.js?5c6e4f0"></script>
<div id="titleAndStats" style="float:left; width:30em"></div>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var points = [];
var hexRadius = 30,
MapRows = 6,
MapColumns = 10,
transDuration = 500,
instructions = "none";
/*** set up board and actions ***/
var selectedPoint = {};
for (var r = 0; r < MapRows; r++) {
for (var c = 0; c < MapColumns; c++) {
points.push([hexRadius * c * 1.75, hexRadius * r * 1.5, c, r, "id-"+c+"-"+r]);
}//for j
}//for i
var color = d3.scale.linear()
.domain([0, 20])
.range(["white", "steelblue"])
.interpolate(d3.interpolateLab);
var hexbin = d3.hexbin()
.size([width, height])
.radius(30);
var x = d3.scale.identity()
.domain([0, width]);
var y = d3.scale.linear()
.domain([0, height])
.range([height, 0]);
var percent = d3.format("%");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("float","left")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("class", "mesh")
.attr("width", width)
.attr("height", height);
svg.append("g")
.attr("clip-path", "url(#clip)")
.selectAll(".hexagon")
.data(hexbin(points))
.enter().append("path")
.attr("class", "hexagon")
.attr("d", hexbin.hexagon())
.attr("transform", function(d) { return "translate(" + (margin.left + d.x) + "," + (margin.left + d.y) + ")"; })
.style("fill", function(d) { return color(d.length); })
.attr("id",function(d){ return d[0][4]; })
.on("click", function(d){
if(selectedPoint != d && d3.select("#"+d[0][4]).classed(teams[team].name)){
selectedPoint = d;
changeNeighbors(d[0][2], d[0][3]);
d3.select("#"+d[0][4])
.attr("class", "hexagon primary "+teams[team].name)
.attr("fill-opacity","")
.transition()
.duration(transDuration)
.style("fill",teams[team].color);
turnover();
}
});
/*** Actions - probably a lot of this code could be consolidated ***/
var ownHex = function(){
if(this[0][0] == null) return; //should only be during init
if(!this.classed(teams[team].name)){ //you don't already own this node
if(!this.classed("primary")) //cannot own an opponents primary node
this.attr("class", "hexagon "+teams[team].name).transition().duration(transDuration).style("fill",teams[team].color).attr("fill-opacity",0.5);
}
}
var previewHex = function(){
if(!this.classed(teams[team].name)){
this.transition().duration(transDuration).style("fill",teams[team].color).attr("fill-opacity",0.25);
}
}
var unviewHex = function(){
if(!this.classed(teams[team].name)){
this.style("fill",color(2)).attr("fill-opacity","");
}
}
function changeNeighbors(c, r){
d3.select("#id-"+(c+0)+"-"+(r+1)).call(ownHex);
d3.select("#id-"+(c+1)+"-"+(r+0)).call(ownHex);
d3.select("#id-"+(c-1)+"-"+(r+0)).call(ownHex);
d3.select("#id-"+(c+0)+"-"+(r-1)).call(ownHex);
if(c % 2 > 0 && r % 2 > 0){
d3.select("#id-"+(c+1)+"-"+(r+1)).call(ownHex);
d3.select("#id-"+(c+1)+"-"+(r-1)).call(ownHex);
}
if(c % 2 > 0 && r % 2 == 0){
d3.select("#id-"+(c-1)+"-"+(r+1)).call(ownHex);
d3.select("#id-"+(c-1)+"-"+(r-1)).call(ownHex);
}
if(c % 2 == 0 && r % 2 > 0){
d3.select("#id-"+(c+1)+"-"+(r+1)).call(ownHex);
d3.select("#id-"+(c+1)+"-"+(r-1)).call(ownHex);
}
if(c % 2 == 0 && r % 2 == 0){
d3.select("#id-"+(c-1)+"-"+(r+1)).call(ownHex);
d3.select("#id-"+(c-1)+"-"+(r-1)).call(ownHex);
}
}
function viewNeighbors(c, r){
d3.select("#id-"+(c+0)+"-"+(r+1)).call(previewHex);
d3.select("#id-"+(c+1)+"-"+(r+0)).call(previewHex);
d3.select("#id-"+(c-1)+"-"+(r+0)).call(previewHex);
d3.select("#id-"+(c+0)+"-"+(r-1)).call(previewHex);
if(c % 2 > 0 && r % 2 > 0){
d3.select("#id-"+(c+1)+"-"+(r+1)).call(previewHex);
d3.select("#id-"+(c+1)+"-"+(r-1)).call(previewHex);
}
if(c % 2 > 0 && r % 2 == 0){
d3.select("#id-"+(c-1)+"-"+(r+1)).call(previewHex);
d3.select("#id-"+(c-1)+"-"+(r-1)).call(previewHex);
}
if(c % 2 == 0 && r % 2 > 0){
d3.select("#id-"+(c+1)+"-"+(r+1)).call(previewHex);
d3.select("#id-"+(c+1)+"-"+(r-1)).call(previewHex);
}
if(c % 2 == 0 && r % 2 == 0){
d3.select("#id-"+(c-1)+"-"+(r+1)).call(previewHex);
d3.select("#id-"+(c-1)+"-"+(r-1)).call(previewHex);
}
}
function clearNeighbors(c, r){
d3.select("#id-"+(c+0)+"-"+(r+1)).call(unviewHex);
d3.select("#id-"+(c+1)+"-"+(r+0)).call(unviewHex);
d3.select("#id-"+(c-1)+"-"+(r+0)).call(unviewHex);
d3.select("#id-"+(c+0)+"-"+(r-1)).call(unviewHex);
if(c % 2 > 0 && r % 2 > 0){
d3.select("#id-"+(c+1)+"-"+(r+1)).call(unviewHex);
d3.select("#id-"+(c+1)+"-"+(r-1)).call(unviewHex);
}
if(c % 2 > 0 && r % 2 == 0){
d3.select("#id-"+(c-1)+"-"+(r+1)).call(unviewHex);
d3.select("#id-"+(c-1)+"-"+(r-1)).call(unviewHex);
}
if(c % 2 == 0 && r % 2 > 0){
d3.select("#id-"+(c+1)+"-"+(r+1)).call(unviewHex);
d3.select("#id-"+(c+1)+"-"+(r-1)).call(unviewHex);
}
if(c % 2 == 0 && r % 2 == 0){
d3.select("#id-"+(c-1)+"-"+(r+1)).call(unviewHex);
d3.select("#id-"+(c-1)+"-"+(r-1)).call(unviewHex);
}
}
function turnover(){
var t = d3.select("#titleAndStats").html("");
t.append("h1").text("You are playing Hexers");
var iBtn = t.append("p").text("Click here to show/hide instructions");
var iDtl = t.append("div")
.html("- Own 50% of hexes to win.<br />- Primary hexes are dark colored; owned hexes are lighter colored.<br />- Click either a primary or owned hex to claim adjascent hexes.<br />- Cannot claim opponent's primary hexes.")
.style("display",instructions);
iBtn.on("click", function(){
instructions = instructions == "none" ? "block" : "none";
iDtl.style("display", instructions);
});
if(d3.selectAll("."+teams[team].name)[0].length/(MapRows*MapColumns) >= .5){ // check for winner
d3.selectAll(".hexagon").on("click","");
t.append("h3").text(function() { return "Team '"+teams[team].name+"' wins!"; }).style("color",teams[team].color).style("font-weight","bold");
svg.style("opacity",.5);
}else{
team = team == 0 ? 1 : 0;
t.append("h3").text(function(){ return "It is currently '"+teams[team].name +"' turn"; }).style("color",teams[team].color);
}
var t1Score = percent(d3.selectAll("."+teams[0].name)[0].length/(MapRows*MapColumns));
t.append("p").text(function(){ return teams[0].name + ": " + d3.selectAll("."+teams[0].name)[0].length + "("+ t1Score +")"; });
var t2Score = percent(d3.selectAll("."+teams[1].name)[0].length/(MapRows*MapColumns));
t.append("p").text(function(){ return teams[1].name + ": " + d3.selectAll("."+teams[1].name)[0].length + "("+ t2Score +")"; });
}
/*** initialize players and starting positions ***/
var team = 1
var teams = [{"name":"teamOne", "color":"green"},{"name":"teamTwo","color":"brown"}];
var teamOneHex = svg.selectAll("."+teams[0].name);
var teamTwoHex = svg.selectAll("."+teams[1].name);
//set up initial tile ownership
initialPoint = d3.select("#id-"+(MapColumns-1)+"-"+(MapRows-1));
initialPoint.classed(teams[team].name,true);
var e = document.createEvent('UIEvents');
e.initUIEvent("click", true, true, window, 1);
initialPoint.node().dispatchEvent(e);
selectedPoint = {};
initialPoint = d3.select("#id-0-0");
initialPoint.classed(teams[team].name,true);
var e = document.createEvent('UIEvents');
e.initUIEvent("click", true, true, window, 1);
initialPoint.node().dispatchEvent(e);
selectedPoint = null;
turnover();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment