관리 메뉴

프로그래밍 삽질 중

모두의 파이썬 - Day 16 거북이 대포 게임 만들기 본문

과거 프로그래밍 자료들/python

모두의 파이썬 - Day 16 거북이 대포 게임 만들기

평부 2022. 9. 14. 13:56

 

https://thebook.io/007026/day16/

 

모두의 파이썬: 20일 만에 배우는 프로그래밍 기초(개정판): DAY 16 거북이 대포 게임 만들기

 

thebook.io

 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=python_math&logNo=221214856867 

 

Python 터틀 그래픽 - 제6강 turtle 모듈 명령어 정리

Python 터틀 그래픽 ◈◈ 제6강 turtle 모듈 명령어 정리 ◈◈ 1. python 의 library 중 turtle 그래픽 tu...

blog.naver.com

 

[조건 1]

turn_up/turn_down 함수 : 사용자가 ↑, ↓를 누르면 대포 각도 조절
fire함수 : 사용자가 spacebar를 누르면 작동

거북이 대포를 발사하고 대포가 땅에 닿으면 목표 지점(초록색 표시)을 맞혔는지 
확인하여 문자(닿으면 파랑색 good, 안 닿으면 빨강색 bad) 출력

작동 순서
1. 먼저 화면에 좌표 (-300, 0)에서 (300, 0)인 선을 그림
2. 목표지점을 초록색으로 표시
3. 대포가 조정되고 스페이스바를 누르면 발사
4. 목표지점에 닿았는지 안 닿았는지에 따라 색상을 달리해서 문자로 결과 표시

5. 발사 후 거북이(여기서는 커서처럼 표시됨)가 원래 위치로 돌아올 것

 

 

 

[조건 1 코드]

* t.color ~ t.setheading(ang) 

- 원문에서는 def 함수들 위치에 있으나 들여쓰기로 해야 함(그렇지 않으면 ang가 연결되지 않아서 오류나옴)

import turtle as t
import random


def turn_up():
    t.left(2)  # ↑ 누르면 거북이 왼쪽으로 2도

def turn_down():
    t.right(2)  # ↓ 누르면 거북이 오른쪽으로 2도


def fire():
    ang = t.heading()  # 스페이스바 누르면 발사하도록 각도 기억
    # 거북이가 땅 위에 존재(대포가 날아가는 동안 거북이 대포이 위치와 각도가 계속 변함)
    while t.ycor() > 0:  # "현재" 위치의 y좌표가 0보다 크면
        t.forward(15)  # 15만큼 앞으로 이동
        t.right(5)  # 오른쪽으로 5도

    # 거북이가 땅에 닿았을 때
    d = t.distance(target, 0)  # 현재 위치와 점(target, 0)의 거리 구함
    # 거북이를 x혹은 y좌표를 지정한 위치로 이동(여기서는 y좌표, x는 setx())
    t.sety(random.randint(10, 100))
    if d < 25:  # 거리차이가 25미만이면 명중 성공
        t.color("blue")
        t.write("Good!", False, "center", ("", 15))
    else:
        t.color("red")
        t.write("Bad!", False, "center", ("", 15))

    t.color("black")  # 검은색으로 되돌림
    t.goto(-200, 10)  # 처음 발사한 곳으로 되돌림
    t.setheading(ang) 


# 땅을 그림
t.goto(-300, 0)  # 좌표 (-300, 0)으로 이동
t.down()
t.goto(300, 0)  # 좌표 (300, 0)으로 이동

# 목표지점
target = random.randint(50, 150)  # 50 ~150 사이의 임의의 수 지정
t.pensize(3)
t.color("green")
t.up()
t.goto(target - 25, 2)
t.down()
t.goto(target+25, 2)

# 거북이 처음 발사한 곳으로 되돌림
t.color("black")
t.up()
t.goto(-200, 10)
t.setheading(20)

# 거북이 동작 설정
t.onkeypress(turn_up, "Up")  # ↑ 누르면 turn_up 실행
t.onkeypress(turn_down, "Down")  # ↓ 누르면 turn_down 실행
t.onkeypress(fire, "space")  # space 누르면 fire 함수 실행
t.listen()  # 거북이 그래픽 창이 키보드 입력을 받도록 함
t.mainloop()

 

 

[조건 2]

- 총 5번 시도 후 움직이지 않게 하기

