Слияние кода завершено, страница обновится автоматически
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap5 实例</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.staticfile.net/twitter-bootstrap/5.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.staticfile.net/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js"></script>
<script src="static/three.min.js"></script>
<style>
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
}
</style>
</head>
<body>
<div class="grid-container">
<div>
<div id="first3d" style="display: none;margin:5px;"></div>
<div id="second3d" style="display: none;margin:5px;"></div>
</div>
<div id="baseid" class="btn-group-vertical" style="margin: auto;">
<div class="input-group">
<button type="button" class="form-control btn btn-primary" onclick="gt.main(event)">New</button>
<button type="button" class="form-control btn btn-primary" onclick="gt.main(event)">Show</button>
</div>
<div class="input-group">
<span id="posColorList" class="badge bg-info" style="width: 35px;">0</span>
<button type="button" class="btn btn-primary" onclick="gt.main(event)">-</button>
<input class="form-control" type="range" id="myRange" onchange="gt.main(event)" value="0" min="0"
max="0" step="1">
<button type="button" class="btn btn-primary" onclick="gt.main(event)">+</button>
<button id="man-auto" type="button" class="btn btn-primary" onclick="gt.main(event)">></button>
</div>
<div class="input-group">
<button type="button" class="form-control btn btn-primary" onclick="gt.main(event)">记录</button>
<button id="qp-mode" type="button" class="form-control btn btn-primary"
onclick="gt.main(event)">下棋模式</button>
</div>
<div style="margin: auto;">
<canvas id="myCanvas" style="border:1px solid gray;"></canvas>
<div id="main3d" style="width:600px;height:600px;margin:auto;display:none;"></div>
</div>
<textarea class="form-control" id="sgftext"></textarea>
</div>
<div>
<div id="third3d" style="display: none;margin:5px;"></div>
<div id="fourth3d" style="display: none;margin:5px;"></div>
</div>
</div>
<script>
var health_alert = false;
function health() {
const now = new Date();
const minutes = now.getMinutes();
if (minutes === 0 || minutes === 30) {
if (health_alert) {
alert("游戏健康忠告:请注意休息,合理安排游戏时间。");
health_alert = false;
}
} else {
health_alert = true;
}
}
class DrawQipan {
constructor(canvasid, grid = 20) {
this.grid = grid;
this.gridHalf = grid / 2;
this.qipanWidth = 20 * this.grid;
this.canvas = document.getElementById(canvasid);
this.canvas.width = this.qipanWidth;
this.canvas.height = this.qipanWidth;
this.ctx = this.create_ctx(this.canvas);
this.positions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"];
this.painting = false;
this.blueList = ["rg", "oc"];
this.selectedList = [];
this.qipanList = [];
this.setupClickListener(this.canvas, this);
this.isShowText = true;
this.strokeStyle = "B";
this.draw({});
}
create_ctx(canvas) {
let ctx = canvas.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
return ctx;
}
setupClickListener(element, someVariable) {
element.addEventListener('mousedown', function (event) {
someVariable.painting = true;
someVariable.canvasListener("mousedown", event.clientX, event.clientY);
});
element.addEventListener('mousemove', function (event) {
if (someVariable.painting) {
someVariable.canvasListener("mousemove", event.clientX, event.clientY);
}
});
element.addEventListener('mouseup', function (event) {
if (someVariable.painting) {
someVariable.painting = false;
someVariable.canvasListener("mouseup", event.clientX, event.clientY);
}
});
}
canvasListener(action, x, y) {
let qpMode = document.getElementById("qp-mode").innerText;
let rect, rx, ry, gr, gc, position;
rect = this.canvas.getBoundingClientRect();
position = this.coordinate_position(x, y);
[rx, ry] = this.position_coordinate(position);
if (qpMode == "下棋模式" && action == "mousedown") {
let sgf = this.strokeStyle + "[" + position + "]";
} else if (qpMode == "选择模式" && action == "mousedown") {
this.startPosition = position;
this.painting = true;
this.selectList = [position];
this.ctx.strokeStyle = "red";
this.ctx.lineWidth = 2;
this.ctx.beginPath();
this.ctx.moveTo(rx, ry);
} else if (qpMode == "选择模式" && action == "mousemove") {
if (this.painting) {
if (position != this.selectList[this.selectList.length - 1]) {
this.selectList.push(position);
this.ctx.lineTo(rx, ry);
this.ctx.stroke();
}
}
} else if (qpMode == "选择模式" && action == "mouseup") {
this.painting = false;
if (this.selectList.length > 0) {
this.selectedList.push(JSON.parse(JSON.stringify(this.selectList)));
}
let [sgf, pcDict, pcList, blueList] = this.select(this.selectList);
this.qipanList.push(JSON.parse(JSON.stringify([sgf, pcDict, pcList, blueList])));
}
}
select(selectedList) {
if (selectedList[0] != selectedList[selectedList.length - 1]) {
selectedList.push(selectedList[0]);
}
let linshiList = [], blueList = [];
sgo.sgf.forEach((item, index) => {
if (this.isPointInPolygon(item.slice(2, 4), selectedList)) {
linshiList.push(item.slice(2, 4));
}
});
selectedList.concat(linshiList).forEach((item, index) => {
blueList.includes(item) || blueList.push(item);
});
let sgf = [], pcDict = {}, pcList = [];
sgo.sgf.forEach((item, index) => {
if (blueList.includes(item.slice(2, 4))) {
sgf.push(item);
pcList.push(JSON.parse(JSON.stringify(sgo.posColorList[index])));
}
});
pcDict = JSON.parse(JSON.stringify(pcList.at(-1)));
return [sgf, pcDict, pcList, blueList];
}
draw(posColor) {
let cx, cy, current;
let start = this.grid;
let end = 19 * this.grid;
let radius = Math.floor(this.grid / 3 - 1);
this.ctx.clearRect(0, 0, this.qipanWidth, this.qipanWidth);
this.ctx.fillStyle = "GoldenRod";
this.ctx.fillRect(0, 0, this.qipanWidth, this.qipanWidth);
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = "black";
this.ctx.beginPath();
this.positions.forEach((row, ri) => {
current = (this.positions.indexOf(row) + 1) * this.grid;
this.ctx.moveTo(current, start);
this.ctx.lineTo(current, end);
this.ctx.moveTo(start, current);
this.ctx.lineTo(end, current);
});
let pos = ["d", "j", "p"];
for (let row in pos) {
for (let col in pos) {
[cx, cy] = this.position_coordinate(pos[row] + pos[col]);
this.ctx.moveTo(cx + radius, cy);
this.ctx.arc(cx, cy, radius, 0, 2 * Math.PI);
}
}
this.ctx.stroke();
let strokeStyle = { B: "black", W: "White" };
for (let pos in posColor) {
this.ctx.beginPath();
[cx, cy] = this.position_coordinate(pos);
this.ctx.moveTo(cx + Math.floor(this.grid / 2 - 1), cy);
this.ctx.lineWidth = 3;
if (pos == sgo.sgf[Number(document.getElementById("myRange").value)].slice(2, 4)) {
this.ctx.strokeStyle = "Gold";
} else if (this.blueList.includes(pos)) {
this.ctx.strokeStyle = "LightBlue";
} else {
this.ctx.strokeStyle = "Gray";
if (this.blueList.length > 0) {
this.ctx.globalAlpha = 0.5;
}
}
this.ctx.arc(cx, cy, Math.floor(this.grid / 2 - 1), 0, 2 * Math.PI);
this.ctx.fillStyle = strokeStyle[posColor[pos][0]];
this.ctx.fill();
this.ctx.globalAlpha = 1.0;
if (this.isShowText) {
if (posColor[pos][0] == "B") {
this.ctx.fillStyle = "White";
} else {
this.ctx.fillStyle = "black";
}
this.ctx.textBaseline = "middle";
this.ctx.fillText(posColor[pos][1], cx - this.ctx.measureText(posColor[pos][1]).width / 2, cy);
}
this.ctx.stroke();
}
//this.ctx.strokeStyle = "black";
this.base64Image = this.canvas.toDataURL('image/png');
}
coordinate_position(x, y) {
let rect, row, col;
rect = this.canvas.getBoundingClientRect();
row = this.minmax(Math.floor((x + this.grid / 2 - rect.left) / this.grid) - 1);
col = this.minmax(Math.floor((y + this.grid / 2 - rect.top) / this.grid) - 1);
return this.positions[row] + this.positions[col];
}
minmax(coordinate) {
return Math.min(18, Math.max(0, coordinate));
}
position_coordinate(position) {
let row, col, rect, rx, cy;
rect = this.canvas.getBoundingClientRect();
row = this.positions.indexOf(position.slice(0, 1));
col = this.positions.indexOf(position.slice(1, 2));
rx = Math.floor((row + 1) * this.grid);
cy = Math.floor((col + 1) * this.grid);
return [rx, cy];
}
canvas_size(qp_row, qp_col) {
document.getElementById("myCanvas").width = this.qipanWidth;
document.getElementById("myCanvas").height = this.qipanWidth;
}
isPointInPolygon(point, polygon) {
let numIntersections = 0;
let [x, y] = this.position_coordinate(point);
const n = polygon.length;
for (let i = 0, j = n - 1; i < n; j = i++) {
let [xi, yi] = this.position_coordinate(polygon[i]);
let [xj, yj] = this.position_coordinate(polygon[j]);
if ((yi > y) != (yj > y) &&
x < (xj - xi) * (y - yi) / (yj - yi) + xi) {
numIntersections++;
}
}
return numIntersections % 2 !== 0;
}
}
const drawQipan = new DrawQipan("myCanvas", 30);
class simpleGo {
constructor() {
this.positions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"];
this.newWeiQi([], {}, []);
this.goString = { string: [], empty: [] };
}
go_handler(item = "B[qd]") {
var position = item.slice(2, 4);
if (this.posColor.hasOwnProperty(position)) {
return false;
} else {
this.posColor[position] = [item[0]];
}
var del_pos = [];
var near_pos = this.near_positions(position);
for (var npn in near_pos) {
if (this.posColor.hasOwnProperty(near_pos[npn])) {
if (this.posColor[near_pos[npn]][0] != this.posColor[position][0]) {
this.goString = { 'string': [], 'empty': [] };
this.go_string(near_pos[npn]);
if (this.goString['empty'].length == 0) {
for (var spn in this.goString['string']) {
del_pos.includes(this.goString['string'][spn]) || del_pos.push(this.goString['string'][spn]);
}
}
}
}
}
if (del_pos.length == 0) {
this.goString = { 'string': [], 'empty': [] };
this.go_string(position);
if (this.goString['empty'].length == 0) {
delete this.posColor[position];
return false;
}
} else {
for (var d_p in del_pos) {
delete this.posColor[del_pos[d_p]];
}
}
this.sgf.push(item);
this.posColor[position].push(this.sgf.length)
this.posColorList.push(JSON.parse(JSON.stringify(this.posColor)));
return true;
}
go_string(position) {
this.goString['string'].push(position);
var nPos = this.near_positions(position);
for (var np in nPos) {
if (this.posColor.hasOwnProperty(nPos[np])) {
if (!this.goString['string'].includes(nPos[np]) && this.posColor[nPos[np]][0] == this.posColor[position][0]) {
this.go_string(nPos[np]);
}
} else {
this.goString['empty'].includes(nPos[np]) || this.goString['empty'].push(nPos[np]);
}
}
}
near_positions(position) {
var near_pos = [];
var row = this.near(position[0]);
var col = this.near(position[1]);
for (var r in row) {
near_pos.push(row[r] + position[1]);
}
for (var c in col) {
near_pos.push(position[0] + col[c]);
}
return near_pos;
}
near(char) {
switch (char) {
case "a":
return ["b"];
case "s":
return ["r"];
case "b": case "c": case "d": case "e": case "f": case "g":
case "h": case "i": case "j": case "k": case "l": case "m":
case "n": case "o": case "p": case "q": case "r":
default:
var pos = this.positions.indexOf(char);
return [this.positions[pos - 1], this.positions[pos + 1]];
}
}
newWeiQi(sgf, posColor, posColorList) {
this.sgf = sgf;
this.posColor = posColor;
this.posColorList = posColorList;
}
}
const sgo = new simpleGo();
class ThreeGo {
constructor() {
let width = 600, height = 600;
this.scene = this.create_scene();
this.camera = this.create_camera(width, height);
this.renderer = this.create_renderer(width, height);
document.getElementById("main3d").innerHTML = "";
document.getElementById("main3d").appendChild(this.renderer.domElement);
this.face = this.create_face([0, 3, 0]);
this.face.rotation.x = -Math.PI / 2;
this.scene.add(this.face);
//this.scene.add(new THREE.AxesHelper(5));
}
create_scene() {
return new THREE.Scene();
}
create_camera(width = 600, height = 600) {
let camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
camera.position.set(5, 9, 5);
camera.lookAt(new THREE.Vector3(0, 0, 0));
return camera;
}
create_renderer(width = 600, height = 600) {
let renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.setClearColor(new THREE.Color('skyblue'));
return renderer;
}
create_material(imgeData) {
let textureLoader = new THREE.TextureLoader();
let texture = textureLoader.load(imgeData);
let material = new THREE.MeshBasicMaterial({ map: texture });
return material;
}
create_face(position = [0, 0, 0]) {
let geometry = new THREE.PlaneGeometry(10, 10);
let material = this.create_material(drawQipan.base64Image);
let mesh = new THREE.Mesh(geometry, material);
mesh.position.set(position[0], position[1], position[2]);
return mesh;
}
}
let tg = new ThreeGo();
class MyThree {
constructor(canvasid, width = 636, height = 380) {
this.width = width;
this.height = height;
document.getElementById(canvasid).width = width;
document.getElementById(canvasid).height = height;
this.scene = this.create_scene();
this.camera = this.create_camera();
this.renderer = this.create_renderer();
this.face = this.create_face(drawQipan.base64Image);
this.face.rotation.x = -Math.PI / 2;
this.scene.add(this.face);
}
create_scene() {
return new THREE.Scene();
}
create_camera(position = [4, 7, 4]) {
let camera = new THREE.PerspectiveCamera(75, this.width / this.height, 0.1, 1000);
camera.position.set(position[0], position[1], position[0]);
camera.lookAt(new THREE.Vector3(0, 0, 0));
return camera;
}
create_renderer() {
let renderer = new THREE.WebGLRenderer();
renderer.setSize(this.width, this.height);
renderer.setClearColor(new THREE.Color('skyblue'));
return renderer;
}
create_material(imgeData) {
let textureLoader = new THREE.TextureLoader();
let texture = textureLoader.load(imgeData);
let material = new THREE.MeshBasicMaterial({ map: texture });
return material;
}
create_face(imgeData, position = [0, 3, 0]) {
let geometry = new THREE.PlaneGeometry(10, 10);
let material = this.create_material(imgeData);
let mesh = new THREE.Mesh(geometry, material);
mesh.position.set(position[0], position[1], position[2]);
return mesh;
}
}
class Tools {
constructor() {
this.positions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"];
this.combinedPattern = /[\u4e00-\u9fa5a-zA-Z0-9;\[\]\-: ]+/g;
this.sgf = [];
this.blueList = [];
this.goldDict = {};
this.autoRun = false;
}
main(event) {
switch (event.target.textContent) {
case "New":
sgo.newWeiQi([], {}, []);
drawQipan.draw({});
break;
case "Show":
drawQipan.blueList = [];
sgo.newWeiQi([], {}, []);
if (document.getElementById("sgftext").value == "") {
egm.handle(sgftext)
} else {
egm.handle(document.getElementById("sgftext").value)
}
document.getElementById("myRange").max = sgo.sgf.length - 1;
document.getElementById("myRange").value = sgo.sgf.length - 1;
document.getElementById("posColorList").textContent = Number(document.getElementById("myRange").value) + 1;
drawQipan.qipanList = [JSON.parse(JSON.stringify([sgo.sgf, sgo.posColor, sgo.posColorList, []]))];
drawQipan.draw(sgo.posColor);
break;
case "-":
document.getElementById("myRange").value = Math.max(0, Number(document.getElementById("myRange").value) - 1);
drawQipan.draw(sgo.posColorList[Number(document.getElementById("myRange").value)]);
break;
case "+":
document.getElementById("myRange").value = Math.min(sgo.sgf.length - 1, Number(document.getElementById("myRange").value) + 1);
drawQipan.draw(sgo.posColorList[Number(document.getElementById("myRange").value)]);
break;
case ">":
let [sgf, pcDict, pcList, blueList] = drawQipan.qipanList.at(-1);
sgo.newWeiQi(sgf, pcDict, pcList);
drawQipan.blueList = blueList;
document.getElementById("myRange").max = sgo.sgf.length - 1;
document.getElementById("myRange").value = 0;
document.getElementById('myCanvas').style.display = "none";
this.renderer({ "main3d": tg })
if (!this.autoRun) { this.autoRun = true; }
break;
case "记录":
break;
case "步数":
drawQipan.isShowText ? drawQipan.isShowText = false : drawQipan.isShowText = true;
break;
case "下棋模式":
drawQipan.selectedList = [];
event.target.textContent = "选择模式";
break;
case "选择模式":
event.target.textContent = "下棋模式";
break;
default:
drawQipan.draw(sgo.posColorList[Number(document.getElementById("myRange").value)]);
break;
}
}
autorunning() {
if (document.getElementById("myRange").value < sgo.posColorList.length - 1) {
drawQipan.draw(sgo.posColorList[document.getElementById("myRange").value]);
document.getElementById("posColorList").textContent = document.getElementById("myRange").value++;
} else {
this.autoRun = false;
this.display(["main3d"], "none");
document.getElementById('myCanvas').style.display = "block";
}
}
display(idList, display) {
for (let index in idList) {
if (display == "none") {
document.getElementById(idList[index]).style.display = "none";
} else if (display == "block") {
document.getElementById(idList[index]).style.display = "block";
}
document.getElementById(idList[index]).innerHTML = "";
}
}
renderer(dict3d) {
for (let key in dict3d) {
document.getElementById(key).innerHTML = "";
document.getElementById(key).appendChild(dict3d[key].renderer.domElement);
document.getElementById(key).style.display = "block";
}
}
}
const gt = new Tools();
const sgftext = `(;CA[UTF-8]AP[YuanYu]GM[1]FF[4]
SZ[19]
GN[2018腾讯世界人工智能围棋大赛决赛第1局 30日10:00]
DT[2018-07-30]
PB[Golaxy]BR[9d]
PW[FineArt]WR[9d]
KM[7.5]HA[0]RU[Chinese]RE[W+R]TM[3600]TC[10]TT[60]
;B[qd];W[pp];B[dd];W[dp];B[qn];W[qo];B[pn];W[np];B[pj];W[od];B[lc]
;W[me];B[lq];W[qe];B[fq];W[cc];B[qq];W[rn];B[cd];W[dc];B[ed];W[ec]
;B[rm];W[or];B[ro];W[rp];B[qp];W[po];B[sn];W[rq];B[fc];W[fb];B[cn]
;W[er];B[bc];W[bb];B[eb];W[db];B[gb];W[pd];B[eo];W[co];B[bn];W[fp]
;B[ep];W[eq];B[do];W[cq];B[fr];W[iq];B[hp];W[gq];B[gp];W[fo];B[fn]
;W[go];B[hn];W[gr];B[gn];W[fs];B[ei];W[bd];B[be];W[ac];B[cf];W[ih]
;B[qc];W[rf];B[pf];W[qh];B[ob];W[nb];B[oc];W[pc];B[pb];W[rd];B[nd]
;W[qb];B[oe];W[rc];B[nc];W[if];B[hg];W[ig];B[je];W[gi];B[fg];W[hf]
;B[fj];W[lg];B[lf];W[mg];B[kg];W[kh];B[mf];W[ff];B[gg];W[fd];B[gc]
;W[hd];B[fe];W[gd];B[ic];W[gj];B[kf];W[bg];B[cg];W[kj];B[bo];W[gk]
;B[fk];W[id];B[jc];W[eh];B[fh];W[fi];B[ej];W[fl];B[el];W[gl];B[lo]
;W[ae];B[bh];W[em];B[dl];W[km];B[ho];W[qk];B[ol];W[bf];B[ce];W[gf]
;B[ef];W[qj];B[hq];W[hr];B[pi];W[qi];B[lk];W[kk];B[lh];W[li];B[mh]
;W[ng];B[oo];W[pq];B[og];W[nh];B[mi];W[oh];B[qr];W[rr];B[mj];W[ph]
;B[lm];W[kl];B[jh];W[ki];B[bq];W[hh];B[eg];W[ll];B[ml];W[no];B[ln]
;W[nk];B[mk];W[nm];B[nn];W[mm];B[nl];W[mn];B[om];W[mo];B[jq];W[rl]
;B[ql];W[pl];B[qm];W[ir];B[jn];W[pk];B[rk];W[on];B[pm];W[rj];B[sl]
;W[cr];B[jg];W[ji];B[hl];W[il];B[hm];W[jp];B[kp];W[kn];B[ko];W[ik]
;B[cp];W[jr];B[jo];W[hc];B[hb];W[ea];B[af];W[ag];B[fq];W[br];B[ar]
;W[lr];B[mr];W[kq];B[mq];W[ad];B[ah];W[af];B[fm];W[sp];B[nn];W[op]
;B[dq];W[dr];B[jm];W[jl];B[ls];W[on];B[kr];W[nf];B[ne];W[ok];B[hk]
;W[hj];B[pg];W[jd])`
class extract_go_manual {
constructor() {
this.positions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"];
this.combinedPattern = /[\u4e00-\u9fa5a-zA-Z0-9;\[\]\-: ]+/g;
}
handle(text) {
sgo.newWeiQi([], {}, []);
var results = text.match(this.combinedPattern) || [];
var format_content = results.join('').split(";");
for (var index in format_content) {
var item = format_content[index];
if (item.length == 5 && this.positions.includes(item[2]) && this.positions.includes(item[3])) {
sgo.go_handler(item);
}
}
}
}
const egm = new extract_go_manual();
let start, ok;
function animate(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
if (gt.autoRun) {
tg.face.rotation.z += 0.002;
tg.renderer.render(tg.scene, tg.camera);
if (ok && progress % 1000 < 30) {
ok = false;
gt.autorunning();
let textureLoader = new THREE.TextureLoader();
textureLoader.load(drawQipan.base64Image, function (texture) {
tg.face.material.map = texture;
tg.face.material.needsUpdate = true;
});
health();
} else {
ok = true;
}
}
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
</script>
</body>
</html>
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )