11일차

Kangdh·2026년 8월 26일

파이썬 교육

목록 보기
12/33

- 예외

예외처리란 에러가 발생했을때 이렇게 해결하라 하면서 프로그램이 갑자기 죽는것을 방지한다.

try,except = try > 뭐뭐를 시도했을때 되지않는다면 except => 이렇게 실행되라 라는 느낌의 코드이다. 이렇게 하면 에러가 발생하지않고 프로그램이 종료된다.
else => if else때와 마찬가지로 ~~가 실행되지 않았을때 실행되는 코드이다.

finally => 에러가 발생해도, 발생하지 않아도 무조건 거치는 구문이다. 만약 try+finally만 사용한다면 에러가 발생한 후 finally 구문까지만 실행되고 프로그램이 죽게 된다.

- random 모듈

랜덤 함수를 사용하기 위해서는 먼저 랜덤 모듈을 임포트 해야한다.(import random)
파이썬에선 난수를 발생시키기 위해 랜덤모듈을 사용한다.

random.random() => 0.0부터 1.0사이의 실수(float)를 반환하는 함수이다. 1.0은 포함하지않고 0.99999...까지만 반환한다.

random.uniform(a,b) => 인자로 들어온 a와 b 사이의 랜덤한 값을 실수로 반환하며 범위는 a와 b를 모두 포함.

random.randint(a,b) => 인자로 들어온 a와 b사이의 랜덤한 정수를 반환한다. 반환하는 값의 범위는 b를 포함한다.

random.randrange() => 두가지 방식으로 사용할 수 있다.

  • randrange(a,b) : a와 b사이의 범위 내에서 랜덤한 정수를 반환한다.
  • randrange(b) : 0부터 b사이의 범위 내에서 랜덤한 정수를 반환한다.
    값에 실수를 넣을 경우 ValueError가 발생.

- set({})

set은 수학의 집합 개념을 구현한, 중복을 허용하지 않고 순서가 없는 데이터의 모음이다.

  • 특징
    중복불가 - 같은 값이 여러 개 있으면 하나만 남고 자동으로 제거됨.
    순서 없음 - 데이터가 입력된 순서를 기억하지 않음.

적 기체와 미슬이 만나면 터지는 기능

강사님이 마지막으로 짜준 코드를 가지고 게임을 실행시켜봤는데 내가 맞추지 않은 기체도 가끔 같이 터져나가는 버그가 존재한다.

몇번 실행을 하면서 가만히 지켜보면서 가설을 세워봤다.

첫번째 - 기존에 있던 기체와 새로 나온 기체의 리스트값이 겹쳐져서 같이 없어지는건가?
Ex) 1,2,3,4번 기체가 각각 다른 x값에서 내려오고 있는데 1번과 4번의 리스트값이 동일하여 1번을 격추했을때 4번도 같이 없어진다.

두번째 - 총알 크기가 커서 주변에 있는 상대 기체까지 맞는건가?
= 총알을 일부러 비껴쏴보면서 테스트 해봤는데 아님.

세번째 - 내려오는 기체들의 y값이 화면 해상도보다 작나?
= 일부러 기체를 흘려보냈지만 화면 끝까지 잘 가는 기체가 있고 아닌 기체가 있음. 하지만 없어진 이후 바로 위에서 기체들이 내려옴 > y값의 문제보다는 리스트가 한번 초기화되고 다시 생성된거같은 느낌의 스폰

네번째 - 미슬이 종종 기체를 뚫고 지나감(관통)
이것도 리스트의 문제라고 생각되는게..원래 의도대로라면 미슬과 기체가 만났을때 미슬과 기체를 각각 삭제할 대상이 들어가는 리스트에 넣고 삭제시켜야 한다. 그런데 기체는 사라지는데 미슬이 남아있다는건 미슬 리스트에서 삭제까지 진행하지 못했다는 뜻으로 생각된다.

