topoffset=100;
leftoffset=100;
tileheight=41;
tilewidth=33;
layeroffset=-3;
copytopoffset=431;
copyleftoffset=561;

var move;
n=144;

function preload()
{
count=0;
image=new Array ('bg.jpg','bamb1.gif','bamb2.gif','bamb3.gif','bamb4.gif','bamb5.gif','bamb6.gif','bamb7.gif','bamb8.gif','bamb9.gif','circ1.gif','circ2.gif','circ3.gif','circ4.gif','circ5.gif','circ6.gif','circ7.gif','circ8.gif','circ9.gif','numb1.gif','numb2.gif','numb3.gif','numb4.gif','numb5.gif','numb6.gif','numb7.gif','numb8.gif','numb9.gif','wind1.gif','wind2.gif','wind3.gif','wind4.gif','drag1.gif','drag2.gif','drag3.gif','flow1.gif','flow2.gif','flow3.gif','flow4.gif','seas1.gif','seas2.gif','seas3.gif','seas4.gif','mark.gif','new.gif','restart.gif','undo.gif','moves.gif','hint.gif','help.gif','info.gif','email.gif');
picture=new Array(image.length);
for (i=0;i<image.length;i++)
{
picture[i]=new Image();
picture[i].onload=loadcheck;
picture[i].src=image[i];
}
}

function loadcheck()
{
count++;
if (count==1) 
{
display="<font style=\"font-family:Arial,sans-serif;font-size:14pt;white-space:nowrap;position:absolute;top:"+(topoffset/3)+";left:"+(leftoffset+tilewidth)+"\">Cargando Mahjongg...<\/font>";
document.getElementById("screen").innerHTML=display;
}
else if (count==image.length) setup();
}

function select(i,face)
{
i=i-120;
suggest=0;
test(i);
if (cond)
{
if (move==1)select2(i,face);
else select1(i,face);
}
else noselect();
}

function noselect()
{
message="La ficha no está libre!";
mark[k]="";
move=0;
show();
wait();
}

function nomatch()
{
message="Las fichas son diferentes!";
mark[k]="";
move=0;
show();
wait();
}

function equal()
{
message="Ninguna ficha seleccionada.";
mark[k]="";
move=0;
show();
wait();
}

function select1(i,face)
{
i1sto=i;
facesto=face;
message="Ficha seleccionada...";
k=i;
mark[k]="<a href=\"javascript:equal()\"><img src=\"mark.gif\" style=\"position:absolute;top:"+(offsetfact[k]*layeroffset+topoffset+tilefacty[k]*tileheight)+";left:"+(offsetfact[k]*layeroffset+leftoffset+tilefactx[k]*tilewidth)+"\" border=\"0\" alt=\"\"><\/a>";
move=1;
showhelp=0;
showinfo=0;
show();
}

function select2(i,face)
{
if (facesto!=face)nomatch();
else
{
i2sto=i;
ihistory[ihistory.length]=i1sto;
ihistory[ihistory.length]=i2sto;
tilehistory[tilehistory.length]=tile[i1sto];
tilehistory[tilehistory.length]=tile[i2sto];
tile[i1sto]=notile[i1sto];
tile[i2sto]=notile[i2sto];
message="Las fichas seleccionadas coinciden!";
mark[k]="";
move=0;
back++;
show();
counter-=2;
wait();
}
}

function shuffle()
{
randomnumber=new Array(n);
for (i=0;i<n;i++)
{
random=parseInt(Math.random()*(i+1));
randomnumber[i]=randomnumber[random];
randomnumber[random]=i;
}
}

