에프톤(FLab 해커톤) 참여 후기

김세준·2024년 9월 15일
2

이야기들

목록 보기
2/2
post-thumbnail

1. 참여 과정

22년 9월에 멘토링 과정을 끝내고 회사 생활을 하던 도중 F-THON 모집 안내문이 슬랙 커뮤니티에 공고되었습니다. 해커톤이라는 것을 한 번도 안해보기도 했고 짧은 시간 내에 프로젝트를 구현해보는 경험도 좋을 것 같아 참여하게 되었습니다.

8월 11일까지 참여 신청을 받았습니다. 저는 구글 폼을 통해 신청했지만, 신청자가 너무 많아 처음에는 선발되지 못했습니다. 그러던 중 취소한 참가자들이 생겨 제게 추가 참여 기회에 대한 문자가 왔습니다. 저는 이를 수락하여 참여하게 되었습니다.

2. 해커톤 진행 - 첫번째 세션

해커톤 장소는 역삼역 부근에서 진행되었고 금요일 오후 8시부터 다음날 오전 6시경까지 진행되었습니다. 첫번째 세션의 진행 순서는 아래와 같았습니다.

2.1 개회사

개회사때는 에프톤을 어떻게 진행해나갈 것인지, 상품은 무엇인지에 대한 이야기를 들었습니다. 참가 비용이 0원인데 비해 너무 많은 것을 지원해주셨습니다. 1차 세션, 2차 세션 야식은 물론이고 모든 참가자들에게 반팔 옷(더블 코튼)도 제공했습니다. 상품들도 다 좋았습니다. 모든 상품은 우승한 팀에 대해 모두 개별 지급 보상이었습니다.

1등: LG 27 인치 모니터.
2등: 로지텍 MX Master 3S 마우스
3등: 교보문고 5만원권

개회사를 들으면서 문득 아래 명언이 떠올랐습니다.
아.. 이러면 무엇이 남나요?

여러분이 남습니다.

2.2 네트워킹

4명의 인원이 한 팀을 이뤄 개발팀이 구성되었고 총 8팀이었습니다. 그리고 모든 팀들은 두 명의 프론트엔드와 두 명의 백엔드로 구성되었습니다. 첫 네트워킹 시간 때 같은 조가 된 분들과 함께 많은 근황과 개발에 관련된 이야기를 나눴습니다.

2.3 주제 선정

주제 선정은 굉장히 재밌게 진행되었습니다. 네 가지 큰 주제가 있었는데요. 두 팀이 한 주제를 공유할 수 있도록 했습니다. 선택 방식은 미니 게임을 통한 선착순이었습니다.

'가장 빠른 사람이 유리하다'는 말에 처음엔 실내 달리기를 상상했습니다. 그러나 실제 게임은 코딩에서 자주 사용하는 키워드를 얼마나 빠르고 정확하게 입력하느냐를 겨루는 것이었습니다.

우리 팀에서는 제가 게임에 참여했습니다. 코틀린의 vararg를 입력하는 과정에서 오타가 많이 나서 6등을 했던 기억이 납니다. vararg 를 좀 많이 써볼걸..

다행히 우리팀이 원래 하기로 했었던 주제는 운동이었는데 운좋게 우리팀까지 그 주제가 남아있어 선택할 수 있게 되었습니다.

밤 11시경 도착한 피자로 야식을 즐기며, 새벽 5시 30분까지 주제에 대한 토론을 진행하고 개발 방향을 결정했습니다. 이 과정에서 멘토님들이 각 팀을 순회하며 큰 도움을 주었습니다. 개발 관련 질문에 답변해주시고, 프로젝트 진행 방향과 효과적인 팀 토론 기법에 대해 조언해 주었습니다. (실제로 저는 이 때의 조언이 아니었으면 개발 방향에 대해 가장 중요한 것을 놓칠뻔했습니다.)

우리팀은 사람들에게 러닝의 동기부여를 위해, 러닝을 할수록(GPS 기반) 캐릭터가 진화하는 컨셉의 애플리케이션을 기획했습니다. 캐릭터를 무엇으로 할까.. 하다가 포켓몬을 선택했습니다. 진화 체계가 명료했고, 무엇보다 귀여웠습니다.

첫 번째 세션은 이렇게 마무리되었고 두 번째(마지막) 세션이 오기까지 6일 간, 각자 팀끼리 개발하는 시간을 가졌습니다.

3. 기술적 도전과 해결책

3.1 개발 환경

빠른 시간 안에 구현해야 하다보니 배포는 최대한 간단하게, 그리고 빠르게 구성해야했습니다. 저와 다른 한 분은 모두 재직 중이셨기 때문에 환경 세팅에 많은 시간적 비용이 들어가는 것은 원치 않았습니다.

