1 //事件处理对象
  2 //addHandler() 方法接受3个参数:要操作的元素、事件名称和事件处理程序函数。
  3 var EventUtil = {
  4     addHandler: function (element, type, handler) {
  5         if (element.addEventListener) {
  6             element.addEventListener(type, handler, false);
  7         } else if (element.attachEvent) {
  8             element.attachEvent("on" + type, handler);
  9         } else {
 10             element["on" + type] = handler;
 11         } //处理浏览器之间的差异
 12     },
 13 
 14     //获取事件对象
 15     getEvent: function (event) {
 16         return event ? event : window.event; //兼容IE
 17     }
 18 
 19 }
 20 
 21 //创建Game对象
 22 function Game2048(tileCon, scoreEle, bestScoreEle) {
 23     this.tileContainer = tileCon;
 24     this.scoreEle = scoreEle;
 25     this.bestScoreEle = bestScoreEle;
 26     this.tiles = new Array(4);//创建存方块数值与dom对象的一维数组
 27     
 28 }
 29 
 30 Game2048.prototype = {  //game的原型方法
 31     init: function () { //初始化游戏
 32         this.posArray = [];//创建存空白方块坐标的数组 position
 33         for (let i = 0, len = this.tiles.length; i < len; i++) {
 34 
 35             this.tiles[i] = []; //变成了二维数组
 36             for (let j = 0; j < len; j++) {
 37                 this.tiles[i][j] = { num: 0 }; //初始化存方块数值与dom对象的数组
 38                 this.posArray.push({ "x": i, "y": j });
 39 
 40                 //初始化存方块坐标的数组
 41             }
 42         }
 43         this.deleteTile(true); //清空全部方块 自定义的方法 传入true 全部clear
 44         this.score = 0; //初始化分数
 45         this.bestScore = this.bestScore || 0;
 46         this.newTile(); //创建两个方块
 47         this.newTile();
 48     },
 49     //创建方块函数
 50     newTile: function () {
 51         var tile = document.createElement("div");
 52         var pos = this.randomPos(); //方块位置
 53         var num = Math.random() < 0.9 ? 2 : 4; //新方块数值2或者4 
 54         this.tiles[pos.x][pos.y] = { num: num, tile: tile };
 55         //将新房块的数字与dom对象 存入数组
 56         this.setTile(tile, num, pos.x, pos.y); //设置方块属性产生移动与淡入效果
 57         this.tileContainer.appendChild(tile);
 58     },
 59     //设置方块class和显示的数字
 60     setTile: function (element, num, x, y) {  //xy 是坐标位置 (x,y)让哪一个格子生成div  根据num的值渲染不同的颜色
 61         element.innerHTML = num;
 62         element.className = "tile tile-" + num + " tile-pos-" + x + "-" + y;
 63     },//设置类名
 64 
 65     randomPos: function () { //随机一个方块位置
 66         let  index = Math.floor(Math.random() * this.posArray.length);
 67         // console.log(index);
 68         let pos = this.posArray[index];  // posArray 存放的是16个格子的位置 随机产生一个数字即可 
 69         // console.log(pos);
 70         this.posArray.splice(index, 1); // 产生之后就不是一个空白方块了????
 71         return pos; //返回的是一个对象  里面存放的位置信息 { "x": i, "y": j }
 72     },
 73 
 74     //方块移动 core
 75     moveTile: function (keyCode) {
 76         let len = this.tiles.length;
 77         let merge; //存合并状态  自定义函数
 78         switch (keyCode) {
 79             //左移
 80             case 37:
 81                 for (let i = 1; i < len; i++) {
 82                     for (let j = 0; j < len; j++) {
 83                         if (this.tiles[i][j].num != 0 && this.leftMove(i, j)) {  //遍历所有的格子不是空格子就左移
 84                             merge = this.merge(i, j); //合并
 85                         }
 86                     }
 87                 }
 88                 break;
 89             //右移动
 90             case 39:
 91                 for (let i = len - 2; i >= 0; i--) {
 92                     for (let j = 0; j < len; j++) {
 93                         if (this.tiles[i][j].num != 0 && this.rightMove(i, j)) {//遍历所有的格子不是空格子就right移
 94                             merge = this.merge(i, j);
 95                         }
 96                     }
 97                 }
 98                 break;
 99             case 38:  //shang yi dong
100                 for (let i = 0; i < len; i++) {
101                     for (let j = 1; j < len; j++) {
102                         if (this.tiles[i][j].num != 0 && this.upMove(i, j)) {//遍历所有的格子不是空格子就 up
103                             merge = this.merge(i, j);
104                         }
105                     }
106                 }
107                 break;
108             case 40:
109                 for (let i = 0; i < len; i++) {
110                     for (let j = len - 2; j >= 0; j--) {
111                         if (this.tiles[i][j].num != 0 && this.downMove(i, j)) { //遍历所有的格子不是空格子就down
112                             
113                             merge = this.merge(i, j);
114                         }
115                     }
116                 }
117                 break;
118         }
119         if (merge) {   //产生了 合并事件就产生一个新的方块
120             this.newTile();//合并后创建一个新的方块
121         } else if (this.posArray.length == 0 && this.gameOverTest()) {
122             this.gameOver(); //游戏结束测试
123         }
124     },
125 
126 
127     leftMove: function (i, j) { //左移函数
128         this.num = this.tiles[i][j].num; //找到该格子的数字
129         this.moveI = undefined;
130         this.moveJ = undefined;
131         for (let n = i - 1; n >= 0; n--) {  //一直试探到碰壁为止
132             if (this.tiles[n][j].num == 0) { //试探左边的的格子是否为空
133                 this.moveI = n;
134             } else if (this.tiles[n][j].num == this.num) { //如果左边的数字相同 则合并
135                 this.num *= 2;
136                 this.moveI = n;
137                 if (this.num == 2048) {
138                     this.gameWin(); //如果有2048出现 则闯关成功
139                 }
140                 this.getScore(this.num); //记录分数
141                 break;
142             } else {
143                 break;
144             }
145         }
146         this.moveJ = j;
147         if (!(this.moveI + 1) || !(this.moveJ + 1)) { //undefined + 1 = NaN; 
148             return; //没有产生移动 直接进入的else break循环
149         }
150         return true;
151     },
152 
153 
154     rightMove: function (i, j) {   //与左移同理
155         let len = this.tiles.length;
156         this.num = this.tiles[i][j].num;
157         this.moveI = undefined;
158         this.moveJ = undefined;
159         for (let n = i + 1; n < len; n++) {
160             if (this.tiles[n][j].num == 0) {
161                 this.moveI = n;
162             } else if (this.tiles[n][j].num == this.num) {
163                 this.num *= 2;
164                 this.moveI = n;
165                 if (this.num == 2048) {
166                     this.gameWin(); 
167                 }
168                 this.getScore(this.num);
169                 break;
170             } else {
171                 break;
172             }
173         }
174         this.moveJ = j;
175         if (!(this.moveI + 1) || !(this.moveJ + 1)) {
176             return;
177         }
178         return true;
179     },
180 
181 
182     upMove: function (i, j) { //与左移同理
183 
184         this.num = this.tiles[i][j].num;
185         this.moveI = undefined;
186         this.moveJ = undefined;
187         for (let n = j - 1; n >= 0; n--) {
188             if (this.tiles[i][n].num == 0) {
189                 this.moveJ = n;
190             } else if (this.tiles[i][n].num == this.num) {
191                 this.moveJ = n;
192                 this.num *= 2;
193                 if (this.num == 2048) {
194                     this.gameWin(); //同理
195                 }
196                 this.getScore(this.num);
197                 break;
198             }
199         }
200         this.moveI = i;
201         if (!(this.moveI + 1) || !(this.moveJ + 1)) {
202             return;
203         }
204         return true;
205     },
206 
207     downMove: function (i, j) {  //与左移同理
208         let len = this.tiles.length;
209         this.num = this.tiles[i][j].num;
210         this.moveI = undefined;
211         this.moveJ = undefined;
212         for (let n = j + 1; n < len; n++) {
213             if (this.tiles[i][n].num == 0) {
214                 this.moveJ = n;
215             } else if (this.tiles[i][n].num == this.num) {
216                 this.moveJ = n;
217                 this.num *= 2;
218                 if (this.num == 2048) {
219                     this.gameWin(); //同理
220                 }
221                 this.getScore(this.num);
222                 break;
223             }
224         }
225         this.moveI = i;
226         if (!(this.moveI + 1) || !(this.moveJ + 1)) {
227             return;
228         }
229         return true;
230     },
231 
232     //合并方块
233     merge: function (i, j) {
234         let me = this; //记录this指向 
235         if (this.num > this.tiles[i][j].num) {
236             //this.num的值变化,即遇到相同值的方块,可移动到其位置,只需删除被覆盖的方块
237             this.deleteTile(false, this.tiles[this.moveI][this.moveJ].tile);
238             this.posArray.push({ x: i, y: j });
239         } else if (this.num == this.tiles[i][j].num) {
240             this.posArray.forEach(function (item) { // binali 
241                 if (item.x == me.moveI && item.y == me.moveJ) {
242                     item.x = i;
243                     item.y = j;
244                 }
245             });
246         }
247         //设置将移动的方块的属性,产生移动效果
248         this.setTile(this.tiles[i][j].tile, this.num, this.moveI, this.moveJ);
249         //在存方块数值与dom对象的数组中将移动的方块的值设为空白值(即num:0),被覆盖的方块的值设为将移动的方块的值
250         this.tiles[this.moveI][this.moveJ] = { num: this.num, tile: this.tiles[i][j].tile };
251         this.tiles[i][j] = { num: 0 };
252         return true;
253     },
254 
255 
256     //删除方块节点
257     deleteTile: function (all, tile) {
258         if (all) {
259             this.tileContainer.innerHTML = ""; //clear;
260         } else {
261             this.tileContainer.removeChild(tile);//删除单个方块
262         }
263     },
264 
265 
266     //计算得分
267     getScore: function (score) {
268         this.score += score;
269         this.scoreEle.innerHTML = this.score;
270         if (this.score > this.bestScore) {
271             this.bestScore = this.score // 分数超过时 , 就刷新 最高记录
272             this.bestScoreEle.innerHTML = this.bestScore;
273         }
274     },
275 
276     //出现2048  gameOver 也可以继续挑战
277     gameWin: function () {
278         let me = this;
279         let win = document.createElement("div");
280         let continueBtn = document.createElement("button");
281         continueBtn.className = "game-win-again";
282         win.className = "game-win";
283         win.appendChild(continueBtn);
284         this.tileContainer.appendChild(win);
285         EventUtil.addHandler(continueBtn, "click", function () {
286             me.deleteTile(false, win);
287         });
288     },
289 
290     // 没有方向移动 gameOver 
291     //test
292     gameOverTest: function () {
293         let len = this.tiles.length;
294         for (let i = 0; i < len; i++) {
295             for (let j = 0; j < len; j++) {
296                 if (this.leftMove(i, j) || this.rightMove(i, j) || this.upMove(i, j) || this.downMove(i, j)) {
297                     return; //任意方向 可以移动就继续游戏
298                 }
299             }
300         }
301         return true;
302     },
303 
304     //游戏结束 消息
305     gameOver: function () {
306         let message = document.createElement("div");
307         message.className = "game-over";
308         this.tileContainer.appendChild(message);
309     },
310 
311 
312     //添加事件处理程序????
313     initEvent: function () {
314         let me = this;
315         console.log(this);  //指向了game2048 对象 ;
316         //限制键盘一直重复触发
317         EventUtil.addHandler(window, "keyup", function (event) {
318             me.moveTile(EventUtil.getEvent(event).keyCode);
319         })
320     },
321 
322 }
323 
324 
325 window.onload = function () {
326     let btn = document.getElementById("newGame");
327     let tileContainer = document.getElementById("tile-container");
328     let scoreEle = document.getElementById("game-score");
329     let bestScoreEle = document.getElementById("game-best-score");
330     var startX, startY, endX, endY;
331     var game = game || new Game2048(tileContainer, scoreEle, bestScoreEle);
332     //创建Game对象 传入game需要的参数
333 
334     game.initEvent();//初始化事件处理???
335     game.init(); //初始化游戏
336 
337     EventUtil.addHandler(btn, "click", function () {
338         game.init();
339         //点击newgame 初始化游戏  
340     });
341 }

