// *******************************************************
// * Dieses Script wurde von Jürgen Berkemeier erstellt. *
// * Version vom 4. 3. / 2. 6. / 30. 12. 2007            *
// * Alle Rechte liegen beim Autor.                      *
// * www.j-berkemeier.de                                 *
// *******************************************************
var pmin,sz,sz2,ntip,kannDOM,to,frust,maxfrust;
var NumArr,Feld,FeldLsg,FeldLsg_nochfrei;
var pVect_l,pVect_v,pVect_nef;
var schwer=false;
var bl=new Image();

function JB_random(min,max) {
  return(Math.floor(min+Math.random()*(max-min+1)));
}
Array.prototype.misch=function() {
 var i=this.length;
  if(i<2) return;
  do {
   var zi=Math.floor(Math.random()*i);
   var t=this[zi];
   this[zi]=this[--i];
   this[i]=t;
  } while (i);
}
Array.prototype.rm=function(ele) {
 var l=this.length;
  for(var i=0,j=0;i<l;i++) if(this[i]!=ele) this[j++]=this[i];
  this.length=j;
}
Array.prototype.srch=function(ele) {
 var l=this.length;
  for(var i=0;i<l;i++) if(this[i]==ele) return true;
  return false;
}
function SudokuFeld(Id,n) {
 var nz=n*n,ns=n*n,w=3;
 var t,tbl,tbdy,tz;
  t = document.getElementById(Id) ;
  if(t.childNodes.length>0) t.removeChild(t.firstChild);
  tbl = document.createElement("table");
  tbl.id = "t_"+Id;
  tbl.className="tabelle";
  tbdy = document.createElement("tbody");
  for (var z=0;z<nz;z++) {
   var trz = document.createElement("tr");
   for (var s=0;s<ns;s++) {
    var tds = document.createElement("td");
    tds.appendChild(document.createTextNode("-")) ;
    trz.appendChild(tds);
   }
   tbdy.appendChild(trz);
  }
  tz=tbdy.getElementsByTagName("tr");
  for(var z=n-1;z<nz;z+=n) {
   var zeile=tz[z].getElementsByTagName("td");
   for(var s=0;s<ns;s++) zeile[s].style.borderBottomWidth=w+"px";
  }
  for(var z=0;z<nz;z++) {
   var zeile=tz[z].getElementsByTagName("td");
   for(var s=n-1;s<ns;s+=n) zeile[s].style.borderRightWidth=w+"px";
  }
  tbl.appendChild(tbdy) ;
  t.appendChild(tbl) ;
}
function make_arr(nz,ns) {
 var Arr=new Array(nz);
  for(var z=0;z<nz;z++) Arr[z]=new Array(ns);
  return(Arr);
}
function m2e(arr,val) {
 var i,p=-1,tmp,l=arr.length-1;
 for(i=0;i<l;i++) if(arr[i][0]==val[0] && arr[i][1]==val[1]) { p=i; break; }
 if(p>=0) {
  tmp=arr[p];
  for(i=p;i<l;i++) arr[i]=arr[i+1];
  arr[l]=tmp;
 }
}
function array2table(TabId,Arr) {
 var tab=document.getElementById(TabId);
 var tbdy=tab.getElementsByTagName("tbody")[0];
 var tz=tbdy.getElementsByTagName("tr");
 var nz=tz.length;
 var ns=tz[0].getElementsByTagName("td").length;
  for(var z=0;z<nz;z++) {
   var zeile=tz[z].getElementsByTagName("td");
   for(var s=0;s<ns;s++) zeile[s].firstChild.data=Arr[z][s];
  }
}
function blank2input(TabId) {
 var tab=document.getElementById(TabId);
 var tbdy=tab.getElementsByTagName("tbody")[0];
 var tz=tbdy.getElementsByTagName("tr");
 var nz=tz.length;
 var ns=tz[0].getElementsByTagName("td").length;
  for(var z=0;z<nz;z++) {
   var zeile=tz[z].getElementsByTagName("td");
   for(var s=0;s<ns;s++) {
    if(zeile[s].firstChild.nodeValue==" ") {
     zeile[s].style.verticalAlign="bottom";
     zeile[s].style.paddingBottom=0;
     var inp = document.createElement("input");
     inp.type="text";
     inp.size=1;
     inp.maxlength=1;
     inp.style.width="1.3em";
     inp.name="X"+((z+1)*100+s);
     inp.value="";
     if (sz==4) inp.onchange=function(){check(this);};
     else        inp.onkeyup=function(){check(this);};
     zeile[s].replaceChild(inp,zeile[s].firstChild);
     var inp = document.createElement("input");
     inp.type="text";
     inp.size=5;
     inp.maxlength=5;
     inp.style.width="4em";
     inp.style.fontSize="0.6em";
     inp.style.textAlign="left";
     inp.style.border="none";
     inp.style.color="#707070";
     inp.value="";
     zeile[s].appendChild(inp,zeile[s].firstChild);
    }
   }
  }
}
function spaltentausch(Arr,s1,s2) {
 var sp=new Array(sz2);
 for(var z=0;z<sz2;z++) sp[z]=Arr[z][s1];
 for(var z=0;z<sz2;z++) Arr[z][s1]=Arr[z][s2];
 for(var z=0;z<sz2;z++) Arr[z][s2]=sp[z];
}
function zeilentausch(Arr,z1,z2) {
 var ze=new Array(sz2);
 for(var s=0;s<sz2;s++) ze[s]=Arr[z1][s];
 for(var s=0;s<sz2;s++) Arr[z1][s]=Arr[z2][s];
 for(var s=0;s<sz2;s++) Arr[z2][s]=ze[s];
}
function blockspaltentausch(Arr,sb1,sb2) {
 var sb=new Array(sz2);
 for(var z=0;z<sz2;z++) sb[z]=new Array(sz);
 for(var z=0;z<sz2;z++) for(var s=0;s<sz;s++) sb[z][s]=Arr[z][s+sb1*sz];
 for(var z=0;z<sz2;z++) for(var s=0;s<sz;s++) Arr[z][s+sb1*sz]=Arr[z][s+sb2*sz];
 for(var z=0;z<sz2;z++) for(var s=0;s<sz;s++) Arr[z][s+sb2*sz]=sb[z][s];
}
function blockzeilentausch(Arr,zb1,zb2) {
 var zb=new Array(sz);
 for(var z=0;z<sz;z++) zb[z]=new Array(sz2);
 for(var z=0;z<sz;z++) for(var s=0;s<sz2;s++) zb[z][s]=Arr[z+zb1*sz][s];
 for(var z=0;z<sz;z++) for(var s=0;s<sz2;s++) Arr[z+zb1*sz][s]=Arr[z+zb2*sz][s];
 for(var z=0;z<sz;z++) for(var s=0;s<sz2;s++) Arr[z+zb2*sz][s]=zb[z][s];
}
function transpose(Arr) {
 var tArr=make_arr(sz2,sz2);
 for(var z=0;z<sz2;z++) for(var s=0;s<sz2;s++) tArr[z][s]=Arr[s][z];
 delete(Arr);
 return tArr;
}
function numok(num) {
 return ((num>0)&&(num<=sz2))||num=="";
}
function check_fld(fld,z,s,num) {
 var i,is,ie,j,js,je;
  if(num==" ")num=20;
  for(j=0;j<s;j++) if(num==fld[z][j]) return false;
  for(j=s+1;j<sz2;j++) if(num==fld[z][j]) return false;
  for(i=0;i<z;i++) if(num==fld[i][s]) return false;
  for(i=z+1;i<sz2;i++) if(num==fld[i][s]) return false;
  is=Math.floor(z/sz)*sz;ie=is+sz;
  js=Math.floor(s/sz)*sz;je=js+sz;
  for(i=is;i<z;i++) {
   for(j=js;j<s;j++) if(num==fld[i][j]) return false;
   for(j=s+1;j<je;j++) if(num==fld[i][j]) return false;
  }
  for(i=z+1;i<ie;i++) {
   for(j=js;j<s;j++) if(num==fld[i][j]) return false;
   for(j=s+1;j<je;j++) if(num==fld[i][j]) return false;
  }
  return true;
}
function check(id) {
 var ij=parseInt(id.name.substr(1,id.name.length-1));
 var j=ij%100;
 var i=(ij-j)/100-1;
 var num=id.value.toLowerCase();
 if (num=="") Feld[i][j]=" ";
 else         Feld[i][j]=num;
 if(!numok(num)) {
  id.style.backgroundColor="red";
  alert("Falsche Eingabe!\nErlaubt sind nur Zahlen von 1 bis "+sz2+".");
  id.value="";
  Feld[i][j]=" ";
  id.style.backgroundColor="white";
 }
 else if(!check_fld(Feld,i,j,num)) {
  id.style.backgroundColor="red";
  alert("Diese Zahl ist schon\n - in einer Zeile,\n - in einer Spalte oder\n - in einem Block\nvorhanden!");
  id.value="";
  Feld[i][j]=" ";
  id.style.backgroundColor="white";
 }
 else {
  if (num=="") Feld[i][j]=" ";
  else         Feld[i][j]=num;
 }
 var rest=0;
 for(i=0;i<document.getElementById("t_feld").getElementsByTagName("input").length;i+=2)
  if(document.getElementById("t_feld").getElementsByTagName("input")[i].value=="") rest++ ;
 if (rest==0) alert("Herzlichen Glückwunsch!");
}
function set_num(Arr,z,s) {
 var i;
 NumArr.misch();
 for(i=0;i<sz2;i++) {
   if(set_a_num(Arr,z,s,NumArr[i])) return true;
 }
 return false;
}
function set_a_num(fld,z,s,num) {
 var i,is,ie,j,js,je;
  is=Math.floor(z/sz)*sz;ie=is+sz;
  js=Math.floor(s/sz)*sz;je=js+sz;
  if(!FeldLsg_nochfrei[z][s].srch(num)) return false;
  for(j=0;j<s;j++)
   if(fld[z][j]==" " && FeldLsg_nochfrei[z][j].length==1 && FeldLsg_nochfrei[z][j][0]==num) return false;
  for(j=s+1;j<sz2;j++)
   if(fld[z][j]==" " && FeldLsg_nochfrei[z][j].length==1 && FeldLsg_nochfrei[z][j][0]==num) return false;
  for(i=0;i<z;i++)
   if(fld[i][s]==" " && FeldLsg_nochfrei[i][s].length==1 && FeldLsg_nochfrei[i][s][0]==num) return false;
  for(i=z+1;i<sz2;i++)
   if(fld[i][s]==" " && FeldLsg_nochfrei[i][s].length==1 && FeldLsg_nochfrei[i][s][0]==num) return false;
  for(i=is;i<z;i++) {
   for(j=js;j<s;j++)
    if(fld[i][j]==" " && FeldLsg_nochfrei[i][j].length==1 && FeldLsg_nochfrei[i][j][0]==num) return false;
   for(j=s+1;j<je;j++)
    if(fld[i][j]==" " && FeldLsg_nochfrei[i][j].length==1 && FeldLsg_nochfrei[i][j][0]==num) return false;
  }
  for(i=z+1;i<ie;i++) {
   for(j=js;j<s;j++)
     if(fld[i][j]==" " && FeldLsg_nochfrei[i][j].length==1 && FeldLsg_nochfrei[i][j][0]==num) return false;
  for(j=s+1;j<je;j++)
    if(fld[i][j]==" " && FeldLsg_nochfrei[i][j].length==1 && FeldLsg_nochfrei[i][j][0]==num) return false;
  }
  fld[z][s]=num;
  FeldLsg_nochfrei[z][s].rm(num);
  if(FeldLsg_nochfrei[z][s].length==1) pVect_nef.push(new Array(z,s));
  for(j=0;j<s;j++) {
   FeldLsg_nochfrei[z][j].rm(num);
   if(FeldLsg_nochfrei[z][j].length==1) pVect_nef.push(new Array(z,j));
  }
  for(j=s+1;j<sz2;j++) {
   FeldLsg_nochfrei[z][j].rm(num);
   if(FeldLsg_nochfrei[z][j].length==1) pVect_nef.push(new Array(z,j));
  }
  for(i=0;i<z;i++) {
   FeldLsg_nochfrei[i][s].rm(num);
   if(FeldLsg_nochfrei[i][s].length==1) pVect_nef.push(new Array(i,s));
  }
  for(i=z+1;i<sz2;i++) {
   FeldLsg_nochfrei[i][s].rm(num);
   if(FeldLsg_nochfrei[i][s].length==1) pVect_nef.push(new Array(i,s));
  }
  for(i=is;i<z;i++) {
   for(j=js;j<s;j++) {
    FeldLsg_nochfrei[i][j].rm(num);
    if(FeldLsg_nochfrei[i][j].length==1) pVect_nef.push(new Array(i,j));
   }
   for(j=s+1;j<je;j++) {
    FeldLsg_nochfrei[i][j].rm(num);
    if(FeldLsg_nochfrei[i][j].length==1) pVect_nef.push(new Array(i,j));
   }
  }
  for(i=z+1;i<ie;i++) {
   for(j=js;j<s;j++) {
    FeldLsg_nochfrei[i][j].rm(num);
    if(FeldLsg_nochfrei[i][j].length==1) pVect_nef.push(new Array(i,j));
   }
   for(j=s+1;j<je;j++) {
    FeldLsg_nochfrei[i][j].rm(num);
    if(FeldLsg_nochfrei[i][j].length==1) pVect_nef.push(new Array(i,j));
   }
  }
  return true;
}
function del_a_num(fld,z,s) {
 var num=fld[z][s];
 fld[z][s]=" ";
 FeldLsg_nochfrei[z][s].push(num);
 var i,is,ie,j,js,je;
  for(j=0;j<s;j++) if(check_fld(fld,z,j,num)) FeldLsg_nochfrei[z][j].push(num);
  for(j=s+1;j<sz2;j++) if(check_fld(fld,z,j,num)) FeldLsg_nochfrei[z][j].push(num);
  for(i=0;i<z;i++) if(check_fld(fld,i,s,num)) FeldLsg_nochfrei[i][s].push(num);
  for(i=z+1;i<sz2;i++) if(check_fld(fld,i,s,num)) FeldLsg_nochfrei[i][s].push(num);
  is=Math.floor(z/sz)*sz;ie=is+sz;
  js=Math.floor(s/sz)*sz;je=js+sz;
  for(i=is;i<z;i++) {
   for(j=js;j<s;j++) if(check_fld(fld,i,j,num)) FeldLsg_nochfrei[i][j].push(num);
   for(j=s+1;j<je;j++) if(check_fld(fld,i,j,num)) FeldLsg_nochfrei[i][j].push(num);
  }
  for(i=z+1;i<ie;i++) {
   for(j=js;j<s;j++) if(check_fld(fld,i,j,num)) FeldLsg_nochfrei[i][j].push(num);
   for(j=s+1;j<je;j++) if(check_fld(fld,i,j,num)) FeldLsg_nochfrei[i][j].push(num);
  }
  return;
}
function num_in_s(z,s,num) {
 var retval=new Array();
 for(var j=0;j<sz2;j++) if(FeldLsg_nochfrei[z][j].srch(num)) retval.push({z:z, s:j});
 return retval;
}
function num_in_z(z,s,num) {
 var retval=new Array();
 for(var i=0;i<sz2;i++) if(FeldLsg_nochfrei[i][s].srch(num)) retval.push({z:i, s:s});
 return retval;
}
function num_in_b(z,s,num) {
 var retval=new Array();
 var is=Math.floor(z/sz)*sz,ie=is+sz;
 var js=Math.floor(s/sz)*sz,je=js+sz;
 for(var i=is;i<ie;i++) for(var j=js;j<je;j++) if(FeldLsg_nochfrei[i][j].srch(num)) retval.push({z:i, s:j});
 return retval;
}
var pVect,pVP,vorg,ct;
function startzahlen_loop() {
  if(schwer&&ct>sz2*sz2/5) {
   for(var ct2=0;ct2<sz2*sz2-ct;ct2++) {
    var z=pVect[ct2][1];
    var s=pVect[ct2][2];
    var is=Math.floor(z/sz)*sz,ie=is+sz;
    var js=Math.floor(s/sz)*sz,je=js+sz;
    if(FeldLsg_nochfrei[z][s].length>1) {
     for(var n=0;n<FeldLsg_nochfrei[z][s].length;n++) {
      var num=FeldLsg_nochfrei[z][s][n];
      var niz=num_in_z(z,s,num),nis=num_in_s(z,s,num),nib=num_in_b(z,s,num);
      var nizl=niz.length,nisl=nis.length;
      if(!(nizl>1||nisl>1||nib.length>1)) { // Zahl nur hier möglich
       FeldLsg_nochfrei[z][s].length=1;
       FeldLsg_nochfrei[z][s][0]=num;
       pVect[ct2][0]=1;
       break;
      }
      else { // Zahl nur an anderer Stelle und nicht hier möglich
       var nass=false,nasz=false; // nur andere Stelle
       var sp=new Array(0,0,0),ze=new Array(0,0,0);
       if(nisl>2) {
        for(var nn=0;nn<nisl;nn++) {
         var ss=nis[nn].s;
         if(ss<sz) sp[0]++;
         else if(ss<2*sz) sp[1]++;
         else sp[2]++;
         if(s<sz) sp[0]=0;
         else if(s<2*sz) sp[1]=0;
         else sp[2]=0;
        } //for(nn)
       } //if(nisl)
       if(nizl>2) {
        for(var nn=0;nn<nizl;nn++) {
         var zz=niz[nn].z;
         if(zz<sz) ze[0]++;
         else if(zz<2*sz) ze[1]++;
         else ze[2]++;
         if(z<sz) ze[0]=0;
         else if(z<2*sz) ze[1]=0;
         else ze[2]=0;
        } //for(nn)
       } //if(nizl)
       for(var nn=0;nn<sz;nn++) {
        if(sp[nn]>1) {
         var bl=num_in_b(z,nn*sz,num);
         var bll=bl.length;
         if(bll<4) {
          nass=true;
          for(var nnn=0;nnn<bll;nnn++) {
           if(bl[nnn].z!=z) { nass=false; break; }
          }
         }
        }
        if(ze[nn]>1) {
         var bl=num_in_b(nn*sz,s,num);
         var bll=bl.length;
         if(bll<4) {
          nasz=true;
          for(var nnn=0;nnn<bll;nnn++) {
           if(bl[nnn].s!=s) { nasz=false; break; }
          }
         }
        }
       } // for(nn)
       if(nass||nasz) {
        FeldLsg_nochfrei[z][s].rm(num);
        pVect[ct2][0]=FeldLsg_nochfrei[z][s].length
       }
      }
     } // for(n)
    }
   }
  }
  pVect.sort(function(a,b){return a[0]-b[0]});
  if(pVect[0][0]==1) pVP=0;
  else pVP=sz2*sz2-ct-1;
  var z=pVect[pVP][1];
  var s=pVect[pVP][2];
  var is=Math.floor(z/sz)*sz,ie=is+sz;
  var js=Math.floor(s/sz)*sz,je=js+sz;
  var num=FeldLsg[z][s];
  if(pVect[pVP][0]==1) {
   pVect[pVP][0]=1000;
  }
  else {
   pVect[pVP][0]=2000;
   Feld[z][s]=num;
//   array2table("t_feld",Feld);
   document.getElementById("t_feld").getElementsByTagName("tbody")[0].
    getElementsByTagName("tr")[z].getElementsByTagName("td")[s].firstChild.data=num;
   vorg++;
  }
  FeldLsg_nochfrei[z][s].length=0;
  for(var j=0;j<s;j++) FeldLsg_nochfrei[z][j].rm(num);
  for(var j=s+1;j<sz2;j++) FeldLsg_nochfrei[z][j].rm(num);
  for(var i=0;i<z;i++) FeldLsg_nochfrei[i][s].rm(num);
  for(var i=z+1;i<sz2;i++) FeldLsg_nochfrei[i][s].rm(num);
  for(var i=is;i<z;i++) {
   for(var j=js;j<s;j++) FeldLsg_nochfrei[i][j].rm(num);
   for(var j=s+1;j<je;j++) FeldLsg_nochfrei[i][j].rm(num);
  }
  for(var i=z+1;i<ie;i++) {
   for(var j=js;j<s;j++) FeldLsg_nochfrei[i][j].rm(num);
   for(var j=s+1;j<je;j++) FeldLsg_nochfrei[i][j].rm(num);
  }
  for(var j=0;j<sz2*sz2;j++) { // pVect[j][0] setzen, =Anzahl der möglichen Zahlen
   var l=FeldLsg_nochfrei[pVect[j][1]][pVect[j][2]].length;
   if(pVect[j][0]<1000) pVect[j][0]=l;
  }
 ct++;
 document.getElementById("info2").firstChild.data=sz2*sz2-ct;
 if(ct<sz2*sz2) to=window.setTimeout("startzahlen_loop()",1);
 else {
  document.getElementById("hinweis2").style.display="none";
  document.body.style.cursor="auto";
// alert(vorg+" Felder vorgegeben, schwer="+schwer); // <--------------------------
  show_all();
 }
}
function startzahlen() {
 document.body.style.cursor="wait";
 document.getElementById("hinweis2").style.display="block";
 pVect=new Array(sz2*sz2) ;
 vorg=0;
 for(var z=0,i=0;z<sz2;z++) for(var s=0;s<sz2;s++) {
  Feld[z][s]=" ";
  pVect[i++]=new Array(sz2,z,s);
  FeldLsg_nochfrei[z][s]=new Array(sz2);
  for(var j=0;j<sz2;j++) FeldLsg_nochfrei[z][s][j]=j+1;
 }
 pVect.misch();
 schwer=schwer&&sz<4;
 ct=0;
 startzahlen_loop();
}
function startzahlen_rnd() {
 var z,s,p=0,np=ntip,sz22=sz2+1;
 for(z=0;z<sz2;z++) for(s=0;s<sz2;s++) Feld[z][s]=" ";
 np=Math.floor(ntip/2);
 if(sz2==9) {
  sz22=Math.floor(sz2/2);
  if(np*2!=ntip) { Feld[sz22][sz22]=FeldLsg[sz22][sz22]; p++; }
 }
 while(p<ntip) {
  z=JB_random(0,sz2-1);
  s=JB_random(0,sz2-1);
  if (Feld[z][s]==" ") if(s!=sz22 || z!=sz22) {
   Feld[z][s]=FeldLsg[z][s] ; p++ ;
   Feld[sz2-1-z][sz2-1-s]=FeldLsg[sz2-1-z][sz2-1-s]; p++;
  }
 }
 show_all();
}
function show_all() {
 array2table("t_feld",Feld);
 blank2input("t_feld");
 SudokuFeld("feldlsg",sz);
 array2table("t_feldlsg",FeldLsg);
}
function do_it_good_loop() {
 var ts=new Date().getTime(),dt,p;
 do {
  p=pVect_l.length-1;
  if(p<pmin) {
   pmin=p;frust=0;
   document.getElementById("info").firstChild.data=pmin;
  }
  else {
   frust++;
   if(frust>maxfrust) { pVect_v.misch(); frust=0; }
  }
  for(var i=0;i<pVect_nef.length;i++) m2e(pVect_v,pVect_nef.pop())
  if(set_num(FeldLsg,pVect_l[p][0],pVect_l[p][1])) {
   pVect_v.push(pVect_l.pop());
  }
  else {
   pVect_l.push(pVect_v.pop());
   del_a_num(FeldLsg,pVect_l[p+1][0],pVect_l[p+1][1]);
   pVect_l.misch();
  }
  dt=new Date().getTime()-ts;
 } while(dt<500&&pVect_l.length>0)
 if(pVect_l.length>0) {
  to=window.setTimeout("do_it_good_loop()",1);
 }
 else {
  document.getElementById("hinweis").style.display="none";
  document.body.style.cursor="auto";
  delete pVect_l;
  delete pVect_v;
  delete pVect_nef;
  if(document.getElementsByName("modus")[0].checked) startzahlen_rnd(); else startzahlen();
 }
}
function do_it_good() {
 if (!kannDOM) return;
 window.clearTimeout(to);
 SudokuFeld("feld",sz);
 document.body.style.cursor="wait";
 document.getElementById("hinweis").style.display="block";
 pVect_l = new Array();
 pVect_v = new Array();
 pVect_nef = new Array();
 pmin=sz2*sz2;
 for(var z=0;z<sz2;z++) for(var s=0;s<sz2;s++) {
  FeldLsg[z][s]=" ";
  FeldLsg_nochfrei[z][s]=new Array(sz2);
  for(var i=0;i<sz2;i++) FeldLsg_nochfrei[z][s][i]=i+1;
  pVect_l.push(new Array(z,s));
 }
 pVect_l.misch();
 do_it_good_loop();
}
function do_it_fast() {
 if (!kannDOM) return;
 window.clearTimeout(to);
 var i,j,z,s;
 SudokuFeld("feld",sz);
 NumArr.misch();
 for(z=0,i=0;z<sz2;z+=sz,i++)
  for(s=0;s<sz2;s++)
   for(j=0;j<sz;j++)
    FeldLsg[z+j][s]=NumArr[(i+s+j*sz)%sz2];
 for(i=0;i<100;i++){
  for(z=0;z<sz;z++) {
   zeilentausch (FeldLsg,JB_random(z*sz,(z+1)*sz-1),JB_random(z*sz,(z+1)*sz-1));
   spaltentausch(FeldLsg,JB_random(z*sz,(z+1)*sz-1),JB_random(z*sz,(z+1)*sz-1));
  }
  blockzeilentausch (FeldLsg,JB_random(0,sz-1),JB_random(0,sz-1));
  blockspaltentausch(FeldLsg,JB_random(0,sz-1),JB_random(0,sz-1));
  if(Math.random()<0.5) FeldLsg=transpose(FeldLsg);
 }
 if(document.getElementsByName("modus")[0].checked) startzahlen_rnd(); else startzahlen();
}
function stop_it() {
 window.clearTimeout(to);
 document.getElementById("hinweis").style.display="none";
 document.getElementById("hinweis2").style.display="none";
 document.body.style.cursor="auto";
}
function select_size(size) {
 switch(size) {
  case "4":
   sz=2;
   maxfrust=10;
   document.getElementById("schwer").style.display="";
   break;
  case "9":
  default:
   sz=3;
   maxfrust=10;
   document.getElementById("schwer").style.display="";
   break;
  case "16":
   sz=4;
   maxfrust=100;
   document.getElementById("schwer").style.display="none";
   break;
 }
 sz2=sz*sz;
 delete Feld; Feld=make_arr(sz2,sz2);
 delete FeldLsg; FeldLsg=make_arr(sz2,sz2);
 delete FeldLsg_nochfrei; FeldLsg_nochfrei=make_arr(sz2,sz2);
 delete NumArr; NumArr=new Array(sz2);for(var i=0;i<sz2;i++)NumArr[i]=i+1;
 ntip=Math.floor(sz2*sz2/2);
 document.getElementById("ntip").value=ntip;
 document.getElementById("maxnum").firstChild.data=sz2;
 document.getElementById("blk").firstChild.data=sz+" mal "+sz;
}
function set_ntip(n) {
 ntip = Math.min(sz2*sz2,Math.max(0,n));
 if(ntip!=n) document.getElementById("ntip").value=ntip;
}
function get_top(obj) {
 var curtop = 0;
 if (obj.offsetParent) {
  while (obj.offsetParent) {
   curtop += obj.offsetTop
   obj = obj.offsetParent;
  }
 }
 else if (obj.y)
  curtop += obj.y;
 return curtop;
}
function start() {
// var par=sz+";"+document.getElementsByName("modus")[1].checked+";";
// if(schwer) par+="schwer;";
// bl.src="http://www.j-berkemeier.de/bl.gif?"+par+Math.random().toString().substr(3,3);
 window.scrollTo(0,get_top(document.getElementById("start"))-10);
 if(sz==4) do_it_fast();
 else      do_it_good();
}
function init() {
 kannDOM=document.getElementsByTagName;
 if (kannDOM) kannDOM=document.getElementsByTagName('body')[0].appendChild;
 if (!kannDOM) alert("Leider unterstützt ihr Browser nicht die notwendigen Methoden.");
 else {
  document.getElementById("size").options.selectedIndex=1;
  document.getElementById("schwer").options.selectedIndex=0;
  select_size("9");
  do_it_good();
 }
}