NHN 클라우드를 하나 띄우고 org.hidetake.ssh 를 이용해 버튼 한 번만 클릭하면 클라우드 서버로 바로 배포되는 방법을 택했습니다.

데이터베이스는 클라우드 인스턴스 내에 MySQL 을 다운로드해서 구축했습니다. 간단한 프로젝트이기 때문에 이렇게 해도 문제가 없다고 판단했습니다. 포켓몬 사진을 저장하기 위해 NHN 클라우드의 오브젝트 스토리지를 사용했습니다. (아마존의 S3 와 똑같습니다.)

3.2 달리기 시뮬레이션

가장 중요한 달리기입니다. 실제 애플리케이션을 만드는 환경이라면 스마트폰으로부터 특정 간격으로 위도와 경도를 받아오고 그 변화량을 기준으로 속도를 측정하고 러닝 페이스를 도출해야합니다.

하지만 여기는 해커톤, 발표는 실내에서 진행하게 됩니다. 노트북으로 발표를 하게될 것이고 노트북을 들고 실내에서 뛸 수도 없을뿐더러, GPS 위치는 실내에서 조금 뛰어봤자 변화량을 일으키기 힘듭니다.

그래서 가상으로 달릴 수 있는 달리기 시뮬레이션 서비스를 구현하기로 했습니다. 달리기 API를 호출하면 그 즉시 싱글 스레드 스케쥴러를 생성합니다. 그리고 가상으로 평균 속력, 랜덤 방향, 처음 출발한 위/경도만 알면 위도 변화량을 계산할 수 있게 됩니다.

  • 위도 변화량 = (이동거리 * cos(방향)) / 지구 반경
  • 경도 변화량 = (이동거리 sin(방향)) / (지구 반경 cos(현재 위도))

그리고 방향은 2D 평면 좌표계에서 적용할 것입니다.

this.direction = new Random().nextDouble() * 2 * Math.PI;
this.speed = 100.0;
double latChange = speed * Math.cos(direction) / 111000.0;
double lngChange = speed * Math.sin(direction) / (111000.0 * Math.cos(Math.toRadians(currentLat)));
  • 111000: 위도 1도에 해당하는 거리(미터)
  • 111000 * xxx: 위도에 따른 경도 간격의 축소 보정

이제 달리기 시뮬레이터 서비스의 구현이 끝났습니다. 달리기 시작 버튼을 누르면 3초마다 위/경도 변화량을 구해서 그 값을 점차 더해주기만 하면 됩니다.

/start-running API를 호출하면 다음과 같은 과정이 진행됩니다:

  • 사용자의 현재 위치에서 달리기를 시작합니다.
  • 위도와 경도 좌표를 이용해 실제 주소를 확인합니다. 이 과정에서 NHN 클라우드의 Map API를 사용한 리버스 지오코딩을 활용합니다.
  • 반경 5Km 내 포켓몬이 있으면 그 포켓몬을 포획
  • 사용자가 시작 지점의 '구' 단위를 벗어나면, 자동으로 달리기 종료 이벤트가 호출됩니다. 이 기능은 사용자가 한 구 내에서만 포켓몬 경험치를 얻을 수 있도록 하기 위해 구현되었습니다.

그리고 /stop-running API 를 호출하면 다음과 같은 과정이 진행됩니다:

  • 페이스, 평균 속력 표시
  • 달린 거리에 따라 경험치 축적
  • 레벨이 3, 5가 될 때마다 포켓몬 1단계 진화, 2단계 진화

3.3 달리기 이벤트 처리

"달리기"를 하나의 이벤트로 뒀을 때 달리기 전, 달리기 후, 달리는 동안의 이벤트 후처리가 필요했습니다.

  • 달리기 전: 데이터베이스에 달리기 시작했다는 레코드 입력
  • 달리는 동안: 반경 5Km 내 포켓몬이 있을 경우 자동 포획
  • 달리기 후: 메인 포켓몬의 경험치 증가 및 레벨에 따른 진화

그래서 달리기 이벤트를 중앙에서 관리하는 RunningOrchestrator 을 두고 거기에서 받은 이벤트 타입에 따라 처리를 담당하도록 구현했습니다.

3.4 실시간 GPS 위치 마커 표시

위치 정보를 로그로만 보는 것은 가시성이 너무 떨어집니다. 다른 사람이 보기좋도록 하기 위해서 실시간 위치 좌표를 서버에서 클라이언트로 전송해야만 했습니다. 이를 구현하기 위해 웹소켓을 사용했습니다. 스프링 부트를 사용하면 웹 소켓을 @Configuration 추가만으로 쉽게 구현 가능합니다.

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(locationWebSocketHandler(), "/location").setAllowedOrigins("*");
    }

    @Bean
    public LocationWebSocketHandler locationWebSocketHandler() {
        return new LocationWebSocketHandler();
    }
}

