摘要:還在上班很無聊數字華容道暢玩地址開發源碼地址這個叫前言年末了。光隨機生成一個亂序數列是不夠的,還得保證這個數列的逆序數為偶數,嗦嘎。所以,我們直接將交換的次數,記為數列逆序數個數,就達到了想要的效果。
還在上班?很無聊?數字華容道暢玩地址
開發源碼地址
這個叫前言年末了。哦,不,要過年了。以前只能一路站到公司的我,今早居然是坐著過來的。新的一年,總要學一個新東西來迎接新的未來吧,所以選擇了一直未碰的那個據說是全宇宙最牛逼的前端框架-React,在上下班的地鐵上看了兩天官方教程,so what。光看不練假把式,于是就想著做個什么,偶然看到一個妹妹發了一條關于玩數字華容道,根本停不下來的朋友圈,這游戲我在今年的最強大腦看過,但是就看兩小天才在滑呀滑呀滑,感覺還不錯,程序猿就該多玩益智類,少玩什么跳一跳。于是去商店下了個,玩著還行,就是廣告太多,而且只能玩五階以下的,看起不難,一個想法涌于腦上,何不拿這練練手做個Demo,畢竟我們屬于智慧家族的。閑話扯完,進入正題。本文包含但不僅包括以下內容:
Demo 開發環境
數字華容道里的秘密
講一講里面算法的實現
React的使用感受及易錯點
Demo 開發環境React:16.2.0
react-router-dom:4.2.2
webpack:3.8.1
JS:ES6
CSS:Scss
React教程
項目目錄結構(很適合React入門 如果感覺不錯,請留下你的star):如下圖所示
項目目錄結構
數字華容道里在外國被稱為puzzle,譯為數字推盤,最經典的就是puzzle15的高價懸賞13 15 14局面的解。怎么玩,一圖勝千言,簡單來說就是講左圖的亂選狀態,滑成右圖所示的順序狀態。個人感覺和小時候玩的推箱子有點類似。
clipboard.png
你不知道的秘密其實寫完Demo的隨機序列頁面生成和操作交互就用了一個周天和一個周一晚上,但到現在線上這個樣子,又多用了三四個晚上(白天上班,晚上學習,這就是前端的日常),為什么?因為當時基礎版部署到線上,讓女朋友試一把,結果玩個三階的,都兩分鐘了還在折騰(我最快是18秒還原),怎么這么笨,于是搶過來,搗騰,再搗騰,怎么回事,感覺無解啊,于是去百度了一下,在知乎里看到了這個問題,還真的有無解的情況,問題地址。看圖,后面還要講(敲黑板)
clipboard.png
噢,原來是醬紫。光隨機生成一個亂序數列是不夠的,還得保證這個數列的逆序數為偶數,嗦嘎。于是在隨機序列的生成中又多加一個過程,判斷序列逆序數奇偶性,并調整。早上地鐵上自己又不斷玩玩測試,三階ok,四階ok,五階ok,然后又一遍,一遍。原以為這樣就大功告成了,但是出現了這樣的畫面。有圖。誰剛說的四階ok。。。。于是又測試了多次,發現三階,五階確實ok,但四階確實有Bug。Why,后面自己每開一局,截一張圖,無解的,標記下來,下面就是幾張立功的圖片。
立了大功的幾張圖
下午年會,領導上面講,自己下面睡。睡得天昏地暗,時過境遷,居然還在叨叨叨,自己就拿起酒店提供的紙和筆找這些數字間的秘密。首先,這幾組數字都是偶逆序列,前一晚寫的調整奇逆序列為偶逆序列的代碼是沒有問題的,那問題出在哪了。抓腦摳鼻,抖腳搖頭,那一組圖片來回翻閱,靈光一閃,水哥附身,原來是這樣:空格項都出現在第三行,哦,不,應該是奇數行。為什么呢?又去百度,又看到了上面知乎和豆瓣的正經說瞎話的大神(此生最討此類人,害死個仙人),看到這,我開始懷疑,這句話的正確性。奇數階,格子上下左右移動確實不會改變數列的逆序奇偶性。但偶數階,格子的上下移動是會改變序列的奇偶性的,簡單總結一下:
奇數階(3x3,5x5):上移或下移一個數字,其調換的位置是偶數,所以不改變數列逆序數的奇偶性,所以奇數階,生成的初始隨機數列的逆序數必須為偶數;
偶數階(4x4,6x6):上移或下移一個數字,其調換的位置是奇數,所以會改變數列逆序數的奇偶性,上下交換一次改變一次奇偶性,交換兩次就回到初始狀態。所以可以大致這樣理解,偶數的平方仍然為偶數,其有數字的滑塊個數為奇數個,所以有一個數字必然會和空滑塊產生位置交換,如果空滑塊位于奇數行(空滑塊是不參于數字序列的逆序數計算的),就會產生2n-1次交換,其會改變數列逆序數的奇偶性;而位于偶數行,就會產生2n次交換,不會改變數列逆序數的奇偶性,所以用一個公式總結就是:(數列初始狀態是否為偶數) === (空行是否為偶數),簡單來講就是求這兩個數的異或。最后的代碼流程的實現
clipboard.png
方法有很多,但我知道的兩種,這里分享一下,有知道其他的,請留言做個評論,讓大家一起進步。
順序數組隨機性調換
思路基本就是,先生成一個順序的1~n的順序數組,然后再通過一個1~n的循環來打亂這個數組,其時間復雜度是O(n)。代碼如下。
export const disorganize = (length) => { const arr = []; let temp; for (var i = 1; i < length; i++) { arr.push(i); } for (i = 0; i < length; i++) { let random = Math.round(Math.random() * (length - 2)); temp = arr[random]; arr[random] = arr[i]; arr[i] = temp; } return arr; };
隨機數生成亂序數組
生成一個隨機數,并判斷其是否在目標數組中已存在,當數組個數為n時,目的達到。其時間復雜度我不知,代碼如下:
export const randomArr = (length) => { const arr = []; let temp; while(arr.length<(length-1)){ let random = 1+Math.round(Math.random() * (length - 2)); if(random雖然代碼看起比上面的簡單,但其時間復雜度最由是O(f(n),最差情況未知,所以,方法一更推薦,如果說的有什么毛病,還請及時指出。
數列逆序性的奇偶性判斷最先想到的就是冒泡排序,因為冒泡排序過程就是判斷兩個數是否逆序,是,就交換,不是,繼續下一組判斷。所以,我們直接將交換的次數,記為數列逆序數個數,就達到了想要的效果。當然這個題用其他排序方法也能達到目的,理解了其排序的原理,就很容易計算數列的逆序性,我這里是直接用的以前冒泡排序的算法。
const bubbleOrder=(arr)=>{ let i ,j ,count=0; const swap=(tar,lastIndex,newIndex)=>{ let temp = tar[lastIndex]; tar[lastIndex] =tar[newIndex]; tar[newIndex] = temp; count++; } for(i=0;ii;j--){ (arr[j] JS寫一個秒表 秒表是啥,start-pause-stop-reset,中間的步驟不是必須的,但前后兩步必須。當然方法有很多,但都離不開setTimeout或則setInterval兩個方法,requestAnimation應該也可以。這里提供一個自己寫的,當然思路來源于網上,只是用自己的思路表達出來。基于setInterval和Date對象。源碼如下:
const timer=(offsetTime)=>{ //offsetTime為0時,表示從0開始計,不為0,表示是暫停后繼續計時 const formatter=(t)=>{ const res =t>9 ? t : "0"+t return res; } let startTime = new Date().getTime(),tPass=0,tOffset=offsetTime||0; this.interId = setInterval(()=> { //this.interId 是組件下面建的一個保持定時器值的,用于暫停和停止 let tNew = new Date().getTime(),ms,sec,min,timeStr; tPass = tOffset +tNew - startTime; ms = Math.floor(tPass/10 % 100); sec = Math.floor((tPass / 1000) % 60); min = Math.floor((tPass / 1000 / 60) % 60); timeStr = formatter(min)+":"+formatter(sec)+":"+formatter(ms); this.tick(timeStr,tPass); },100) } tick(timeStr,tPass){ //這是游戲頁面一個react組件中的一個用于更新顯示dom的觸發器 this.setState({ timePass:tPass, time:timeStr }) }React的使用感受及易錯點(大神留步)用Vue與用React的區別,抱頭痛哭,Vue半年沒上項目了,忘得差不多了,個人觀點(非喜勿噴)。
直接感受就是,Vue確實比React容易上手,其模板,js,css的組件式的開發方式,更接近我們以前工作中常用的template + requireJs的開發模式。
React更強調js的編程和項目的整體架構,state放在哪一級,哪一級通過props來控制,當然route 4.0的組件化設計更強調這一點;
React在國內還是不像Vue那么大眾,比方說,出了問題,很多只有在stackOverflow有相關答案;
不過,不論是Vue還是React,熟悉ES6和面向對象的編程,兩者上手都是很快的(裝個逼,別打我)。
在整個學習過程中,將很多教程中敲黑板指出來的坑,又結結實實踩了一遍,現在可以說影響深刻。自己整理了一下,做個小分享,愿和我一樣剛入門的,遇見下面的錯誤,不會那么迷茫
Cannot read property "setState" of undefined"
不要在解釋:這個問題,主要是組件對象的構造constructor中,未在constructor綁定事件處理函數的this指向。這個在教程中是有明確說明的,解決辦法就是constructor()中添加:this.resetClick = this.resetClick.bind(this);
Cannot read property "size" of undefined"
clipboard.png解釋:這個問題,主要是組件對象的構造constructor中,未傳入props對象,導致整個組件對象無props屬性;其實除了理解繼承,理解React組件的生命周期也很重要。
clipboard.png
you are adding a new property in the Synthetic event Object解釋:可以簡單理解為SyntheticEvent是react為瀏覽器兼容寫的一個dom事件代理,除了她原有的那些屬性,你不能私自為其添加屬性。
iphone,元素滑動,頁面會跟隨滑動
clipboard.png
clipboard.png這個真的是一個讓人頭疼的東西,太影響交互體驗了。如果做過h5都知道加滑動阻止.而react有他自己的一套事件機制封裝,所以在跟元素直接添加touchmove的preventDefault是不行的。得用最原始的事件寫法寫一個阻止滑動的觸摸事件,如下所示。
componentDidMount() { document.addEventListener("touchmove", (e) => { e.preventDefault(); }, { passive: false }); }``` ### 其他,后面持續補充 ### ## 一個疑問 ## 一開始我的游戲盒子是用的flex布局,但一考慮,盒子里面的方塊要滑動效果,我要做滑動的緩動效果,于是又改用了絕對定位布局,每個 方塊計算其定位點。但事實證明,我當時確實太菜,我用了state來管理每個方塊在盒子的位置,但我調整state時,React的virtualDom 會自動計算,并更新dom節點,那我保持整個項目,怎么才能自己做出緩動效果呢?純CSS不行,請各位大神給點建議。 ## 結束語 ## 在放假的前幾個小時,把拖了幾天的文章寫完,有點趕,有不足的地方還請及時指出。關于這個項目,后期自己想繼續優化,做一些功能拓展,比如接入數據記錄,NxM階這樣的玩法,有思路的,還請能分享給我,郵箱:closertb@163.com。在最后,送給2017未曾放棄努力的自己一些鼓勵,愿2018年能用更好的發展。也祝各位戰友2018新年快樂,年后再見!!!!! [1]: http://closertb.site/Klotski/#/ [2]: https://github.com/closertb/firstRect [3]: https://doc.react-china.org/docs/hello-world.html [4]: https://www.zhihu.com/question/266065256/ [5]: https://user-gold-cdn.xitu.io/2018/2/13/1618cb629aace0d9?w=796&h=360&f=png&s=53732 [6]: https://user-gold-cdn.xitu.io/2018/2/13/1618cb629ab569ec?w=711&h=628&f=png&s=71949 [7]: https://user-gold-cdn.xitu.io/2018/2/13/1618cb62a7e093f4?w=800&h=286&f=png&s=75406 [8]: https://user-gold-cdn.xitu.io/2018/2/13/1618cb629ac112bc?w=737&h=274&f=png&s=16593 [9]: https://user-gold-cdn.xitu.io/2018/2/13/1618d487f446f29f?w=792&h=64&f=png&s=34023 [10]: https://user-gold-cdn.xitu.io/2018/2/13/1618cb629d17bc25?w=800&h=166&f=png&s=71885 [11]: https://user-gold-cdn.xitu.io/2018/2/13/1618d487f004387d?w=800&h=234&f=png&s=114244 [12]: https://user-gold-cdn.xitu.io/2018/2/13/1618deda973d9c73?w=800&h=121&f=png&s=85783 [17]: https://m.douban.com/mip/group/topic/21451258/?qq-pf-to=pcqq.c2c [18]: https://user-gold-cdn.xitu.io/2018/2/13/1618dfabca309cb6?w=800&h=404&f=png&s=39405 [19]: https://juejin.im/entry/587de1b32f301e0057a28897
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/107487.html
摘要:本文從底層原理到實際應用詳細介紹了中的變量和類型相關知識。內存空間又被分為兩種,棧內存與堆內存。一個值能作為對象屬性的標識符這是該數據類型僅有的目的。 導讀 變量和類型是學習JavaScript最先接觸到的東西,但是往往看起來最簡單的東西往往還隱藏著很多你不了解、或者容易犯錯的知識,比如下面幾個問題: JavaScript中的變量在內存中的具體存儲形式是什么? 0.1+0.2為什...
摘要:華容道游戲看似簡單,但求解需要設計的數據結構比較復雜,還牽涉到棋類游戲的棋局判斷,所以整個過程還是挺費勁的。 此為《算法的樂趣》讀書筆記,我用javascript(ES6)重新實現算法。 華容道游戲看似簡單,但求解需要設計的數據結構比較復雜,還牽涉到棋類游戲的棋局判斷,所以整個過程還是挺費勁的。我盡量用面向對象的思想來進行封裝,整個過程將分成幾個部分記錄下來,今天是最后一部分,棋局的廣...
摘要:請記住,這些書中的一些可能不是最新的,但概念和基礎仍應適用。是最好的老師之一。的秘密由部分組成。在你完成這些書后,查看書籍和最好的本土書籍。 我看過三本,第1本,第二本,第四本。第一本買的的實體書,其他兩本看的是電子書。第一本是大名鼎鼎老道寫的,書很薄,但是非常經典。javascirpt忍者秘籍是jquery的作者寫的,也是非常經典。you dont kown js系列也是非常好。看了...
閱讀 2839·2021-09-28 09:45
閱讀 1511·2021-09-26 10:13
閱讀 908·2021-09-04 16:45
閱讀 3669·2021-08-18 10:21
閱讀 1094·2019-08-29 15:07
閱讀 2638·2019-08-29 14:10
閱讀 3151·2019-08-29 13:02
閱讀 2468·2019-08-29 12:31