本次講一下數(shù)獨游戲的開發(fā),數(shù)獨游戲是一個填數(shù)字的游戲,在一個9x9的方格內(nèi),這個9x9的大格子又可以分為9個3x3的小的九宮格,在這些格子內(nèi)填寫上1至9的數(shù)字,使得每一行,每一列,并且每個小的九宮格內(nèi)的數(shù)字都不重復,游戲玩法簡單,數(shù)字組合千變?nèi)f化,所以玩起來特別有意思。
在中國數(shù)獨游戲似乎沒那么流行,但是在日本這個游戲非常受歡迎,在通勤的電車上,經(jīng)常能看到一些人一個手拿著一本數(shù)獨游戲的書,另一個手拿著一支鉛筆,就這么一路計算著?,F(xiàn)在我用lufylegend.js引擎來將這款游戲搬到瀏覽器上來,游戲界面如下圖所示。
圖1
游戲分為兩個階段,第一個階段,是比較簡單的玩法,只需要橫,豎,沒有重復的數(shù)字就可以了,另一個高級階段,還需要保證每一個小的九宮格內(nèi)的數(shù)字也不重復。想挑戰(zhàn)一下的朋友,可以點擊下面的游戲鏈接試一下自己能通過幾關(guān)。
http://lufylegend.com/demo/sudoku
和之前的推箱子游戲一樣,一共6關(guān),游戲里也有排名系統(tǒng),每過一關(guān)可以上傳自己的成績,跟大家比拼一下。
下面是我在博客的lufylegend-1.6發(fā)布帖
http://blog.csdn.net/lufy_legend/article/details/8593968
下面一步步來進入開發(fā)正題。
這個游戲,我們首先要解決的就是數(shù)字如何打亂的問題,因為不但要把數(shù)字打亂,還要保證這些數(shù)字被打亂后,依然符合數(shù)獨的規(guī)則,然后在打亂的數(shù)字中隱藏一部分,就可以開始游戲了。
我們先來看一組數(shù)字
圖2
可以看到,在這組數(shù)字中,它的橫,豎列上的數(shù)字都是不重復的。我們?nèi)绾蝸戆阉捻樞虼騺y呢?不難看出,如果我們只把它的每一行打亂,那么它的完整性是不受影響的。同樣,我們只把它的每一列進行打亂,它也是不會受到影響的。所以,要打亂它只需要以行和列為單位進行打亂就行了,算法如下。
function randomNum01(lv){ var i,j,list = new Array(),result = new Array(); for(i=0;i<9;i++){ list.push([1,2,3,4,5,6,7,8,9]); for(j=0;j.5?-1:1;}); var rand = new Array(0,1,2,3,4,5,6,7,8).sort(function(a,b){return Math.random()>.5?-1:1;}); for(i=0;i<9;i++){ for(j=0;j<9;j++){ result[i].push(list[i][rand[j]]); } } for(i=0;i<9;i++){ for(j=0;j>> 0; result[i][ran1] = 0; ran1 = Math.random()*9 >>> 0; result[ran1][i] = 0; } } return result; }
上面的函數(shù),我首先生成了一組有規(guī)律的數(shù)字,然后按照行和咧進行打亂,最后,隨機拿掉一些數(shù)字。
下面再看另一組數(shù)字。
圖3
這種情況下,我們還要保證每個小九宮格內(nèi)的數(shù)字的完整性,又要怎么做呢?在這里我有一種偷懶的算法,看下面的圖4。
圖4
我們將行和列每3個作為一個單位進行打亂,就很簡單的達到了目的了,當然這只是一種偷懶的算法,如果你有更好的算法,歡迎一起討論,我的算法如下。
function randomNum02(lv){ var i,j,k,list = [],result = [],rand; for(i=0;i<9;i++){ list.push([1,2,3,4,5,6,7,8,9]); for(j=0;j.5?-1:1;}).concat( new Array(3,4,5).sort(function(a,b){return Math.random()>.5?-1:1;}), new Array(6,7,8).sort(function(a,b){return Math.random()>.5?-1:1;}) ); for(i=0;i<9 i="" result="" push="" list="" rand="" i="" list="result;" rand="new" array="" 0="" 1="" 2="" sort="" function="" a="" b="" return="" math="" random="">.5?-1:1;}).concat( new Array(3,4,5).sort(function(a,b){return Math.random()>.5?-1:1;}), new Array(6,7,8).sort(function(a,b){return Math.random()>.5?-1:1;}) ); result = []; for(i=0;i<9;i++){ result.push([]); for(j=0;j<9;j++){ result[i].push(list[i][rand[j]]); } } for(i=0;i<9;i++){ for(j=0;j>> 0; result[i][ran1] = 0; ran1 = Math.random()*9 >>> 0; result[ran1][i] = 0; } } return result; }
當玩家將所有被取走的數(shù)字都恢復了之后,就要判斷一下他們填寫的數(shù)字是否正確,是不是符合數(shù)獨的游戲規(guī)則,方法很簡單,就是驗證每一行,每一列,以及高級階段的時候每個九宮格內(nèi)的數(shù)字,是不是沒有重復,下面是代碼
function checkWin(){ var check01,check02; for(var i=0;i<9;i++){ check01 = []; check02 = []; for(var j=0;j<9 j="" if="" stagenumlist="" i="" j="" value=""> 0)check01.push(stageNumList[i][j].value); if(stageNumList[j][i].value > 0)check02.push(stageNumList[j][i].value); } check01 = deleteEleReg(check01); check02 = deleteEleReg(check02); if(check01.length < 9)return false; if(check02.length < 9)return false; } var stage = stageMenu[stageIndex]; if(stage.flag){ return checkWin02(); } return true; } function checkWin02(){ for(var i=0;i<3;i++){ for(var j=0;j<3;j++){ if(!check_mini(i,j))return false; } } return true; } function check_mini(i2,j2){ var check_arr = []; for(var i=i2*3;i<i2*3+3;i++){ for(var j=j2*3;j<j2*3+3;j++){ if(check_arr[stageNumList[i][j].value])return false; check_arr[stageNumList[i][j].value] = 1; } } return true; }
這個游戲很簡單,以上,整個游戲的核心算法都已經(jīng)解決了。
如下。
圖4
上次我也說了,使用lufylegend.js引擎做個界面,可以說毫無難度,代碼如下。
function GameLogo(){ base(this,LSprite,[]); var self = this; var logolist = [[1,1,1,1],[1,2,4,1],[1,4,2,1],[1,1,1,1]]; var bitmap,logoLayer; logoLayer = new LSprite(); bitmap = new LBitmap(new LBitmapData(imglist["logo"])); bitmap.scaleX = bitmap.scaleY = 2; logoLayer.addChild(bitmap); self.addChild(logoLayer); var social = new Social(); social.x = 60; social.y = 500; self.addChild(social); labelText = new LTextField(); labelText.font = "HG行書體"; labelText.size = 14; labelText.x = 50; labelText.y = 650; labelText.text = "- Html5 Game Engine lufylegend.js"; self.addChild(labelText); labelText = new LTextField(); labelText.color = "#006400"; labelText.font = "HG行書體"; labelText.size = 14; labelText.x = 50; labelText.y = 700; labelText.text = "http://www.lufylegend.com/lufylegend"; self.addChild(labelText); self.addEventListener(LMouseEvent.MOUSE_UP,menuShow); };
這一次我用了一張圖片做界面,代碼就更簡單了,文字顯示依然是LTextField對象,使用方法請參考官方API文檔。
如下。
圖5
代碼如下。
function GameMenu(){ base(this,LSprite,[]); var self = this; var menuLayer; menuLayer = new LSprite(); bitmap = new LBitmap(new LBitmapData(imglist["menu_back"])); bitmap.scaleX = bitmap.scaleY = 2; menuLayer.addChild(bitmap); self.addChild(menuLayer); labelText = new LTextField(); labelText.color = "#B22222"; labelText.font = "HG行書體"; labelText.size = 40; labelText.x = 30; labelText.y = 700; labelText.stroke = true; labelText.lineWidth = 4; labelText.text = "Please select !!"; menuLayer.addChild(labelText); for(var i=0;i<stageMenu.length;i++){ self.stageVsMenu(stageMenu[i]); } }; GameMenu.prototype.stageVsMenu = function(obj){ var self = this; var menuButton = new LSprite(); var bitmap = new LBitmap(new LBitmapData(imglist["menu_stage"])); menuButton.addChild(bitmap); menuButton.x = obj.x * 220 + 30; menuButton.y = obj.y * 200 + 50; self.addChild(menuButton); if(obj.open){ labelText = new LTextField(); labelText.color = "#ffffff"; labelText.font = "HG行書體"; labelText.size = 20; labelText.x = 50; labelText.y = 90; menuButton.addChild(labelText) labelText.text = "第"+(obj.index+1)+"關(guān)"; labelText = new LTextField(); labelText.color = "#ffffff"; labelText.font = "HG行書體"; labelText.size = 12; labelText.x = 30; labelText.y = 30; menuButton.addChild(labelText) labelText.text = "times:"+obj.times; menuButton.obj = obj; menuButton.addEventListener(LMouseEvent.MOUSE_UP,function(event,self){ gameStart(self.obj.index); }); }else{ labelText = new LTextField(); labelText.color = "#ffffff"; labelText.font = "HG行書體"; labelText.size = 20; labelText.x = 60; labelText.y = 40; menuButton.addChild(labelText) labelText.text = "???"; }; }
好了,游戲基本的代碼已經(jīng)都貼出來了。
下面提供完整游戲源代碼,想研究一下的朋友可以點擊下面的連接下載。
http://lufylegend.com/lufylegend_download/sudoku.rar
注意:該附件只包含本次文章源碼,lufylegend.js引擎請到http://www.gxlcms.com/進行下載。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com