-
20240524_Playgrounds 값 증가시키기, 포탈 활성화하기, 포탈 비활성화하기개발...................../TIL 2024. 5. 24. 23:11
플레이그라운드의 장점은 문법에 대해 간단한 소개를 하고 실제 예제를 통해 코드를 써볼 수 있기 때문에 이론 공부와 실습을 동시에 할 수 있다는 점입니다. 당분간은 플레이그라운드에서 활용한 함수에 대해 추가적으로 심화 학습을 하는 방식으로 공부를 해보려고 합니다.
값 증가시키기
* 목표 : 변수를 증가시켜 수집한 보석의 개수를 파악하기
** 캐릭터 동선 : 동선을 보시다시피 막다른 곳이 나올 때 방향을 틀어줘야 하고, 보석을 수집한 뒤에 집계까지 할 수 있어야 합니다.
*** 작성한 코드
시도 1 : 모든 미션은 클리어했으나, 게임이 끝나지 않는 오류가 발생했습니다.
while !isBlocked{
moveForward()
if isOnGem{
collectGem()
gemCounter = gemCounter + 1
}
}
while isBlocked{
turnRight()
while !isBlocked{
moveForward()
if isOnGem{
collectGem()
gemCounter = gemCounter + 1
}
}
}문제점
- 내부 while !isBlocked 루프: 외부의 while isBlocked 루프가 조건을 만족하면, 내부의 while !isBlocked 루프가 실행됩니다. 이 내부 루프가 종료되면 다시 외부 루프의 조건을 평가합니다. 만약 다시 isBlocked 상태가 되면, 외부 루프는 계속해서 반복됩니다. 이는 무한 루프를 야기할 수 있습니다.
- 루프 조건의 변경: 내부 루프가 끝나고 외부 루프로 돌아갔을 때, turnRight()가 제대로 방향을 바꾸지 못하거나 장애물 상태가 변경되지 않으면 외부 루프가 계속 반복됩니다.
무한 루프의 원인
- 외부 루프 while isBlocked이 계속해서 실행될 조건이 충족되면 내부 루프 while !isBlocked가 반복되는데, 내부 루프가 끝나고 다시 외부 루프로 돌아갔을 때, isBlocked 조건이 여전히 참이면 외부 루프가 계속 반복됩니다.
- turnRight()가 예상대로 동작하지 않거나, isBlocked 상태가 변경되지 않으면 내부 루프와 외부 루프 사이에서 무한히 반복될 수 있습니다.
시도 2 : 모든 미션을 클리어하고, 게임도 끝났습니다.
while !isBlocked{
moveForward()
if isOnGem{
collectGem()
gemCounter = gemCounter + 1
}
}
turnRight()
while !isBlocked{
moveForward()
if isOnGem{
collectGem()
gemCounter = gemCounter + 1
}
}
turnRight()
while !isBlocked{
moveForward()
if isOnGem{
collectGem()
gemCounter = gemCounter + 1
}
}문제 해결 요약 최대한 간단히 코드를 짜고 싶어서 시도했지만 오류가 나서 문제 해결을 위해 다음과 같이 시도했습니다.
1. 중첩된 while루프 제거 : 첫 번째 코드의 중첩된 while 루프는 조건에 따라 무한 루프에 빠질 수 있는 구조적 문제를 야기하기 때문에 중첩된 루프를 제거했습니다.
2. 명확한 흐름 제어 : 각 구간에서 명확히 방향을 바꾸고 다음 구간으로 이동하는 구조로 변경했습니다.
포털 비활성화하기
* 목표 : 포털을 비활성화하여 스위치에 도달하기
** 캐릭터 동선 : 십자가 모양이면서 하나의 스위치를 활성화 시켰다면, 회전하여 다음 스위치로 이동할 수 있도록 해야 합니다. 포탈이 활성화되어 있으면 다른 포탈로 이동하기 때문에 미션 수행을 위해서 deactivate 해줘야 합니다.
*** 작성한 코드
시도 1 : 성공했지만 반복되는 조건문이 있어서 가독성을 위해 더 나은 작성법이 있어보입니다.
greenPortal.isActive = false
while !isBlocked{
moveForward()
}
if isOnClosedSwitch{
toggleSwitch()
}
turnRight()
turnRight()
moveForward()
moveForward()
moveForward()
turnRight()
moveForward()
moveForward()
moveForward()
if isOnClosedSwitch{
toggleSwitch()
}
turnRight()
turnRight()
while !isBlocked{
moveForward()
}
if isOnClosedSwitch{
toggleSwitch()
}시도 2 : 반복되는 조건문에는 for_in을 활용했더니 해당 액션이 몇번 반복되는지 알아보기 쉬워졌습니다.
greenPortal.isActive = false
while !isBlocked{
moveForward()
}
if isOnClosedSwitch{
toggleSwitch()
}
for i in 1...2{
turnRight()
}
for i in 1...3{
moveForward()
}
turnRight()
for i in 1...3{
moveForward()
}
if isOnClosedSwitch{
toggleSwitch()
}
for i in 1...2{
turnRight()
}
while !isBlocked{
moveForward()
}
if isOnClosedSwitch{
toggleSwitch()
}인사이트
- 'for' 루프 반복으로 반복 패턴이 명확하게 드러나서 코드의 흐름을 이해하기 쉬워졌습니다.
- 각 작업의 반복 횟수가 명확히 드러나므로, 코드의 의도를 빠르게 파악할 수 있습니다.
- 코드를 나중에 수정하거나 확장할 때, 수정할 부분이 명확하여 더 쉽게 접근할 수 있습니다.
올바른 포탈 설정하기
* 목표 : 각 포털의 상태를 변경하여 보석 수집하기
** 캐릭터 동선 : 보석을 수집하기 전에 포탈로 인한 경로 이탈을 막되, 필요한 시기에 포털을 활성화하기 위해 변수를 선언해줘야 할 것 같습니다. 또한 포탈 이용 후 막다른 곳을 바라보는 캐릭터를 제대로된 방향으로 이동시키는 것에 유의해서 코드를 작성해야겠습니다.
*** 작성한 코드
시도 1 : 성공했지만 'for'루프를 적용하지 않은 조건문이 있어서 다시 시도해봤습니다.
bluePortal.isActive = false
pinkPortal.isActive = false
while !isBlocked{
moveForward()
if isOnGem{
collectGem()
}
}
for i in 1...2{
turnRight()
}
pinkPortal.isActive = true
moveForward()
if isBlocked{
for i in 1...2{
turnRight()
}
moveForward()
if isOnGem{
collectGem()
}
}
for i in 1...2{
turnRight()
}
moveForward()
bluePortal.isActive = true
moveForward()
moveForward()
if isOnGem{
collectGem()
}
for i in 1...2{
turnRight()
}
bluePortal.isActive = false
for i in 1...2{
moveForward()
}
if isOnGem{
collectGem()
}시도 2 : 큰 변화는 없습니다. func을 이용한다면 더 간단한 코드가 나오지 않을까 상상만 했습니다^^ 배워서 활용해봐야겠습니다.
bluePortal.isActive = false
pinkPortal.isActive = false
while !isBlocked{
moveForward()
if isOnGem{
collectGem()
}
}
for i in 1...2{
turnRight()
}
pinkPortal.isActive = true
moveForward()
if isBlocked{
for i in 1...2{
turnRight()
}
moveForward()
if isOnGem{
collectGem()
}
}
for i in 1...2{
turnRight()
}
moveForward()
bluePortal.isActive = true
for i in 1...2{
moveForward()
}
if isOnGem{
collectGem()
}
for i in 1...2{
turnRight()
}
bluePortal.isActive = false
for i in 1...2{
moveForward()
}
if isOnGem{
collectGem()
}딱히 이 부분에서는 인사이트를 못 느꼈습니다.
글을 쓰다보니 내 입장에서 뿐만 아니고 혹시 저처럼 기초에서 갈피를 잡아보려 하는 분들에게 조금이나마 도움이 될 수 있게 작성하고 싶은데 사전처럼 일관성을 갖기에는 저도 방황중이라서 조금 어지럽고 두서 없는 글을 올리게 되어 부끄럽네요..생각만 하는 것보다는 무작정 해보면서 가꿔 나가는 게 더 남는 것이 많을 것 같아서 일단은 해보는중입니다 ㅎㅎ
그럼 다들 화이팅~
'개발..................... > TIL' 카테고리의 다른 글
20240528_미니프로젝트_오토레이아웃을 위한 StackView 사용 (0) 2024.05.29 20240527_개강입니다. (0) 2024.05.27 20240523_Playgrounds_for-in을 활용한 else if 사용하기 (0) 2024.05.23 20240521_Swift_변수와 상수 (0) 2024.05.21 20240425 소프트웨어 아키텍처 외 (0) 2024.04.25