function setup()
{
counter=n;
message="Juego preparado: "+n+" fichas colocadas.";
move=0;
showhelp=0;
showinfo=0;
k=0;
suggest=0;
back=0;
tile=new Array(n);
notile=new Array(n);
mark=new Array(n);
value=new Array(n);
ihistory=new Array();
tilehistory=new Array();
fig=new Array(n);
tilevalue=new Array(10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,25,25,25,25,26,26,26,26,27,27,27,27,28,28,28,28,29,29,29,29,30,30,30,30,31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,44,44,44,44,45,45,45,45);
tileface=new Array('circ1','circ1','circ1','circ1','circ2','circ2','circ2','circ2','circ3','circ3','circ3','circ3','circ4','circ4','circ4','circ4','circ5','circ5','circ5','circ5','circ6','circ6','circ6','circ6','circ7','circ7','circ7','circ7','circ8','circ8','circ8','circ8','circ9','circ9','circ9','circ9','bamb1','bamb1','bamb1','bamb1','bamb2','bamb2','bamb2','bamb2','bamb3','bamb3','bamb3','bamb3','bamb4','bamb4','bamb4','bamb4','bamb5','bamb5','bamb5','bamb5','bamb6','bamb6','bamb6','bamb6','bamb7','bamb7','bamb7','bamb7','bamb8','bamb8','bamb8','bamb8','bamb9','bamb9','bamb9','bamb9','numb1','numb1','numb1','numb1','numb2','numb2','numb2','numb2','numb3','numb3','numb3','numb3','numb4','numb4','numb4','numb4','numb5','numb5','numb5','numb5','numb6','numb6','numb6','numb6','numb7','numb7','numb7','numb7','numb8','numb8','numb8','numb8','numb9','numb9','numb9','numb9','wind1','wind1','wind1','wind1','wind2','wind2','wind2','wind2','wind3','wind3','wind3','wind3','wind4','wind4','wind4','wind4','drag1','drag1','drag1','drag1','drag2','drag2','drag2','drag2','drag3','drag3','drag3','drag3','seas1','seas2','seas3','seas4','flow1','flow2','flow3','flow4');
shuffle();
for (i=0;i<n;i++)
{
tile[i]="<a href=\"javascript:select("+(randomnumber[i]+120)+","+tilevalue[i]+")\"><img src=\""+tileface[i];
notile[i]="";
mark[i]="";
value[i]=(randomnumber[i]+120)*1000+tilevalue[i];
}
tile.sort();
value.sort();
tilepos=".gif\" style=\"position:absolute;top:";
offsetfact=new Array(4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
tilefacty=new Array(3.5,3,3,4,4,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3.5,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3.5,3.5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7);
tilefactx=new Array(6.5,6,7,6,7,5,6,7,8,5,6,7,8,5,6,7,8,5,6,7,8,4,5,6,7,8,9,4,5,6,7,8,9,4,5,6,7,8,9,4,5,6,7,8,9,4,5,6,7,8,9,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,10,11,12,3,4,5,6,7,8,9,10,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12,13,14,2,3,4,5,6,7,8,9,10,11,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,11,12);
for (i=0;i<n;i++)
tile[i]=tile[i]+tilepos+(offsetfact[i]*layeroffset+topoffset+tilefacty[i]*tileheight)+";left:"+(offsetfact[i]*layeroffset+leftoffset+tilefactx[i]*tilewidth)+"\" border=\"0\" alt=\"\"><\/a>";
background="<img src=\"bg.jpg\" style=\"position:absolute;top:"+(topoffset-10)+";left:"+(leftoffset-10)+"\" alt=\"\">";
copyright="<font style=\"font-family:Arial,sans-serif;font-size:7pt;white-space:nowrap;position:absolute;top:"+copytopoffset+";left:"+copyleftoffset+"\">&copy; 2003 twb<\/font>";
menu="<br><br><a href=\"javascript:setup()\"><img src=\"new.gif\" border=\"0\" alt=\"\" title=\"Nuevo juego\"><\/a><a href=\"javascript:restart()\"><img src=\"restart.gif\" border=\"0\" alt=\"\" title=\"Reiniciar juego\"><\/a><a href=\"javascript:undo()\"><img src=\"undo.gif\" border=\"0\" alt=\"\" title=\"Deshacer movimiento\"><\/a><a href=\"javascript:moves()\"><img src=\"moves.gif\" border=\"0\" alt=\"\" title=\"Mostrar número de movimientos posibles\"><\/a><a href=\"javascript:hint()\"><img src=\"hint.gif\" border=\"0\" alt=\"\" title=\"Mostrar movimiento\"><\/a><a href=\"javascript:help()\"><img src=\"help.gif\" border=\"0\" alt=\"\" title=\"Reglas del juego\"><\/a><a href=\"javascript:info()\"><img src=\"info.gif\" border=\"0\" alt=\"\" title=\"Información del juego\"><\/a><a href=\"mailto:thomas.weibel@bluewin.ch\"><img src=\"email.gif\" border=\"0\" alt=\"\" title=\"Email al autor\"><\/a>";
show();
wait();
}

function show()
{
for (i=0;i<n;i++)fig[i]=tile[i]+mark[i];
display="<font style=\"font-family:Arial,sans-serif;font-size:24pt;white-space:nowrap;position:absolute;top:"+(topoffset/3)+";left:"+(leftoffset+tilewidth)+"\">Mahjongg<\/font>"+background+copyright+fig[57]+fig[58]+fig[59]+fig[60]+fig[61]+fig[62]+fig[63]+fig[64]+fig[65]+fig[66]+fig[67]+fig[68]+fig[69]+fig[70]+fig[71]+fig[72]+fig[73]+fig[74]+fig[75]+fig[76]+fig[77]+fig[78]+fig[79]+fig[80]+fig[81]+fig[82]+fig[83]+fig[84]+fig[85]+fig[86]+fig[87]+fig[88]+fig[89]+fig[90]+fig[91]+fig[92]+fig[93]+fig[94]+fig[95]+fig[96]+fig[97]+fig[98]+fig[99]+fig[100]+fig[101]+fig[102]+fig[103]+fig[104]+fig[105]+fig[106]+fig[107]+fig[108]+fig[109]+fig[110]+fig[111]+fig[112]+fig[113]+fig[114]+fig[115]+fig[116]+fig[117]+fig[118]+fig[119]+fig[120]+fig[121]+fig[122]+fig[123]+fig[124]+fig[125]+fig[126]+fig[127]+fig[128]+fig[129]+fig[130]+fig[131]+fig[132]+fig[133]+fig[134]+fig[135]+fig[136]+fig[137]+fig[138]+fig[139]+fig[140]+fig[141]+fig[142]+fig[143]+fig[21]+fig[22]+fig[23]+fig[24]+fig[25]+fig[26]+fig[27]+fig[28]+fig[29]+fig[30]+fig[31]+fig[32]+fig[33]+fig[34]+fig[35]+fig[36]+fig[37]+fig[38]+fig[39]+fig[40]+fig[41]+fig[42]+fig[43]+fig[44]+fig[45]+fig[46]+fig[47]+fig[48]+fig[49]+fig[50]+fig[51]+fig[52]+fig[53]+fig[54]+fig[55]+fig[56]+fig[5]+fig[6]+fig[7]+fig[8]+fig[9]+fig[10]+fig[11]+fig[12]+fig[13]+fig[14]+fig[15]+fig[16]+fig[17]+fig[18]+fig[19]+fig[20]+fig[1]+fig[2]+fig[3]+fig[4]+fig[0]+"<table width=\""+(tilewidth*12)+"\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" style=\"position:absolute;top:"+(topoffset+tileheight*9)+";left:"+(leftoffset+tilewidth)+"\"><tr><td style=\"font-family:Arial,sans-serif;font-size:14pt\">"+message+"<\/td><\/tr><tr><td>"+menu+"<\/td><\/tr><\/table>";
document.getElementById("screen").innerHTML=display;
}

function wait()
{
showhelp=0;
showinfo=0;
if (counter!=0) message="Puntuación: "+(n-counter);
else message="Puntuación: "+(n-counter)+" &#150; felicidades! Has ganado!";
setTimeout('show()',2000);
}

function help()
{
if (showhelp==0)
{
showhelp=1;
message="Mahjongg, tambien llamado Taipei, Taipeh or Shanghai, es la adaptación web de un antiguo juego chino de mesa. El objetivo es retirar todas las "+n+" fichas del tablero; por cada pareja de fichas eliminadas obtendrás dos puntos.<p>Opciones:<p><ul><li>New: empieza un juego nuevo.<\/li><li>Restart: reinicia la partida actual.<\/li><li>Undo: deshace los movimientos uno a uno.<\/li><li>Moves: muestra el número de posibles movimientos.<\/li><li>Hints: muestra los posibles movimientos uno a uno.<\/li><li>Help: muestra las reglas del juego.<\/li><li>Info: muestra información del juego.<\/li><li>Email: envia un correo al autor.<\/li><\/ul><p>Las reglas son simples:<p>Empezando por los laterales o por la ficha central de la parte superior, retira las fichas clicando sobre dos símbolos idénticos. Si las fichas son idénticas, desapareceran, y tu puntuación se incrementará.<p>Las fichas seleccionables deben tener almenos un lado (izquierdo o derecho) libre. Si en ambos lados de la ficha existe una vecina del mismo nivel, no es posible seleccionarla.<p><img src=\"seas1.gif\" alt=\"\"><img src=\"seas2.gif\" alt=\"\"><img src=\"seas3.gif\" alt=\"\"><img src=\"seas4.gif\" alt=\"\">&nbsp;&nbsp;<img src=\"flow1.gif\" alt=\"\"><img src=\"flow2.gif\" alt=\"\"><img src=\"flow3.gif\" alt=\"\"><img src=\"flow4.gif\" alt=\"\"><br>Nota: Las cuatro fichas con símbolos estacionales (arriba a la izquierda) son emparejables aun cuando sus símbolos son distintos; las cuatro fichas de flores (arriba a la derecha) coinciden de la misma manera.";
suggest=0;
mark[k]="";
move=0;
show();
}
else
{
message="Regresar al juego.";
show();
wait();
}
}

function info()
{
if (showinfo==0)
{
showinfo=1;
message="En términos matemáticos, Mahjongg se describe fácilmente. Hay 144!/(4!)<sup>36<\/sup> juegos diferentes, la probabilidad de jugar dos veces el mismo juego (con la misma disposición de las fichas) es  1/1.1394912*10<sup>200<\/sup>. El número de juegos que se pueden ganar no está calculado exactamente, los expertos estiman que un buen jugador puede ganar una de cada dos o tres partidas.<p>Esta versión web de Mahjongg consiste en dos ficheros codificados en DHTML/CSS y Javascript. además de las imágenes utiloizadas para las fichas botones y fondo del juego. No se necesita ningún tipo de pluggin para jugar al juego. No existen requisitos especiales excepto un navegadro que acepte DHTML. Si la opción Javascript está habilitada, simplemente ponte a jugar.<p>La idea de este juego proviene de la competición www.the5k.org iniciada en el 2000, cuyo objetivo es promocionar el desarrollo de programas web originales y bien desarrollados. La versión de Mahjongg con menos de 5kb ha tomado parte de la edición 2002.<p>Solitaire Mahjongg v2.4<br>copyright &copy; 2002/2003 by Thomas Weibel<br>4102 Binningen, Switzerland<p>Last update: January 27th, 2003";
suggest=0;
mark[k]="";
move=0;
show();
}
else
{
message="Regresar al juego.";
show();
wait();
}
}

function undo()
{
if (ihistory.length==0)
{
message="No es posible deshacer!";
suggest=0;
mark[k]="";
move=0;
show();
wait();
}
else
{
restore();
message="Movimiento deshecho.";
suggest=0;
mark[k]="";
move=0;
back--;
show();
counter+=2;
wait();
}
}

function restart()
{
if (ihistory.length==0)
{
message="No es posible reiniciar!";
suggest=0;
mark[k]="";
move=0;
show();
wait();
}
else
{
for (i=0;i<back;i++) restore();
message="Juego reiniciado.";
suggest=0;
mark[k]="";
move=0;
back=0;
show();
counter=n;
wait();
}
}

function restore()
{
tile[ihistory[ihistory.length-1]]=tilehistory[tilehistory.length-1];
tile[ihistory[ihistory.length-2]]=tilehistory[tilehistory.length-2];
ihistory.length=ihistory.length-2;
tilehistory.length=tilehistory.length-2;
}

function moves()
{
suggest=0;
remain=0;
calc=new Array();
free=new Array();
for (i=0;i<n;i++)
{
remaining(i);
if (cond)
free[free.length]=calc[i];
}
free.sort();
for (i=0;i<(free.length-1);i++)
{
if (free[i]==free[i+1]&&free[i]==free[i+2]&&free[i]==free[i+3])
{
remain+=2; i+=3;
}
if (free[i]==free[i+1]&&free[i]==free[i+2])
{
remain++; i+=2;
}
if (free[i]==free[i+1])
{
remain++; i++;
}
}
if (remain==0) message="Fin del juevo: todas las parejas están bloqueadas!";
else message="Movimientos posibles: "+remain;
mark[k]="";
move=0;
show();
wait();
}

function hint()
{
if (suggest==0)
{
calc=new Array();
free=new Array();
hints=new Array();
for (i=0;i<n;i++)
{
remaining(i);
if (cond)
free[free.length]=calc[i]*1000+i;
}
free.sort();
for (i=0;i<(free.length-1);i++)
{
if (parseInt(free[i]/1000)==parseInt(free[i+1]/1000))
{
hints[hints.length]=free[i]-parseInt(free[i]/1000)*1000;
hints[hints.length]=free[i+1]-parseInt(free[i+1]/1000)*1000;
}
}
if (hints.length==0)
{
message="Fin del juevo: todas las parejas están bloqueadas!";
suggest=0;
}
else
{
remainmsg();
suggest=1;
}
}
else if (suggest==1)
{
remainmsg();
}
move=0;
show();
mark[hints[0]]="";
mark[hints[1]]="";
mark[k]="";
hints[hints.length]=hints[0];
hints[hints.length]=hints[1];
for (i=0;i<hints.length-2;i++)
hints[i]=hints[i+2];
hints.length=hints.length-2;
wait();
}

function remaining(i)
{
calc[i]=value[i]-parseInt(value[i]/1000)*1000;
test(i);
}

function remainmsg()
{
message="Movimiento posible";
mark[hints[0]]="<img src=\"mark.gif\" style=\"position:absolute;top:"+(offsetfact[hints[0]]*layeroffset+topoffset+tilefacty[hints[0]]*tileheight)+";left:"+(offsetfact[hints[0]]*layeroffset+leftoffset+tilefactx[hints[0]]*tilewidth)+"\" alt=\"\">";
mark[hints[1]]="<img src=\"mark.gif\" style=\"position:absolute;top:"+(offsetfact[hints[1]]*layeroffset+topoffset+tilefacty[hints[1]]*tileheight)+";left:"+(offsetfact[hints[1]]*layeroffset+leftoffset+tilefactx[hints[1]]*tilewidth)+"\" alt=\"\">";
}

function test(i)
{
lr=(tile[i-1]==notile[i-1]||tile[i+1]==notile[i+1]);
loop=new Array();
vari=new Array(10,11,14,15,28,29,30,31,34,35,36,37,40,41,42,43,46,47,48,49,70,71,72,73,74,75,79,80,81,82,83,84,91,92,93,94,95,96,103,104,105,106,107,108,116,117,118,119,120,121,125,126,127,128,129,130);
for (j=1;j<57;j++) loop[j]=(i==vari[j-1]&&(lr&&tile[j]==notile[j]));
cond=((i==0||i==5||i==8||i==9||i==12||i==13||i==16||i==17||i==20||i==21||i==26||i==27||i==32||i==33||i==38||i==39||i==44||i==45||i==50||i==51||i==56||i==57||i==68||i==69||i==76||i==77||i==86||i==87||i==113||i==114||i==123||i==124||i==131||i==132||i==143||
((i>=1&&i<=4)&&tile[0]==notile[0])||
((i==6||i==7||i==18||i==19||(i>=22&&i<=25)||(i>=52&&i<=55)||(i>=58&&i<=67)||i==78||i==85||(i>=88&&i<=90)||i==97||i==98||i==101||i==102||(i>=109&&i<=111)||i==115||i==122||i==133||(i>=134&&i<=142))&&lr)||
loop[1]||loop[2]||loop[3]||loop[4]||loop[5]||loop[6]||loop[7]||loop[8]||loop[9]||loop[10]||loop[11]||loop[12]||loop[13]||loop[14]||loop[15]||loop[16]||loop[17]||loop[18]||loop[19]||loop[20]||loop[21]||loop[22]||loop[23]||loop[24]||loop[25]||loop[26]||loop[27]||loop[28]||loop[29]||loop[30]||loop[31]||loop[32]||loop[33]||loop[34]||loop[35]||loop[36]||loop[37]||loop[38]||loop[39]||loop[40]||loop[41]||loop[42]||loop[43]||loop[44]||loop[45]||loop[46]||loop[47]||loop[48]||loop[49]||loop[50]||loop[51]||loop[52]||loop[53]||loop[54]||loop[55]||loop[56]||
(i==99&&(tile[98]==notile[98]||tile[112]==notile[112]))||
(i==100&&(tile[87]==notile[87]||tile[101]==notile[101]))||
(i==112&&((tile[99]==notile[99]&&tile[111]==notile[111])||tile[113]==notile[113])))&&
tile[i]!=notile[i]);
}
