Chess.com Piece Numbers

Adds piece number data to pieces in the chess board

  1. // ==UserScript==
  2. // @name Chess.com Piece Numbers
  3. // @namespace https://theusaf.org
  4. // @version 0.0.5
  5. // @description Adds piece number data to pieces in the chess board
  6. // @author theusaf
  7. // @match https://www.chess.com/**
  8. // @icon https://www.google.com/s2/favicons?domain=chess.com
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. let tries = 0;
  14.  
  15. function init() {
  16. const board = document.querySelector("chess-board"),
  17. pieces = {
  18. black: {
  19. p: 2 // to fix promotion stuff
  20. },
  21. white: {
  22. p: 2
  23. }
  24. };
  25.  
  26. if (board) {
  27. const observer = new MutationObserver((mutations, observer) => {
  28. const attributeMutations = new Set();
  29. for (const mutation of mutations) {
  30. if (mutation.type === "childList") {
  31. const {addedNodes, removedNodes} = mutation;
  32. for (const node of addedNodes) {
  33. if (node.nodeName !== "DIV") {continue;}
  34. if (Array.from(node.classList)?.includes("piece")) {
  35. addPiece(node);
  36. }
  37. }
  38. for (const node of removedNodes) {
  39. if (node.nodeName !== "DIV") {continue;}
  40. if (Array.from(node.classList)?.includes("piece")) {
  41. removePiece(node);
  42. }
  43. }
  44. } else {
  45. const filter = (mutation) => {
  46. return (/piece/.test(mutation.oldValue) ||
  47. /piece/.test(mutation.target.className)) &&
  48. (!/dragging/.test(mutation.target.className) &&
  49. !/dragging/.test(mutation.oldValue) &&
  50. mutation.oldValue !== null);
  51. };
  52. if (filter(mutation)) {
  53. attributeMutations.add(mutation);
  54. }
  55. }
  56. }
  57. const out = [],
  58. moveSquaresProcessed = new Set(),
  59. toSwap = new Set();
  60. for (const mutation of attributeMutations) {
  61. out.push(mutation);
  62. const piecePosition = getPieceSquare(mutation.target.className),
  63. [pieceTeam, pieceType] = getPieceType(mutation.target.className),
  64. [originalPieceTeam, originalPieceType] = getPieceType(mutation.oldValue);
  65. if (piecePosition in moveSquaresProcessed) {continue;}
  66. moveSquaresProcessed.add(piecePosition);
  67. let shouldContinue = false;
  68. // console.log(piecePosition, pieceTeam, pieceType, originalPieceTeam, originalPieceType)
  69. for (const swap of toSwap) {
  70. const {team, type, swapWith} = swap;
  71. if (pieceTeam === team && pieceType === type) {
  72. console.log("swapping");
  73. swapPieces(mutation.target, swapWith);
  74. toSwap.delete(swap);
  75. shouldContinue = true;
  76. break;
  77. }
  78. }
  79. if (shouldContinue) {continue;}
  80. if (pieceTeam === originalPieceTeam && pieceType === originalPieceType) {
  81. // no change required
  82. } else {
  83. // uh oh, need to swap!
  84. toSwap.add({
  85. team: originalPieceTeam,
  86. type: originalPieceType,
  87. swapWith: mutation.target
  88. });
  89. }
  90. }
  91. if (out.length) {
  92. /*console.log(out.map(mutation => {
  93. return [`${mutation.oldValue} --> ${mutation.target.className}`, mutation.target];
  94. }));*/
  95. // Check for any abnormalities and fix issues
  96. moveSquaresProcessed.clear();
  97. for (const mutation of attributeMutations) {
  98. const piecePosition = getPieceSquare(mutation.target.className),
  99. currentPiece = getPieceType(mutation.target.className).join(""),
  100. originalPiece = mutation.target.getAttribute("original-piece");
  101. if (piecePosition in moveSquaresProcessed) {continue;}
  102. moveSquaresProcessed.add(piecePosition);
  103. if (!currentPiece || !piecePosition) {continue;}
  104. if (currentPiece !== originalPiece) {
  105. const pieces = [...document.querySelectorAll(`[original-piece=${currentPiece}]`)];
  106. for (const piece of pieces) {
  107. const pieceOrignalPiece = piece.getAttribute("original-piece"),
  108. pieceCurrentPiece = getPieceType(piece.className).join("");
  109. if (pieceOrignalPiece !== pieceCurrentPiece) {
  110. console.log("Swapping #2", mutation.target, piece);
  111. swapPieces(piece, mutation.target);
  112. // swap original pieces also
  113. mutation.target.setAttribute("original-piece", pieceOrignalPiece);
  114. piece.setAttribute("original-piece", originalPiece);
  115. break;
  116. }
  117. }
  118. }
  119. }
  120. }
  121. });
  122. observer.observe(board, {
  123. childList: true,
  124. subtree: true,
  125. attributeFilter: ["class"],
  126. attributeOldValue: true
  127. });
  128. const existingPieces = document.querySelectorAll("chess-board .piece");
  129. for (const piece of existingPieces) {
  130. addPiece(piece);
  131. }
  132. } else {
  133. if (++tries > 10) {return;}
  134. setTimeout(init, 500);
  135. }
  136.  
  137. function swapPieces(a, b) {
  138. const myNumber = a.getAttribute("piece-number"),
  139. myOriginalPiece = a.getAttribute("original-piece");
  140. a.setAttribute("piece-number", b.getAttribute("piece-number"));
  141. a.setAttribute("original-piece", b.getAttribute("original-piece"));
  142. b.setAttribute("piece-number", myNumber);
  143. b.setAttribute("original-piece", myOriginalPiece);
  144. }
  145. function getPieceSquare(name) {
  146. const piece = name.split(" ").find(word => /^square/.test(word));
  147. return piece?.split("-")[1];
  148. }
  149. function getPieceType(name) {
  150. const piece = name.split(" ").find(word => word.length === 2 && /^[wb]/.test(word));
  151. return piece?.split("") || [];
  152. }
  153. function addPiece(piece) {
  154. const colorPieces = piece.classList[1][0] === "w" ? pieces.white : pieces.black,
  155. actualPiece = piece.classList[1][1];
  156. if (typeof colorPieces[actualPiece] !== "number") {colorPieces[actualPiece] = 0;}
  157. colorPieces[actualPiece]++;
  158. piece.setAttribute("piece-number", colorPieces[actualPiece]);
  159. piece.setAttribute("original-piece", getPieceType(piece.className).join(""));
  160. }
  161. function removePiece(piece) {
  162. const colorPieces = piece.classList[1][0] === "w" ? pieces.white : pieces.black,
  163. actualPiece = piece.classList[1][1];
  164. if (typeof colorPieces[actualPiece] !== "number") {colorPieces[actualPiece] = 0;}
  165. colorPieces[actualPiece]--;
  166. }
  167. }
  168.  
  169. init();

QingJ © 2025

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