LearningNote
[오토핫키] 반복문(2) 본문
반복문과 조건문은 함께 다닐 때가 많습니다.
반복 중에 특정한 조건이 충족되면 그 루프를 빠져나가게끔 하는 거죠.
조건문에 대해 배울 때 숫자 맞히기 게임을 예로 들어 보겠습니다.
반복문을 배우지 않았을 때는,
응답을 하면 그 숫자가 맞았는지 틀렸는지 메시지를 띄운 다음,
곧바로 종료하게끔 코드를 작성했습니다.
반복문을 조합하면,
정답이 아닌 경우 계속에서 숫자를 입력할 수 있는 창을 띄워주고,
정답을 맞혔을 경우에만 반복문을 빠져나가 종료하도록 만들 수 있습니다.
그 예제를 해볼게요.
그전에, 먼저 루프를 빠져나가는 방법을 알아야겠죠.
그 명령어는 간단합니다.
break [, LoopLabel]
LoopLabel 은 생략이 가능하며,
사용할 일은 거의 없으니 모르셔도 무방합니다.
LoopLabel 인자를 생략한다면 현재 속한 반복문을 빠져나갑니다.
다음의 예제를 통해 감을 잡아 보세요.
!4::
Loop, 5
{
MsgBox, %A_Index% 번째 반복입니다.
if (A_Index > 2) {
MsgBox, 반복문을 중지합니다.
break
}
}
return
A_Index 는 전에 말씀드린 것처럼,
AutoHotkey 내장 변수로써 몇 번째 반복인지를 담고 있습니다.
반복이 2 보다 커지는 경우
반복문을 중지하고 루프를 빠져나가겠군요.
감을 좀 잡으셨나요?
감은 왜 항상 나무 높은 곳에 달려 있는지,
사실 그래서 감 잡기가 쉽지는 않더라고요.
이제 숫자 맞히기 게임에 반복문을 입혀 보겠습니다.
틀리면 다시 도전,
맞으면 종료합니다.
다음의 예제를 따라 하기 전에 조건문에서 작성했던 숫자 맞히기 게임 소스 코드를,
하나 복사한 후 직접 수정해보세요. 그러면서 실력이 많이 늘거든요.
!5::
correctAnswer := 5
Loop
{
InputBox, answer, 숫자 맞히기 게임, 1에서 10까지의 숫자를 입력하세요.
if (answer < 1 or answer > 10) {
MsgBox, 1에서 10까지의 숫자를 입력하세요.
} else if (answer < correctAnswer) {
MsgBox, 정답은 더 큰 수입니다.
} else if (answer > correctAnswer) {
MsgBox, 정답은 더 작은 수입니다.
} else {
MsgBox, 정답입니다.
break
}
}
return
정답인 경우에만 break 명령어로 Loop 를 빠져나가면 됩니다.
다양한 형태의 오답과 정답을 입력해가며 테스트해보세요.
반복문은 조건문과 마찬가지로 여러 개를 중첩해서 사용할 수 있습니다.
반복문 안에 또 반복문을 쓸 수 있는 것이죠.
대표적으로 구구단을 예로 들 수 있습니다.
말이 나온 김에 이중 루프를 이용해서 구구단을 한번 만들어볼게요.
구구단은 이런 식으로 진행됩니다. 맞나요?
2 x 1 = 2
2 x 2 = 4
. . .
. . .
. . .
2 x 9 = 18
3 x 1 = 3
3 x 2 = 6
. . .
. . .
. . .
3 x 9 = 27
. . .
. . .
. . .
좌변을 살펴보면,
뒤의 숫자가 1부터 9까지 반복적으로 증가하고,
그다음에는 앞의 숫자가 2부터 9까지 반복적으로 증가합니다.
값이 변한다는 뜻은 변수를 써야 한다는 뜻이라고 말씀드렸습니다.
두 군데가 변하므로 간단하게 변수 두 개를 쓰면 되겠습니다.
그런데 그냥 변하는 것이 아니라 1이라는 일정한 값이 반복적으로 증가되며 변하는군요.
이럴 때는 반복문을 쓰면 되겠네, 하고 생각하시면 됩니다.
일단 다음의 코드를 작성하면서 로직과 저의 의도를 이해하려 해 보세요.
메모장을 띄우고 실행도 한번 해보세요.
나머지는 그 이후에 마저 설명드릴게요.
!6::
Loop, 9
{
a := A_Index
if (a == 1) {
continue
}
Loop, 9
{
b := A_Index
SendInput, % a " x " b " = " a * b "`n"
}
SendInput, `n
}
return
다른 명령어는 다 배웠는데,
딱 한 가지 처음 보는 게 있네요.
바로 continue 입니다.
break 가 루프문을 완전히 빠져나가는 명령어라면,
continue 는 이 명령어 아랫부분은 넘어가되,
루프를 빠져나가지 않고 다음으로 이어가는 명령어입니다.
좀 전에 보여드렸던 예제를 보시면,
a 값이 1 이면 continue 명령어를 만나서,
그 아래에 있는 Loop 문과 SendInput 을 수행하지 않고 넘어갑니다.
그러고 나서 루프의 다음으로 이어간다면 a 는 2가 되어 있겠죠.
눈치채셨겠지만, 1단은 무시하고 2단부터 외우기 위해
작성한 코드였습니다.
만약 continue 가 아니라 break 였다면,
그 아래에 있는 명령어들은 모두 무시될 뿐만 아니라,
그 즉시 루프를 빠져나가 아무런 결과를 내지 않고 끝날 것입니다.
백문이 불여일견!
continue 로도 실행해보시고,
break 로 고쳐서도 실행해보세요.
그 차이를 확실히 알 수 있습니다.
SendInput, % a " x " b " = " a * b "`n"
이 부분은 아직 문법에 익숙하지 않으시다면,
다소 복잡하게 느끼실 수도 있습니다.
실행 결과를 같이 보면서 이해해보세요.
2 x 1 = 2
2 x 2 = 4
. . .
. . .
. . .
9 x 9 = 81
SendInput 과 첫 번째 인자 사이에 콤마와 퍼센트(%) 기호가 있으므로
뒤쪽은 모두 표현식 형태로 인식됩니다.
가장 앞에 있는 a 는 변수의 값이 들어가야 하므로
큰따옴표 없이 작성했습니다.
곱하기 기호는 'x' 를 그대로 출력해야 하므로,
큰따옴표로 감싸고 'x' 를 작성했습니다.
b 는 a 와 마찬가지로 변수의 값이 들어가야 하므로
큰따옴표 없이 작성했습니다.
등호 기호는 '=' 를 그대로 출력해야 하므로,
큰따옴표로 감싸고 '=' 를 작성했습니다.
우변은 a 와 b 의 곱셈 연산 결과를 출력해야 합니다.
따라서 a 와 b 의 연산 결과를 가져오기 위해
큰따옴표 없이 a 와 b, 그리고 곱셈 연산자를 작성했습니다.
구구단을 외울 때마다 아래로 줄을 내리기 위해
개행문자(`n) 를 넣었습니다.
안쪽의 루프가 끝나면,
1부터 9까지 반복이 끝났다는 뜻이며,
구구단의 단 하나가 끝났다는 의미입니다.
그래서 이 때는 개행문자(`n) 를 넣어 한 줄을 더 띄워줍니다.
A_Index 는 해당 루프가 몇 번 돌았는지를 알려줍니다.
루프가 두 개라면 각각의 A_Index 가 존재하겠네요.
그런데, 안쪽의 루프에서 바깥쪽 루프의 A_Index 값을 가져오려면 어떻게 해야 할까요?
둘 다 변수명이 A_Index 라면 구분할 수가 없을 것입니다.
따라서 A_Index 를 각각 a 와 b 라는 서로 다른 변수에 넣어두고,
어떤 걸 출력하고 싶은지 컴퓨터에게 알려주었습니다.
다시 코드를 살펴보세요.
이제 모든 코드가 이해되셨나요?
아직 안 되셨다면, 설명을 다시 읽어보시고
또다시 코드를 반복해서 살펴보세요.
반복문은 매우 중요합니다.
반복문 전체 예제 코드를 보면서
반복문을 반복 학습해보세요.
#SingleInstance, Force
F4::
ExitApp
!1::
Loop
{
MsgBox, 무한 반복 중입니다.
}
return
!2::
i := 1
Loop, 5
{
MsgBox, %i% 번째 반복입니다.
i := i + 1
}
return
!3::
Loop, 5
{
MsgBox, %A_Index% 번째 반복입니다.
}
return
!4::
Loop, 5
{
MsgBox, %A_Index% 번째 반복입니다.
if (A_Index > 2) {
MsgBox, 반복문을 중지합니다.
break
}
}
return
!5::
correctAnswer := 5
Loop
{
InputBox, answer, 숫자 맞히기 게임, 1에서 10까지의 숫자를 입력하세요.
if (answer < 1 or answer > 10) {
MsgBox, 1에서 10까지의 숫자를 입력하세요.
} else if (answer < correctAnswer) {
MsgBox, 정답은 더 큰 수입니다.
} else if (answer > correctAnswer) {
MsgBox, 정답은 더 작은 수입니다.
} else {
MsgBox, 정답입니다.
break
}
}
return
!6::
Loop, 9
{
a := A_Index
if (a == 1) {
continue
}
Loop, 9
{
b := A_Index
SendInput, % a " x " b " = " a * b "`n"
}
SendInput, `n
}
return
'오토핫키' 카테고리의 다른 글
[오토핫키] 이미지 서치(2) (0) | 2020.07.20 |
---|---|
[오토핫키] 이미지 서치(1) (0) | 2020.07.16 |
[오토핫키] 반복문(1) (0) | 2020.07.10 |
[오토핫키] 조건문(2) (0) | 2020.07.08 |
[오토핫키] 조건문(1) (0) | 2020.07.07 |