PTN Viewer
Loads and replays PTN notation of Tak games.
by Ben Wochinski
HTML
<div style="text-align: center;">
<h1>PTN Viewer</h1>
<div id="enterPTN" style="position: absolute; top: 50px; left: 35%; background-color: tan; border: 2px solid grey; padding: 20px; display: none; margin-left: auto; margin-right: auto;">
<form>
<h3>Enter notation:</h3>
<br/>[Size "5"] tag is required! Move numbers are required.
<br/>Separate all elements with spaces or newlines.
<br/>
<textarea id="ptnArea" style="height:500px; width:500px; border: 1px solid black;"></textarea>
<br/>
<input type="button" value=" Load " onClick="parseText()" style="margin: 10px;">
<input type="button" value="Cancel" onClick="cancelParse()" style="margin: 10px;">
</form>
</div>
<input type="button" value="Load PTN" onClick="showEnterPTN()">
<br/>
<br/>
<div id="boardContainer" style="width: 800px; margin-left: auto; margin-right: auto; overflow: hidden;">
<canvas id="board" width="450" height="450" style="float: left; padding-right: 20px;"></canvas>
<div style="float: left; width: auto; height: auto;">
<div id="tagInfo" style="width: 350px; height: 50px; border: 1px solid black; background-color: white; padding: 5px; overflow: hidden;"></div>
<div style="margin-top: 10px; font-size: 16px; font-weight: bold;">Move List</div>
<div id="moveList" style="width: 340px; height: 300px; border: 1px solid black; font-size: 18px; font-family: 'Courier New'; padding: 10px; overflow-y: scroll; background-color: white; text-align: left;">move list here</div>
<div style="float: left; margin: 10px;">
<input type="button" value="|<" onClick="beginning()">
<input type="button" value="<" onClick="rewind()">
<input type="button" value=">" onClick="forward()">
<input type="button" value=">|" onClick="end()">
<br/>
<input id="aPlay" type="button" value=" AutoPlay..." onClick="autoMove()" style="margin-top: 10px; width: 90px;">
</div>
<div...
CSS
body {
background-color: #ddd;
}
#moveList span,
#moveList div {
cursor: pointer;
cursor: hand;
}
#moveList span.note {
font-weight: bold;
font-size: 20px;
color: red;
}
div.comment {
color: green;
font-size: 14px;
font-weight: bold;
margin-left: 30px;
margin-bottom: 0px;
padding-bottom: 0px;
display: block;
}
JavaScript
var testPTN = '[Event "PTN Viewer Demo"]\n[Site "Here"]\n[Date "2015.11.21"]\n[Player1 "No One"]\n[Player2 "N/A"]\n[Clock "10:0 +15"]\n[Result "It Works!"]\n[Size "5"]\n[TPS "x5/x3,2112S,x/x5/x,1221,x3/x5 1 1"]\n\n1. a3 c2\n2. c2> {What a nub} a3+\n3. d2+ a4>\n4. d3- b4-\n5. d2< Cc5? {Can you even believe this guy?}\n6. c2+ b3>\'\n7. a5 2c3-2!';
var PTNPlay = PTNPlay || {};
var stones = [0, 0, 0];
var inPTN = testPTN;
var playerInterval;
var redditLink = "";
var takSquare = function() {
//Track pieces currently on the square in an array
this.pieces = [],
this.movedFrom = false
};
var takPiece = function(pNum, location, player, type) {
this.pNum = pNum;
this.location = location;
this.player = player;
this.type = type || "F";
this.moved = true;
this.flattened = 0;
this.draw = function() {
flatH = PTNPlay.Board.squareSize / 12;
flatW = PTNPlay.Board.squareSize * 0.6;
var pStackPos = 0;
var sqArray = PTNPlay.Board.sq[this.location].pieces;
for (var i = 0; i < sqArray.length; i++) {
if (sqArray[i].pNum == this.pNum) {
pStackPos = i;
//break;
}
}
var pX = PTNPlay.Board.squareSize * (this.location.charCodeAt(0) - 97) + 20 + 50;
var pY = PTNPlay.Board.squareSize * (PTNPlay.Board.boardSize - this.location.charAt(1) + 1) - 15 - (flatH * 2) - ((flatH - 2) * pStackPos);
var c = PTNPlay.Board.canvas.getContext("2d");
if (this.player == 1) {
pX -= 5;
} else if (this.player == 2) {
//pX += 2;
}
c.beginPath();
if (this.type == "F") {
c.rect(pX, pY, flatW, flatH * 3);
} else if (this.type == "S") {
//pY -= flatH * 2;
pX += (flatW * 0.4);
if (this.player == 1) {
pX += flatH * 2;
//c.rect(pX, pY, flatH, flatH * 3);
c.moveTo(pX + flatH, pY);
c.lineTo(pX - flatH, pY - (flatH * 2));
c.lineTo(pX - (flatH * 2), pY - (flatH * 2));
c.lineTo(pX - (flatH * 2), pY + flatH);
...