본문 바로가기
Programming/LOGO

LOGO : 변수(Variables) - 013 - FullHouse

by The Programmer 2024. 6. 9.

1. Introduction

 

이 예제는 여러 집을 한 줄로 이어서 그립니다. 이 예제는 로고 워크샵에 게시된 FMSLogo 공식 예제로 기본기에 충실하고 제 눈에는 매우 이뻐(?) 보여서 소개합니다. 약간 수정한 것입니다. 이 예제를 확장 응용하여 컬러풀 타운을 만들어보면 좋겠습니다. 예제 이름은 제 마음대로 붙였습니다.

 

이하 코드는 파라미터 변수, Repeat 반복문 등을 사용하며, 대문자, 비축약 형태의 원래 명령어 코드 스타일로 작성되었습니다. 편리함 때문에 축약 스타일에 더 익숙하겠지만, 이렇게도 할 수 있습니다. 참고.

 

[ 그림 13 - 0. FullHouse ]

 

2. Code

 

▶ 코드는 '더보기' 클릭.

더보기

;; 13-1. FullHouse

 

TO DRAW
  HOUSEROW
  HT
END

TO HOUSE :SIZE
  ; draw the house
  RECTANGLE (10 * :SIZE) (10 * :SIZE)

  ; draw the roof
  FORWARD  10 * :SIZE
  TRIANGLE 10 * :SIZE
  BACK     10 * :SIZE

  ; draw the door
  RIGHT     90
  FORWARD   6 * :SIZE
  LEFT      180
  RECTANGLE (2 * :SIZE) (4 * :SIZE)
  BACK      4 * :SIZE
  RIGHT     90
END

TO HOUSEROW
  REPEAT 24 [ HOUSE RANDOM 9 ]
END

TO MAIN
  ;; 로고 워크샵에 흥미로운 예제가 있어서 가져왔습니다. 출처
  ;; 약간 수정한 것입니다.
  SETUP
  DRAW
END

TO RECTANGLE :HEIGHT :WIDTH
  REPEAT 2 [
    FORWARD :HEIGHT
    RIGHT   90
    FORWARD :WIDTH
    RIGHT   90
  ]
END

TO SETUP
  WINDOW HOME CS PPT PD ST
  PU LT 90 FD 470 RT 90 PD
END

TO TRIANGLE :LENGTH
  RIGHT 45
  FORWARD :LENGTH * (SQRT 2) / 2
  RIGHT 90
  FORWARD :LENGTH * (SQRT 2) / 2
  RIGHT 135
  FORWARD :LENGTH
  RIGHT 90
END

 

 

 

3. Result

 

[ 예제 13 - 1. FullHouse ]

 

 

4. Notes

 

이 예제는 여러 집을 한 줄로 이어서 그립니다. 이 예제는 로고 워크샵에 게시된 FMSLogo 공식 예제로 기본기에 충실하고 제 눈에는 매우 이뻐(?) 보여서 소개합니다. 소스 코드 원본을 약간 수정했습니다.

 

파라미터 변수를 어떻게 만들고 사용하는지 이 예제를 통해서 익숙해지면 좋겠습니다.

 

랜덤 사용법도 중요.

RANDOM number RANDOM 10 Returns a random number from 0 to 9

 

TO HOUSEROW
    REPEAT 24 [ HOUSE RANDOM 9 ]     
END

 

;; 여기서 RANDOM 9은 HOUSE 함수의 파라미터 변수로 사용됩니다. House :SIZE의 :SIZE 값으로 사용됨.

 

1) SQRT는 루트(root)값을 구하는 LOGO 내장함수입니다. root는 제곱의 반대 개념에 해당한다고 할 수 있습니다. 2의 제곱이 4라면, 루트 4는 2를 의미합니다. 단, +2, -2 모두 해당 ( 2 * 2 = 4, -2 * -2 = 4 ). 그러므로 'SQRT 4'는 루트 4를 의미하고 루트 4는 수학적으로 +2 또는 -2를 의미합니다.

 

