您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Highlights playable cards, adds keyboard controls, displays a helper message for Grundo's Cafe Pyramids game, and handles game over conditions.
// ==UserScript== // @name GC Shalane's Pyramids Game Helper and Keyboard Controls // @namespace https://gf.qytechs.cn/en/users/1192105 // @version 1.0 // @description Highlights playable cards, adds keyboard controls, displays a helper message for Grundo's Cafe Pyramids game, and handles game over conditions. // @match https://www.grundos.cafe/games/pyramids/ // @icon https://www.google.com/s2/favicons?sz=64&domain=grundos.cafe // @license MIT // ==/UserScript== // Add event listener for key presses document.addEventListener('keydown', function(event) { // If "Enter" or "Left Arrow" key is pressed if (event.key === "Enter" || event.key === "ArrowLeft") { // Simulate a click on the "Play Pyramids Again!" button document.querySelector("input[value='Play Pyramids Again!']").click(); } }); // Add event listener for key presses document.addEventListener('keydown', function(event) { // If "Enter" or "Left Arrow" key is pressed if (event.key === "Enter" || event.key === "ArrowLeft") { // Simulate a click on the "Play Pyramids!" button document.querySelector("input[value='Play Pyramids!']").click(); } }); // Helper function to get the numerical value of a card based on its image source function getCardValue(cardImgSrc) { const fileName = cardImgSrc.split('/').pop(); const numMatch = fileName.match(/(\d+)_/); if (numMatch) { const num = parseInt(numMatch[1], 10); return num === 14 ? 14 : num; // Ace is 14 } return null; } // Helper function to get the name of the card (e.g., "Queen of Spades") based on the card's image source function getCardName(cardImgSrc) { const fileName = cardImgSrc.split('/').pop(); const parts = fileName.split('_'); const cardValue = parseInt(parts[0], 10); const suit = parts[1].replace('.gif', '').charAt(0).toUpperCase() + parts[1].replace('.gif', '').slice(1); // Patch for Neggs instead of Hearts const suitDisplay = (suit === "Hearts") ? "Neggs" : suit; let cardName; switch (cardValue) { case 11: cardName = `Jack of ${suitDisplay}`; break; case 12: cardName = `Queen of ${suitDisplay}`; break; case 13: cardName = `King of ${suitDisplay}`; break; case 14: cardName = `Ace of ${suitDisplay}`; break; default: cardName = `${cardValue} of ${suitDisplay}`; break; } return cardName; } // Function to check if a card is playable based on the top card's value function isPlayable(cardValue, topCardValue) { if (cardValue === null || topCardValue === null) return false; // Allow wrapping between Ace (14) and 2 if (topCardValue === 14 && cardValue === 2) return true; if (topCardValue === 2 && cardValue === 14) return true; // Check for difference of 1 (either direction) return Math.abs(cardValue - topCardValue) === 1; } // Check if a card is revealed (not hidden or blank) function isRevealed(card) { const src = card.src; return !src.includes("pyramid.gif") && !src.includes("blank.gif"); // Revealed cards do not have "pyramid" or "blank" } // Function to display a helper message at the bottom of the screen function displayHelperMessage(message) { let helperDiv = document.querySelector("#helperMessage"); if (!helperDiv) { // Create the helper message div if it doesn't exist helperDiv = document.createElement("div"); helperDiv.id = "helperMessage"; helperDiv.style.cssText = "text-align: center; padding: 10px; border: 1px solid #ccc; background: #f8f8f8; margin: 10px auto; width: 80%; font-size: 16px;"; const desertButton = document.querySelector("input[value='Return to The Lost Desert']"); desertButton.parentNode.insertBefore(helperDiv, desertButton); } helperDiv.innerHTML = message; } // Function to handle the game state when the deck is empty function handleGameOver() { const collectButton = document.querySelector("input[value='Collect Winnings']"); if (collectButton) { collectButton.classList.add('highlight'); collectButton.style.border = '5px solid red'; // Highlight with red for game over displayHelperMessage("Game is Over! ⬅️ Collect Winnings"); // Add event listener for clicking "Collect Winnings" document.addEventListener("keydown", function collectWinningsListener(event) { if (event.key === "ArrowLeft") { collectButton.click(); // Simulate clicking the Collect Winnings button document.removeEventListener("keydown", collectWinningsListener); // Remove listener after clicking } }); } } // Highlight playable cards and add keyboard controls function highlightPlayableCards() { // Reset previous highlights document.querySelectorAll('.highlight').forEach(card => { card.classList.remove('highlight'); card.style.border = ''; }); const topCard = document.querySelector("#pyramids_board .hand.face_up"); const deckEmpty = document.querySelector("img[src='https://grundoscafe.b-cdn.net/desert/pyramids/empty.gif']"); if (!topCard || topCard.src.includes("empty.gif")) { if (deckEmpty) { handleGameOver(); // Handle game over if no draws are left } return; } const topCardValue = getCardValue(topCard.src); const revealedCards = Array.from(document.querySelectorAll("#pyramids_board .rows img")).filter(card => { const cardValue = getCardValue(card.src); const playable = cardValue && isPlayable(cardValue, topCardValue); const revealed = isRevealed(card); return revealed && playable; }); if (revealedCards.length === 0) { if (deckEmpty) { handleGameOver(); // Handle game over if deck is empty and no playable cards } else { const deck = document.querySelector("img[src='https://grundoscafe.b-cdn.net/games/php_games/sakhmetsolitaire/pyramid.gif']"); deck.classList.add('highlight'); deck.style.border = '5px solid red'; displayHelperMessage("No playable cards. ⬅️ Reveal Card"); document.addEventListener("keydown", function deckDrawListener(event) { if (event.key === "ArrowLeft" || event.key === "Enter") { if (deck) deck.click(); // Check if deck is available before clicking document.removeEventListener("keydown", deckDrawListener); // Remove listener after clicking } }); } } else { // If there are playable cards, highlight and show helper message const arrowMap = ["⬅️", "⬆️", "➡️", "⬇️"]; let message = `Playable cards:<br>`; revealedCards.forEach((card, index) => { card.classList.add('highlight'); card.style.border = '5px solid yellow'; const cardName = getCardName(card.src); message += `${cardName} ${arrowMap[index] || ""}<br>`; // Display correct arrow document.addEventListener("keydown", function arrowKeyListener(event) { const arrowKeys = ["ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown"]; if (event.key === arrowKeys[index]) { // Ensure correct key if (card) { card.click(); // Safeguard to check if card is present before clicking } else { console.warn("Card is missing or not available for interaction."); } document.removeEventListener("keydown", arrowKeyListener); // Remove listener after clicking } }); }); displayHelperMessage(message); } } // Run the highlight function initially and whenever the Enter key is pressed to draw a new card document.addEventListener("keydown", (event) => { if (event.key === "Enter") { const deck = document.querySelector("img[src='https://grundoscafe.b-cdn.net/games/php_games/sakhmetsolitaire/pyramid.gif']"); if (deck) { deck.click(); } setTimeout(highlightPlayableCards, 500); // Wait a bit for the new card to load before highlighting } }); highlightPlayableCards(); // Initial run
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址