By sunyin
—
Last update
Feb 21, 2006
—
Installed
730 times.
// ==UserScript==
// @namespace http://127.0.0.1/
// @name WebSudoku Helper+PopupNumber
// @description Provides some strategic add-ons/cheats to Web Sudoku
// @include http://*.websudoku.com/*
// @version 1.0
// @GM_version 0.6.4
// @FF_version 1.5
// ==/UserScript==
function addGlobalStyle(css) { //found at http://diveintogreasemonkey.org/patterns/add-css.html
var head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
}
var styles = 'a.selector:hover {background:blue !important;color:#fff;text-decoration:none;} ';
styles += 'a.selector {font-size:12pt;font-family:courier,monospaced;padding-top:1px;padding-bottom:1px;padding-left:4px;padding-right:5px}';
styles += 'table.selectorTable {width:4em;height:4em;text-align:center}';
addGlobalStyle(styles);
//GM_setValue('id','');
//GM_setValue('innerHTML','');
//GM_setValue('value','');
g_id = '';
g_innerHTML = '';
g_value = '';
function get_at(x,y) {
return document.getElementById("f" + x.toString() + y.toString());
}
function dump_poss(p) {
var x,y;
for(y=0;y<9;y++)
for(x=0;x<9;x++)
get_at(x,y).parentNode.style.background=p[y*9+x]?'#FFFFFF':'#FFCC33';
}
function obvious() {
var state=new Array();
var i,j,x,y,x2,y2,x0,y0;
var num,done=0;
for(y=0;y<9;y++) {
for(x=0;x<9;x++) {
var sq=get_at(x,y);
if(sq.value!='')
state[y*9+x]=sq.value;
else
state[y*9+x]=0;
}
}
while(!done) {
done=1;
var poss=new Array();
for(i=0;i<81*9;i++) poss[i]=1;
for(y=0;y<9;y++) {
for(x=0;x<9;x++) {
num=state[y*9+x];
if(num) {
num--;
// rows
for(x2=0;x2<9;x2++)
poss[y*81+x2*9+num]=0;
// cols
for(y2=0;y2<9;y2++)
poss[y2*81+x*9+num]=0;
// square
x0=Math.floor(x/3)*3;
y0=Math.floor(y/3)*3;
for(y2=y0;y2<y0+3;y2++)
for(x2=x0;x2<x0+3;x2++)
poss[y2*81+x2*9+num]=0;
// self
for(i=0;i<9;i++)
poss[y*81+x*9+i]=0;
}
}
}
// only one poss?
for(y=0;y<9;y++) {
for(x=0;x<9;x++) {
if(!state[y*9+x]) {
j=0;
for(i=0;i<9;i++)
if(poss[y*81+x*9+i])
num=i+1,j++;
if(j==1) {
state[y*9+x]=num;
get_at(x,y).value=num;
done=0;
}
}
}
}
// alert(done);
// elimination (most powerful)
for(j=1;j<10;j++) {
// alert("j="+j);
for(y=0;y<9;y++)
for(x=0;x<9;x++)
poss[y*9+x]=(0==state[y*9+x]);
for(y=0;y<9;y++) {
for(x=0;x<9;x++) {
// learn nothing from blanks
if(!(num=state[9*y+x]))
continue;
if(num!=j) continue;
// rows
for(x2=0;x2<9;x2++)
poss[9*y+x2]=0;
// cols
for(y2=0;y2<9;y2++)
poss[9*y2+x]=0;
// squares
x0=Math.floor(x/3)*3;
y0=Math.floor(y/3)*3;
for(y2=y0;y2<y0+3;y2++)
for(x2=x0;x2<x0+3;x2++)
poss[y2*9+x2]=0;
// dump_poss(poss);
// alert(j+":("+x+","+y+")");
}
}
// dump_poss(poss);
for(y0=0;y0<9;y0+=3) {
for(x0=0;x0<9;x0+=3) {
i=0;
for(y2=y0;y2<y0+3;y2++) {
for(x2=x0;x2<x0+3;x2++) {
if(poss[y2*9+x2]) {
x=x2;
y=y2;
i++;
}
}
}
if(1==i) {
// alert("("+x+","+y+")="+j);
state[y*9+x]=j;
get_at(x,y).value=j;
done=0;
}
}
}
}
}
}
function showNumbers(num) {
var x,y,k;
var numn = new Array(10);
for(k=1;k<10;k++) numn[k]=0;
for(x=0;x<9;x++) {
for(y=0;y<9;y++) {
var sq=get_at(x,y);
var ok=1;
if(sq.readOnly) ok=0;
if(sq.value!='') {
ok=0;
if(0<sq.value && sq.value<10)
numn[sq.value]++;
}
// check rows
for(k=0;k<9;k++) {
if(num==get_at(k,y).value)
ok=0;
}
// check cols
for(k=0;k<9;k++) {
if(num==get_at(x,k).value)
ok=0;
}
// check square
var kx,ky,sx,sy;
sx=Math.floor(x/3)*3;
sy=Math.floor(y/3)*3;
for(kx=sx;kx<sx+3;kx++) {
for(ky=sy;ky<sy+3;ky++) {
if(num==get_at(kx,ky).value)
ok=0;
}
}
// update
if(!ok) {
sq.parentNode.style.background = '#FFCC33';
} else {
sq.parentNode.style.background = '#FFFFFF';
}
}
}
var colors=new Array(
'#FFFFFF','#FFCC33', // normal
'#CCFFCC','#33FF33', // all digits placed
'#FF3333','#FF0000'); // too many digits
for(k=1;k<10;k++)
document.getElementById('gm_sel'+k).style.background=
colors[((numn[k]>=9)?2:0)+((numn[k]>9)?2:0)+(num==k)];
}
// popupnumbers ------------
function showNumOptions(id){
var square = document.getElementById(id);
var readOnly = square.readOnly;
if(!readOnly){
g_id=id;
g_innerHTML = square.parentNode.innerHTML;
(square.value != '') ? g_value=square.value : g_value='';
var selector = '<table id="'+g_id+'" class="selectorTable">';
selector += '<tr><td><a class="selector" href="javascript:;">1</a></td>';
selector += '<td><a class="selector" href="javascript:;">2</a></td>';
selector += '<td><a class="selector" href="javascript:;">3</a></td></tr>';
selector += '<tr><td><a class="selector" href="javascript:;">4</a></td>';
selector += '<td><a class="selector" href="javascript:;">5</a></td>';
selector += '<td><a class="selector" href="javascript:;">6</a></td></tr>';
selector += '<tr><td><a class="selector" href="javascript:;">7</a></td>';
selector += '<td><a class="selector" href="javascript:;">8</a></td>';
selector += '<td><a class="selector" href="javascript:;">9</a></td></tr>';
selector += '<tr><td colspan="3"><a class="selector" href="javascript:;">Clear</a></td></tr>';
selector += '</table>';
square.parentNode.innerHTML = selector;
var squareSelector = document.getElementById(id);
var squareSelectorLinks = squareSelector.getElementsByTagName('a');
for(i=0;i<9;i++){
squareSelectorLinks[i].addEventListener('click',hideNumOptions,false);
if(squareSelectorLinks[i].innerHTML == g_value){
squareSelectorLinks[i].setAttribute('style','color:white;background:red;');
}
}
}
}
function hideNumOptions(e){
var id = g_id;
if(id){
var selector,tempValue,square;
selector = document.getElementById(id);
e.target.className=='selector' ? tempValue = e.target.innerHTML : tempValue = g_value;
selector.parentNode.innerHTML = g_innerHTML;
square = document.getElementById(id);
tempValue=='Clear' ? square.value='' : square.value=tempValue;
g_id = '';
g_innerHTML='';
g_value= '';
}
}
//----------------------
//sudoku 9 x 9 Matrix is organized as TD id c00-c01, INPUT id f00-f01
function clicky(e){
id = e.target.id
if (id && id.substr(0,1) == 'f' && g_id != id){
hideNumOptions(e);
showNumOptions(id);
} else {
hideNumOptions(e);
}
}
function fillall() {
var str=document.getElementsByName('cheat').item(0).value;
var i=0,x,y;
for(y=0;y<9;y++) {
for(x=0;x<9;x++) {
get_at(x,y).value = str.substr(i,1);
i++;
}
}
}
function sel_num(e) {
if(e.target.id && 'gm_sel'== e.target.id.substr(0,6))
showNumbers(e.target.id.substr(6,1));
}
// add cheat controls after 9x9 matrix
function addtools() {
var p=document.getElementById('c00');
if(p) {
p=p.parentNode.parentNode.parentNode.parentNode;
var toolhtml = "<table border=1><tr>";
var i;
for(i=1;i<10;i++)
toolhtml += "<td class=c0 id=gm_sel"+i+">"+i+"</td>";
toolhtml += "</tr><tr>" +
"<td colspan=4 class=c0 id=gm_cheat>CHEAT</td>" +
"<td colspan=5 class=c0 id=gm_obvious>OBVIOUS</td>" +
"</tr></table>";
p.innerHTML += toolhtml;
document.getElementById('gm_cheat').addEventListener('click',fillall,true);
document.getElementById('gm_obvious').addEventListener('click',obvious,true);
for(i=1;i<10;i++)
document.getElementById('gm_sel'+i).addEventListener('click',sel_num,true);
}
}
addtools();
// trap click
document.addEventListener('click',clicky,false);