지붕을 이루고 있는 삼각형과 하우스 몸통을 이루고 있는 사각형과 한 변의 크기를 일치시켜야 하기 때문에 약간의 비법이 필요합니다. :LENGTH를 기준으로. 

 

지붕 삼각형 중 바닥 한 변의 길이 그리기 : 

 FORWARD :LENGTH

 

지붕 삼각형 윗 부분 그리기 :

FORWARD :LENGTH * (SQRT 2) / 2

 

아, 이건 또 뭔가요? 루트 2를 2로 나누는 것인가요? 이게 왜 필요하죠? ^.^;;;;

(SQRT 2) / 2

 

 

5. 응용 연습

 

1) 응용 연습 과제 1 : House 지붕을 컬러 색상으로 칠하여 컬러링 예제로 쓰면 좋겠습니다. 

 

2) 응용 연습 과제 2 : 한 줄로 이어진 하우스... 에서 여러 줄로 뉴타운을 건설하면 어떨까요?

 

3) 할 수 있다면 Python으로 다시 만들어 볼 수도 있겠습니다. ^.^;

 

 

5-1. 컬러 지붕 예제 -  1 단계 : 시간 지연 추가

 

지붕을 이루고 있는 삼각형 모양이 어떻게 그려지는지 시각적으로 이해하고자 할 때 Wait 명령어를 추가하여 삼각형 지붕이 그려지는 속도를 느리게 할 수 있습니다. 다음 처럼 필요한 곳에 Wait 60을 추가하면 됩니다. 이때 60은 1초를 의미합니다. 2초는 60 * 2 = 120, Wait 120 하면 2초 느리게 만듭니다. 그러므로 Wait 뒤에 오는 숫자는 60분의 1초(= 1/60 초)를 의미합니다.

 

TO HOUSE :SIZE
 ; draw the house
  RECTANGLE (10 * :SIZE) (10 * :SIZE)

  ; draw the roof
  FORWARD  10 * :SIZE WAIT 60
  TRIANGLE 10 * :SIZE
  BACK     10 * :SIZE

  ; draw the door
  RIGHT     90
  FORWARD   6 * :SIZE
  LEFT      180
  RECTANGLE (2 * :SIZE) (4 * :SIZE)
  BACK      4 * :SIZE
  RIGHT     90
END

 

 

필요한 곳 모든 곳에 추가해서 이런 저런 테스트를 수행하는 데에 사용할 수 있습니다. 그럼 이제 삼각형 지붕 부분에 추가해 보겠습니다. 지연 시간값을 늘려서 필요한 곳 어디든 추가하면 됩니다.

 

TO TRIANGLE :LENGTH
  RIGHT 45
  FORWARD :LENGTH * (SQRT 2) / 2
  WAIT 60    ;; 1초
  RIGHT 90
  FORWARD :LENGTH * (SQRT 2) / 2
  WAIT 240    ;; 4초
  RIGHT 135
  FORWARD :LENGTH
  RIGHT 90
  WAIT 300    ;; 5초
END

 

 

5-2. 컬러 지붕 예제 -  2 단계 : 리스트 확실하게 이해하기

 

컬러링은 삼각형 지붕 그리기 함수가 끝나면 추가하거나 삼각형 지붕이 완성되자마자 그 함수 내부 끝부분에 이어서 추가할 수 있습니다.

 

지난 예제에서 랜덤으로 면 색상을 칠하는 부분을 가져와서 참고하도록 합니다.

 

to setBoxColor1
    make "cR random 256    ;; 0~255 사이의 아무 값이나 뽑아서 cR 변수에 저장합니다. 나머지도 거의 비슷합니다.
    make "cG random 256    ;; 주의. 256은 포함되지 않습니다.
    make "cB random 256
    make "myList (List :cR :cG :cB)
    setFC :myList
end

 

 

◈  약간의 도움말이 필요해 보입니다.     

 

# (List  :cR  :cG  :cB)