웹소켓으로부터 받은 위/경도 좌표를 리액트에서 받아 지도를 가리키는 마커의 위치를 실시간으로 바꾸도록 했습니다. 아래 GIF 사진은 3초마다 달리는 방향으로 마커 위치가 바뀌는 것을 나타내는 것입니다.

그리고 관리자가 주소/포켓몬 이름을 입력하면 그 위치에 마커를 포켓몬 사진으로 바꿔, 포켓몬이 출몰했다는 사실을 시각적으로 표현하도록 했습니다. 과정은 아래와 같습니다.

  • 주소창에 부산을 입력
  • 서버에서 부산을 위도/경도 좌표로 변환
  • 위도/경도 좌표와 포켓몬 이름을 서버 데이터베이스에서 검색해 응답 리턴
  • 응답을 이용해 클라이언트에서 표현

4. 해커톤 진행 - 두번째 세션

발표는 해커톤 두번째 세션 때 진행되었습니다.

첫번째 세션은 (금-토) 에 이뤄졌고
두번째 세션은 다음주 (금-토) 였습니다.

첫번째 세션과 두번째 세션 사이 기간 동안 데일리 스크럼을 진행하며 개발 진척도를 서로 공유했습니다. 두번째 세션의 진행 일정은 아래 사진에 있습니다.

4.1 마무리 개발

미처 구현하지 못했던 것들을 이 시간에 개발했습니다. 저는 지도 시뮬레이션 기능을 이 시간을 통해 대부분 구현했습니다. 그 외 발표를 어떻게 해야할지도 곰곰히 생각하는 시간을 가졌습니다.

이후 3시까지 개발을 종료하고, 각 팀 간의 네트워킹 시간이 있었습니다. 이 시간 동안 다른 팀들과 교류할 수 있었고, 각자 구현한 프로젝트에 대해 설명하고 의견을 나눌 수 있었습니다. 또한 프로젝트 진행 중 겪은 고민들을 서로 공유할 수 있었습니다. 특히 익명으로 멘토에게 질문을 할 수 있는 기회도 제공되어, 매우 유익한 시간이었습니다

우리팀은 발표 자료 없이 실제 웹 앱 구동 장면과 시뮬레이션 지도 장면들을 보여주면서 기능들 위주로 설명해나가는 방식으로 발표를 진행했습니다. 아래는 발표 때 보여준 실제 웹 앱 구동 장면입니다.

더 자세한 구동되는 웹 앱 사진 및 코드는 아래의 깃허브에서 확인하실 수 있습니다. 참고로 비용 문제로 NHN 클라우드 및 지도 SDK 는 모두 닫아놓은 상태입니다.

구동하려면 포켓몬 GIF 사진 링크와 데이터베이스 DDL 이 필요한데, DDL 의 경우 프로젝트 내에 넣어두었고 GIF 사진 링크는 아래에 남기겠습니다.

https://github.com/orgs/f-pokerunner/repositories

  • pokerunner-frontend: 웹 앱 화면
  • pokerunner-backend: 웹 앱 서버
  • pokerunner-admin: 웹 앱 어드민 화면
  • 포켓몬 GIF 링크

4.2 시상

모든 프로젝트가 쟁쟁했던 가운데 무사히 발표를 마쳤습니다. 시상식 발표 때는 조마조마했지만, 감사하게도 최우수상을 받게 되어 MX Master 3S 마우스를 상품으로 받았습니다. 평가는 각 조의 발표가 끝난 후 이루어졌으며, 참가자들의 상호 평가와 멘토님들의 평가를 합산하여 순위를 매겼습니다. 평가는 구글 폼을 통해 진행되었습니다. 모든 상품은 당일에 지급되었습니다.

5. 마무리 및 소감

에프톤을 위해 에프랩에서 많은 준비를 하셨다는 것이 느껴졌습니다. 다음 2회차가 열릴 때 참여하지 못하신 분들은 참여 해보는 것을 권장드립니다.

해커톤을 진행하면서 짧은 시간 내에 기술적 고민과 그에 대한 결과를 도출하는 것이 꽤 재밌었습니다. 그리고 실제 상용 소프트웨어로써 출시하게 된다면 이런 부분에 대해 어떤 보완 코드를 작성할 수 있을지, 프로젝트가 끝나고 많은 생각을 하게 되었습니다.

또한 참가자분들 그리고 멘토님들과 네트워킹을 통해 얻은 인사이트도 좋은 경험이었습니다.

마지막으로, 이런 귀중한 기회를 제공해 주신 에프랩과 모든 관계자 분들께 감사드립니다. 에프랩 파이팅!

0개의 댓글

관련 채용 정보