반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

LearningNote

[오토핫키] 반복문(2) 본문

오토핫키

[오토핫키] 반복문(2)

LN 2020. 7. 13. 20:47
반응형

반복문과 조건문은 함께 다닐 때가 많습니다.

반복 중에 특정한 조건이 충족되면 그 루프를 빠져나가게끔 하는 거죠.

 

조건문에 대해 배울 때 숫자 맞히기 게임을 예로 들어 보겠습니다.

반복문을 배우지 않았을 때는,

응답을 하면 그 숫자가 맞았는지 틀렸는지 메시지를 띄운 다음,

곧바로 종료하게끔 코드를 작성했습니다.

 

반복문을 조합하면,

정답이 아닌 경우 계속에서 숫자를 입력할 수 있는 창을 띄워주고,

정답을 맞혔을 경우에만 반복문을 빠져나가 종료하도록 만들 수 있습니다.

 

그 예제를 해볼게요.

 

그전에, 먼저 루프를 빠져나가는 방법을 알아야겠죠.

그 명령어는 간단합니다.

 

break [, LoopLabel]

LoopLabel 은 생략이 가능하며,

사용할 일은 거의 없으니 모르셔도 무방합니다.

LoopLabel 인자를 생략한다면 현재 속한 반복문을 빠져나갑니다.

 

다음의 예제를 통해 감을 잡아 보세요.

 

!4::
Loop, 5
{
	MsgBox, %A_Index% 번째 반복입니다.
	
	if (A_Index > 2) {
		MsgBox, 반복문을 중지합니다.
		break
	}
}
return

 

A_Index 는 전에 말씀드린 것처럼,

AutoHotkey 내장 변수로써 몇 번째 반복인지를 담고 있습니다.

 

반복이 2 보다 커지는 경우

반복문을 중지하고 루프를 빠져나가겠군요.

 

break

 

감을 좀 잡으셨나요?

감은 왜 항상 나무 높은 곳에 달려 있는지,

사실 그래서 감 잡기가 쉽지는 않더라고요.

 

이제 숫자 맞히기 게임에 반복문을 입혀 보겠습니다.

틀리면 다시 도전,

맞으면 종료합니다.

 

다음의 예제를 따라 하기 전에 조건문에서 작성했던 숫자 맞히기 게임 소스 코드를,

하나 복사한 후 직접 수정해보세요. 그러면서 실력이 많이 늘거든요.

 

!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
Comments