이 부분은 일단 괄호가 없다고 생각해봅니다. 그럼 다음처럼 됩니다. List는 리스트 뒤에 제공되는 목록 데이터들을 이용해서 리스트 한 덩어리를 만들어 달라는 명령어입니다.

 

List  :cR  :cG  :cB

 

예를 들어 세 변수  :cR, :cG, :cB 변수에 각각 1, 2, 3이 저장되어 있다고 가정해보겠습니다. 그럼 

 

List  :cR  :cG  :cB 이 명령문은 최종적으로 다음과 같은 리스트를 만들어 냅니다. 

 

[  1     2     3  ]

 

LOGO 언어에서 리스트는 대괄호( [  .... ] )로 표현합니다.

 

참고. 1
소괄호(( ))
중괄호({ })
대괄호([ ])
겹화살괄호(《 》)
홑화살괄호(〈 〉)
겹낫표(『 』)
홑낫표(「 」)

 

 

List 명령어 뒤에 오는 내용들이 List로 만들어집니다. List는 목록의 일종입니다. 그 목록을 리스트라고 합니다. 목록은 하나의 덩어리로 취급됩니다. 그러므로 변수를 만들 때 사용될 수 있습니다.

 

make    "A               B

make    "myList    (List :cR :cG :cB)

 

변수 myList에는 목록이 저장됩니다. 그런데 이 목록은 평범한 목록이 아니라 랜덤으로 0~255 사이의 값 아무거나로 결정된 목록이 저장됩니다. 

 

변수 :cR 에도 아무값

변수 :cG 에도 아무값

변수 :cB 에도 아무값

 

... 이 저장됩니다.

 

(단, 0~255 사이의 아무값만 허용됩니다. 컴퓨터가 알아서 아무거나 서로 다르게 골라줍니다. 이것이 랜덤 선택 방식이라는 것입니다.)

 

세 변수  :cR, :cG, :cB 변수에 각각 120, 225, 62가 저장되어 있다고 가정해보겠습니다. 그럼 List  :cR  :cG  :cB 이 명령문은 최종적으로 다음과 같은 리스트를 만들어 냅니다. 리스트는 이렇게 생겼습니다. ^.^;

 

[  120     225     62  ]

 

아래 세 문장은 사실상의 문장 형식이 서로 동일합니다. 변수를 만드는 일반 규칙을 따르고 있습니다.

 

make    "A               B

make    "myList    (List :cR :cG :cB)

make    "myList    120     225     62  ]

 

 

5-3. 컬러 지붕 예제 -  3 단계 : 실제로 색상 칠하기

색상을 랜덤으로 결정하는 방법을 살펴보았으니 색을 칠하는 부분을 살펴보겠습니다.

 

역시 이전 예제를 참고해서. 중요한 부분은 빨강색으로 강조된 부분 딱 한 줄입니다. 다른 줄은 건너뛰기. ^.^;

 

to box256 :num
    repeat 256 [ 
        box1 :side1 
        moveIn rt 90 setBoxColor1 Fill lt 90 moveOut    ;; 여기 이 부분!!

        move1
        print repCount   ;; Check repCount Number
        if ((modulo repCount :num) = 0) [
            gotoNextLine
        ]
    ]
end

 

 

다음 부분만 필요합니다.

 

moveIn rt 90 setBoxColor1 Fill lt 90 moveOut    

 

setBoxColor1함수는 색상을 결정하고 Fill은 실제로 색상을 칠합니다. 함수 이름은 내용에 맞게 수정하면 되겠죠? 삼각형 지붕 그리기 코드 부분을 다시 가져와보겠습니다.

 

TO TRIANGLE :LENGTH
  RIGHT 45
  FORWARD :LENGTH * (SQRT 2) / 2
  WAIT 60
  RIGHT 90
  FORWARD :LENGTH * (SQRT 2) / 2
  WAIT 60
  RIGHT 135
  FORWARD :LENGTH
  RIGHT 90
  WAIT 60
END

 

내용이 아니라 코드 모양만 약간 수정해보겠습니다.

 

