1.代码

 <!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>万能的React</title>
<style>
.app{
margin:10px;
font-family: arial;
}
.board{
display:block;
position:relative;
margin:10px 0px 10px 0px;
border:1px solid #ccc;
width:215px;
height:215px;
padding:5px;
}
.board span{
font-family: arial;
letter-spacing: -1px;
display:block;
width:50px;
height:36px;
position:absolute;
text-align:center;
color:white;
font-weight:bold;
font-size:20px;
padding-top:14px;
background-color:#ebe76f;
border-radius: 5px;
transition: all 100ms linear;
}
.a1, .b1, .c1, .d1{ left:5px; }
.a2, .b2, .c2, .d2{ left:60px; }
.a3, .b3, .c3, .d3{ left:115px; }
.a4, .b4, .c4, .d4{ left:170px; }
.a1, .a2, .a3, .a4{ top:5px; }
.b1, .b2, .b3, .b4{ top:60px; }
.c1, .c2, .c3, .c4{ top:115px; }
.d1, .d2, .d3, .d4{ top:170px; }
span.value2{ background-color:#ebb26f; }
span.value4{ background-color:#ea6feb; }
span.value8{ background-color:#eb6fa3; }
span.value16{ background-color:#7a6feb; }
span.value32{ background-color:#af6feb; }
span.value64{ background-color:#6febcf; }
span.value128{ background-color:#6fbeeb; }
span.value256{ background-color:#afeb6f; }
span.value512{ background-color:#7aeb6f; }
span.value1024{ background-color:#e4eb6f; }
</style>
</head>
<body>
<script src="./react-0.13.2/react-0.13.2/build/react.js"></script>
<script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script>
<script type="text/jsx">
var initial_board = {
a1:null,a2:null,a3:null,a4:null,
b1:null,b2:null,b3:null,b4:null,
c1:null,c2:null,c3:null,c4:null,
d1:null,d2:null,d3:null,d4:null
}; function available_spaces(board){
return Object.keys(board).filter(function(key){
return board[key] == null
});
} function used_spaces(board){
return Object.keys(board).filter(function(key){
return board[key] !== null
});
} function score_board(board){
return used_spaces(board).map(function(key){
return (board[key].values.reduce(function(a, b) {
return a + b; //sum tile values
})) - board[key].values[0]; //don't count initial value
}).reduce(function(a,b){return a+b}, 0);
} function tile_value(tile){
return tile ? tile.values[tile.values.length-1] : null;
} function can_move(board){
var new_board = [up,down,left,right].reduce(function(b, direction){
return fold_board(b, direction);
}, board);
return available_spaces(new_board).length > 0
} function same_board(board1, board2){
return Object.keys(board1).reduce(function(ret, key){
return ret && board1[key] == board2[key];
}, true);
} function fold_line(board, line){
var tiles = line.map(function(key){
return board[key];
}).filter(function(tile){
return tile !== null
});
var new_tiles = [];
if(tiles){
//must loop so we can skip next if matched
for(var i=0; i < tiles.length; i++){
var tile = tiles[i];
if(tile){
var val = tile_value(tile);
var next_tile = tiles[i+1];
if(next_tile && val == tile_value(next_tile)){
//skip next tile;
i++;
new_tiles.push({
id: next_tile.id, //keep id
values: tile.values.concat([val * 2])
});
}
else{
new_tiles.push(tile);
}
}
}
}
var new_line = {};
line.forEach(function(key, i){
new_line[key] = new_tiles[i] || null;
});
return new_line;
} function fold_order(xs, ys, reverse_keys){
return xs.map(function(x){
return ys.map(function(y){
var key = [x,y];
if(reverse_keys){
return key.reverse().join("");
}
return key.join("");
});
});
} function fold_board(board, lines){
//copy reference
var new_board = board;
lines.forEach(function(line){
var new_line = fold_line(board, line);
Object.keys(new_line).forEach(function(key){
//mutate reference while building up board
new_board = set_tile(new_board, key, new_line[key]);
});
});
return new_board;
} var tile_counter = 0;
function new_tile(initial){
return {
id: tile_counter++,
values: [initial]
};
} function set_tile(board, where, tile){
//do not destory the old board
var new_board = {};
Object.keys(board).forEach(function(key, i){
//copy by reference for structual sharing
new_board[key] = (key == where) ? tile : board[key];
});
return new_board;
} var left = fold_order(["a","b","c","d"], ["1","2","3","4"], false);
var right = fold_order(["a","b","c","d"], ["4","3","2","1"], false);
var up = fold_order(["1","2","3","4"], ["a","b","c","d"], true);
var down = fold_order( ["1","2","3","4"], ["d","c","b","a"], true); var GameBoard = React.createClass({
getInitialState: function(){
return this.addTile(this.addTile(initial_board));
},
keyHandler:function(e){
var directions = {
37: left,
38: up,
39: right,
40: down
};
if(directions[e.keyCode]
&& this.setBoard(fold_board(this.state, directions[e.keyCode]))
&& Math.floor(Math.random() * 30, 0) > 0){
setTimeout(function(){
this.setBoard(this.addTile(this.state));
}.bind(this), 100);
}
},
setBoard:function(new_board){
if(!same_board(this.state, new_board)){
this.setState(new_board);
return true;
}
return false;
},
addTile:function(board){
var location = available_spaces(board).sort(function() {
return .5 - Math.random();
}).pop();
if(location){
var two_or_four = Math.floor(Math.random() * 2, 0) ? 2 : 4;
return set_tile(board, location, new_tile(two_or_four));
}
return board;
},
newGame:function(){
this.setState(this.getInitialState());
},
componentDidMount:function(){
window.addEventListener("keydown", this.keyHandler, false);
},
render:function(){
var status = !can_move(this.state)?" - Game Over!":"";
return <div className="app">
<span className="score">
Score: {score_board(this.state)}{status}
</span>
<Tiles board={this.state}/>
<button onClick={this.newGame}>New Game</button>
</div>
}
}); var Tiles = React.createClass({
render: function(){
var board = this.props.board;
//sort board keys first to stop re-ordering of DOM elements
var tiles = used_spaces(board).sort(function(a, b) {
return board[a].id - board[b].id;
});
return <div className="board">{
tiles.map(function(key){
var tile = board[key];
var val = tile_value(tile);
return <span key={tile.id} className={key + " value" + val}>
{val}
</span>;
})}</div>
}
}); React.render(<GameBoard />, document.body);
</script>
</body>
</html>

2.结果

最新文章

  1. Devexpress Ribbon
  2. oracle中scn(系统改变号)
  3. Model View Controller
  4. CentOS5.5挂载本地ISO镜像
  5. jq数组,得到遍历生成的id后面的id
  6. 解决Visual Studio 2010/2012的RC4011 warnings
  7. SVN代码的回滚二
  8. Linux网络配置命令ifconfig输出信息解析
  9. Logger之Logger.getLogger(CLass)
  10. maven 搭新建成之后 无法创建 src/main/java 目录解决
  11. Oracle_基本函数查询综合
  12. 框架学习之Spring(一IOC)----HelloWrod
  13. vue 追书神器
  14. NightWatch端到端测试
  15. 利用特性和反射给泛型Model赋值
  16. P2659 美丽的序列
  17. [NOIP模拟赛] 序列
  18. Axure RP Pro 7.0苏宁易购式标签切换效果教程
  19. .net源码调试 http://referencesource.microsoft.com/
  20. Linux下SSL证书申请以及配置到Nginx

热门文章

  1. 第29章 项目10:DIY街机游戏
  2. Java方法重载
  3. Linux命令练级初级
  4. SSMS 2008R2没有智能感知方法解决
  5. bnuoj 4207 台风(模拟题)
  6. 【读书笔记】Redis入门
  7. firefox同步ajax请求报错的问题 A parameter or an operation is not supported by the underlying object
  8. EXT4.2--Ext Designer 使用
  9. 【HDOJ】【3555】Bomb
  10. maven+springMVC+mybatis+junit详细搭建过程 ***