您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Attempts to solve World Kaiju sync.
// ==UserScript== // @name BvS WK Sync // @namespace BvS // @version 1.3 // @history 1.3 New domain - animecubedgaming.com - Channel28 // @history 1.2 Now https compatible (Updated by Channel28) // @history 1.1 Added grant permissions (Updated by Channel28) // @history 1.0 Initial Release // @description Attempts to solve World Kaiju sync. // @include http*://*animecubed.com/billy/bvs/worldkaiju-group.html // @include http*://*animecubedgaming.com/billy/bvs/worldkaiju-group.html // @licence MIT; http://www.opensource.org/licenses/mit-license.php // @copyright 2010, Daniel Karlsson // @grant GM_log // ==/UserScript== const TIMELIMIT = 5000; // ms var options = document.evaluate("//form[@name='groupcheck']/select[@name='c1']/option", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); var colours = []; for (var i = 0; i < options.snapshotLength; i++) { var value = parseInt(options.snapshotItem(i).value); var colour = options.snapshotItem(i).textContent; colours[value] = colour; } function find(val, arr) { for (var i in arr) if (arr[i] == val) return i; return -1; } function print(arr) { var xarr = []; for (var i in arr) xarr.push(colours[arr[i]]); return xarr.join(","); } function Mastermind(pegs, colours) { var my = this; my.colours = colours; my.pegs = pegs; my.prevGuesses = []; // Create array of all possible combinations my.combinations = []; for (var i = 0; i < Math.pow(my.colours, my.pegs); i++) { var n = i; var comb = []; for (var p = 0; p < my.pegs; p++) { comb.push(n % my.colours); n = Math.floor(n / my.colours); } my.combinations.push(comb); } my.appendGuess = function(g, s) { my.prevGuesses.push({guess: g, score: s}); } // Determine score as [<correct colour, correct position>, <correct colour, wrong position>] my.score = function(guess, board) { var boardColours = []; var guessColours = []; for (var i = 0; i < my.colours; i++) { boardColours.push(0); guessColours.push(0); } var correctPosition = 0; for (var i = 0; i < my.pegs; i++) { if (board[i] == guess[i]) correctPosition++; else { boardColours[board[i]]++; guessColours[guess[i]]++; } } var correctColour = 0; for (var c = 0; c < my.colours; c++) correctColour += Math.min(guessColours[c], boardColours[c]); return [correctPosition, correctColour]; } my.possibleScores = []; for (var c = 0; c <= my.pegs; c++) for (var p = 0; p <= my.pegs - c; p++) my.possibleScores.push([p, c]); // Remove combinations based on guess and score my.eliminateCombinations = function(guess, score, splice) { var keepers = []; var removals = 0; for (var c in my.combinations) { var s = my.score(guess, my.combinations[c]); if (s[0] == score[0] && s[1] == score[1]) { if (splice) keepers.push(my.combinations[c]); } else { removals++; } } if (splice) my.combinations = keepers; return removals; } // Calculate minimum number of eliminations my.guessScore = function(guess) { var score = my.combinations.length + 1; for (var s in my.possibleScores) { var removals = my.eliminateCombinations(guess, my.possibleScores[s], false); score = Math.min(removals, score); } return score; } // Estimate time of bsetGuess brute force method my.estimateTime = function() { var t1 = new Date(); var score = my.guessScore(my.combinations[0]); var t2 = new Date(); var t = t2.getTime() - t1.getTime(); return t * my.combinations.length; } // Brute force search of all possibilities my.bestGuess = function() { var bestGuess; var bestScore = -1; for (var guess in my.combinations) { var score = my.guessScore(my.combinations[guess]); if (score > bestScore) { bestScore = score; bestGuess = my.combinations[guess]; } } my.bestScore = bestScore; my.bestGuess = bestGuess; return bestGuess; } // Try random guesses until we run out of time my.fastGuess = function(limit) { var t1 = new Date(); t1 = t1.getTime(); var bestGuess; var bestScore = -1; var time = 0; var tried = []; do { var guess; guess = Math.floor(Math.random() * my.combinations.length); while (find(guess, tried) >= 0) guess = (guess + 1) % my.combinations.length; tried.push(guess); var score = my.guessScore(my.combinations[guess]); if (score > bestScore) { bestScore = score; bestGuess = my.combinations[guess]; } var t2 = new Date(); time = t2.getTime() - t1; if (tried.length >= my.combinations.length) break; } while (time < limit) my.bestScore = bestScore; my.bestGuess = bestGuess; return bestGuess; } } var form = document.evaluate("//form[@name='groupcheck']", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null); if (form) { form = form.singleNodeValue; var guesses = document.evaluate("//table/tbody/tr[count(descendant::td)=5]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); var prevGuesses = 0; var board = new Mastermind(4, colours.length); // Legacy hint if (/You have a strong feeling that the first Chakra isn.t (\w+)/.test(form.textContent)) { GM_log("Legacy: " + RegExp.lastParen); var chakra = find(RegExp.lastParen, colours); if (chakra >= 0) { keepers = []; for (var i in board.combinations) if (board.combinations[i][0] != chakra) keepers.push(board.combinations[i]); GM_log("Kept " + keepers.length + " / " + board.combinations.length); board.combinations = keepers; } } for (var g = 0; g < guesses.snapshotLength; g++) { var tds = guesses.snapshotItem(g).getElementsByTagName("td"); var guess = []; var res = [] for (var i = 0; i < 4; i++) { var col = tds[i].textContent; if (find(col, colours)) guess.push(find(col, colours)); else continue; } var match = tds[4].textContent.match(/(\d+)[^\d]+(\d+)/); if (match && guess.length == 4) { res = [parseInt(match[1]), parseInt(match[2])]; board.appendGuess(guess, res); board.eliminateCombinations(guess, res, true); prevGuesses++; } } var div = document.createElement("div"); form.parentNode.insertBefore(div, form.nextSibling); div.textContent = "Searching..."; setTimeout(function() { var limited = false; var bestGuess; if (board.estimateTime() > TIMELIMIT) { bestGuess = board.fastGuess(TIMELIMIT); limited = true; } else bestGuess = board.bestGuess(); if (board.combinations.length > 0) { if (limited) div.textContent = "Guess (" + Math.round(TIMELIMIT / 1000) + " s search): " + print(bestGuess); else div.textContent = "Best guess: " + print(bestGuess); } }, 100); }