TO TRIANGLE :LENGTH
  RIGHT  45   FORWARD  :LENGTH  *  (SQRT 2)  /  2  WAIT 60    ;; 지붕 꼭대기 왼쪽
  RIGHT  90   FORWARD  :LENGTH  *  (SQRT 2)  /  2  WAIT 60   ;; 지붕 꼭대기 오른쪽. 이 지붕은 직각 삼각형!이군요.
  RIGHT 135  FORWARD  :LENGTH    ;; 지붕 아래쪽. 여기서 사실상 삼각형 구성이 끝납니다.
  RIGHT 90  WAIT 60
END

 

함수 내 3행에서 사실상 삼각형이 완성됩니다. 이 부분.

RIGHT 135  FORWARD  :LENGTH

 

그렇지만 그 다음 줄에 있는 RIGHT 90까지 포함, 기존 코드를 최소 수정하는 방향으로 진행합니다.

Wait 60 코드들은 이제 필요가 없으므로 전부 삭제합니다.

 

TO TRIANGLE :LENGTH
  RIGHT  45   FORWARD  :LENGTH  *  (SQRT 2)  /  2
  RIGHT  90   FORWARD  :LENGTH  *  (SQRT 2)  /  2   ;; 이 지붕은 직각 삼각형!이군요.
  RIGHT 135  FORWARD  :LENGTH    ;; 여기서 사실상 삼각형 구성이 끝납니다.
  RIGHT 90

  ;; 여기에 컬러링 코드를 추가합니다.
END

 

컬러링 코드가 추가되면 삼각형 지붕을 그릴 때마다 랜덤 컬러로 지붕이 칠해질 것입니다. 아마도! ^.^;

moveIn 함수와 moveOut 함수도 필요합니다.

 

moveIn rt 90 setBoxColor1 Fill lt 90 moveOut

 

자 그럼 정리해보겠습니다. 색상 결정은 Coloring1 함수로, 실제 색상 칠하기는 Fill로.

 

to Coloring1
    make "cR random 256 
    make "cG random 256 
    make "cB random 256
    make "myList (List :cR :cG :cB)
    setFC :myList
end

 

TO TRIANGLE :LENGTH
  RIGHT  45   FORWARD  :LENGTH  *  (SQRT 2)  /  2
  RIGHT  90   FORWARD  :LENGTH  *  (SQRT 2)  /  2   ;; 이 지붕은 직각 삼각형!이군요.
  RIGHT 135  FORWARD  :LENGTH    ;; 여기서 사실상 삼각형 구성이 끝납니다.
  RIGHT 90

  moveIn   Coloring1    Fill   moveOut    ;; 실제로는 한 칸씩만 띄어쓰기.

END

 

 

moveIn 함수와 moveOut 함수를 추가합니다. 직각 삼각형 모양인 것을 반드시 고려해서!

삼각형 지붕 함수 끝에 있는 RIGHT 90 덕분에 거북이는 하늘을 보고 있는 상태. RT 45~ 90도 사이만 허용.

 

TO moveIn

    PU RT 75 FD 5 PD     

END

 

순서만 바꾸고 거의 같은 방식으로,  

 

TO moveOut

    PU BK 5 LT 75 PD     

END

 

이게 그럼 완성인가요?

 

5-4. 컬러 지붕 예제 -  4 단계 : 전체 코드

전체 코드는 다음과 같습니다.

 

▶ 코드는 '더보기' 클릭.

더보기

;; 5-4. 컬러 지붕 예제 -  4 단계 : 전체 코드

 

TO DRAW
  HOUSEROW
  HT
END

TO HOUSE :SIZE
  ; draw the house
  RECTANGLE (10 * :SIZE) (10 * :SIZE)

  ; draw the roof
  FORWARD  10 * :SIZE
  TRIANGLE 10 * :SIZE
  BACK     10 * :SIZE

  ; draw the door
  RIGHT     90
  FORWARD   6 * :SIZE
  LEFT      180
  RECTANGLE (2 * :SIZE) (4 * :SIZE)
  BACK      4 * :SIZE
  RIGHT     90
