No technical content, just used to practice code logic. In order to have a clear code structure, I wrote the logic control part in global variables, and the user interface operations were encapsulated in UI objects, and that's about it. For reference only. At work, someone complained that my coding style was too messy, so I wanted to try to write something that was not so messy. .
2048 DEMO
MSIE is SB
<script><br>
//全局方法用于逻辑控制<br>
function x4(n){<br>
var t=[];<br>
while(n-->0)t.push([]);<br>
return t;<br>
}<br>
function xx(f){<br>
for(var i=0;i<UI.nw;i ){<br />
for(var j=0;j<UI.nw;j ){<br />
f(i,j);<br />
}<br />
}<br />
}<br />
function make(n){<br />
return {<br />
number:n,<br />
moveStep:0,<br />
newNumber:n,<br />
needKill:0<br />
};<br />
}<br />
function tran(_arr,md){<br />
var undo=x4(UI.nw);<br />
var out=x4(UI.nw);<br />
var ud=UI.undo;<br />
if(ud.push(undo)>32)ud.shift();<br>
for(var i=0;i<UI.nw;i ){<br />
var t=[],o=md%2^1;<br />
for(var k=0;k<UI.nw;k ){<br />
undo[i][k]=_arr[i][k].number;<br />
if(md<3)t.push(_arr[i][k]);else t.push(_arr[k][i]);<br />
}<br />
o && t.reverse();<br />
t=trans(t);<br />
if(o)t[0].reverse(),t[1].reverse();<br />
for(var j=0;j<UI.nw;j ){<br />
var x=i,y=j;<br />
if(md>2)x=j,y=i;<br>
_arr[x][y]=t[0][j];<br>
out[x][y]=t[1][j];<br>
}<br>
}<br>
return [_arr,out];<br>
}<br>
function trans(arr){<br>
for(var i=0,m=0;i<UI.nw;i ){<br />
if(arr[i].number===0)m ;else arr[i].moveStep =m;<br />
var _i=arr[i];<br />
for(var j=i-1;j>=0;j--){<br>
if(!arr[j].number)continue;<br>
if(arr[j].needKill)break;<br>
if(arr[j].number==_i.number){<br>
arr[j].needKill=1;<br>
arr[i].newNumber*=2;<br>
arr[i].moveStep ;<br>
m ;<br>
}<br>
}<br>
}<br>
var out=[];<br>
for(var i=UI.nw;i--;){<br>
!arr[i].needKill && arr[i].number && out.unshift(arr[i].newNumber);<br>
}<br>
while(out.length<UI.nw)out.push(0);<br />
return [arr,out];<br />
}<br />
//界面操作开始,界面操作的参数通过全局方法来获得<br />
function $(a){return document.getElementById(a);}<br />
UI={};<br />
UI.update=function(d){<br />
if(UI.locked)return;<br />
var map=this.map;<br />
var n=this.times;<br />
UI.locked=1;//未完成动画之前阻止用户动作<br />
var out=tran(map,d)[1];<br />
var _n=0,_begin=x4(UI.nw);<br />
(function(){<br />
if(_n>n){<br>
var _q=0;<br>
xx(function(i,j){<br>
_q=_q||this.map[i][j].moveStep;<br>
var o=$('i'+i+'j'+j);<br>
o.innerHTML=out[i][j]||'';<br>
o.className='x r'+o.innerText;<br>
this.map[i][j]=make(out[i][j]);<br>
o=o.style;<br>
o.display='block';<br>
o.left=UI.size*j+"px";<br>
o.top=UI.size*i+"px";<br>
});<br>
return _q ? UI.addNew():(UI.locked=0);<br>
}<br>
xx(function(i,j){<br>
var o=$('i'+i+'j'+j),t,o1=o.style,s=d<3?'left':'top';<br />
if(t=map[i][j][_n==n?'newNumber':'number'])o.innerHTML=t;else o1.display='none';<br />
if(_begin[i][j]===undefined)_begin[i][j]=parseInt(o1[s]);<br />
o1[s]=(_begin[i][j]+(map[i][j].moveStep*100/n*_n)*Math.pow(-1,d))+'px';<br />
});<br />
_n++;<br />
setTimeout(arguments.callee,10);<br />
})();<br />
}<br />
UI.undo=[];<br />
UI.addNew=function(_q){<br />
UI.locked=1;<br />
var r=[];<br />
xx(function(i,j){<br />
this.map[i][j].number || r.push([i,j]);<br />
});<br />
if(!r.length)return UI.locked=0;<br />
var q=new Date%r.length;q=r[q];<br />
var b=$('i'+q[0]+'j'+q[1]);<br />
var m=this.map[q[0]][q[1]];<br />
b.innerHTML=m.number=m.newNumber=2<<new Date%2;<br />
b.className='x r'+b.innerText;<br />
var o=0,q=5;<br />
(function(){<br />
if(o<100)setTimeout(arguments.callee,10);<br />
b.style.opacity=Math.min(o+=q++,100)/100;<br />
})();<br />
UI.locked=0;//解除锁定<br />
};<br />
//创建<br />
UI.init=function(nw,maxUndo,size,times){<br />
UI.times=times||8;//动画过度次数<br />
UI.nw=nw||5;//方阵边长<br />
UI.map=map=x4(UI.nw);//创建数字块对象<br />
UI.size=size||100;//单元格宽度<br />
UI.maxUndo=maxUndo||5;//最大撤销步数<br />
$('box').innerHTML='';<br />
xx(function(i,j){<br />
map[i][j]=make(0);<br />
document.write("<div class='x' id='i"+i+"j"+j+"'\<br />
style='left:"+(UI.size*j)+"px;top:"+(UI.size*i)+"px;'></div>\<br>
<div class='y' \<br />
style='left:"+(UI.size*j)+"px;top:"+(UI.size*i)+"px;'></div>");<br>
});<br>
UI.addNew();<br>
UI.addNew();<br>
};<br>
UI.init(6,3,100,20);<br>
//自动播放,仅用来做演示的。没有做事件绑定<br>
setInterval(function(){UI.update([1,2,3,4][Math.random()*4|0]);},200);<br>
</script>