라고 생각을 하여 리스트 함수들을 체크해봐야할거같다.

  • 1번 시도
    delete_crash_missile_list.reverse()
    delete_crash_enemy_list.reverse()

두 문장을 삭제하고 실행 > 똑같은 현상이 나옴

  • 2번 시도
    list(set(delete_crash_missile_list))
    list(set(delete_crash_enemy_list))

기체 스폰 사이클을 5번 정도 돌려봤는데 한번에 두 기체가 삭제되는 현상과 미슬이 관통하여 지나가는 문제는 해결된거 같다.
이게 맞다고는 생각된다. 이유는 set을 쓰면 중복된 값은 다 없애버리고 하나만 남아있게되는 중복불가 특성인데 같은 값의 기체가 나와 엉뚱한 기체가 없어지는건 이 특성에 위반되어 없어진것이라 추측한다.
=> 라고 생각했지만, 일정시간동안 하고있으면 게임 자체가 뻗어버리는 문제 발생

  • 3번 시도
    delete_crash_missile_list.reverse()
    delete_crash_enemy_list.reverse()에 .reverse()를 지워서 역행되는 리스트를 다시 정방향으로 가게끔 만들고 게임을 돌려봐도 첫번째 문제는 계속됨

===============================================================================

답안 :
delete_missile_list.reverse() > 삭제
delete_enemy_list.reverse() > 삭제
가 정답이였다.

미슬이 화면밖으로 나갔을때 그 미슬들을 삭제할 미슬 리스트에 넣어둔 뒤 그 미슬들의 순서를 뒤집고 삭제하는 식이였는데 처음 삭제된 delete_missile_list.revsere()에서 적과 미슬이 충돌될때 + 였던 값들이 - 로 역행,두번째 delete_crash_missile_list.reverse()에서 겹치는 값들이 존재하기 시작하여 게임이 실행되는 도중 set에 의해 삭제되는 현상이 발생함.

delete_crash_missile_list로 m(미슬)값이 가기 전 이미 delete_missile_list에서 역행된 결과가 있다. 예를 들면 1,2,3,4,5번의 미사일이 있는데 이를 1회 역행시켜 5,4,3,2,1로 만들고 두번째 _crash_missile_list 에서 다시 1,2,3,4,5로 진행되기에 두 리스트값에 겹치는게 존재, 이 상황이 게임 도중에 발생하고 이 겹친값들이 set의 특성인 중복 불가에 의해 삭제됨.

delete_enemy_list와 delete_crash_enemy_list도 위 미슬과 같은 현상때문에 일어났던 버그라고 생각된다.

강사님 풀이 ===================================================

  • 지우는 기준이 바뀜.
    원래는 몇 번째 칸으로 지웠고(missile_list[d]), 수정본은 그 객체 자체로 지운다(crash_missile_list.remove(m))
  • 원본은 왜 틀렸는가
    해당 객체가 예상한 위치에 없을 수도 있다.
  • 왜 가끔은 멀쩡해보였나
    한 프레임에 딱 하나만 지울 때는 우연히 맞는다. 지울게 하나면 d는 0뿐이다. 이러면 마침 삭제 목록에도 하나만 있으니 결과가 같아진다. 그래서 잘 되는것 같은 상황이 발생
  • 수정본은 왜 잘 되는가
    remove()는 몇 번째를 안 본다. 지워져야 하는 대상 자체를 리스트에서 찾아서 지운다. 어디에 위치해 있는가, 몇 개를 동시에 지워야하는가는 상관이 없어진다.

===============================================================

내가 생각한것과는 꽤 다른 답이였다. 너무 리스트만 신경쓰고 다른쪽 접근은 제대로 못했던거 같다. 혼자 자습하면서 꽤 코드에 대해 공부했다고 생각했는데 아직 부족한 점이 많은거 같다. 계속해서 지금 배우는것도 배우는거고 복습도 꾸준히 해야겠다

0개의 댓글