
已运用了先期方案者进行如下调整:
1、猴头右箭头,选下图圈红。
2、选下图圈红。
3、选下图圈红。
4、将之中的代码全部替换下面**间的代码,后保存
***************
// ==UserScript==
// @name 励精教室棋谱辅助
// @namespace renju
// @description 申劲作品
// @include http://www.ljrenju.com/news/*
// @include http://www.ljrenju.cn/news/*
// @version 2.0
// @grant none
// ==/UserScript==
/** 初始化变量 */
var left = 60;// 左边距
var top = 20;// 上边距
var r = 31;// 棋盘格子宽度
var xs = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"];// 横坐标集
var map = {A : 0, B : 1, C : 2, D : 3, E : 4, F : 5, G : 6, H : 7, I : 8, J : 9, K : 10, L : 11, M : 12, N : 13, O : 14,
a : 0, b : 1, c : 2, d : 3, e : 4, f : 5, g : 6, h : 7, i : 8, j : 9, k : 10, l : 11, m : 12, n : 13, o : 14};// 坐标字典
var cavs = new Map();// 棋盘数据集
var showNumbers = [];// 数字按钮集
var backgrounds = [];// 背景按钮集
var isShow = true;// 是否显示数字
var chessboardColorView = "#dead00";// 看谱时棋盘背景色
var chessboardColorEdit = "#efce73";// 编辑时棋盘背景色
var bkstate = true;// 辅助变量
// 屏蔽右键
document.oncontextmenu = function(){return false;}
// 复制棋谱功能辅助栏
var copyarea = document.createElement("textarea");
copyarea.style.display = "none";
copyarea.id = "copyarea";
document.body.appendChild(copyarea);
// 背景色复位提示语栏
var ljtips = document.createElement("div");
ljtips.style.display = "none";
ljtips.style.position = "absolute";
ljtips.style.background = "#f9e4a9";
document.body.appendChild(ljtips);
// 棋评栏
var chessCommentDiv = document.createElement("div");
chessCommentDiv.style.display = "none";
chessCommentDiv.style.position = "absolute";
// 棋评内容区
var commentContent = document.createElement("textarea");
commentContent.style.height = "510px";
commentContent.style.width = "200px";
commentContent.style.background = "#efce73";
commentContent.readOnly = true;
// 添加到页面
chessCommentDiv.appendChild(commentContent);
document.body.appendChild(chessCommentDiv);
// 读取配置
readCookie();
/** 获得所有棋谱内容, 并初始化*/
// 此标签含有棋谱数据
var fiveObjs = document.getElementsByName('moves');
// 遍历棋谱数据
for(var i=0; i<fiveObjs.length; i++){
// 获得棋谱数据标签
var fiveObj = fiveObjs[i];
// 找到父节点
var fiveObjF = fiveObj.parentNode;
// 去掉java代码
fiveObjF.code = "";
// 去掉无关内容
fiveObjF.innerHTML = fiveObjF.innerHTML.substring(fiveObjF.innerHTML.indexOf("<param"));
// 创建头部信息栏
var headMenu = document.createElement("div");
headMenu.style.width = "525px";// 宽度
headMenu.style.height = "70px";
// 创建棋谱开局信息
var title = document.createElement("div");// 创建标签
title.style.width = "40%";// 宽度
title.style.height = "70px";
title.style.background = "#cccccc";// 背景颜色
title.style.textAlign = "center";
title.style.lineHeight = title.style.height;
title.style.fontSize = "50px";// 字体大小
// title.style.fontFamily = "华文行楷";// 字体类型
// title.style.color = "red";// 字体颜色
title.style.float = "left";
title.style.cursor = "default";
// 创建设置栏
var mySetup = document.createElement("div");// 创建标签
mySetup.style.content = "ON";
mySetup.style.width = "13%";
mySetup.style.float = "left";
mySetup.style.background = "#dddddd";
mySetup.style.paddingLeft = "10px";
mySetup.style.paddingRight = "5px";
mySetup.style.height = "70px";
mySetup.style.lineHeight = "70px";
mySetup.style.textAlign = "center";
// 创建是否显示数字选项
var showNumber = document.createElement("input");// 创建标签
showNumber.type = "text";
showNumber.checked = true;
showNumber.style.height = 23;
showNumber.style.width = 23;
showNumber.style.fontWeight = "bold";
showNumber.style.color = "black";
showNumber.style.textAlign = "center";
showNumber.style.background = "#ffffff";
showNumber.style.marginRight = "5px";
showNumber.style.cursor = "pointer";
if(isShow){
showNumber.value = "√";
}else{
showNumber.value = "";
}
showNumber.onfocus = function(){
this.blur();
}
showNumbers.push(showNumber);
// 添加控制显示数字功能
showNumber.onclick = function(){
isShow = !isShow;
setCookie("isShowStepNumber=" + isShow);
// 重新画所有棋盘
rePrintAllStones();
}
// 创建“数字”标签
var showNumberTips = document.createElement("span");// 创建标签
showNumberTips.innerHTML = "数字";
showNumberTips.style.cursor = "default";
// showNumberTips.style.fontFamily = "宋体";
showNumberTips.style.fontWeight = "bold";
mySetup.appendChild(showNumber);
mySetup.appendChild(showNumberTips);
// 创建背景颜色设置栏
var colorMenu = document.createElement("div");
colorMenu.style.width = "15%"
colorMenu.style.background = "#eeeeee";
colorMenu.style.float = "left";
colorMenu.style.height = "70px";
colorMenu.style.textAlign = "center";
// 创建“背景色”标签
var colorTips = document.createElement("div");// 创建标签
colorTips.innerHTML = "背景色";
colorTips.style.cursor = "default";
// colorTips.style.fontFamily = "宋体";
colorTips.style.fontWeight = "bold";
colorTips.style.height = "70px";
colorTips.style.paddingTop = "5px";
colorTips.onselectstart = function(){
return false;
};
// 双击恢复默认背景色
colorTips.ondblclick = function(){
chessboardColorView = "#dead00";
chessboardColorEdit = "#efce73";
setCookie("chessboardColorView=#dead00;chessboardColorEdit=#dead00")
rePrintAllStones();
};
// 鼠标放上去显示提示
colorTips.onmousemove = function(e){
if(!bkstate){
return;
}
ljtips.innerHTML = "双击此处恢复默认颜色";
ljtips.style.display = "";
ljtips.style.left = e.pageX + 10 +"px";
ljtips.style.top = e.pageY - 25 + "px";
}
// 鼠标离开隐藏提示
colorTips.onmouseout = function(e){
ljtips.innerHTML = "";
ljtips.style.display = "none";
}
colorMenu.appendChild(colorTips);
// 设置背景颜色按钮
var colorButton = document.createElement("input");
colorButton.type = "color";
colorButton.style.height = "30px";
colorButton.target = "c" + i;
colorButton.id = "colorc" + i;
colorButton.value = chessboardColorView;
// 改变背景色
colorButton.onchange = function(){
if(cavs.get(this.target).isEdit){
chessboardColorEdit = this.value;
setCookie("chessboardColorEdit=" + chessboardColorEdit);
}else{
chessboardColorView = this.value;
setCookie("chessboardColorView=" + chessboardColorView);
}
rePrintAllStones();
}
colorButton.onmouseenter = function(){
bkstate = false;
ljtips.innerHTML = "";
ljtips.style.display = "none";
}
colorButton.onmouseout = function(){
bkstate = true;
}
backgrounds.push(colorButton);
colorTips.appendChild(colorButton);
// 复制棋谱功能栏
var copyMenu = document.createElement("div");
copyMenu.style.float = "left";
copyMenu.style.height = "70px";
copyMenu.style.background = "#abedef";
// 复制棋谱按钮
var copyButton = document.createElement("button");
copyButton.type = "button";
copyButton.target = "c" + i;
copyButton.innerHTML = "复制棋谱";
copyButton.style.textAlign = "center";
copyButton.style.width = "60px";
copyButton.style.height = "70px";
copyButton.style.fontSize = "18px";
copyButton.style.padding = "0 0 0 0";
// 添加复制功能
copyButton.onclick = function(){
copyarea.innerHTML = cavs.get(this.target).lib.join(" ");
copyarea.style.display = "";
copyarea.select();
document.execCommand("Copy"); // 执行浏览器复制命令
copyarea.style.display = "none";
alert("已复制到剪贴板!");
}
copyMenu.appendChild(copyButton);
// 棋评功能栏
var commentMenu = document.createElement("div");
commentMenu.style.width = "93px";
commentMenu.style.float = "left";
commentMenu.style.height = "70px";
commentMenu.style.textAlign = "center";
// 查看棋评按钮
var commentButton = document.createElement("input");
commentButton.type = "button";
commentButton.name = "commentButton";
commentButton.value = "查看棋评";
commentButton.style.fontSize = "18px";
commentButton.style.height = "70px";
commentButton.style.width = "100%";
commentButton.onclick = function(){
var value = this.value;
var coms = document.getElementsByName("commentButton");
for(var j=0; j<coms.length; j++){
if(coms[j].disabled){
continue;
}
coms[j].value = "查看棋评";
}
this.value = value;
if(this.value == "查看棋评"){
this.value = "关闭棋评";
commentContent.innerHTML = this.comment;
chessCommentDiv.style.display = "";
var lc = getAbsolutePosition(this);
chessCommentDiv.style.left = lc.x + 93 + "px";
chessCommentDiv.style.top = lc.y + 70 + "px";
}else{
this.value = "查看棋评";
commentContent.innerHTML = "";
chessCommentDiv.style.display = "none";
}
}
commentMenu.appendChild(commentButton);
// 组装设置功能栏
headMenu.appendChild(title);
headMenu.appendChild(mySetup);
headMenu.appendChild(colorMenu);
headMenu.appendChild(copyMenu);
headMenu.appendChild(commentMenu);
// 将头部信息栏添加到页面
fiveObjF.appendChild(headMenu);
// 如有棋评,隐藏
var chessComment = fiveObjF.nextElementSibling;
if(chessComment == undefined){
commentButton.value = "无棋评";
commentButton.disabled = true;
}else{
commentButton.comment = chessComment.innerHTML;
chessComment.innerHTML = "";
}
// 创建棋盘画布
var canvas = document.createElement("canvas");// 创建标签
canvas.id = "c" + i;// 设置ID
canvas.height = 510;// 高度
canvas.width = 525;// 宽度
fiveObjF.appendChild(canvas);// 添加到页面
// 创建功能栏
var toolbar = document.createElement("div");// 创建标签
toolbar.style.height = 50;
toolbar.style.width = 525;
toolbar.style.background = "#cccccc";// 背景颜色
toolbar.style.padding = "5 0 5 0";// 文字位置
// 创建"去棋谱首"功能按钮
var btBegin = document.createElement("input");
btBegin.value = "[<";// 按钮名称
btBegin.type = "button";// 类型:按钮
btBegin.style.fontSize = "20px";
btBegin.style.height = 50;
btBegin.style.width = 75;
btBegin.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btBegin.onclick = function(){// 绑定功能
goBegin(this);
}
// 创建"快退"功能按钮
var btRewind = document.createElement("input");
btRewind.value = "<<";
btRewind.type = "button";
btRewind.style.fontSize = "20px";
btRewind.style.height = 50;
btRewind.style.width = 75;
btRewind.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btRewind.onclick = function(){// 绑定功能
rewind(this);
}
// 创建"后退"功能按钮
var btBack = document.createElement("input");
btBack.value = "<";
btBack.type = "button";
btBack.style.fontSize = "20px";
btBack.style.height = 50;
btBack.style.width = 75;
btBack.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btBack.onclick = function(){// 绑定功能
goBack(null, this);
}
// 创建"前进"功能按钮
var btForward = document.createElement("input");
btForward.value = ">";
btForward.type = "button";
btForward.style.fontSize = "20px";
btForward.style.height = 50;
btForward.style.width = 75;
btForward.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btForward.onclick = function(){// 绑定功能
goForward(null, this);
}
// 创建"快进"功能按钮
var btFastForward = document.createElement("input");
btFastForward.value = ">>";
btFastForward.type = "button";
btFastForward.style.fontSize = "20px";
btFastForward.style.height = 50;
btFastForward.style.width = 75;
btFastForward.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btFastForward.onclick = function(){// 绑定功能
fastForward(this);
}
// 创建"去棋谱尾"功能按钮
var btEnd = document.createElement("input");
btEnd.value = ">]";
btEnd.type = "button";
btEnd.style.fontSize = "20px";
btEnd.style.height = 50;
btEnd.style.width = 75;
btEnd.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btEnd.onclick = function(){// 绑定功能
goEnd(this);
}
// 创建"研究/看谱"功能按钮
var btEdit = document.createElement("input");
btEdit.value = "研究";
btEdit.type = "button";
btEdit.style.fontSize = "20px";
btEdit.style.height = 50;
btEdit.style.width = 75;
btEdit.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btEdit.onclick = function(){// 绑定功能
edit(this);
}
// 组装起来
toolbar.appendChild(btBegin);
toolbar.appendChild(btRewind);
toolbar.appendChild(btBack);
toolbar.appendChild(btForward);
toolbar.appendChild(btFastForward);
toolbar.appendChild(btEnd);
toolbar.appendChild(btEdit);
fiveObjF.appendChild(toolbar);
// 初始化数据
init(fiveObj.value, canvas);
title.innerHTML = getOpenName(canvas.id);// 显示开局名称
// 鼠标点击功能
canvas.onmousedown = function(e){
// 获得诶点击的棋盘
var me = e.target;
// 获得棋盘数据
var data = cavs.get(me.id);
// 判断是否是"研究"状态
if(data.isEdit){// 研究状态, 可以落子
// 判断鼠标左右键: 0是左键, 执行落子功能, 2是右键, 后退一步
if(e.button == 0){
// 获得落子坐标
var lcCode = getLocation(e.clientX, e.clientY, me);
// 如果坐标有效且当前位置没有棋子, 则可以落子
if(lcCode != null && !haveStone(lcCode, data)){
// 落子之前, 需要把当前步数之后的数据清除
data.lib.length = data.step;
// 写入新的数据
data.lib.push(lcCode);
// 步数加一
data.step ++;
// 重新绘制棋局
rePrintStones(me);
}
}else if(e.button == 2){
// 鼠标右键, 后退一步
goBack(me);
}
}else{// "看谱"状态
// 0是左键, 前进一步, 2是右键, 后退一步
if(e.button == 0){
goForward(me);
}else if(e.button == 2){
goBack(me);
}
}
}
}
/**
画棋盘的方法
*/
function qipan(canvas){
// 获得画笔
var context = canvas.getContext('2d');
// "研究"状态和"看谱"状态棋盘背景颜色不一样
if(cavs.get(canvas.id).isEdit){
context.fillStyle = chessboardColorEdit;
}else{
context.fillStyle = chessboardColorView;
}
context.lineWidth = 1;// 线条宽度
context.fillRect(0, 0, canvas.width, canvas.height);// 画背景
context.strokeStyle = "rgb(0,0,0)";// 线条颜色
context.fillStyle = "rgb(0,0,0)";// 线条内部填充颜色
context.beginPath();// 开启路径
context.font = "bold 15pt Consolas";// 字体
context.textAlign = "center";// 字体水平居中
context.textBaseline = "middle";// 字体垂直居中
context.save();// 保存画笔状态
context.translate(0.5, 0.5);// 为宜0.5像素, 这样棋盘的线条会比较细
// 画横线
for(var j=0; j<=14; j++){
context.moveTo(left, top + j*r);
context.lineTo(14*r+left, top + j*r);
// 横坐标
context.fillText((15 - j), left - 40, top + j*r + 4);
}
// 画竖线
for(var j=0; j<=14; j++){
context.moveTo(left + j*r, top);
context.lineTo(left + j*r, 14*r+top);
// 纵坐标
context.fillText((xs[j]), left + j*r, top + 14*r + 35);
}
context.stroke();// 画到棋盘上
var h = 4;// 星位标记宽度
var s = h/2;// 偏移距离, 为了让星位正好在标记正中央
// 画星位
context.fillRect(left + r*7 - s, top + r*7 - s, h, h);// 天元
context.fillRect(left + r*3 - s, top + r*3 - s, h, h);
context.fillRect(left + r*11 - s, top + r*11 - s, h, h);
context.fillRect(left + r*11 - s, top + r*11 - s, h, h);
context.fillRect(left + r*3 - s, top + r*11 - s, h, h);
context.fillRect(left + r*11 - s, top + r*3 - s, h, h);
context.closePath();// 关闭路径
context.restore();// 恢复画笔状态
}
/**
获得落子坐标方法
可以落子的坐标都在棋盘线的交叉点上, 此方法来计算距离鼠标点击位置最近的落子坐标
*/
function getLocation(x, y, canvas){
// 获得画布的绝对位置
var bbox = canvas.getBoundingClientRect();
// 计算鼠标点击的坐标
var x = (x - bbox.left) * (canvas.width/bbox.width);
var y = (y - bbox.top) * (canvas.height/bbox.height);
// 如果鼠标点击在棋盘合理的范围内(棋盘向外10像素的范围都算合理), 则开始计算落子坐标
if(x > left - 10 && y > top - 10 && x < left + r*14 + 10 && y < top + r*14 + 10){
// 横坐标修正, 以便后续计算
if(x < left){
x = left;
}else if(x > r*14 + left){
x = left + r*14;
}
// 纵坐标修正
if(y < top){
y = top;
}else if(y > top + r*14){
y = top + r*14;
}
// 减去边距
var ex = x - left;
var ey = y - top;
// 计算减去后的数值包含几个棋盘格子的宽度, 四舍五入, 这样就得到了距离鼠标点击位置最近的落子坐标
ex = (ex / r).toFixed(0) ;
ey = 15 - (ey / r).toFixed(0);
// 转换成标准格式, 如:H8
return xs[ex] + "" + ey;
}else{// 无效点击不返回坐标
return null;
}
}
/**
画黑棋
*/
function drawBlack(lcCode, canvas, num){
// 解析坐标
var lc = parseLc(lcCode);
// 获得画笔
var cx = canvas.getContext("2d");
cx.beginPath();// 开启路径
cx.arc(lc.x, lc.y, r/2 - 2, 0, Math.PI*2, true);// 画圆
cx.fillStyle = "#000000";// 设置棋子颜色
cx.fill();// 填充
// 判断是否显示步数
if(isShow){
cx.font = "bold 11pt Arial";// 设置画笔字体
cx.fillStyle = "#ffffff";// 设置字体颜色
cx.fillText(num, lc.x, lc.y + 1);// 画步数
}
cx.closePath();// 关闭路径
}
/**
画白棋
*/
function drawWhite(lcCode, canvas, num){
// 解析坐标
var lc = parseLc(lcCode);
var cx = canvas.getContext("2d");// 获得画笔
cx.beginPath();// 开启路径
cx.arc(lc.x, lc.y, r/2 - 2, 0, Math.PI*2, true);// 画圆
cx.fillStyle = "#ffffff";// 设置棋子颜色
cx.strokeStyle = "#000000";// 设置白棋边缘颜色
cx.lineWidth = 1;// 线条宽度
cx.fill();// 填充
cx.stroke();// 描边
// 判断是否显示步数
if(isShow){
cx.fillStyle = "#000000";// 设置字体颜色
cx.fillText(num, lc.x, lc.y + 1);// 画步数
}
cx.closePath();// 关闭路径
}
/**
解析坐标方法
将对应的字母转换成数字
*/
function parseLc(lc){
if(lc == null){return lc;}
return {x: map[lc.substring(0, 1)] * r + left, y: (15 - lc.substring(1, lc.length)) * r + top};
}
/**
判断当前位置是否有棋子
*/
function haveStone(lcCode, data){
/* 遍历当前棋盘的棋谱数据, 判断是否包含此位置
注意, 此处不一定是完全遍历, 只遍历到当前步数
后面的步数未显示在棋盘上, 视为未落子
*/
for(var i=0; i<data.step; i++){
if(lcCode.toUpperCase() == data.lib[i].toUpperCase()){
return true;
}
}
return false;
}
/**
初始化棋盘
*/
function init(data, canvas){
// 解析棋谱
var ss = data.split(" ");
// 保存棋谱数据
cavs.set(canvas.id, {lib: ss, step: ss.length, canvas: canvas, isEdit: false, tstep:0, tlib: []});
// 画棋盘
qipan(canvas);
// 画棋子
for(var i=0; i<ss.length; i++){
// 奇数步画黑棋, 偶数步画白棋
if(i%2==0){
drawBlack(ss[i], canvas, i+1);
}else{
drawWhite(ss[i], canvas, i+1);
}
}
}
/**
去棋局首
*/
function goBegin(btBegin){
// 获得当前棋盘信息
var data = cavs.get(btBegin.target);
// 设置步数为1
data.step = 1;
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
快退
*/
function rewind(btRewind){
// 获得当前棋盘信息
var data = cavs.get(btRewind.target);
// 默认回退5步
var backSteps = 5;
// 如果当前小于等于5步, 则回到第1步
if(data.step <= backSteps){
data.step = 1;
}else{
// 步数减5
data.step = data.step - backSteps;
}
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
后退
*/
function goBack(canvas, bt){
// 棋盘为空, 则重新获得棋盘
if(canvas == null){
canvas = cavs.get(bt.target).canvas;
}
// 获得当前棋盘信息
var data = cavs.get(canvas.id);
// 如果当前步数大于1步, 则步数减1
if(data.step > 1){
data.step --;
}
// 重新绘制棋局
rePrintStones(canvas);
}
/**
前进
*/
function goForward(canvas, bt){
// 棋盘为空, 则重新获得棋盘
if(canvas == null){
canvas = cavs.get(bt.target).canvas;
}
// 获得当前棋盘信息
var data = cavs.get(canvas.id);
if(data.step < data.lib.length){
// 如果不是最后一步, 则步数加1
data.step ++;
// 重新绘制棋局
rePrintStones(canvas);
}
}
/**
快进
*/
function fastForward(btFastForward){
// 获得当前棋盘信息
var data = cavs.get(btFastForward.target);
// 默认前进5步
var forwardSteps = 5;
// 如果剩余棋谱不够5步, 则步数置为最后一步
if(data.step + forwardSteps > data.lib.length){
data.step = data.lib.length;
}else{
// 剩余棋谱够5步, 则步数加5
data.step += forwardSteps;
}
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
去棋谱尾
*/
function goEnd(btEnd){
// 获得当前棋盘信息
var data = cavs.get(btEnd.target);
// 步数置为最后一步
data.step = data.lib.length;
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
重绘棋局方法
*/
function rePrintStones(canvas){
// 获得最新棋盘信息
var data = cavs.get(canvas.id);
var step = data.step;
var stones = data.lib;
// 绘制棋盘
qipan(canvas);
// 绘制棋子
for(var i=0; i<step; i++){
if(i%2==0){
drawBlack(stones[i], canvas, i+1);
}else{
drawWhite(stones[i], canvas, i+1);
}
}
}
/**
重绘所有棋盘
*/
function rePrintAllStones(){
// 更新是否显示数字选项
for(var i=0; i<showNumbers.length; i++){
if(isShow){
showNumbers[i].value = "√";
}else{
showNumbers[i].value = "";
}
}
for(var i=0; i<cavs.size; i++){
var data = cavs.get("c" + i);
rePrintStones(data.canvas);
if(data.isEdit){
backgrounds[i].value = chessboardColorEdit;
}else{
backgrounds[i].value = chessboardColorView;
}
}
}
/**
"研究/看谱"功能
*/
function edit(btEdit){
// 获得当前棋盘信息
var data = cavs.get(btEdit.target);
// 棋盘状态转换
data.isEdit = !data.isEdit;
// 判断棋盘状态
if(data.isEdit){
// 如果当前是"研究"状态, 则按钮名称需改为"看谱"
btEdit.value = "看谱";
// 将当前步数备份
data.tstep = data.step;
// 将当前棋谱备份, 注意, 此处不可以浅复制
data.tlib = new Array();
data.tlib = data.tlib.concat(data.lib);
// 修改背景色按钮颜色
document.getElementById("color" + btEdit.target).value = chessboardColorEdit;
}else{
// 如果当前是"看谱"状态, 则按钮名称需改为"研究"
btEdit.value = "研究";
// 将备份的步数恢复
data.step = data.tstep;
// 将备份的棋谱恢复
data.lib = new Array();
data.lib = data.lib.concat(data.tlib);
// 修改背景色按钮颜色
document.getElementById("color" + btEdit.target).value = chessboardColorView;
}
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
判断开局名称
*/
function getOpenName(canvasId){
// 获得当前棋盘信息
var stones = cavs.get(canvasId).lib;
// 大于等于3步才进行判断
if(stones.length >= 3){
// 获得前三步
var s1 = stones[0];
var s2 = stones[1];
var s3 = stones[2];
// 判断第一步, 如果在天元, 则进行下一步
if("h8" == s1){
// 判断第二步, 如果在天元1X1范围内, 则判断第三步, 这里直指斜指分开进行判断, 代码比较清晰
if("h9,h7,g8,i8".indexOf(s2) >= 0){
if("h9" == s2){
if("f10" == s3 || "j10" == s3){
return "疏星";
}
if("f9" == s3 || "j9" == s3){
return "残月";
}
if("f8" == s3 || "j8" == s3){
return "金星";
}
if("f7" == s3 || "j7" == s3){
return "新月";
}
if("f6" == s3 || "j6" == s3){
return "游星";
}
if("g10" == s3 || "i10" == s3){
return "溪月";
}
if("g9" == s3 || "i9" == s3){
return "花月";
}
if("g8" == s3 || "i8" == s3){
return "雨月";
}
if("g7" == s3 || "i7" == s3){
return "丘月";
}
if("g6" == s3 || "i6" == s3){
return "山月";
}
if("h10" == s3){
return "寒星";
}
if("h7" == s3){
return "松月";
}
if("h6" == s3){
return "瑞星";
}
return "其他开局";
}else if("h7" == s2){
if("f9" == s3 || "j9" == s3){
return "疏星";
}
if("f7" == s3 || "j7" == s3){
return "残月";
}
if("f8" == s3 || "j8" == s3){
return "金星";
}
if("f9" == s3 || "j9" == s3){
return "新月";
}
if("f10" == s3 || "j10" == s3){
return "游星";
}
if("g6" == s3 || "i6" == s3){
return "溪月";
}
if("g7" == s3 || "i7" == s3){
return "花月";
}
if("g8" == s3 || "i8" == s3){
return "雨月";
}
if("g9" == s3 || "i9" == s3){
return "丘月";
}
if("g10" == s3 || "i10" == s3){
return "山月";
}
if("h6" == s3){
return "寒星";
}
if("h9" == s3){
return "松月";
}
if("h10" == s3){
return "瑞星";
}
return "其他开局";
}else if("g8" == s2){
if("f10" == s3 || "f6" == s3){
return "疏星";
}
if("g10" == s3 || "g6" == s3){
return "残月";
}
if("h10" == s3 || "h6" == s3){
return "金星";
}
if("i10" == s3 || "i6" == s3){
return "新月";
}
if("j10" == s3 || "j6" == s3){
return "游星";
}
if("f7" == s3 || "f9" == s3){
return "溪月";
}
if("g7" == s3 || "g9" == s3){
return "花月";
}
if("h7" == s3 || "h9" == s3){
return "雨月";
}
if("i7" == s3 || "i9" == s3){
return "丘月";
}
if("j7" == s3 || "j9" == s3){
return "山月";
}
if("f8" == s3){
return "寒星";
}
if("i8" == s3){
return "松月";
}
if("j8" == s3){
return "瑞星";
}
return "其他开局";
}else if("i8" == s2){
if("j10" == s3 || "j6" == s3){
return "疏星";
}
if("i10" == s3 || "i6" == s3){
return "残月";
}
if("h10" == s3 || "h6" == s3){
return "金星";
}
if("g10" == s3 || "g6" == s3){
return "新月";
}
if("f10" == s3 || "f6" == s3){
return "游星";
}
if("j7" == s3 || "j9" == s3){
return "溪月";
}
if("i7" == s3 || "i9" == s3){
return "花月";
}
if("h7" == s3 || "h9" == s3){
return "雨月";
}
if("f7" == s3 || "f9" == s3){
return "丘月";
}
if("j7" == s3 || "j9" == s3){
return "山月";
}
if("j8" == s3){
return "寒星";
}
if("g8" == s3){
return "松月";
}
if("f8" == s3){
return "瑞星";
}
return "其他开局";
}
}else if("i9,i7,g7,g9".indexOf(s2) >= 0){
if("i9" == s2){
if("f10" == s3 || "j6" == s3){
return "流星";
}
if("f9" == s3 || "i6" == s3){
return "岚月";
}
if("f8" == s3 || "h6" == s3){
return "明星";
}
if("f7" == s3 || "g6" == s3){
return "名月";
}
if("f6" == s3){
return "彗星";
}
if("g7" == s3){
return "斜月";
}
if("g8" == s3 || "h7" == s3){
return "银月";
}
if("g9" == s3 || "i7" == s3){
return "蒲月";
}
if("g10" == s3 || "j7" == s3){
return "水月";
}
if("h10" == s3 || "j8" == s3){
return "恒星";
}
if("h9" == s3 || "i8" == s3){
return "云月";
}
if("i10" == s3 || "j9" == s3){
return "峡月";
}
if("j10" == s3){
return "长星";
}
return "其他开局";
}else if("i7" == s2){
if("j10" == s3 || "f6" == s3){
return "流星";
}
if("i10" == s3 || "f7" == s3){
return "岚月";
}
if("f8" == s3 || "h10" == s3){
return "明星";
}
if("g10" == s3 || "f9" == s3){
return "名月";
}
if("f10" == s3){
return "彗星";
}
if("g9" == s3){
return "斜月";
}
if("g8" == s3 || "h9" == s3){
return "银月";
}
if("i9" == s3 || "g7" == s3){
return "蒲月";
}
if("g6" == s3 || "j10" == s3){
return "水月";
}
if("h6" == s3 || "j8" == s3){
return "恒星";
}
if("h7" == s3 || "i8" == s3){
return "云月";
}
if("i6" == s3 || "j7" == s3){
return "峡月";
}
if("j6" == s3){
return "长星";
}
return "其他开局";
}else if("g7" == s2){
if("f10" == s3 || "j6" == s3){
return "流星";
}
if("g10" == s3 || "j7" == s3){
return "岚月";
}
if("j8" == s3 || "h10" == s3){
return "明星";
}
if("i10" == s3 || "j9" == s3){
return "名月";
}
if("j10" == s3){
return "彗星";
}
if("i9" == s3){
return "斜月";
}
if("i8" == s3 || "h9" == s3){
return "银月";
}
if("g9" == s3 || "i7" == s3){
return "蒲月";
}
if("i6" == s3 || "f10" == s3){
return "水月";
}
if("h6" == s3 || "f8" == s3){
return "恒星";
}
if("h7" == s3 || "g8" == s3){
return "云月";
}
if("g6" == s3 || "f7" == s3){
return "峡月";
}
if("f6" == s3){
return "长星";
}
return "其他开局";
}else if("g9" == s2){
if("j10" == s3 || "f6" == s3){
return "流星";
}
if("j9" == s3 || "g6" == s3){
return "岚月";
}
if("j8" == s3 || "h6" == s3){
return "明星";
}
if("j7" == s3 || "i6" == s3){
return "名月";
}
if("j6" == s3){
return "彗星";
}
if("i7" == s3){
return "斜月";
}
if("i8" == s3 || "h7" == s3){
return "银月";
}
if("i9" == s3 || "g7" == s3){
return "蒲月";
}
if("i10" == s3 || "f7" == s3){
return "水月";
}
if("h10" == s3 || "f8" == s3){
return "恒星";
}
if("h9" == s3 || "g8" == s3){
return "云月";
}
if("g10" == s3 || "f9" == s3){
return "峡月";
}
if("f10" == s3){
return "长星";
}
return "其他开局";
}
}else{
return "其他开局";
}
}else{
return "其他开局";
}
}else{
return "未知";
}
}
/**
设置Cookie
*/
function setCookie(data){
var expireDate = new Date();
expireDate.setFullYear(3017);
document.cookie = data + ";expires=" + expireDate.toGMTString();
}
/**
读取Cookie
*/
function readCookie(){
var cs = document.cookie.split(";");
for(var i=0; i<cs.length; i++){
if(cs[i].trim().indexOf("isShowStepNumber") == 0){
isShow = cs[i].split("=")[1] == "true";
}
if(cs[i].trim().indexOf("chessboardColorEdit") == 0){
chessboardColorEdit = cs[i].split("=")[1];
}
if(cs[i].trim().indexOf("chessboardColorView") == 0){
chessboardColorView = cs[i].split("=")[1];
}
}
}
/**
获得元素的绝对位置
*/
function getAbsolutePosition(obj){
var left = obj.offsetLeft;
var o = obj;
while(o.offsetParent!=null) {
var oParent = o.offsetParent;
left += oParent.offsetLeft;
o = oParent;
}
var top = obj.offsetTop;
o = obj;
while(o.offsetParent!=null) {
var oParent = o.offsetParent;
top += oParent.offsetTop;
o = oParent;
}
return {x:left, y:top};
}
****************************
****************************
初次采取此方案者进行下面设置
1下载火狐浏览器
2安装greasemonkey插件
点击右上角菜单,选择“附加组件”

点击左边“扩展”菜单,然后在右上角的搜索框中输入“greasemonkey”,点击“放大镜”图标进行搜索


安装下列插件:

点击“安装”按钮,安装完毕后会有如下提示:

点击“立即重启”重启火狐浏览器,重启完之后,浏览器右上角会有Greasemonkey图标


点击右边的“倒三角”,选择“新建用户脚本”


在弹出的窗口中填写如下内容:

点击“确定”,进入脚本编辑界面:


将文档最下方的代码粘贴到里面:
可能会有不允许粘贴的情况,这时需要先把提示语中的英文记下来,在第9行代码下面输入:// 你记下的英文
然后就可以粘贴刚才的代码了


按Ctrl + S 保存,然后关闭页面即可。
下面就可以浏览励精教室网站了。
代码内容(分割线下面的代码都要复制进去):
-----------------------------------------------------------------------------------------------------------
/** 初始化变量 */
var left = 60;// 左边距
var top = 20;// 上边距
var r = 31;// 棋盘格子宽度
var xs = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"];// 横坐标集
var map = {A : 0, B : 1, C : 2, D : 3, E : 4, F : 5, G : 6, H : 7, I : 8, J : 9, K : 10, L : 11, M : 12, N : 13, O : 14,
a : 0, b : 1, c : 2, d : 3, e : 4, f : 5, g : 6, h : 7, i : 8, j : 9, k : 10, l : 11, m : 12, n : 13, o : 14};// 坐标字典
var cavs = new Map();// 棋盘数据集
var showNumbers = [];// 数字按钮集
var backgrounds = [];// 背景按钮集
var isShow = true;// 是否显示数字
var chessboardColorView = "#dead00";// 看谱时棋盘背景色
var chessboardColorEdit = "#efce73";// 编辑时棋盘背景色
var bkstate = true;// 辅助变量
// 屏蔽右键
document.oncontextmenu = function(){return false;}
// 复制棋谱功能辅助栏
var copyarea = document.createElement("textarea");
copyarea.style.display = "none";
copyarea.id = "copyarea";
document.body.appendChild(copyarea);
// 背景色复位提示语栏
var ljtips = document.createElement("div");
ljtips.style.display = "none";
ljtips.style.position = "absolute";
ljtips.style.background = "#f9e4a9";
document.body.appendChild(ljtips);
// 棋评栏
var chessCommentDiv = document.createElement("div");
chessCommentDiv.style.display = "none";
chessCommentDiv.style.position = "absolute";
// 棋评内容区
var commentContent = document.createElement("textarea");
commentContent.style.height = "510px";
commentContent.style.width = "200px";
commentContent.style.background = "#efce73";
commentContent.readOnly = true;
// 添加到页面
chessCommentDiv.appendChild(commentContent);
document.body.appendChild(chessCommentDiv);
// 读取配置
readCookie();
/** 获得所有棋谱内容, 并初始化*/
// 此标签含有棋谱数据
var fiveObjs = document.getElementsByName('moves');
// 遍历棋谱数据
for(var i=0; i<fiveObjs.length; i++){
// 获得棋谱数据标签
var fiveObj = fiveObjs[i];
// 找到父节点
var fiveObjF = fiveObj.parentNode;
// 去掉java代码
fiveObjF.code = "";
// 去掉无关内容
fiveObjF.innerHTML = fiveObjF.innerHTML.substring(fiveObjF.innerHTML.indexOf("<param"));
// 创建头部信息栏
var headMenu = document.createElement("div");
headMenu.style.width = "525px";// 宽度
headMenu.style.height = "70px";
// 创建棋谱开局信息
var title = document.createElement("div");// 创建标签
title.style.width = "40%";// 宽度
title.style.height = "70px";
title.style.background = "#cccccc";// 背景颜色
title.style.textAlign = "center";
title.style.lineHeight = title.style.height;
title.style.fontSize = "50px";// 字体大小
// title.style.fontFamily = "华文行楷";// 字体类型
// title.style.color = "red";// 字体颜色
title.style.float = "left";
title.style.cursor = "default";
// 创建设置栏
var mySetup = document.createElement("div");// 创建标签
mySetup.style.content = "ON";
mySetup.style.width = "13%";
mySetup.style.float = "left";
mySetup.style.background = "#dddddd";
mySetup.style.paddingLeft = "10px";
mySetup.style.paddingRight = "5px";
mySetup.style.height = "70px";
mySetup.style.lineHeight = "70px";
mySetup.style.textAlign = "center";
// 创建是否显示数字选项
var showNumber = document.createElement("input");// 创建标签
showNumber.type = "text";
showNumber.checked = true;
showNumber.style.height = 23;
showNumber.style.width = 23;
showNumber.style.fontWeight = "bold";
showNumber.style.color = "black";
showNumber.style.textAlign = "center";
showNumber.style.background = "#ffffff";
showNumber.style.marginRight = "5px";
showNumber.style.cursor = "pointer";
if(isShow){
showNumber.value = "√";
}else{
showNumber.value = "";
}
showNumber.onfocus = function(){
this.blur();
}
showNumbers.push(showNumber);
// 添加控制显示数字功能
showNumber.onclick = function(){
isShow = !isShow;
setCookie("isShowStepNumber=" + isShow);
// 重新画所有棋盘
rePrintAllStones();
}
// 创建“数字”标签
var showNumberTips = document.createElement("span");// 创建标签
showNumberTips.innerHTML = "数字";
showNumberTips.style.cursor = "default";
// showNumberTips.style.fontFamily = "宋体";
showNumberTips.style.fontWeight = "bold";
mySetup.appendChild(showNumber);
mySetup.appendChild(showNumberTips);
// 创建背景颜色设置栏
var colorMenu = document.createElement("div");
colorMenu.style.width = "15%"
colorMenu.style.background = "#eeeeee";
colorMenu.style.float = "left";
colorMenu.style.height = "70px";
colorMenu.style.textAlign = "center";
// 创建“背景色”标签
var colorTips = document.createElement("div");// 创建标签
colorTips.innerHTML = "背景色";
colorTips.style.cursor = "default";
// colorTips.style.fontFamily = "宋体";
colorTips.style.fontWeight = "bold";
colorTips.style.height = "70px";
colorTips.style.paddingTop = "5px";
colorTips.onselectstart = function(){
return false;
};
// 双击恢复默认背景色
colorTips.ondblclick = function(){
chessboardColorView = "#dead00";
chessboardColorEdit = "#efce73";
setCookie("chessboardColorView=#dead00;chessboardColorEdit=#dead00")
rePrintAllStones();
};
// 鼠标放上去显示提示
colorTips.onmousemove = function(e){
if(!bkstate){
return;
}
ljtips.innerHTML = "双击此处恢复默认颜色";
ljtips.style.display = "";
ljtips.style.left = e.pageX + 10 +"px";
ljtips.style.top = e.pageY - 25 + "px";
}
// 鼠标离开隐藏提示
colorTips.onmouseout = function(e){
ljtips.innerHTML = "";
ljtips.style.display = "none";
}
colorMenu.appendChild(colorTips);
// 设置背景颜色按钮
var colorButton = document.createElement("input");
colorButton.type = "color";
colorButton.style.height = "30px";
colorButton.target = "c" + i;
colorButton.id = "colorc" + i;
colorButton.value = chessboardColorView;
// 改变背景色
colorButton.onchange = function(){
if(cavs.get(this.target).isEdit){
chessboardColorEdit = this.value;
setCookie("chessboardColorEdit=" + chessboardColorEdit);
}else{
chessboardColorView = this.value;
setCookie("chessboardColorView=" + chessboardColorView);
}
rePrintAllStones();
}
colorButton.onmouseenter = function(){
bkstate = false;
ljtips.innerHTML = "";
ljtips.style.display = "none";
}
colorButton.onmouseout = function(){
bkstate = true;
}
backgrounds.push(colorButton);
colorTips.appendChild(colorButton);
// 复制棋谱功能栏
var copyMenu = document.createElement("div");
copyMenu.style.float = "left";
copyMenu.style.height = "70px";
copyMenu.style.background = "#abedef";
// 复制棋谱按钮
var copyButton = document.createElement("button");
copyButton.type = "button";
copyButton.target = "c" + i;
copyButton.innerHTML = "复制棋谱";
copyButton.style.textAlign = "center";
copyButton.style.width = "60px";
copyButton.style.height = "70px";
copyButton.style.fontSize = "18px";
copyButton.style.padding = "0 0 0 0";
// 添加复制功能
copyButton.onclick = function(){
copyarea.innerHTML = cavs.get(this.target).lib.join(" ");
copyarea.style.display = "";
copyarea.select();
document.execCommand("Copy"); // 执行浏览器复制命令
copyarea.style.display = "none";
alert("已复制到剪贴板!");
}
copyMenu.appendChild(copyButton);
// 棋评功能栏
var commentMenu = document.createElement("div");
commentMenu.style.width = "93px";
commentMenu.style.float = "left";
commentMenu.style.height = "70px";
commentMenu.style.textAlign = "center";
// 查看棋评按钮
var commentButton = document.createElement("input");
commentButton.type = "button";
commentButton.name = "commentButton";
commentButton.value = "查看棋评";
commentButton.style.fontSize = "18px";
commentButton.style.height = "70px";
commentButton.style.width = "100%";
commentButton.onclick = function(){
var value = this.value;
var coms = document.getElementsByName("commentButton");
for(var j=0; j<coms.length; j++){
if(coms[j].disabled){
continue;
}
coms[j].value = "查看棋评";
}
this.value = value;
if(this.value == "查看棋评"){
this.value = "关闭棋评";
commentContent.innerHTML = this.comment;
chessCommentDiv.style.display = "";
var lc = getAbsolutePosition(this);
chessCommentDiv.style.left = lc.x + 93 + "px";
chessCommentDiv.style.top = lc.y + 70 + "px";
}else{
this.value = "查看棋评";
commentContent.innerHTML = "";
chessCommentDiv.style.display = "none";
}
}
commentMenu.appendChild(commentButton);
// 组装设置功能栏
headMenu.appendChild(title);
headMenu.appendChild(mySetup);
headMenu.appendChild(colorMenu);
headMenu.appendChild(copyMenu);
headMenu.appendChild(commentMenu);
// 将头部信息栏添加到页面
fiveObjF.appendChild(headMenu);
// 如有棋评,隐藏
var chessComment = fiveObjF.nextElementSibling;
if(chessComment == undefined){
commentButton.value = "无棋评";
commentButton.disabled = true;
}else{
commentButton.comment = chessComment.innerHTML;
chessComment.innerHTML = "";
}
// 创建棋盘画布
var canvas = document.createElement("canvas");// 创建标签
canvas.id = "c" + i;// 设置ID
canvas.height = 510;// 高度
canvas.width = 525;// 宽度
fiveObjF.appendChild(canvas);// 添加到页面
// 创建功能栏
var toolbar = document.createElement("div");// 创建标签
toolbar.style.height = 50;
toolbar.style.width = 525;
toolbar.style.background = "#cccccc";// 背景颜色
toolbar.style.padding = "5 0 5 0";// 文字位置
// 创建"去棋谱首"功能按钮
var btBegin = document.createElement("input");
btBegin.value = "[<";// 按钮名称
btBegin.type = "button";// 类型:按钮
btBegin.style.fontSize = "20px";
btBegin.style.height = 50;
btBegin.style.width = 75;
btBegin.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btBegin.onclick = function(){// 绑定功能
goBegin(this);
}
// 创建"快退"功能按钮
var btRewind = document.createElement("input");
btRewind.value = "<<";
btRewind.type = "button";
btRewind.style.fontSize = "20px";
btRewind.style.height = 50;
btRewind.style.width = 75;
btRewind.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btRewind.onclick = function(){// 绑定功能
rewind(this);
}
// 创建"后退"功能按钮
var btBack = document.createElement("input");
btBack.value = "<";
btBack.type = "button";
btBack.style.fontSize = "20px";
btBack.style.height = 50;
btBack.style.width = 75;
btBack.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btBack.onclick = function(){// 绑定功能
goBack(null, this);
}
// 创建"前进"功能按钮
var btForward = document.createElement("input");
btForward.value = ">";
btForward.type = "button";
btForward.style.fontSize = "20px";
btForward.style.height = 50;
btForward.style.width = 75;
btForward.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btForward.onclick = function(){// 绑定功能
goForward(null, this);
}
// 创建"快进"功能按钮
var btFastForward = document.createElement("input");
btFastForward.value = ">>";
btFastForward.type = "button";
btFastForward.style.fontSize = "20px";
btFastForward.style.height = 50;
btFastForward.style.width = 75;
btFastForward.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btFastForward.onclick = function(){// 绑定功能
fastForward(this);
}
// 创建"去棋谱尾"功能按钮
var btEnd = document.createElement("input");
btEnd.value = ">]";
btEnd.type = "button";
btEnd.style.fontSize = "20px";
btEnd.style.height = 50;
btEnd.style.width = 75;
btEnd.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btEnd.onclick = function(){// 绑定功能
goEnd(this);
}
// 创建"研究/看谱"功能按钮
var btEdit = document.createElement("input");
btEdit.value = "研究";
btEdit.type = "button";
btEdit.style.fontSize = "20px";
btEdit.style.height = 50;
btEdit.style.width = 75;
btEdit.target = canvas.id;// 设置棋盘ID, 以便于以后区分是哪个棋盘的功能按钮
btEdit.onclick = function(){// 绑定功能
edit(this);
}
// 组装起来
toolbar.appendChild(btBegin);
toolbar.appendChild(btRewind);
toolbar.appendChild(btBack);
toolbar.appendChild(btForward);
toolbar.appendChild(btFastForward);
toolbar.appendChild(btEnd);
toolbar.appendChild(btEdit);
fiveObjF.appendChild(toolbar);
// 初始化数据
init(fiveObj.value, canvas);
title.innerHTML = getOpenName(canvas.id);// 显示开局名称
// 鼠标点击功能
canvas.onmousedown = function(e){
// 获得诶点击的棋盘
var me = e.target;
// 获得棋盘数据
var data = cavs.get(me.id);
// 判断是否是"研究"状态
if(data.isEdit){// 研究状态, 可以落子
// 判断鼠标左右键: 0是左键, 执行落子功能, 2是右键, 后退一步
if(e.button == 0){
// 获得落子坐标
var lcCode = getLocation(e.clientX, e.clientY, me);
// 如果坐标有效且当前位置没有棋子, 则可以落子
if(lcCode != null && !haveStone(lcCode, data)){
// 落子之前, 需要把当前步数之后的数据清除
data.lib.length = data.step;
// 写入新的数据
data.lib.push(lcCode);
// 步数加一
data.step ++;
// 重新绘制棋局
rePrintStones(me);
}
}else if(e.button == 2){
// 鼠标右键, 后退一步
goBack(me);
}
}else{// "看谱"状态
// 0是左键, 前进一步, 2是右键, 后退一步
if(e.button == 0){
goForward(me);
}else if(e.button == 2){
goBack(me);
}
}
}
}
/**
画棋盘的方法
*/
function qipan(canvas){
// 获得画笔
var context = canvas.getContext('2d');
// "研究"状态和"看谱"状态棋盘背景颜色不一样
if(cavs.get(canvas.id).isEdit){
context.fillStyle = chessboardColorEdit;
}else{
context.fillStyle = chessboardColorView;
}
context.lineWidth = 1;// 线条宽度
context.fillRect(0, 0, canvas.width, canvas.height);// 画背景
context.strokeStyle = "rgb(0,0,0)";// 线条颜色
context.fillStyle = "rgb(0,0,0)";// 线条内部填充颜色
context.beginPath();// 开启路径
context.font = "bold 15pt Consolas";// 字体
context.textAlign = "center";// 字体水平居中
context.textBaseline = "middle";// 字体垂直居中
context.save();// 保存画笔状态
context.translate(0.5, 0.5);// 为宜0.5像素, 这样棋盘的线条会比较细
// 画横线
for(var j=0; j<=14; j++){
context.moveTo(left, top + j*r);
context.lineTo(14*r+left, top + j*r);
// 横坐标
context.fillText((15 - j), left - 40, top + j*r + 4);
}
// 画竖线
for(var j=0; j<=14; j++){
context.moveTo(left + j*r, top);
context.lineTo(left + j*r, 14*r+top);
// 纵坐标
context.fillText((xs[j]), left + j*r, top + 14*r + 35);
}
context.stroke();// 画到棋盘上
var h = 4;// 星位标记宽度
var s = h/2;// 偏移距离, 为了让星位正好在标记正中央
// 画星位
context.fillRect(left + r*7 - s, top + r*7 - s, h, h);// 天元
context.fillRect(left + r*3 - s, top + r*3 - s, h, h);
context.fillRect(left + r*11 - s, top + r*11 - s, h, h);
context.fillRect(left + r*11 - s, top + r*11 - s, h, h);
context.fillRect(left + r*3 - s, top + r*11 - s, h, h);
context.fillRect(left + r*11 - s, top + r*3 - s, h, h);
context.closePath();// 关闭路径
context.restore();// 恢复画笔状态
}
/**
获得落子坐标方法
可以落子的坐标都在棋盘线的交叉点上, 此方法来计算距离鼠标点击位置最近的落子坐标
*/
function getLocation(x, y, canvas){
// 获得画布的绝对位置
var bbox = canvas.getBoundingClientRect();
// 计算鼠标点击的坐标
var x = (x - bbox.left) * (canvas.width/bbox.width);
var y = (y - bbox.top) * (canvas.height/bbox.height);
// 如果鼠标点击在棋盘合理的范围内(棋盘向外10像素的范围都算合理), 则开始计算落子坐标
if(x > left - 10 && y > top - 10 && x < left + r*14 + 10 && y < top + r*14 + 10){
// 横坐标修正, 以便后续计算
if(x < left){
x = left;
}else if(x > r*14 + left){
x = left + r*14;
}
// 纵坐标修正
if(y < top){
y = top;
}else if(y > top + r*14){
y = top + r*14;
}
// 减去边距
var ex = x - left;
var ey = y - top;
// 计算减去后的数值包含几个棋盘格子的宽度, 四舍五入, 这样就得到了距离鼠标点击位置最近的落子坐标
ex = (ex / r).toFixed(0) ;
ey = 15 - (ey / r).toFixed(0);
// 转换成标准格式, 如:H8
return xs[ex] + "" + ey;
}else{// 无效点击不返回坐标
return null;
}
}
/**
画黑棋
*/
function drawBlack(lcCode, canvas, num){
// 解析坐标
var lc = parseLc(lcCode);
// 获得画笔
var cx = canvas.getContext("2d");
cx.beginPath();// 开启路径
cx.arc(lc.x, lc.y, r/2 - 2, 0, Math.PI*2, true);// 画圆
cx.fillStyle = "#000000";// 设置棋子颜色
cx.fill();// 填充
// 判断是否显示步数
if(isShow){
cx.font = "bold 11pt Arial";// 设置画笔字体
cx.fillStyle = "#ffffff";// 设置字体颜色
cx.fillText(num, lc.x, lc.y + 1);// 画步数
}
cx.closePath();// 关闭路径
}
/**
画白棋
*/
function drawWhite(lcCode, canvas, num){
// 解析坐标
var lc = parseLc(lcCode);
var cx = canvas.getContext("2d");// 获得画笔
cx.beginPath();// 开启路径
cx.arc(lc.x, lc.y, r/2 - 2, 0, Math.PI*2, true);// 画圆
cx.fillStyle = "#ffffff";// 设置棋子颜色
cx.strokeStyle = "#000000";// 设置白棋边缘颜色
cx.lineWidth = 1;// 线条宽度
cx.fill();// 填充
cx.stroke();// 描边
// 判断是否显示步数
if(isShow){
cx.fillStyle = "#000000";// 设置字体颜色
cx.fillText(num, lc.x, lc.y + 1);// 画步数
}
cx.closePath();// 关闭路径
}
/**
解析坐标方法
将对应的字母转换成数字
*/
function parseLc(lc){
if(lc == null){return lc;}
return {x: map[lc.substring(0, 1)] * r + left, y: (15 - lc.substring(1, lc.length)) * r + top};
}
/**
判断当前位置是否有棋子
*/
function haveStone(lcCode, data){
/* 遍历当前棋盘的棋谱数据, 判断是否包含此位置
注意, 此处不一定是完全遍历, 只遍历到当前步数
后面的步数未显示在棋盘上, 视为未落子
*/
for(var i=0; i<data.step; i++){
if(lcCode.toUpperCase() == data.lib[i].toUpperCase()){
return true;
}
}
return false;
}
/**
初始化棋盘
*/
function init(data, canvas){
// 解析棋谱
var ss = data.split(" ");
// 保存棋谱数据
cavs.set(canvas.id, {lib: ss, step: ss.length, canvas: canvas, isEdit: false, tstep:0, tlib: []});
// 画棋盘
qipan(canvas);
// 画棋子
for(var i=0; i<ss.length; i++){
// 奇数步画黑棋, 偶数步画白棋
if(i%2==0){
drawBlack(ss[i], canvas, i+1);
}else{
drawWhite(ss[i], canvas, i+1);
}
}
}
/**
去棋局首
*/
function goBegin(btBegin){
// 获得当前棋盘信息
var data = cavs.get(btBegin.target);
// 设置步数为1
data.step = 1;
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
快退
*/
function rewind(btRewind){
// 获得当前棋盘信息
var data = cavs.get(btRewind.target);
// 默认回退5步
var backSteps = 5;
// 如果当前小于等于5步, 则回到第1步
if(data.step <= backSteps){
data.step = 1;
}else{
// 步数减5
data.step = data.step - backSteps;
}
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
后退
*/
function goBack(canvas, bt){
// 棋盘为空, 则重新获得棋盘
if(canvas == null){
canvas = cavs.get(bt.target).canvas;
}
// 获得当前棋盘信息
var data = cavs.get(canvas.id);
// 如果当前步数大于1步, 则步数减1
if(data.step > 1){
data.step --;
}
// 重新绘制棋局
rePrintStones(canvas);
}
/**
前进
*/
function goForward(canvas, bt){
// 棋盘为空, 则重新获得棋盘
if(canvas == null){
canvas = cavs.get(bt.target).canvas;
}
// 获得当前棋盘信息
var data = cavs.get(canvas.id);
if(data.step < data.lib.length){
// 如果不是最后一步, 则步数加1
data.step ++;
// 重新绘制棋局
rePrintStones(canvas);
}
}
/**
快进
*/
function fastForward(btFastForward){
// 获得当前棋盘信息
var data = cavs.get(btFastForward.target);
// 默认前进5步
var forwardSteps = 5;
// 如果剩余棋谱不够5步, 则步数置为最后一步
if(data.step + forwardSteps > data.lib.length){
data.step = data.lib.length;
}else{
// 剩余棋谱够5步, 则步数加5
data.step += forwardSteps;
}
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
去棋谱尾
*/
function goEnd(btEnd){
// 获得当前棋盘信息
var data = cavs.get(btEnd.target);
// 步数置为最后一步
data.step = data.lib.length;
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
重绘棋局方法
*/
function rePrintStones(canvas){
// 获得最新棋盘信息
var data = cavs.get(canvas.id);
var step = data.step;
var stones = data.lib;
// 绘制棋盘
qipan(canvas);
// 绘制棋子
for(var i=0; i<step; i++){
if(i%2==0){
drawBlack(stones[i], canvas, i+1);
}else{
drawWhite(stones[i], canvas, i+1);
}
}
}
/**
重绘所有棋盘
*/
function rePrintAllStones(){
// 更新是否显示数字选项
for(var i=0; i<showNumbers.length; i++){
if(isShow){
showNumbers[i].value = "√";
}else{
showNumbers[i].value = "";
}
}
for(var i=0; i<cavs.size; i++){
var data = cavs.get("c" + i);
rePrintStones(data.canvas);
if(data.isEdit){
backgrounds[i].value = chessboardColorEdit;
}else{
backgrounds[i].value = chessboardColorView;
}
}
}
/**
"研究/看谱"功能
*/
function edit(btEdit){
// 获得当前棋盘信息
var data = cavs.get(btEdit.target);
// 棋盘状态转换
data.isEdit = !data.isEdit;
// 判断棋盘状态
if(data.isEdit){
// 如果当前是"研究"状态, 则按钮名称需改为"看谱"
btEdit.value = "看谱";
// 将当前步数备份
data.tstep = data.step;
// 将当前棋谱备份, 注意, 此处不可以浅复制
data.tlib = new Array();
data.tlib = data.tlib.concat(data.lib);
// 修改背景色按钮颜色
document.getElementById("color" + btEdit.target).value = chessboardColorEdit;
}else{
// 如果当前是"看谱"状态, 则按钮名称需改为"研究"
btEdit.value = "研究";
// 将备份的步数恢复
data.step = data.tstep;
// 将备份的棋谱恢复
data.lib = new Array();
data.lib = data.lib.concat(data.tlib);
// 修改背景色按钮颜色
document.getElementById("color" + btEdit.target).value = chessboardColorView;
}
// 重新绘制棋局
rePrintStones(data.canvas);
}
/**
判断开局名称
*/
function getOpenName(canvasId){
// 获得当前棋盘信息
var stones = cavs.get(canvasId).lib;
// 大于等于3步才进行判断
if(stones.length >= 3){
// 获得前三步
var s1 = stones[0];
var s2 = stones[1];
var s3 = stones[2];
// 判断第一步, 如果在天元, 则进行下一步
if("h8" == s1){
// 判断第二步, 如果在天元1X1范围内, 则判断第三步, 这里直指斜指分开进行判断, 代码比较清晰
if("h9,h7,g8,i8".indexOf(s2) >= 0){
if("h9" == s2){
if("f10" == s3 || "j10" == s3){
return "疏星";
}
if("f9" == s3 || "j9" == s3){
return "残月";
}
if("f8" == s3 || "j8" == s3){
return "金星";
}
if("f7" == s3 || "j7" == s3){
return "新月";
}
if("f6" == s3 || "j6" == s3){
return "游星";
}
if("g10" == s3 || "i10" == s3){
return "溪月";
}
if("g9" == s3 || "i9" == s3){
return "花月";
}
if("g8" == s3 || "i8" == s3){
return "雨月";
}
if("g7" == s3 || "i7" == s3){
return "丘月";
}
if("g6" == s3 || "i6" == s3){
return "山月";
}
if("h10" == s3){
return "寒星";
}
if("h7" == s3){
return "松月";
}
if("h6" == s3){
return "瑞星";
}
return "其他开局";
}else if("h7" == s2){
if("f9" == s3 || "j9" == s3){
return "疏星";
}
if("f7" == s3 || "j7" == s3){
return "残月";
}
if("f8" == s3 || "j8" == s3){
return "金星";
}
if("f9" == s3 || "j9" == s3){
return "新月";
}
if("f10" == s3 || "j10" == s3){
return "游星";
}
if("g6" == s3 || "i6" == s3){
return "溪月";
}
if("g7" == s3 || "i7" == s3){
return "花月";
}
if("g8" == s3 || "i8" == s3){
return "雨月";
}
if("g9" == s3 || "i9" == s3){
return "丘月";
}
if("g10" == s3 || "i10" == s3){
return "山月";
}
if("h6" == s3){
return "寒星";
}
if("h9" == s3){
return "松月";
}
if("h10" == s3){
return "瑞星";
}
return "其他开局";
}else if("g8" == s2){
if("f10" == s3 || "f6" == s3){
return "疏星";
}
if("g10" == s3 || "g6" == s3){
return "残月";
}
if("h10" == s3 || "h6" == s3){
return "金星";
}
if("i10" == s3 || "i6" == s3){
return "新月";
}
if("j10" == s3 || "j6" == s3){
return "游星";
}
if("f7" == s3 || "f9" == s3){
return "溪月";
}
if("g7" == s3 || "g9" == s3){
return "花月";
}
if("h7" == s3 || "h9" == s3){
return "雨月";
}
if("i7" == s3 || "i9" == s3){
return "丘月";
}
if("j7" == s3 || "j9" == s3){
return "山月";
}
if("f8" == s3){
return "寒星";
}
if("i8" == s3){
return "松月";
}
if("j8" == s3){
return "瑞星";
}
return "其他开局";
}else if("i8" == s2){
if("j10" == s3 || "j6" == s3){
return "疏星";
}
if("i10" == s3 || "i6" == s3){
return "残月";
}
if("h10" == s3 || "h6" == s3){
return "金星";
}
if("g10" == s3 || "g6" == s3){
return "新月";
}
if("f10" == s3 || "f6" == s3){
return "游星";
}
if("j7" == s3 || "j9" == s3){
return "溪月";
}
if("i7" == s3 || "i9" == s3){
return "花月";
}
if("h7" == s3 || "h9" == s3){
return "雨月";
}
if("f7" == s3 || "f9" == s3){
return "丘月";
}
if("j7" == s3 || "j9" == s3){
return "山月";
}
if("j8" == s3){
return "寒星";
}
if("g8" == s3){
return "松月";
}
if("f8" == s3){
return "瑞星";
}
return "其他开局";
}
}else if("i9,i7,g7,g9".indexOf(s2) >= 0){
if("i9" == s2){
if("f10" == s3 || "j6" == s3){
return "流星";
}
if("f9" == s3 || "i6" == s3){
return "岚月";
}
if("f8" == s3 || "h6" == s3){
return "明星";
}
if("f7" == s3 || "g6" == s3){
return "名月";
}
if("f6" == s3){
return "彗星";
}
if("g7" == s3){
return "斜月";
}
if("g8" == s3 || "h7" == s3){
return "银月";
}
if("g9" == s3 || "i7" == s3){
return "蒲月";
}
if("g10" == s3 || "j7" == s3){
return "水月";
}
if("h10" == s3 || "j8" == s3){
return "恒星";
}
if("h9" == s3 || "i8" == s3){
return "云月";
}
if("i10" == s3 || "j9" == s3){
return "峡月";
}
if("j10" == s3){
return "长星";
}
return "其他开局";
}else if("i7" == s2){
if("j10" == s3 || "f6" == s3){
return "流星";
}
if("i10" == s3 || "f7" == s3){
return "岚月";
}
if("f8" == s3 || "h10" == s3){
return "明星";
}
if("g10" == s3 || "f9" == s3){
return "名月";
}
if("f10" == s3){
return "彗星";
}
if("g9" == s3){
return "斜月";
}
if("g8" == s3 || "h9" == s3){
return "银月";
}
if("i9" == s3 || "g7" == s3){
return "蒲月";
}
if("g6" == s3 || "j10" == s3){
return "水月";
}
if("h6" == s3 || "j8" == s3){
return "恒星";
}
if("h7" == s3 || "i8" == s3){
return "云月";
}
if("i6" == s3 || "j7" == s3){
return "峡月";
}
if("j6" == s3){
return "长星";
}
return "其他开局";
}else if("g7" == s2){
if("f10" == s3 || "j6" == s3){
return "流星";
}
if("g10" == s3 || "j7" == s3){
return "岚月";
}
if("j8" == s3 || "h10" == s3){
return "明星";
}
if("i10" == s3 || "j9" == s3){
return "名月";
}
if("j10" == s3){
return "彗星";
}
if("i9" == s3){
return "斜月";
}
if("i8" == s3 || "h9" == s3){
return "银月";
}
if("g9" == s3 || "i7" == s3){
return "蒲月";
}
if("i6" == s3 || "f10" == s3){
return "水月";
}
if("h6" == s3 || "f8" == s3){
return "恒星";
}
if("h7" == s3 || "g8" == s3){
return "云月";
}
if("g6" == s3 || "f7" == s3){
return "峡月";
}
if("f6" == s3){
return "长星";
}
return "其他开局";
}else if("g9" == s2){
if("j10" == s3 || "f6" == s3){
return "流星";
}
if("j9" == s3 || "g6" == s3){
return "岚月";
}
if("j8" == s3 || "h6" == s3){
return "明星";
}
if("j7" == s3 || "i6" == s3){
return "名月";
}
if("j6" == s3){
return "彗星";
}
if("i7" == s3){
return "斜月";
}
if("i8" == s3 || "h7" == s3){
return "银月";
}
if("i9" == s3 || "g7" == s3){
return "蒲月";
}
if("i10" == s3 || "f7" == s3){
return "水月";
}
if("h10" == s3 || "f8" == s3){
return "恒星";
}
if("h9" == s3 || "g8" == s3){
return "云月";
}
if("g10" == s3 || "f9" == s3){
return "峡月";
}
if("f10" == s3){
return "长星";
}
return "其他开局";
}
}else{
return "其他开局";
}
}else{
return "其他开局";
}
}else{
return "未知";
}
}
/**
设置Cookie
*/
function setCookie(data){
var expireDate = new Date();
expireDate.setFullYear(3017);
document.cookie = data + ";expires=" + expireDate.toGMTString();
}
/**
读取Cookie
*/
function readCookie(){
var cs = document.cookie.split(";");
for(var i=0; i<cs.length; i++){
if(cs[i].trim().indexOf("isShowStepNumber") == 0){
isShow = cs[i].split("=")[1] == "true";
}
if(cs[i].trim().indexOf("chessboardColorEdit") == 0){
chessboardColorEdit = cs[i].split("=")[1];
}
if(cs[i].trim().indexOf("chessboardColorView") == 0){
chessboardColorView = cs[i].split("=")[1];
}
}
}
/**
获得元素的绝对位置
*/
function getAbsolutePosition(obj){
var left = obj.offsetLeft;
var o = obj;
while(o.offsetParent!=null) {
var oParent = o.offsetParent;
left += oParent.offsetLeft;
o = oParent;
}
var top = obj.offsetTop;
o = obj;
while(o.offsetParent!=null) {
var oParent = o.offsetParent;
top += oParent.offsetTop;
o = oParent;
}
return {x:left, y:top};
}
转载请注明出处。