上面是js部分

 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 
 4 <head>
 5     <meta charset="UTF-8">
 6     <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
 7     <link rel="stylesheet" type="text/css" href="style.css">
 8     <title>2048</title>
 9 </head>
10 
11 <body>
12     <div class="container" id="container">
13         <div class="header">
14             <h1 class="game-title">2048</h1>
15             <div class="game-info">
16                 <span id="game-best-score">0</span>
17                 <span id="game-score">0</span>
18                 <button id="newGame" type="button">New Game</button>
19             </div>
20         </div>
21         <div class="game-container" id="game-container">
22             <div class="game-result">
23                 <p></p>
24             </div>
25             <div class="gird-container">
26                 <div class="gird-row">
27                     <div class="gird-col"></div>
28                     <div class="gird-col"></div>
29                     <div class="gird-col"></div>
30                     <div class="gird-col"></div>
31                 </div>
32                 <div class="gird-row">
33                     <div class="gird-col"></div>
34                     <div class="gird-col"></div>
35                     <div class="gird-col"></div>
36                     <div class="gird-col"></div>
37                 </div>
38                 <div class="gird-row">
39                     <div class="gird-col"></div>
40                     <div class="gird-col"></div>
41                     <div class="gird-col"></div>
42                     <div class="gird-col"></div>
43                 </div>
44                 <div class="gird-row">
45                     <div class="gird-col"></div>
46                     <div class="gird-col"></div>
47                     <div class="gird-col"></div>
48                     <div class="gird-col"></div>
49                 </div>
50             </div>
51             <div class="tile-container" id="tile-container"></div>
52         </div>
53     </div>
54     <!-- <script type="text/javascript" src="main.js"></script> -->
55     <script type="text/javascript" src="Game2048.js"></script>
56 </body>
57 
58 </html>

