While 循環(huán)
有時(shí)我們不知道自己想循環(huán)多少次,而是希望當(dāng)某個(gè)條件達(dá)成時(shí)或某個(gè)檢驗(yàn)失敗時(shí)完箩,退出循環(huán)赐俗。這個(gè)時(shí)候就要用while
循環(huán)了。Swift 提供了兩種while
循環(huán):
-
do-while
循環(huán)嗜憔。用日常的語(yǔ)言解釋就是:反復(fù)做這件事秃励,直到那件事失敗了。do-while
總是首先執(zhí)行一遍代碼區(qū)域中的代碼吉捶,然后執(zhí)行條件語(yǔ)句
,如果條件語(yǔ)句為false
就退出皆尔,否則循環(huán)呐舔。 -
while
循環(huán)。while
與do-while
有所不同慷蠕,他會(huì)在執(zhí)行代碼區(qū)域前首先判斷條件語(yǔ)句
珊拼,如果條件語(yǔ)句
是true
那么才執(zhí)行代碼區(qū)域中的代碼,反復(fù)進(jìn)行這個(gè)過程流炕。
While
while
循環(huán)的標(biāo)準(zhǔn)格式如下:
while 條件語(yǔ)句 {
代碼區(qū)域
}
while
循環(huán)首先執(zhí)行條件語(yǔ)句
澎现,如果該語(yǔ)句執(zhí)行的結(jié)果是true
才會(huì)執(zhí)行代碼區(qū)域中的代碼,當(dāng)代碼執(zhí)行結(jié)束每辟,回再次判斷條件語(yǔ)句
剑辫,反復(fù)執(zhí)行該流程。與for
循環(huán)一樣渠欺,條件語(yǔ)句必須返回一個(gè)布爾類型妹蔽,非true
即false
。
我們用小時(shí)候玩的一個(gè)蛇形棋的游戲來(lái)介紹while
循環(huán)挠将。蛇形棋有很多版本胳岂,我們現(xiàn)在玩一個(gè)最簡(jiǎn)單的版本。棋盤是5x5見方的舔稀,我們從棋盤的左下角開始乳丰,按照蛇形的順序,在格子里填上數(shù)字内贮,從1填到25产园。格子上除了有數(shù)字,還可能有梯子贺归。梯子連接了兩個(gè)格子淆两,并且梯子只能沿固定的方向爬。例如我們可以在第3號(hào)格子與第11號(hào)格子建搭建一個(gè)梯子拂酣,要求只能從3爬到11秋冰,而不能從11爬回來(lái)。現(xiàn)在我們就可以玩了婶熬。玩法如下:
- 游戲開始時(shí)剑勾,你把一個(gè)代表你的塑料小人放在1號(hào)格子左側(cè)的桌面上埃撵,這是0號(hào)格子的位置;
- 如果你站在25號(hào)格子虽另,或者除了0號(hào)格子以外的棋盤外暂刘,你就勝利了,否則執(zhí)行后面的步驟捂刺;
- 現(xiàn)在你擲骰子來(lái)獲取一個(gè)[1,6]之間的數(shù)字谣拣;
- 你沿著棋盤上數(shù)字增大的方向前進(jìn)該數(shù)字個(gè)格子,例如你現(xiàn)在在0號(hào)格子族展,擲骰子的數(shù)字是6森缠,那么就前進(jìn)6步,停在6號(hào)格子上仪缸;如果現(xiàn)在在24號(hào)格子贵涵,前進(jìn)6步,就停在30號(hào)格子上恰画,即使這個(gè)格子在棋盤之外宾茂。
- 如果還在棋盤上,看看腳下有沒有梯子拴还,如果有跨晴,就沿著他爬到連接的格子;
- 重復(fù)執(zhí)行第2步自沧。
我們用 Swift 模擬一下這個(gè)游戲坟奥。在此之前,我們先改變一下擲骰子的方式拇厢。每次擲骰子不是隨機(jī)的數(shù)字爱谁,而是當(dāng)前的進(jìn)行的回合數(shù)對(duì)6的余數(shù)加1,這樣可以保證每次的骰子數(shù)都是[1,6]中的一個(gè)孝偎,但不是隨機(jī)的访敌。
我們用數(shù)組表示這個(gè)棋盤,數(shù)組一共有26個(gè)元素衣盾,其中0號(hào)格子在棋盤外面嗡综,而[1,25]都在棋盤上巨双。數(shù)組元素都初始化為0盆赤。
let finalSquare = 25
var board = Int[](count: finalSquare + 1, repeatedValue: 0)
放置了梯子的格子對(duì)應(yīng)的元素值設(shè)置為沿該梯子攀爬時(shí)你需要前進(jìn)或后退的格數(shù)(后退用負(fù)數(shù)表示)从隆。
現(xiàn)在我們?cè)谶@條蛇身上放置一些梯子。首先從3放一個(gè)到11的梯子果复,這意味著當(dāng)你的塑料小人站在第3號(hào)格子時(shí)陈莽,會(huì)爬到11號(hào)格子,也就是前進(jìn)8步,所以給board[3]
賦值為8:
board[3] = 8
然后再放置這些梯子:6->17走搁,9->18独柑,10->12,14->4私植,19->7忌栅,22->20,24->16
board[6] = 11
board[9] = 9
board[10] = 2
board[14] = -10
board[19] = -11
board[22] = -2
board[24] = -9
這樣我們用數(shù)組的下標(biāo)表示格子的編號(hào)曲稼,用數(shù)組元素的值表示梯子指向的格子∷餍鳎現(xiàn)在可以開始玩了:
var square = 0
var turns = 0
while square < finalSquare {
// 擲骰子
var diceRoll = turns % 6 + 1
// 前進(jìn)骰子數(shù)個(gè)格子
square += diceRoll
if square < board.count {
// 如果我們還在棋盤上,沿著梯子爬吧躯肌!
square += board[square]
}
// 回合數(shù)增加1
++turns
}
println("You win after \(turns + 1) turns")
這段代碼會(huì)輸出
You win after 11 turns
Do-While
do-while
與while
不同者春,他總是先執(zhí)行一段代碼然后才判斷條件的合法性。
我們用do-while
來(lái)玩蛇形棋的游戲
let finalSquare = 25
var board = Int[](count: finalSquare + 1, repeatedValue: 0)
board[3] = 8
board[6] = 11
board[9] = 9
board[10] = 2
board[14] = -10
board[19] = -11
board[22] = -2
board[24] = -9
var square = 0
var turns = 0
do {
// 爬梯子
square += board[square]
// 擲骰子
var diceRoll = turns % 6 + 1
// 前進(jìn)骰子數(shù)個(gè)格子清女,在這種寫法中
square += diceRoll
// 回合數(shù)增加1
++turns
} while square < finalSquare
println("You win after \(turns + 1) turns")
這次我們簡(jiǎn)單修改了一下游戲的流程:
- 游戲開始時(shí),你把一個(gè)代表你的塑料小人放在1號(hào)格子左側(cè)的桌面上晰筛,這是0號(hào)格子的位置嫡丙;
- 現(xiàn)在檢查你腳下有沒有梯子,如果有梯子读第,就沿著他爬到連接的格子曙博;
- 然后擲骰子,獲取[1,6]之間的一個(gè)數(shù)字怜瞒;
- 沿著棋盤上數(shù)字增大的方向前進(jìn)該數(shù)字個(gè)格子父泳,例如你現(xiàn)在在0號(hào)格子,擲骰子的數(shù)字是6吴汪,那么就前進(jìn)6步惠窄,停在6號(hào)格子上;如果現(xiàn)在在24號(hào)格子漾橙,前進(jìn)6步杆融,就停在30號(hào)格子上,即使這個(gè)格子在棋盤之外霜运。
- 如果你站在第25號(hào)格子或棋盤外脾歇,你就勝利了,否則重復(fù)執(zhí)行第2步淘捡。