while 루프는 조건이 false 가 될 때까지 구문을 수행한다.
이러한 루프는 첫번째 반복이 시작되기 전에 반복 횟수를 알 수 없을 때 가장 잘 사용된다.
Swift는 두 종류의 while 루프를 제공한다.
while 루프는 단일 조건의 평가로 시작한다.
조건이 true이면, 조건이 false가 될 때까지 구문을 반복한다.
while 루프의 기본 형식
while <#condition#> {
<#statements#>
}
이 예제는 Snakes and Ladders (또는 Chutes and Ladders) 게임을 플레이한다.

게임의 규칙은 아래와 같다.
게임 보드는 Int 값의 배열로 표현된다.
크기는 finalSquare 라는 상수를 기반으로 하며 배열을 초기화하고 나중에 예제에서 승리 조건을 확인하는데 사용된다.
"정사각형 0"에서 플레이어는 시작하기 때문에 보드는 0 Int 값을 포함하여 25가 아닌 26의 크기로 초기화 됩니다.
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
정사각형 3은 정사각형 11로 이동하는 사다리 바닥이 포함된다.
이것을 표현하기 위해 board[03] 은 정수값 8 (3 과 11 의 차이)과 동등한 +08 을 대입한다.
값과 구문을 정렬하기 위해 단항 덧셈 연산자 (+i) / 단항 빼기 연산자 (-i)를 명시적으로 사용하고 10보다 작은 숫자의 앞에 0을 채운다(두 스타일 모두 꼭 필요한 것은 아니지만 코드가 깔끔해 집니다).
var square = 0
var diceRoll = 0
while square < finalSquare {
// roll the dice
diceRoll += 1
if diceRoll == 7 { diceRoll = 1 }
// move by the rolled amount
square += diceRoll
if square < board.count {
// if we're still on the board, move up or down for a snake or a ladder
square += board[square]
}
}
print("Game over!")
위의 예는 주사위 굴리기에 매우 간단한 접근 방식을 사용한다.
난수를 생성하는 대신에 diceRoll 은 0 의 값으로 시작한다.
매 while 루프를 실행할 때 마다 diceRoll 은 1씩 증가하고 너무 커졌는지 확인한다.
반환된 값이 7 과 같을 때마다 주사위 굴림이 너무 커지므로 값을 1 로 재설정한다.
그 결과 diceRoll 값은 항상 1, 2, 3, 4, 5, 6, 1, 2 등과 같이 시퀀스이다.
주사위를 굴리고 난 후에 플레이어는 diceRoll 정사각형으로 앞으로 이동한다.
주사위 굴림이 플레이어를 정사각 25를 넘어 이동할 수 있으며 이럴 경우 게임이 끝난다.
이 시나리오에 대처하기 위해 board 배열의 count 프로퍼티가 square 보다 작은지 확인한다.
square 가 유효하다면 board[square] 에 저장된 값은 현재 square 값이 추가되어 플레이어를 이동시킨다.
Note:
확인을 수행하지 않으면 board[square] 는 board 배열의 범위를 넘는 값을 접근하려 시도할 수 있다. 이런 경우 런타임 에러가 발생한다.
현재 while 루프의 실행이 끝나면 루프를 다시 실행해야 되는지 알기 위해 조건을 확인한다.
플레이어가 정사각형 숫자 25 에 위치하거나 넘으면 루프 조건은 false 가 되고 게임은 종료된다.
while 루프가 시작될 때 게임의 길이가 명확하지 않으므로 이러한 경우 while 루프가 적절하다.
대신에 루프는 특정 조건이 만족할 때까지 실행된다.
while 루프의 다른 하나는 루프의 조건을 판단하기 전에 루프 블럭을 처음에 한 번 먼저 통과하는 repeat-while 루프가 있다.
조건이 false가 될 때 까지 루프를 반복한다.
Swift의 repeat-while 루프는 다른 언어의 do-while 루프와 유사하다.
repeat-while 루프의 일반적인 형식
repeat {
<#statements#>
} while <#condition#>
Snakes and Ladders 예제에서는 while 루프보다 repeat-while 루프를 쓰는 것이 더 좋다.
finalSquare, board, square, diceRoll 의 값은 while 루프에서와 같은 방식으로 초기화된다.
let finalSquare = 25
var board = [Int](repeating: 0, count: finalSquare + 1)
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
var square = 0
var diceRoll = 0
이 게임의 버전에서는 루프에서 첫번째 행동은 사다리 또는 뱀인지 확인한다.
보드에 사다리가 없으면 플레이어는 바로 정사각형 25로 이동하게 되고 사다리를 위로 이동하여 게임에서 이길 수 없다.
따라서 루프의 첫번째 동작으로 뱀 또는 사다리를 확인하는 것이 안전하다.
게임을 시작할 때 플레이어는 "정사각형 0"에 있다.
board[0]은 항상 0과 같으며 영향이 없다.
repeat {
// move up or down for a snake or ladder
square += board[square]
// roll the dice
diceRoll += 1
if diceRoll == 7 { diceRoll = 1 }
// move by the rolled amount
square += diceRoll
} while square < finalSquare
print("Game over!")
뱀과 사다리를 코드가 확인 후 주사위를 굴리고 플레이어를 diceRoll 정사각형에 따라 앞으로 이동한다.
그러면 현재 루프는 종료된다.
루프의 조건 (while square < finalSquare)은 이전과 같지만 루프를 통과하는 첫번째 실행의 끝까지는 동일하지 않다.
이전 예제의 while 루프보다 이 게임에서는 repeat-while 루프가 더 적합하다.
위의 repeat-while 루프에서 square += board[square] 는 루프의 while 조건이 square 가 항상 보드 위에 있는 것을 확인 한 직후에 실행된다.
이 동작은 이전 예제에서의 while 루프 버전처럼 배열의 범위를 체크할 필요가 없다.