按照自己的理解用js實現八皇后的算法

八皇后規則:任意兩個棋子都不能處於同一行、同一列或同一斜線上

 分析:(下面 將要放的棋子用a表示,已經放下的棋子用b表示)

  一、橫軸不重複

            橫軸不重複,也就是說水平方向只能有一個棋子 :所以我們可以採取一行一行放,這樣一定是不重複的

  二、縱軸不重複 

           縱軸不重複,也就是說垂直方向只能有一個棋子。那麼,放下的棋子(這裏用a表示)與已經放下的棋子(這裏用b表示)兩者               的y軸相比,不相等說明豎着沒有重複

  三、斜着不重複 

           斜着不重複,每條斜線只能有一個棋子。這個實際上比較的是a到b的水平方向和a到b的垂直方向相等就是斜向(相當於ab爲邊長的正方形的對角線),最終用公式表示:ax-bx = ay-by 只要保證ax-bx 不等於 ay-by 就可以了

 

下面代碼演示:


 先實現2,3步 的函數,用一個數組arr表示已經放入的所有棋子,將要放的棋子爲a,如果條件符合爲true,反之爲false。

const arr = []
function fn (ax, ay) {
  for (let i = 1; i < ax; i++) {
    if (ay === arr[i-1].y || Math.abs(ax - arr[i-1].x) === Math.abs(ay - arr[i-1].y)) return false
  }
  return true
}

 其次,實現按行嘗試放棋子 row:將要放的第幾行  n:能放置的行數與列數
 

const n = 8
function ab (row) {
  if (row > n) console.log(arr.map(item => item.y)) // 這裏的n是行
  for (let i = 1; i <= n; i++) {                     // 這裏的n是列
    // 若是第一個棋子直接進入下一行
    if (row === 1 || fn(row, i)) {
      arr[row-1] = {x: row, y: i}
      ab(row + 1)
    }
  }
}

最後,執行

ab(1)

結果,92種

遊戲玩完了。現在說一下解決的這種算法:回溯算法

回溯算法

https://baike.baidu.com/item/%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95/9258495?fr=aladdin

百度百科這麼解釋:

回溯算法實際上一個類似枚舉的搜索嘗試過程,主要是在搜索嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就“回溯”返回,嘗試別的路徑。回溯法是一種選優搜索法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術爲回溯法,而滿足回溯條件的某個狀態的點稱爲“回溯點”。

上面八皇后的遊戲就是如此,一行一行,一列一列的嘗試放下棋子,當符合條件就嘗試去下一行放下棋子,反之,嘗試放下當前行的下一列繼續嘗試!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章