HTML部分

 

 

 

  1 * {
  2     margin: 0;
  3     padding: 0;
  4 }
  5 
  6 .container {
  7     width: 500px;
  8     height: 640px;
  9     position: absolute;
 10     top: 0;
 11     left: 0;
 12     right: 0;
 13     bottom: 0;
 14     margin: auto;
 15     font-family: "微软雅黑";
 16 }
 17 
 18 .header {
 19     height: 120px;
 20     margin-bottom: 20px;
 21 }
 22 
 23 .game-title {
 24     font-size: 50px;
 25     color: #776e65;
 26     text-align: center;
 27     margin-bottom: 10px;
 28 }
 29 
 30 .game-info {
 31     height: 40px;
 32 }
 33 
 34 #game-score, #game-best-score {
 35     height: 100%;
 36     float: left;
 37     min-width: 65px;
 38     background-color: #bbada0;
 39     color: #fff;
 40     font-size: 18px;
 41     border-radius: 5px;
 42     text-align: center;
 43     line-height: 58px;
 44     position: relative;
 45 }
 46 
 47 #game-score:after {
 48     content: "Score";
 49     position: absolute;
 50     width: 100%;
 51     left: 0;
 52     top: -21px;
 53     text-align: center;
 54     color: #e9dfd4;
 55     font-size: 13px;
 56 }
 57 
 58 #game-best-score {
 59     margin-right: 15px;
 60 }
 61 
 62 #game-best-score:after {
 63     content: "Best";
 64     position: absolute;
 65     width: 100%;
 66     left: 0;
 67     top: -21px;
 68     text-align: center;
 69     color: #e9dfd4;
 70     font-size: 13px;
 71 }
 72 
 73 #newGame {
 74     height: 100%;
 75     width: 100px;
 76     float: right;
 77     border-radius: 5px;
 78     background-color: #8f7a66;
 79     border: none;
 80     box-shadow: none;
 81     color: #fff;
 82     font-size: 16px;
 83     cursor: pointer;
 84 }
 85 
 86 #newGame:focus {
 87     outline: none;
 88 }
 89 
 90 .game-container {
 91     width: 500px;
 92     height: 500px;
 93     position: relative;
 94     background-color: #bbada0;
 95     padding: 15px;
 96     border-radius: 5px;
 97     box-sizing: border-box;
 98     -moz-box-sizing: border-box;
 99     /* Firefox */
100     -webkit-box-sizing: border-box;
101     /* Safari */
102 }
103 
104 .gird-container {
105     width: 470px;
106     height: 470px;
107 }
108 
109 .gird-row {
110     width: 470px;
111     height: 106.25px;
112     margin-bottom: 15px;
113     clear: both;
114 }
115 
116 .gird-row:last-child {
117     margin-bottom: 0;
118 }
119 
120 .gird-col {
121     width: 106.25px;
122     height: 106.25px;
123     margin-right: 15px;
124     background-color: #cdc1b4;
125     float: left;
126 }
127 
128 .gird-col:last-child {
129     margin-right: 0;
130 }
131 
132 .tile-container {
133     color: #f9f6f2;
134     width: 470px;
135     height: 470px;
136     position: absolute;
137     top: 15px;
138 }
139 
140 .game-over {
141     position: absolute;
142     top: 0;
143     bottom: 0;
144     left: 0;
145     right: 0;
146     z-index: 10;
147     background-color: rgba(204, 204, 204, 0.5);
148 }
149 
150 .game-over:after {
151     content: "Game Over";
152     font-size: 60px;
153     color: #fff;
154     position: absolute;
155     top: 0;
156     bottom: 0;
157     left: 0;
158     right: 0;
159     height: 70px;
160     margin: auto;
161     text-align: center;
162 }
163 
164 .game-win {
165     position: absolute;
166     top: 0;
167     bottom: 0;
168     left: 0;
169     right: 0;
170     z-index: 10;
171     background-color: rgba(204, 204, 204, 0.5);
172 }
173 
174 .game-win:after {
175     content: "You Win";
176     font-size: 60px;
177     color: #fff;
178     position: absolute;
179     top: 0;
180     bottom: 0;
181     left: 0;
182     right: 0;
183     height: 70px;
184     margin: auto;
185     text-align: center;
186 }
187 
188 .game-win-again {
189     width: 160px;
190     height: 50px;
191     border-radius: 5px;
192     background-color: #8f7a66;
193     border: none;
194     box-shadow: none;
195     color: #fff;
196     cursor: pointer;
197     position: absolute;
198     bottom: 120px;
199     left: 0;
200     right: 0;
201     margin: auto;
202     font-size: 30px;
203 }
204 
205 .game-win-again:after {
206     content: "Continue";
207 }
208 
209 .tile {
210     position: absolute;
211     width: 106.25px;
212     height: 106.25px;
213     text-align: center;
214     line-height: 106.25px;
215     font-size: 50px;
216     top: 0;
217     transition: transform 150ms ease-out;
218     -moz-transition: transform 150ms ease-out;
219     /* Firefox 4 */
220     -webkit-transition: transform 150ms ease-out;
221     /* Safari 和 Chrome */
222     -o-transition: transform 150ms ease-out;
223     /* Opera */
224     animation: tiledisplay 300ms 1;
225     -webkit-animation: tiledisplay 300ms 1;
226     /* Safari 和 Chrome */
227 }
228 
229 @keyframes tiledisplay {
230     0% {
231         opacity: 0;
232         filter: alpha(opacity=0);
233     }
234     50% {
235         opacity: 0;
236         filter: alpha(opacity=0);
237     }
238     100% {
239         opacity: 1;
240         filter: alpha(opacity=100);
241     }
242 }
243 
244 @-webkit-keyframes tiledisplay
245 /* Safari and Chrome */
246 
247     {
248     0% {
249         opacity: 0;
250         filter: alpha(opacity=0);
251     }
252     50% {
253         opacity: 0;
254         filter: alpha(opacity=0);
255     }
256     100% {
257         opacity: 1;
258         filter: alpha(opacity=100);
259     }
260 }
261 
262 .tile-container .tile-2 {
263     color: #776e65;
264     background: #eee4da;
265 }
266 
267 .tile-container .tile-4 {
268     color: #776e65;
269     background: #ede0c8;
270 }
271 
272 .tile-container .tile-8 {
273     background: #f2b179;
274 }
275 
276 .tile-container .tile-16 {
277     background: #f59563;
278 }
279 
280 .tile-container .tile-32 {
281     background: #f67c5f;
282 }
283 
284 .tile-container .tile-64 {
285     background: #f65e3b;
286 }
287 
288 .tile-container .tile-128 {
289     background: #edcf72;
290 }
291 
292 .tile-container .tile-256 {
293     background: #edcc61;
294 }
295 
296 .tile-container .tile-512 {
297     background: #edc850;
298 }
299 
300 .tile-container .tile-1024 {
301     background: #edc53f;
302 }
303 
304 .tile-container .tile-2048 {
305     background: #edc22e;
306 }
307 
308 .tile-container .tile-pos-0-0 {
309     -webkit-transform: translate(0, 0);
310     -ms-transform: translate(0, 0);
311     -o-transform: translate(0, 0);
312     transform: translate(0, 0);
313 }
314 
315 .tile-container .tile-pos-0-1 {
316     -webkit-transform: translate(0, 121.25px);
317     -ms-transform: translate(0, 121.25px);
318     -o-transform: translate(0, 121.25px);
319     transform: translate(0, 121.25px);
320 }
321 
322 .tile-container .tile-pos-0-2 {
323     -webkit-transform: translate(0, 242.5px);
324     -ms-transform: translate(0, 242.5px);
325     -o-transform: translate(0, 242.5px);
326     transform: translate(0, 242.5px);
327 }
328 
329 .tile-container .tile-pos-0-3 {
330     -webkit-transform: translate(0, 363.75px);
331     -ms-transform: translate(0, 363.75px);
332     -o-transform: translate(0, 363.75px);
333     transform: translate(0, 363.75px);
334 }
335 
336 .tile-container .tile-pos-1-0 {
337     -webkit-transform: translate(121.25px, 0);
338     -ms-transform: translate(121.25px, 0);
339     -o-transform: translate(121.25px, 0);
340     transform: translate(121.25px, 0);
341 }
342 
343 .tile-container .tile-pos-1-1 {
344     -webkit-transform: translate(121.25px, 121.25px);
345     -ms-transform: translate(121.25px, 121.25px);
346     -o-transform: translate(121.25px, 121.25px);
347     transform: translate(121.25px, 121.25px);
348 }
349 
350 .tile-container .tile-pos-1-2 {
351     -webkit-transform: translate(121.25px, 242.5px);
352     -ms-transform: translate(121.25px, 242.5px);
353     -o-transform: translate(121.25px, 242.5px);
354     transform: translate(121.25px, 242.5px);
355 }
356 
357 .tile-container .tile-pos-1-3 {
358     -webkit-transform: translate(121.25px, 363.75px);
359     -ms-transform: translate(121.25px, 363.75px);
360     -o-transform: translate(121.25px, 363.75px);
361     transform: translate(121.25px, 363.75px);
362 }
363 
364 .tile-container .tile-pos-2-0 {
365     -webkit-transform: translate(242.5px, 0);
366     -ms-transform: translate(242.5px, 0);
367     -o-transform: translate(242.5px, 0);
368     transform: translate(242.5px, 0);
369 }
370 
371 .tile-container .tile-pos-2-1 {
372     -webkit-transform: translate(242.5px, 121.25px);
373     -ms-transform: translate(242.5px, 121.25px);
374     -o-transform: translate(242.5px, 121.25px);
375     transform: translate(242.5px, 121.25px);
376 }
377 
378 .tile-container .tile-pos-2-2 {
379     -webkit-transform: translate(242.5px, 242.5px);
380     -ms-transform: translate(242.5px, 242.5px);
381     -o-transform: translate(242.5px, 242.5px);
382     transform: translate(242.5px, 242.5px);
383 }
384 
385 .tile-container .tile-pos-2-3 {
386     -webkit-transform: translate(242.5px, 363.75px);
387     -ms-transform: translate(242.5px, 363.75px);
388     -o-transform: translate(242.5px, 363.75px);
389     transform: translate(242.5px, 363.75px);
390 }
391 
392 .tile-container .tile-pos-3-0 {
393     -webkit-transform: translate(363.75px, 0);
394     -ms-transform: translate(363.75px, 0);
395     -o-transform: translate(363.75px, 0);
396     transform: translate(363.75px, 0);
397 }
398 
399 .tile-container .tile-pos-3-1 {
400     -webkit-transform: translate(363.75px, 121.25px);
401     -ms-transform: translate(363.75px, 121.25px);
402     -o-transform: translate(363.75px, 121.25px);
403     transform: translate(363.75px, 121.25px);
404 }
405 
406 .tile-container .tile-pos-3-2 {
407     -webkit-transform: translate(363.75px, 242.5px);
408     -ms-transform: translate(363.75px, 242.5px);
409     -o-transform: translate(363.75px, 242.5px);
410     transform: translate(363.75px, 242.5px);
411 }
412 
413 .tile-container .tile-pos-3-3 {
414     -webkit-transform: translate(363.75px, 363.75px);
415     -ms-transform: translate(363.75px, 363.75px);
416     -o-transform: translate(363.75px, 363.75px);
417     transform: translate(363.75px, 363.75px);
418 }
419 
420 @media screen and (max-width: 525px) {
421     .container {
422         width: 280px;
423         height: 405px;
424     }
425     .header {
426         height: 110px;
427         margin-bottom: 15px;
428     }
429     .game-info {
430         height: 40px;
431     }
432     .game-title {
433         font-size: 50px;
434     }
435     .game-container {
436         width: 280px;
437         height: 280px;
438         padding: 7px;
439     }
440     .gird-container {
441         width: 266px;
442         height: 266px;
443     }
444     .gird-row {
445         width: 266px;
446         height: 61.25px;
447         margin-bottom: 7px;
448     }
449     .gird-col {
450         width: 61.25px;
451         height: 61.25px;
452         margin-right: 7px;
453     }
454     .tile-container {
455         width: 266px;
456         height: 266px;
457         top: 7px;
458     }
459     .game-over:after {
460         font-size: 40px;
461         height: 70px;
462     }
463     .game-win:after {
464         font-size: 45px;
465         height: 60px;
466     }
467     .game-win-again {
468         width: 130px;
469         height: 40px;
470         bottom: 60px;
471         font-size: 25px;
472     }
473     .game-win-again:after {
474         content: "Continue";
475     }
476     .tile {
477         width: 61.25px;
478         height: 61.25px;
479         line-height: 61.25px;
480         font-size: 35px;
481     }
482     .tile-container .tile-pos-0-1 {
483         -webkit-transform: translate(0, 68.25px);
484         -ms-transform: translate(0, 68.25px);
485         -o-transform: translate(0, 68.25px);
486         transform: translate(0, 68.25px);
487     }
488     .tile-container .tile-pos-0-2 {
489         -webkit-transform: translate(0, 136.5px);
490         -ms-transform: translate(0, 136.5px);
491         -o-transform: translate(0, 136.5px);
492         transform: translate(0, 136.5px);
493     }
494     .tile-container .tile-pos-0-3 {
495         -webkit-transform: translate(0, 204.75px);
496         -ms-transform: translate(0, 204.75px);
497         -o-transform: translate(0, 204.75px);
498         transform: translate(0, 204.75px);
499     }
500     .tile-container .tile-pos-1-0 {
501         -webkit-transform: translate(68.25px, 0);
502         -ms-transform: translate(68.25px, 0);
503         -o-transform: translate(68.25px, 0);
504         transform: translate(68.25px, 0);
505     }
506     .tile-container .tile-pos-1-1 {
507         -webkit-transform: translate(68.25px, 68.25px);
508         -ms-transform: translate(68.25px, 68.25px);
509         -o-transform: translate(68.25px, 68.25px);
510         transform: translate(68.25px, 68.25px);
511     }
512     .tile-container .tile-pos-1-2 {
513         -webkit-transform: translate(68.25px, 136.5px);
514         -ms-transform: translate(68.25px, 136.5px);
515         -o-transform: translate(68.25px, 136.5px);
516         transform: translate(68.25px, 136.5px);
517     }
518     .tile-container .tile-pos-1-3 {
519         -webkit-transform: translate(68.25px, 204.75px);
520         -ms-transform: translate(68.25px, 204.75px);
521         -o-transform: translate(68.25px, 204.75px);
522         transform: translate(68.25px, 204.75px);
523     }
524     .tile-container .tile-pos-2-0 {
525         -webkit-transform: translate(136.5px, 0);
526         -ms-transform: translate(136.5px, 0);
527         -o-transform: translate(136.5px, 0);
528         transform: translate(136.5px, 0);
529     }
530     .tile-container .tile-pos-2-1 {
531         -webkit-transform: translate(136.5px, 68.25px);
532         -ms-transform: translate(136.5px, 68.25px);
533         -o-transform: translate(136.5px, 68.25px);
534         transform: translate(136.5px, 68.25px);
535     }
536     .tile-container .tile-pos-2-2 {
537         -webkit-transform: translate(136.5px, 136.5px);
538         -ms-transform: translate(136.5px, 136.5px);
539         -o-transform: translate(136.5px, 136.5px);
540         transform: translate(136.5px, 136.5px);
541     }
542     .tile-container .tile-pos-2-3 {
543         -webkit-transform: translate(136.5px, 204.75px);
544         -ms-transform: translate(136.5px, 204.75px);
545         -o-transform: translate(136.5px, 204.75px);
546         transform: translate(136.5px, 204.75px);
547     }
548     .tile-container .tile-pos-3-0 {
549         -webkit-transform: translate(204.75px, 0);
550         -ms-transform: translate(204.75px, 0);
551         -o-transform: translate(204.75px, 0);
552         transform: translate(204.75px, 0);
553     }
554     .tile-container .tile-pos-3-1 {
555         -webkit-transform: translate(204.75px, 68.25px);
556         -ms-transform: translate(204.75px, 68.25px);
557         -o-transform: translate(204.75px, 68.25px);
558         transform: translate(204.75px, 68.25px);
559     }
560     .tile-container .tile-pos-3-2 {
561         -webkit-transform: translate(204.75px, 136.5px);
562         -ms-transform: translate(204.75px, 136.5px);
563         -o-transform: translate(204.75px, 136.5px);
564         transform: translate(204.75px, 136.5px);
565     }
566     .tile-container .tile-pos-3-3 {
567         -webkit-transform: translate(204.75px, 204.75px);
568         -ms-transform: translate(204.75px, 204.75px);
569         -o-transform: translate(204.75px, 204.75px);
570         transform: translate(204.75px, 204.75px);
571     }
572 }