END

TO HOUSEROW
  REPEAT 24 [ HOUSE RANDOM 9 ]
END

TO MAIN
  ;; 로고 워크샵에 흥미로운 예제가 있어서 가져왔습니다. 출처
  ;; 약간 수정한 것입니다.
  SETUP
  DRAW
END

TO RECTANGLE :HEIGHT :WIDTH
  REPEAT 2 [
    FORWARD :HEIGHT
    RIGHT   90
    FORWARD :WIDTH
    RIGHT   90
  ]
END

TO SETUP
  WINDOW HOME CS PPT PD ST
  PU LT 90 FD 470 RT 90 PD
END

TO TRIANGLE :LENGTH
  RIGHT 45
  FORWARD :LENGTH * (SQRT 2) / 2
  RIGHT 90
  FORWARD :LENGTH * (SQRT 2) / 2
  RIGHT 135
  FORWARD :LENGTH
  RIGHT 90

  moveIn   Coloring1    Fill   moveOut    ;; 실제로는 한 칸씩만 띄어쓰기.
END

 

to Coloring1
    make "cR random 256 
    make "cG random 256 
    make "cB random 256
    make "myList (List :cR :cG :cB)
    setFC :myList
end

 

TO moveIn

    PU RT 75 FD 3 PD

    ;; 지붕의 크기가 대략 3보다 작으면 배경에 색이 칠해지는 버그있음.
    ;; 배경색이 있어도 나쁘지 않아 이대로 패스.
END

 

TO moveOut

    PU BK 3 LT 75 PD

;; moveIn 함수와 값 일치시켜야 함.

END

 

 

5-5. 컬러 지붕 예제 결과 !

 

실행할 때마다 바뀜. 랜덤의 힘!

 

[ 그림 5-5. 컬러 지붕 예제 결과 1 ]

 

 

[ 그림 5-5. 컬러 지붕 예제 결과 2 ]

 

 

[ 그림 5-5. 컬러 지붕 예제 결과 3 ]

 

5-6. 컬러풀 뉴타운 건설 !

헥헥.. 

컬러 지붕 뉴타운을 건설해보겠습니다.

절대좌표를 사용해서 상대적으로 쉬운 방법으로 해결. ㅡ.ㅡ;

 

▶ 코드는 '더보기' 클릭.

더보기

;; 5-6 컬러풀 뉴타운

 

to Coloring1
    make "cR random 256 
    make "cG random 256 
    make "cB random 256
    make "myList (List :cR :cG :cB)
    setFC :myList
end

TO DRAW
  repeat 4 [ 
    HOUSEROW
    pu setx -470  back 130 pd
  ]
  HT
END

TO HOUSE :SIZE
  ; BASE VALUE Added.
  if (:SIZE < 4) [
    MAKE "SIZE :SIZE + :BASE
  ]

  ; draw the house
  RECTANGLE (10 * :SIZE) (10 * :SIZE)

  ; draw the roof, 좌하단에서 시작해서.
  FORWARD  (10 * :SIZE)    
; 지붕 위치로 올라가고
  TRIANGLE (10 * :SIZE)
  BACK     (10 * :SIZE)   
 ; 출발 지점으로 복귀.

  ; draw the door
  RIGHT     90
  FORWARD   (6 * :SIZE)
  LEFT      180
  RECTANGLE (2 * :SIZE) (4 * :SIZE)
  BACK      (4 * :SIZE)
  RIGHT     90
END

TO HOUSEROW
  REPEAT 24 [ HOUSE RANDOM 9 ]
END

TO MAIN
  ;; 로고 워크샵에 흥미로운 예제가 있어서 가져왔습니다. 출처
  ;; 약간 수정한 것입니다.

  SETUP
  DRAW
END

TO moveIn 
    PU RT 75 FD 3 PD
    ;; 지붕의 크기가 대략 3보다 작으면 배경에 색이 칠해지는 버그있음.
    ;; 배경색이 있어도 나쁘지 않아 이대로 패스.