- 총 시도 횟수(sc), 성공 횟수(scGood), 실패 횟수(scBad) 색깔별로 표시 

 

* 오류부분 

▶ 함수 fire에 바로 sc를 넣으니 "UnboundLocalError: local variable 'sc' referenced before assignment" 문제 발생

▶ 해결할 때 도움을 준 글 : https://sikaleo.tistory.com/99

 

python 범위 규칙, 할당, assignment, UnboundLocalError: local variable referenced before assignment

파이썬 namespace 를 공부하다 보면, unboundlocalerror 때문에 혼란이 오게 되는 경우가 있다. 이 포스팅은 그러한 사람들을 위한 포스팅이다. 먼저, 파이썬 네임스페이스에 대한 기본적인 이미지는 아

sikaleo.tistory.com

전역 변수를 참조하여 지역 네임스페이스에 없을 경우, 전역 네임스페이스를 참조해서 처리 

 

 

결과 화면

 

 

[조건 2 코드]

 

import turtle as t
import random


def turn_up():
    t.left(2)  # ↑ 누르면 거북이 왼쪽으로 2도


def turn_down():
    t.right(2)  # ↓ 누르면 거북이 오른쪽으로 2도


def fire():
    ang = t.heading()  # 스페이스바 누르면 발사하도록 각도 기억
    # 거북이가 땅 위에 존재(대포가 날아가는 동안 거북이 대포이 위치와 각도가 계속 변함)
    while t.ycor() > 0:  # "현재" 위치의 y좌표가 0보다 크면
        t.forward(15)  # 15만큼 앞으로 이동
        t.right(5)  # 오른쪽으로 5도
    
    # global로 전역변수 할당
    global sc
    global scGood
    global scBad
    print("inner sc", sc)
    print("inner scBad", scBad)
    print("inner scGood", scGood)
    # 거북이가 땅에 닿았을 때
    d = t.distance(target, 0)  # 현재 위치와 점(target, 0)의 거리 구함
    # 거북이를 x혹은 y좌표를 지정한 위치로 이동(여기서는 y좌표, x는 setx())
    t.sety(random.randint(10, 100))

    if(sc < 5):
        if d < 25:  # 거리차이가 25미만이면 명중 성공
            t.color("blue")
            t.write("Good!", False, "center", ("", 15))
            sc += 1
            scGood += 1
        else:
            t.color("red")
            t.write("Bad!", False, "center", ("", 15))
            sc += 1
            scBad += 1
        t.color("black")  # 검은색으로 되돌림
        t.goto(-200, 10)  # 처음 발사한 곳으로 되돌림
        t.setheading(ang)

    if (sc == 5):
        t.goto(0, -120)
        t.color("black")
        t.write("Done!!", False, "center", ("", 12))
        t.goto(0, -135)
        t.write("총 시도 횟수 : ", False, "center", ("", 12))
        t.goto(50, -135)
        t.write(sc, False, "center", ("", 12))
        t.goto(0, -160)
        t.color("blue")
        t.write("성공한 횟수 : ", False, "center", ("", 12))
        t.goto(50, -160)
        t.write(scGood, False, "center", ("", 12))
        t.goto(0, -180)
        t.color("red")
        t.write("실패한 횟수 : ", False, "center", ("", 12))
        t.goto(50, -180)
        t.write(scBad, False, "center", ("", 12))


sc = 0  # 시도횟수
scGood = 0  # 성공횟수
scBad = 0  # 실패횟수
print("sc", sc)

# 땅을 그림
t.goto(-300, 0)  # 좌표 (-300, 0)으로 이동
t.down()
t.goto(300, 0)  # 좌표 (300, 0)으로 이동

# 목표지점
target = random.randint(50, 150)  # 50 ~150 사이의 임의의 수 지정
t.pensize(3)
t.color("green")
t.up()
t.goto(target - 25, 2)
t.down()
t.goto(target+25, 2)

# 거북이 처음 발사한 곳으로 되돌림
t.color("black")
t.up()
t.goto(-200, 10)
t.setheading(20)

# 거북이 동작 설정
t.onkeypress(turn_up, "Up")  # ↑ 누르면 turn_up 실행
t.onkeypress(turn_down, "Down")  # ↓ 누르면 turn_down 실행
t.onkeypress(fire, "space")  # space 누르면 fire 함수 실행
t.listen()  # 거북이 그래픽 창이 키보드 입력을 받도록 함
t.mainloop()