連連看算法
第一步:我們考慮在同行或者同列的情況:
同行或者同列又分三種情況:
第一:邊線,RowNum或者ColNum等於0或者9
第二:兩個相鄰
第三:同行不相鄰,這種事有條件的,所在行(或列)的上下(或左右)緊鄰行必須在兩個按鈕之間已全部消除?好,有出問題了,怎么根據已知的行和列,獲取Button是否被消除呢?我們可以
定義一個Button的二維數組。並在初始化的時候給它賦值
MyButton[,] maps=new MyButton[10,10];
maps[i, j] = btn;
好,怎么獲取Button是否隱藏已經解決。
同行步相鄰的又分是從上側、右側和中間連。
第二步:既不同行又不同列的要考慮的更多,東西南北都要考慮到了,而連連看的規則是最多轉兩個彎,
好了不說了直接上代碼了:算法可以自己慢慢琢磨(如果想要最優算法你可以考慮研究下最短路徑算法)
private bool Check(MyButton btn1, MyButton btn2) { for (int c = 0; c < 10; c++) { if (c != btn1.ColNum && !(btn1.RowNum == btn2.RowNum && btn1.ColNum == c) && maps[btn1.RowNum, c].Visibility == Visibility.Visible) //不為A和B的障礙 continue; if (!IsLine(btn1.RowNum, btn2.RowNum, btn1.RowNum, c)) //Aa continue; for (int c2 = 0; c2 < 10; c2++) { if (c2 != btn2.ColNum && !(btn1.RowNum == btn2.RowNum && btn1.ColNum == c2) && maps[btn2.RowNum, c2].Visibility == Visibility.Visible) continue; if (!IsLine(btn1.RowNum, c, btn1.RowNum, c2)) //ab continue; if (!IsLine(btn2.RowNum, c2, btn2.RowNum, btn2.ColNum)) //bB continue; return true; } for (int r = 0; r < 10; r++) { if (r != btn2.RowNum && !(r == btn1.RowNum && btn2.ColNum == btn1.ColNum) && maps[r, btn2.ColNum].Visibility == Visibility.Visible) continue; if (!IsLine(btn1.RowNum, c, r, btn2.ColNum)) //ab continue; if (!IsLine(r, btn2.ColNum, btn2.RowNum, btn2.ColNum)) //bB continue; return true; } } for (int r = 0; r < 10; r++) { if (r != btn1.RowNum && !(r == btn2.RowNum && btn1.ColNum == btn2.ColNum) && maps[r, btn1.RowNum].Visibility == Visibility.Visible) //不為A和B的障礙 continue; if (!IsLine(btn1.RowNum, btn1.ColNum, r, btn1.ColNum)) //Aa continue; for (int c2 = 0; c2 < 10; c2++) { if (c2 != btn2.ColNum && maps[btn2.RowNum, c2].Visibility == Visibility.Visible) continue; if (!IsLine(r, btn1.RowNum, btn2.RowNum, c2)) //ab continue; if (!IsLine(btn2.RowNum, c2, btn2.RowNum, btn2.ColNum)) //bB continue; return true; } for (int r2 = 0; r2 < 10; r2++) { if (r2 != btn2.RowNum && !(r2 == btn1.RowNum && btn2.ColNum == btn1.ColNum) && maps[r2, btn2.ColNum].Visibility == Visibility.Visible) continue; if (!IsLine(r, btn1.ColNum, r2, btn2.ColNum)) //ab continue; if (!IsLine(r2, btn2.ColNum, btn2.RowNum, btn2.ColNum)) //bB continue; return true; } } return false; } private bool IsLine(int r1, int c1, int r2, int c2) { int max, min; if (r1 == r2) //同行 { max = ((c1 > c2) ? c1 : c2) - 1; min = ((c1 > c2) ? c2 : c1) + 1; while (min <= max) { if (maps[r1, min].Visibility == Visibility.Visible) return false; min++; } return true; } if (c1 == c2) //同列 { max = ((r1 > r2) ? r1 : r2) - 1; min = ((r1 > r2) ? r2 : r1) + 1; while (min <= max) { if (maps[min, c1].Visibility == Visibility.Visible) return false; min++; } return true; } return false; }
第三步:上面我們完成了算法,也就是我們基本可以玩了。但是玩的過程我們又發現了新問題,
我們沒有保證每個圖像都是偶數個,如圖:
這個問題要從初始化的時候着手,我們現在要做一百個背景,那么我們先做50個,然后再分別從這個50個中取出
代碼如下:
public List<int> Get() { Random rand = new Random(); List<int> ran = new List<int>(); for (int n = 0; n < 50; n++) ran.Add(rand.Next(1, 10)); for (int i = 1; i < 50; i++) { List<int> temp = new List<int>(); temp.AddRange(ran); for (int n = 0; n < 50; n++) { int r = rand.Next(0, temp.Count); ran.Insert(rand.Next(0, ran.Count), temp[r]); temp.RemoveAt(r); } } return ran; }
這種思路應該是對的,但是沒有達到預期的效果,還是會有剩下,由於缺少時間,可能要過一段時間來弄這個,有
看出問題的高手可以幫我留言,我會爭取早點解決問題的。
我下一步准備是將動畫連線與倒計時加上,這可能要等一段時間了。下面是我在網上找的一段練練看算法,希望
能給大家一個參考:
public class LineCore { //整體寬度 public int width { get; set; } //整體高度 public int height { get; set; } //前次被點擊的圖片 public Position lastPicture { get; set; } //當前被電擊的圖片 public Position currentPicture { get; set; } // 圖片矩陣,-1表示沒有圖片,初始化時,任意matrix[x,y]當x==0或y==0時,matrix[x,y]=-1 public int[,] matrix { get; set; } public bool testLine(Position current) { //上次連接成功后,第一次點擊, if (currentPicture == null) { currentPicture = current; return false; } //連續點擊了同一幅圖片 if (currentPicture.x==current.x&¤tPicture.y==current.y) { return false; } //不是相同的圖像,不能消除 if (current.picture != currentPicture.picture) { lastPicture = null; currentPicture = current; return false; } lastPicture = currentPicture; currentPicture = current; //記錄連接路徑 List<Position> paths = new List<Position>(); paths.Add(currentPicture); bool finded=false; //向東搜索 finded = _find(paths, 2, Direct.East, lastPicture); if (finded) { return true; } //向南搜索 finded = _find(paths, 2, Direct.South, lastPicture); if (finded) { return true; } //向西搜索 finded = _find(paths, 2, Direct.West, lastPicture); if (finded) { return true; } //向北搜索 finded = _find(paths, 2, Direct.North, lastPicture); if (finded) { return true; } //搜索失敗 return false; } /*** * results-> 搜索路徑 * chance-> 還剩有轉彎的機會,最多2次 * direct-> 當前前進的方向 * target-> 搜索的目標 * **/ protected bool _find(List<Position> results, int chance, Direct direct, Position target) { //路徑中不能為空 if (results.Count <= 0) { return false; } //取路徑中最后一個 Position currentPos = results.ElementAt(results.Count - 1); //構造下一個將要檢測的路徑 Position nextPos = new Position(); switch(direct){ case Direct.East: nextPos.x=currentPos.x+1; nextPos.y=currentPos.y; break; case Direct.West: nextPos.x=currentPos.x-1; nextPos.y=currentPos.y; break; case Direct.South: nextPos.x=currentPos.x; nextPos.y=currentPos.y+1; break; case Direct.North: nextPos.x=currentPos.x; nextPos.y=currentPos.y-1; break; } bool overFlow = false; //檢測是否已經走出邊界 if (nextPos.x < 0 || nextPos.x >= width || nextPos.y < 0 || nextPos.y>=height) { overFlow = true; } if (overFlow) { return false; } //檢測是否是目標 if (target.x == nextPos.x&&target.y==nextPos.y) { results.Add(nextPos); return true; } //不是-1 說明該位置有圖片,不能通過 if (matrix[nextPos.x, nextPos.y]!=-1) { return false; } //加入路徑 results.Add(nextPos); bool find = false; //按照當前方向繼續試探 find = _find(results, chance, direct, target); if (find) { return true; } //轉彎機會已經耗盡 if (chance <= 0) { //此路不通,將路徑最后一個位置刪除 results.RemoveAt(results.Count - 1); return false; } //當前方向向東,還可以轉彎向南,向北繼續試探 if (Direct.East == direct) { find = _find(results, chance-1, Direct.North, target); if (find) { return true; } find = _find(results, chance-1, Direct.South, target); if (find) { return true; } results.RemoveAt(results.Count - 1); return false; } //當前方向向南,還可以轉彎向東,向西繼續試探 else if (Direct.South == direct) { find = _find(results, chance-1, Direct.East, target); if (find) { return true; } find = _find(results, chance-1, Direct.West, target); if (find) { return true; } results.RemoveAt(results.Count - 1); return false; } //當前方向向西,還可以轉彎向南,向北繼續試探 else if (Direct.West == direct) { find = _find(results, chance-1, Direct.North, target); if (find) { return true; } find = _find(results, chance-1, Direct.South, target); if (find) { return true; } results.RemoveAt(results.Count - 1); return false; } //當前方向向北,還可以轉彎向東,向西繼續試探 else { find = _find(results, chance-1, Direct.East, target); if (find) { return true; } find = _find(results, chance-1, Direct.West, target); if (find) { return true; } results.RemoveAt(results.Count - 1); return false; } } //聯通成功后,將兩個位置設置成空 public void onSuccess() { this.matrix[this.lastPicture.x, this.lastPicture.y] = -1; this.matrix[this.currentPicture.x, this.currentPicture.y] = -1; this.currentPicture = null; this.lastPicture = null; } } public class Position { public int x { get; set; } public int y { get; set; } //picture 表示不同圖像,如果是-1,表示為空 public int picture { get; set; } } public enum Direct : int { East = 0, South = 1, West = 2, North = 3 }
請高手多多指正……