END

TO moveOut
    PU BK 3 LT 75 PD
;; moveIn 함수와 값 일치시켜야 함.
END

TO RECTANGLE :HEIGHT :WIDTH
  REPEAT 2 [
    FORWARD :HEIGHT
    RIGHT   90
    FORWARD :WIDTH
    RIGHT   90
  ]
END

TO SETUP
  WINDOW HOME CS PPT PD ST
  PU setx -470 sety 150 PD   

  ; 음수값과 양수값이 사용되는 이유는 가운데가 좌표 원점(0, 0). 우상단이 1 사분면, (+, +).
  MAKE "BASE 3
END

TO TRIANGLE :LENGTH
  RIGHT 45
  FORWARD (:LENGTH * (SQRT 2) / 2)
  RIGHT 90
  FORWARD (:LENGTH * (SQRT 2) / 2)
  RIGHT 135
  FORWARD :LENGTH
  RIGHT 90
  moveIn Coloring1 Fill moveOut    
;; 실제로는 한 칸씩만 띄어쓰기.
END


 

결과 화면은 여기에.

 

[ 그림. 5-6. 컬러풀 뉴타운 건설 ]

 

 

절대좌푯값을 사용하지 않으려면, 랜덤값을 추적해야 하고, 좀 더 복잡해져서 이 예제에서는 패스합니다. 절대좌푯값 사용은 장단점이 있습니다.

^.^;

 

6. Bug Report !

 

▣ 버그 

 

1) 최소 크기 버그 : 삼각형 모양 지붕의 크기가 랜덤값으로 결정되면 값의 범위가 문제의 원인이 될 수도 있습니다. 3 이하일 때, 버그 방어해야.

 

 

▣  Solution :

 

1) 한 변의 길이를 결정할 때 if 문을 도입하여 일정 크기 이하라면 한 변의 길이에 최소 기본값 5 혹은 10 을 더하고나서 그리게 하면  랜덤값이 0이나 1이어도 최소한의 크기로 그리게 하면 될 듯.

 

2) if 문 도입 없이, 아예 처음부터 모든 도형의 한 변의 길이 기본값이 5 혹은 10 이상이 되도록 처음부터 정해놓고 그리기.

 

먼저, SETUP 함수 끝에 BASE 변수값을 지정해줍니다.

 

TO SETUP
  WINDOW HOME CS PPT PD ST
  PU LT 90 FD 470 RT 90 PD
  MAKE "BASE 3
END

 

 

위 BASE 변수값을 이용해서 HOUSE 함수도 if 문을 추가하고 아래와 같이 수정합니다.

 

TO HOUSE :SIZE

 ; BASE VALUE Added.
  if (:SIZE < 4) [
    MAKE "SIZE :SIZE + :BASE
  ]

.

.

 

나머지 코드는 동일합니다. 이제 실행 테스트.

 

위 코드 추가 수정으로 버그가 현저하게 줄어든 모습을 볼 수 있습니다.

 

 

7. Files

 

Houserow_Ex_001_.lgo
0.00MB

 

Houserow_Ex_002_Color_Roof_001_.lgo
0.00MB

 

Houserow_Ex_002_Color_Roof_002_.lgo
0.00MB

 

Houserow_Ex_003_Color_Roof_Town_001_.lgo
0.00MB

 

 

8. Reference

 

1) FMSLogo download | SourceForge.net

 

FMSLogo

Download FMSLogo for free. A Logo programming environment for Microsoft Windows. A Logo programming environment for Microsoft Windows operating systems. FMSLogo (contrasted with other Logo dialects) has an easy-to-use GUI that encourages learning, especial

sourceforge.net

 

2) Logo Workshop Homepage (sourceforge.io) 

 

Logo Workshop Homepage

 

fmslogo.sourceforge.io

 

3) FMSLogo 자체 도움말. setx, sety.

 

 

즐거운 프로그래밍!

 

^.^;