Tweaking

just 4 smth

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/471295/1222885/Tweaking.js

  1. // ==UserScript==
  2. // @name chess-helper
  3. // @namespace chess-helper
  4. // @version 0.0.1
  5. // @author monkey
  6. // @icon https://images.chesscomfiles.com/uploads/v1/images_users/tiny_mce/SamCopeland/phpmeXx6V.png
  7. // @match https://www.chess.com/*
  8. // @run-at document-end
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. "use strict";
  13. let playerIsWhiteCache = false;
  14. const playerIsWhite = () => {
  15. if (playerIsWhiteCache)
  16. return playerIsWhiteCache;
  17. const firstCoordinateIsEight = document.querySelector(".coordinates").childNodes[0].textContent === "8";
  18. playerIsWhiteCache = firstCoordinateIsEight;
  19. return firstCoordinateIsEight;
  20. };
  21. const init$1 = () => {
  22. playerIsWhite();
  23. };
  24. const configService = { playerIsWhite, init: init$1 };
  25. const createElement = ({
  26. type,
  27. classes
  28. }) => {
  29. const element = document.createElement(type);
  30. classes.forEach((c) => element.classList.add(c));
  31. return element;
  32. };
  33. const getBoard = () => {
  34. const board = document.querySelector("chess-board");
  35. if (!board)
  36. return null;
  37. return board;
  38. };
  39. const domService = { createElement, getBoard };
  40. const chessMoves = {
  41. pawn: [
  42. {
  43. x: 0,
  44. y: 1,
  45. condition: ["base"]
  46. },
  47. {
  48. x: 0,
  49. y: 2,
  50. condition: ["isFirstMove"]
  51. },
  52. {
  53. y: 1,
  54. x: 1,
  55. condition: ["canAttack"]
  56. },
  57. {
  58. y: 1,
  59. x: -1,
  60. condition: ["canAttack"]
  61. }
  62. ],
  63. rook: [
  64. {
  65. y: "n",
  66. x: 0
  67. },
  68. {
  69. y: 0,
  70. x: "n"
  71. }
  72. ],
  73. bishop: [
  74. {
  75. y: "n1",
  76. x: "n1"
  77. }
  78. ],
  79. queen: [
  80. {
  81. y: "n1",
  82. x: "n1"
  83. },
  84. {
  85. y: "n",
  86. x: 0
  87. },
  88. {
  89. y: 0,
  90. x: "n"
  91. }
  92. ],
  93. knight: [
  94. {
  95. y: 2,
  96. x: 1,
  97. condition: ["always"]
  98. },
  99. {
  100. y: 2,
  101. x: -1,
  102. condition: ["always"]
  103. },
  104. {
  105. y: -2,
  106. x: 1,
  107. condition: ["always"]
  108. },
  109. {
  110. y: -2,
  111. x: -1,
  112. condition: ["always"]
  113. },
  114. {
  115. y: 1,
  116. x: 2,
  117. condition: ["always"]
  118. },
  119. {
  120. y: 1,
  121. x: -2,
  122. condition: ["always"]
  123. },
  124. {
  125. y: -1,
  126. x: 2,
  127. condition: ["always"]
  128. },
  129. {
  130. y: -1,
  131. x: -2,
  132. condition: ["always"]
  133. }
  134. ],
  135. king: [
  136. {
  137. y: 1,
  138. x: 0,
  139. condition: ["isSafe"]
  140. },
  141. {
  142. y: 1,
  143. x: 1,
  144. condition: ["isSafe"]
  145. },
  146. {
  147. y: 1,
  148. x: -1,
  149. condition: ["isSafe"]
  150. },
  151. {
  152. y: -1,
  153. x: 0,
  154. condition: ["isSafe"]
  155. },
  156. {
  157. y: -1,
  158. x: 1,
  159. condition: ["isSafe"]
  160. },
  161. {
  162. y: -1,
  163. x: -1,
  164. condition: ["isSafe"]
  165. },
  166. {
  167. y: 0,
  168. x: 1,
  169. condition: ["isSafe"]
  170. },
  171. {
  172. y: 0,
  173. x: -1,
  174. condition: ["isSafe"]
  175. },
  176. // castling moves
  177. {
  178. y: 0,
  179. x: 2,
  180. condition: ["isSafe", "isFirstMove", "towerUntouched", "castling"]
  181. },
  182. {
  183. y: 0,
  184. x: -2,
  185. condition: ["isSafe", "isFirstMove", "towerUntouched", "castling"]
  186. }
  187. ]
  188. };
  189. const chessTypes = {
  190. p: "pawn",
  191. r: "rook",
  192. n: "knight",
  193. b: "bishop",
  194. q: "queen",
  195. k: "king"
  196. };
  197. const ALTERATION_FIRST = 10;
  198. const ALTERATION_LAST = 1;
  199. const Square = (square, metaData, startSquare = null) => {
  200. startSquare = startSquare ?? Number(square);
  201. let current = Number(square);
  202. let isOnPiece = false;
  203. let id = crypto.randomUUID();
  204. let isOnEnemyPiece = false;
  205. let isOnEndOfBoard = false;
  206. let isOutsideBoard = false;
  207. let isActivePiece = true;
  208. let canAttack = true;
  209. const validate = () => {
  210. const info = squareService.getCurrentLocationPieceInfo(
  211. current,
  212. startSquare
  213. );
  214. if (info) {
  215. isOnPiece = info.isOnPiece;
  216. isOnEnemyPiece = info.isOnEnemyPiece;
  217. } else {
  218. isOnPiece = false;
  219. isOnEnemyPiece = false;
  220. }
  221. if (squareService.isLocatedOnEndOfBoard(current)) {
  222. isOnEndOfBoard = true;
  223. }
  224. if (squareService.isOutsideOfBoard(current)) {
  225. isOutsideBoard = true;
  226. }
  227. };
  228. validate();
  229. const getFirst = () => Number(String(current).charAt(0));
  230. const getLast = () => Number(String(current).charAt(1));
  231. const moveRight = () => {
  232. current += ALTERATION_FIRST;
  233. validate();
  234. return Square(current, metaData, startSquare);
  235. };
  236. const moveLeft = () => {
  237. current -= ALTERATION_FIRST;
  238. validate();
  239. return Square(current, metaData, startSquare);
  240. };
  241. const moveUp = () => {
  242. current += ALTERATION_LAST;
  243. validate();
  244. return Square(current, metaData, startSquare);
  245. };
  246. const moveDown = () => {
  247. current -= ALTERATION_LAST;
  248. validate();
  249. return Square(current, metaData, startSquare);
  250. };
  251. const setActivePiece = (active) => {
  252. isActivePiece = active;
  253. };
  254. const setCanAttack = (attacking) => {
  255. canAttack = attacking;
  256. };
  257. return {
  258. getStartSquareNumber: () => startSquare,
  259. getStartSquare: () => Square(startSquare, metaData),
  260. getFirst,
  261. getLast,
  262. getCurrent: () => current,
  263. getMetaData: () => metaData,
  264. getId: () => id,
  265. moveRight,
  266. moveLeft,
  267. moveUp,
  268. moveDown,
  269. setActivePiece,
  270. setCanAttack,
  271. isActivePiece: () => isActivePiece,
  272. canAttack: () => canAttack,
  273. isOnPiece: () => isOnPiece,
  274. isOnEnemyPiece: () => isOnEnemyPiece,
  275. isOnEndOfBoard: () => isOnEndOfBoard,
  276. isOutsideBoard: () => isOutsideBoard,
  277. isOnRow: (row) => getLast() === row,
  278. getSquare: () => Square(current, metaData, startSquare)
  279. };
  280. };
  281. const handleRepeatedMoveUntilBreak = (square, moves2, callback) => {
  282. let tempSquare = square.getSquare();
  283. while (true) {
  284. tempSquare = callback(tempSquare);
  285. if ((tempSquare == null ? void 0 : tempSquare.isOutsideBoard()) || tempSquare === null) {
  286. break;
  287. }
  288. if (tempSquare.isOnPiece()) {
  289. if (tempSquare.isOnEnemyPiece()) {
  290. moves2.push(tempSquare.getSquare());
  291. } else {
  292. tempSquare.setActivePiece(false);
  293. moves2.push(tempSquare.getSquare());
  294. }
  295. break;
  296. }
  297. moves2.push(tempSquare.getSquare());
  298. }
  299. };
  300. const handleAxis = (axis, square, moveOnAxis) => {
  301. const isPositive = moveOnAxis > 0;
  302. const isNegative = moveOnAxis < 0;
  303. if (isPositive) {
  304. for (let i = 0; i < moveOnAxis; i++) {
  305. if (axis === "y")
  306. square.moveUp();
  307. if (axis === "x")
  308. square.moveRight();
  309. }
  310. }
  311. if (isNegative) {
  312. for (let i = 0; i > moveOnAxis; i--) {
  313. if (axis === "y")
  314. square.moveDown();
  315. if (axis === "x")
  316. square.moveLeft();
  317. }
  318. }
  319. };
  320. const prepareKingMove = (move, metaData) => {
  321. var _a;
  322. const x = move.x;
  323. const y = move.y;
  324. if (Number.isNaN(x) || Number.isNaN(y)) {
  325. console.log("Both need to be numbers");
  326. return null;
  327. }
  328. const square = Square(metaData.square, metaData);
  329. if ((_a = move.condition) == null ? void 0 : _a.includes("castling")) {
  330. return null;
  331. }
  332. handleAxis("x", square, x);
  333. handleAxis("y", square, y);
  334. return square;
  335. };
  336. const prepareKnightMove = (move, metaData) => {
  337. const x = move.x;
  338. const y = move.y;
  339. if (Number.isNaN(x) || Number.isNaN(y)) {
  340. console.log("Both need to be numbers");
  341. return null;
  342. }
  343. const square = Square(metaData.square, metaData);
  344. handleAxis("x", square, x);
  345. handleAxis("y", square, y);
  346. return square;
  347. };
  348. const prepareN1Moves = (move, metaData) => {
  349. let moves2 = [];
  350. if (move.x !== "n1" || move.y !== "n1") {
  351. console.log("Both need to be n1");
  352. return moves2;
  353. }
  354. const startSquare = Square(metaData.square, metaData);
  355. handleRepeatedMoveUntilBreak(startSquare, moves2, (square) => {
  356. square.moveUp();
  357. return square.moveRight();
  358. });
  359. handleRepeatedMoveUntilBreak(startSquare, moves2, (square) => {
  360. square.moveUp();
  361. return square.moveLeft();
  362. });
  363. handleRepeatedMoveUntilBreak(startSquare, moves2, (square) => {
  364. square.moveDown();
  365. return square.moveRight();
  366. });
  367. handleRepeatedMoveUntilBreak(startSquare, moves2, (square) => {
  368. square.moveDown();
  369. return square.moveLeft();
  370. });
  371. return moves2;
  372. };
  373. const prepareNMoves = (move, metaData) => {
  374. let moves2 = [];
  375. if (move.x === "n" && move.y === "n") {
  376. console.log("handle special case");
  377. return moves2;
  378. }
  379. if (move.x !== "n" && move.y !== "n") {
  380. console.log("Cannot have both x and y as n");
  381. return moves2;
  382. }
  383. const handleVertical = move.y === "n";
  384. const square = Square(metaData.square, metaData);
  385. if (handleVertical) {
  386. handleRepeatedMoveUntilBreak(
  387. square,
  388. moves2,
  389. (square2) => square2.moveUp()
  390. );
  391. handleRepeatedMoveUntilBreak(
  392. square,
  393. moves2,
  394. (square2) => square2.moveDown()
  395. );
  396. } else {
  397. handleRepeatedMoveUntilBreak(
  398. square,
  399. moves2,
  400. (square2) => square2.moveRight()
  401. );
  402. handleRepeatedMoveUntilBreak(
  403. square,
  404. moves2,
  405. (square2) => square2.moveLeft()
  406. );
  407. }
  408. return moves2;
  409. };
  410. const preparePawnMove = (move, metaData) => {
  411. var _a, _b, _c, _d, _e, _f, _g;
  412. let square = Square(metaData.square, metaData);
  413. const isWhitePiece = metaData.isWhite;
  414. const checkIfFirstMove = (square2) => {
  415. if (isWhitePiece) {
  416. return square2.getSquare().isOnRow(2);
  417. } else {
  418. return square2.getSquare().isOnRow(7);
  419. }
  420. };
  421. const isFirstMove = checkIfFirstMove(square);
  422. const handleAxis2 = (axis, move2, callbacks) => {
  423. const value = move2[axis];
  424. if (value !== 0 && Number.isInteger(value)) {
  425. let x = value;
  426. const isPositive = x > 0;
  427. if (isWhitePiece) {
  428. for (let i = 0; i < Math.abs(x); i++) {
  429. if (isPositive) {
  430. callbacks.whiteAndPositive(square);
  431. } else {
  432. callbacks.whiteAndNegative(square);
  433. }
  434. if (square.isOnPiece()) {
  435. break;
  436. }
  437. }
  438. } else {
  439. for (let i = 0; i < Math.abs(x); i++) {
  440. if (isPositive) {
  441. callbacks.blackAndPositive(square);
  442. } else {
  443. callbacks.blackAndNegative(square);
  444. }
  445. if (square.isOnPiece()) {
  446. break;
  447. }
  448. }
  449. }
  450. }
  451. };
  452. handleAxis2("y", move, {
  453. blackAndPositive: (square2) => square2.moveDown(),
  454. blackAndNegative: (square2) => square2.moveUp(),
  455. whiteAndPositive: (square2) => square2.moveUp(),
  456. whiteAndNegative: (square2) => square2.moveDown()
  457. });
  458. handleAxis2("x", move, {
  459. blackAndPositive: (square2) => square2.moveLeft(),
  460. blackAndNegative: (square2) => square2.moveRight(),
  461. whiteAndPositive: (square2) => square2.moveRight(),
  462. whiteAndNegative: (square2) => square2.moveLeft()
  463. });
  464. if (((_a = move == null ? void 0 : move.condition) == null ? void 0 : _a.includes("isFirstMove")) && !isFirstMove) {
  465. return null;
  466. }
  467. if (((_b = move == null ? void 0 : move.condition) == null ? void 0 : _b.includes("isFirstMove")) && isFirstMove && square.isOnPiece()) {
  468. square.setCanAttack(false);
  469. square.setActivePiece(false);
  470. return square;
  471. }
  472. if (((_c = move == null ? void 0 : move.condition) == null ? void 0 : _c.includes("isFirstMove")) && isFirstMove) {
  473. square.setCanAttack(false);
  474. return square;
  475. }
  476. if (((_d = move == null ? void 0 : move.condition) == null ? void 0 : _d.includes("canAttack")) && !square.isOnEnemyPiece()) {
  477. square.setActivePiece(false);
  478. return square;
  479. }
  480. if (((_e = move == null ? void 0 : move.condition) == null ? void 0 : _e.includes("canAttack")) && square.isOnEnemyPiece()) {
  481. square.setCanAttack(true);
  482. return square;
  483. }
  484. if (!((_f = move == null ? void 0 : move.condition) == null ? void 0 : _f.includes("canAttack")) && square.isOnPiece()) {
  485. square.setActivePiece(false);
  486. square.setCanAttack(false);
  487. return square;
  488. }
  489. if ((_g = move == null ? void 0 : move.condition) == null ? void 0 : _g.includes("base")) {
  490. square.setCanAttack(false);
  491. return square;
  492. }
  493. return square;
  494. };
  495. const moveService = {
  496. preparePawnMove,
  497. prepareKnightMove,
  498. prepareKingMove,
  499. prepareNMoves,
  500. prepareN1Moves
  501. };
  502. const clearSquare = (board) => {
  503. var _a, _b;
  504. const toRemove = board.querySelectorAll(".doRemove");
  505. for (const element of toRemove) {
  506. (_a = element == null ? void 0 : element.parentNode) == null ? void 0 : _a.removeChild(element);
  507. }
  508. const highlightsToRemove = board.querySelectorAll(".highlight");
  509. for (const element of highlightsToRemove) {
  510. (_b = element == null ? void 0 : element.classList) == null ? void 0 : _b.remove("highlight");
  511. }
  512. };
  513. const getCurrentLocationPieceInfo = (square, start) => {
  514. if (square === start)
  515. return null;
  516. const isOnPiece = (current2) => {
  517. var _a;
  518. return (_a = current2 == null ? void 0 : current2.className) == null ? void 0 : _a.includes("piece");
  519. };
  520. const startSquare = Array.from(
  521. document.querySelectorAll(`.square-${start}`)
  522. ).find((e) => isOnPiece(e));
  523. const current = Array.from(
  524. document.querySelectorAll(`.square-${square}`)
  525. ).find((e) => isOnPiece(e));
  526. const metaData = getMetaDataForSquare(startSquare);
  527. const isBlackPiecePlaying = !metaData.isWhite;
  528. const isStandingOnWhitePiece = (current2) => {
  529. const metaData2 = getMetaDataForSquare(current2);
  530. return (metaData2 == null ? void 0 : metaData2.isWhite) ?? false;
  531. };
  532. const isOnEnemy = isBlackPiecePlaying && isStandingOnWhitePiece(current) || !isBlackPiecePlaying && !isStandingOnWhitePiece(current);
  533. return {
  534. isOnPiece: isOnPiece(current),
  535. isOnEnemyPiece: isOnPiece(current) ? isOnEnemy : false
  536. };
  537. };
  538. const isLocatedOnEndOfBoard = (square) => {
  539. const first = Number(String(square).charAt(0));
  540. const last = Number(String(square).charAt(1));
  541. if (first === 8 || first === 1)
  542. return true;
  543. if (last === 8 || last === 1)
  544. return true;
  545. return false;
  546. };
  547. const isOutsideOfBoard = (square) => {
  548. const first = Number(String(square).charAt(0));
  549. const last = Number(String(square).charAt(1));
  550. if (!first || !last)
  551. return true;
  552. if (first > 8 || first < 1)
  553. return true;
  554. if (last > 8 || last < 1)
  555. return true;
  556. return false;
  557. };
  558. const getPossibleMoveSquares = (moves2, metaData) => {
  559. let totalMoves = [];
  560. for (const move of moves2) {
  561. let tempMoves = [];
  562. switch (metaData.type) {
  563. case "pawn":
  564. const pawnMove = moveService.preparePawnMove(move, metaData);
  565. if (pawnMove)
  566. tempMoves = [pawnMove];
  567. break;
  568. case "rook":
  569. tempMoves = moveService.prepareNMoves(move, metaData);
  570. break;
  571. case "bishop":
  572. tempMoves = moveService.prepareN1Moves(move, metaData);
  573. break;
  574. case "queen":
  575. const isNMove = move.x === "n" || move.y === "n";
  576. if (isNMove) {
  577. tempMoves = moveService.prepareNMoves(move, metaData);
  578. } else {
  579. tempMoves = moveService.prepareN1Moves(move, metaData);
  580. }
  581. break;
  582. case "knight":
  583. const knightMove = moveService.prepareKnightMove(
  584. move,
  585. metaData
  586. );
  587. if (knightMove)
  588. tempMoves = [knightMove];
  589. break;
  590. case "king":
  591. const kingMove = moveService.prepareKingMove(move, metaData);
  592. if (kingMove)
  593. tempMoves = [kingMove];
  594. break;
  595. default:
  596. console.log("Not implemented yet");
  597. }
  598. totalMoves = [...totalMoves, ...tempMoves];
  599. }
  600. return totalMoves;
  601. };
  602. const getMetaDataForSquare = (target) => {
  603. var _a;
  604. if (target instanceof SVGElement)
  605. return null;
  606. if (!((_a = target == null ? void 0 : target.className) == null ? void 0 : _a.includes("piece")))
  607. return null;
  608. const data = target.className.split(" ");
  609. let pieceInfo = data[1];
  610. let squareInfo = data[2];
  611. if (pieceInfo.includes("square")) {
  612. const temp = pieceInfo;
  613. pieceInfo = squareInfo;
  614. squareInfo = temp;
  615. }
  616. const square = squareInfo.split("-")[1];
  617. const pieceAbbreviation = pieceInfo[1];
  618. return {
  619. isWhite: pieceInfo.startsWith("b") ? false : true,
  620. type: chessTypes[pieceAbbreviation],
  621. square: Number(square),
  622. element: target
  623. };
  624. };
  625. const squareService = {
  626. clearSquare,
  627. isOutsideOfBoard,
  628. getCurrentLocationPieceInfo,
  629. isLocatedOnEndOfBoard,
  630. getPossibleMoveSquares,
  631. getMetaDataForSquare
  632. };
  633. const moves = [];
  634. const addMoves = (square) => {
  635. if (!square)
  636. return;
  637. const validate = (square2) => {
  638. if (squareService.isOutsideOfBoard(square2.getCurrent()))
  639. return;
  640. moves.push(square2);
  641. };
  642. if (Array.isArray(square)) {
  643. square.forEach(validate);
  644. return;
  645. }
  646. validate(square);
  647. };
  648. const getMoves = () => {
  649. return moves;
  650. };
  651. const clearMoves = () => {
  652. moves.length = 0;
  653. };
  654. const displayMoveService = { addMoves, getMoves, clearMoves };
  655. const getCurrentEnemyPieces = () => {
  656. const enemyPieces = Array.from(document.querySelectorAll(".piece")).filter(
  657. (element) => {
  658. const metaData = squareService.getMetaDataForSquare(element);
  659. return (metaData == null ? void 0 : metaData.isWhite) !== configService.playerIsWhite();
  660. }
  661. );
  662. return enemyPieces;
  663. };
  664. const getCurrentUserPieces = () => {
  665. const userPieces = Array.from(document.querySelectorAll(".piece")).filter(
  666. (element) => {
  667. const metaData = squareService.getMetaDataForSquare(element);
  668. return (metaData == null ? void 0 : metaData.isWhite) === configService.playerIsWhite();
  669. }
  670. );
  671. return userPieces;
  672. };
  673. const getPossibleEnemyMoves = () => {
  674. const enemies = getCurrentEnemyPieces().map(
  675. (element) => squareService.getMetaDataForSquare(element)
  676. );
  677. const possibleEnemyMoves = enemies.reduce(
  678. (accumulator, enemy) => {
  679. const moves2 = chessMoves[enemy.type];
  680. const possibleMoves = squareService.getPossibleMoveSquares(
  681. moves2,
  682. enemy
  683. );
  684. return [
  685. ...accumulator,
  686. ...possibleMoves.filter((s) => s.canAttack())
  687. ];
  688. },
  689. []
  690. );
  691. return possibleEnemyMoves;
  692. };
  693. const getPossibleUserMoves = () => {
  694. const userPieces = getCurrentUserPieces().map(
  695. (element) => squareService.getMetaDataForSquare(element)
  696. );
  697. const possibleUserMoves = userPieces.reduce(
  698. (accumulator, userPiece) => {
  699. const moves2 = chessMoves[userPiece.type];
  700. const possibleMoves = squareService.getPossibleMoveSquares(
  701. moves2,
  702. userPiece
  703. );
  704. return [
  705. ...accumulator,
  706. ...possibleMoves.filter((s) => s.canAttack())
  707. ];
  708. },
  709. []
  710. );
  711. return possibleUserMoves;
  712. };
  713. const pieceService = {
  714. getPossibleEnemyMoves,
  715. getPossibleUserMoves,
  716. getCurrentEnemyPieces,
  717. getCurrentUserPieces
  718. };
  719. const BACKGROUND_COLORS = {
  720. green: "lightgreen",
  721. gray: "lightgray",
  722. red: "red",
  723. orange: "orange"
  724. };
  725. const showPiecesInDanger = ({
  726. board,
  727. currentUserPieces,
  728. possibleEnemyMoves,
  729. allPossibleUserMoves
  730. }) => {
  731. currentUserPieces.forEach((piece) => {
  732. const squareMetaData = squareService.getMetaDataForSquare(piece);
  733. const isPieceInDanger = possibleEnemyMoves.some(
  734. (s) => s.getCurrent() === squareMetaData.square
  735. );
  736. const possibleMovesExludedCurrentPiece = allPossibleUserMoves.filter(
  737. (s) => {
  738. return piece.isEqualNode(s.getMetaData().element) === false;
  739. }
  740. );
  741. const pieceHasBackup = possibleMovesExludedCurrentPiece.some((s) => {
  742. return s.getCurrent() === squareMetaData.square;
  743. });
  744. const element = domService.createElement({
  745. type: "div",
  746. classes: [
  747. "capture-hint",
  748. `square-${squareMetaData.square}`,
  749. "doRemove"
  750. ]
  751. });
  752. if (isPieceInDanger && pieceHasBackup) {
  753. element.style.borderColor = BACKGROUND_COLORS.orange;
  754. } else if (isPieceInDanger) {
  755. element.style.borderColor = BACKGROUND_COLORS.red;
  756. }
  757. if (isPieceInDanger) {
  758. element.style.borderWidth = "8px";
  759. element.style.opacity = "0.5";
  760. board == null ? void 0 : board.appendChild(element);
  761. }
  762. });
  763. };
  764. const showPossibleMoves = ({
  765. board,
  766. activeMoves,
  767. possibleEnemyMoves
  768. }) => {
  769. activeMoves.forEach((square) => {
  770. if (square === null || square === void 0)
  771. return;
  772. if (square.getCurrent() === square.getStartSquareNumber())
  773. return;
  774. if (square.isOnPiece() && !square.isOnEnemyPiece())
  775. return;
  776. const classes = ["hint", `square-${square.getCurrent()}`, "doRemove"];
  777. if (square.isOnEnemyPiece())
  778. classes.push("enemy");
  779. const element = domService.createElement({
  780. type: "div",
  781. classes
  782. });
  783. const isPossibleEnemyMove = possibleEnemyMoves.some(
  784. (s) => s.getCurrent() === square.getCurrent()
  785. );
  786. const isUserPiece = configService.playerIsWhite() && square.getMetaData().isWhite || !configService.playerIsWhite() && !square.getMetaData().isWhite;
  787. const pieceCoveredByAmount = possibleEnemyMoves.filter(
  788. (s) => s.getCurrent() === square.getCurrent()
  789. ).length;
  790. let color = BACKGROUND_COLORS.gray;
  791. if (isUserPiece) {
  792. if (isPossibleEnemyMove && square.isOnEnemyPiece()) {
  793. color = BACKGROUND_COLORS.orange;
  794. } else if (isPossibleEnemyMove) {
  795. color = BACKGROUND_COLORS.orange;
  796. } else if (square.isOnEnemyPiece()) {
  797. color = BACKGROUND_COLORS.green;
  798. }
  799. if (pieceCoveredByAmount > 1) {
  800. element.textContent = pieceCoveredByAmount.toString();
  801. element.style.display = "grid";
  802. element.style.placeItems = "center";
  803. }
  804. }
  805. element.style.backgroundColor = color;
  806. element.style.opacity = "0.5";
  807. board == null ? void 0 : board.appendChild(element);
  808. });
  809. };
  810. const showPossibleFreeCaptures = ({
  811. board,
  812. allPossibleUserMoves,
  813. possibleEnemyMoves
  814. }) => {
  815. allPossibleUserMoves.forEach((square) => {
  816. if (square === null || square === void 0)
  817. return;
  818. if (square.getCurrent() === square.getStartSquareNumber())
  819. return;
  820. if (square.isOnPiece() && !square.isOnEnemyPiece())
  821. return;
  822. if (!square.isOnEnemyPiece())
  823. return;
  824. const isPossibleEnemyMove = possibleEnemyMoves.some(
  825. (s) => s.getCurrent() === square.getCurrent()
  826. );
  827. const isUserPiece = configService.playerIsWhite() && square.getMetaData().isWhite || !configService.playerIsWhite() && !square.getMetaData().isWhite;
  828. const classes = [
  829. "capture-hint",
  830. `square-${square.getCurrent()}`,
  831. "doRemove"
  832. ];
  833. const element = domService.createElement({
  834. type: "div",
  835. classes
  836. });
  837. if (isUserPiece && !isPossibleEnemyMove) {
  838. element.style.borderWidth = "8px";
  839. element.style.borderColor = BACKGROUND_COLORS.green;
  840. element.style.opacity = "0.5";
  841. board == null ? void 0 : board.appendChild(element);
  842. }
  843. });
  844. };
  845. const displayMoves = () => {
  846. const board = domService.getBoard();
  847. const possibleEnemyMoves = pieceService.getPossibleEnemyMoves();
  848. const moves2 = displayMoveService.getMoves();
  849. const activeMoves = moves2.filter((s) => s.isActivePiece());
  850. const currentUserPieces = pieceService.getCurrentUserPieces();
  851. const allPossibleUserMoves = pieceService.getPossibleUserMoves();
  852. showPiecesInDanger({
  853. board,
  854. currentUserPieces,
  855. possibleEnemyMoves,
  856. allPossibleUserMoves
  857. });
  858. showPossibleMoves({ board, activeMoves, possibleEnemyMoves });
  859. showPossibleFreeCaptures({
  860. board,
  861. allPossibleUserMoves,
  862. possibleEnemyMoves
  863. });
  864. };
  865. const displayService = { displayMoves };
  866. let firstRun = true;
  867. const addLeftClickEvent = () => {
  868. const board = domService.getBoard();
  869. if (board === null)
  870. return false;
  871. board.addEventListener("click", () => {
  872. squareService.clearSquare(board);
  873. displayMoveService.clearMoves();
  874. });
  875. return true;
  876. };
  877. const addRightClickEvent = () => {
  878. if (firstRun) {
  879. configService.init();
  880. firstRun = false;
  881. }
  882. const board = domService.getBoard();
  883. if (board === null)
  884. return false;
  885. board.addEventListener("contextmenu", (e) => {
  886. squareService.clearSquare(board);
  887. displayMoveService.clearMoves();
  888. const target = e.target;
  889. const metaData = squareService.getMetaDataForSquare(target);
  890. if (metaData === null)
  891. return;
  892. const moves2 = chessMoves[metaData.type];
  893. const possibleMoves = squareService.getPossibleMoveSquares(
  894. moves2,
  895. metaData
  896. );
  897. displayMoveService.addMoves(possibleMoves);
  898. displayService.displayMoves();
  899. });
  900. return true;
  901. };
  902. const eventService = { addLeftClickEvent, addRightClickEvent };
  903. const main = () => {
  904. try {
  905. const leftClickSuccess = eventService.addLeftClickEvent();
  906. const rightClickSuccess = eventService.addRightClickEvent();
  907. if (!leftClickSuccess || !rightClickSuccess)
  908. return false;
  909. return true;
  910. } catch (error) {
  911. console.error(error);
  912. return false;
  913. }
  914. };
  915. const IS_TM_SCRIPT = document.readyState === "interactive";
  916. const TIMEOUT_BEFORE_START = 2e3;
  917. const init = () => {
  918. let success = true;
  919. try {
  920. success = main();
  921. } catch (error) {
  922. console.error(error);
  923. success = false;
  924. }
  925. if (success) {
  926. console.log("%c Chess helper initialized!", "color: lightgreen");
  927. } else {
  928. console.error("%c Failed to initialize application", "color: lightred");
  929. }
  930. };
  931. const run = () => {
  932. console.log("%c Chess helper starting...", "color: lightblue");
  933. const boardExists = domService.getBoard();
  934. if (boardExists) {
  935. init();
  936. return;
  937. }
  938. console.log("%c Board not found, waiting...", "color: lightblue");
  939. const startup = setInterval(() => {
  940. const correctBoard = domService.getBoard();
  941. if (correctBoard) {
  942. clearInterval(startup);
  943. init();
  944. }
  945. }, TIMEOUT_BEFORE_START);
  946. };
  947. if (IS_TM_SCRIPT) {
  948. window.onload = () => {
  949. setTimeout(run, TIMEOUT_BEFORE_START);
  950. };
  951. } else {
  952. run();
  953. }
  954. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址