앱인토스 미니앱 로또 번호 생성기 화면 세 장
|

앱인토스 미니앱 3 – 로또 번호 생성기

앱인토스 미니앱 제작기 세 번째는 로또 번호 생성기입니다. 이름 그대로 이번 주 로또 번호를 뽑아 주는 앱인데, 제가 만든 것 중에 다시 찾아오는 사람 비율이 유독 높았어요.

그래서 사람들이 돌아오는 바로 그 순간에 맞는 기능을 하나 더했습니다. 뽑아 둔 번호가 몇 등인지 토요일 추첨 뒤에 자동으로 맞춰 주는 화면이에요. 이 글은 그걸 만든 과정입니다.

로컬에서 앱을 직접 실행해 찍은 시연 영상. 맞춰본 번호는 시연용으로 넣어 둔 것입니다 (소리 없음)

로또 번호 생성기는 어떤 앱인토스 미니앱인가

로또 번호 생성기 번호 뽑기 화면. 여섯 개 번호 아래에 1245회 번호로 자동 보관했다는 안내가 보인다
번호 뽑기
보관함 화면. 1245회와 1244회에 뽑아 둔 번호가 회차별로 정리돼 있다
회차별 보관함

랜덤, 통계, 꿈해몽, 생년월일 네 가지 방식으로 번호를 뽑습니다. 홈 화면 아래에 “모든 번호 조합의 당첨 확률은 같다”는 문장을 넣어 뒀는데, 당첨을 예측해 주는 앱처럼 보이면 안 되기 때문입니다.

매주 돌아오는 앱에 더한 것

60명9월 28일 주 사용자
44명쯤그중 전부터 쓰던 사람

새로 들어온 사람보다 전부터 쓰던 사람이 훨씬 많습니다. 로또 추첨이 매주 토요일에 있기 때문이에요. 바깥에서 정해진 일정이 사람을 다시 데려오는 구조인 거죠.

그렇다면 토요일에 다시 온 사람이 가장 궁금해할 것부터 보여주는 게 맞겠다고 생각했습니다. 내가 뽑은 번호가 몇 개 맞았는지요.

전에는

  • 번호를 뽑아 주고 끝
  • 저장하려면 버튼을 눌러야 함
  • 맞았는지는 직접 비교

지금은

  • 뽑은 번호를 토요일에 자동으로 채점
  • 저장 버튼 없이 그 회차에 보관
  • 몇 개 맞았고 몇 등인지 바로 표시
함께 읽기앱인토스 미니앱 10 – 결정의 신앱인토스 미니앱 결정의 신 제작기입니다. 매일 바뀌는 오늘의 한 수 카드와 다섯 가지 결정 도구로 일상의 작은 선택을 정해 주는 앱을 만…

한 주가 이렇게 흘러가도록

사용자가 따로 할 일 없이 한 주가 굴러가게 만드는 것이 목표였습니다.

  1. 목요일 저녁 7시. 이번 주 번호를 뽑으라는 알림이 갑니다.
  2. 번호 뽑기. 뽑는 순간 그 회차 번호로 보관됩니다. 저장 버튼은 없앴어요.
  3. 토요일 저녁 8시 45분. 추첨이 시작되면 보관함의 그 회차가 결과 대기로 바뀝니다.
  4. 토요일 밤 9시부터. 앱 첫 화면 맨 위에 채점 카드가 올라오고, 다음 주 목요일이 되기 전까지 그대로 있습니다.

추첨 뒤의 첫 화면. 1244회 결과 카드에 당첨번호가 나왔다는 문구와 뽑아 둔 번호, 결과 확인하기 버튼
추첨이 끝난 뒤 첫 화면
채점 결과. 3개 맞아 5등 번호라는 문구와 일치한 공 세 개가 강조돼 있다
뽑아 둔 번호를 맞춰본 결과

위 화면의 번호는 채점 장면을 보여드리려고 지난 회차에 넣어 둔 시연용입니다. 결과 아래에는 “앱에서 뽑은 번호 기준이고 실제 당첨은 구입한 복권으로 확인하라”는 안내가 붙습니다.

날짜만으로 회차를 계산한다

“지금 뽑은 번호가 몇 회차 것인가”를 알아야 자동 보관이 됩니다. 확인해 보니 로또는 1회부터 한 주도 거르지 않고 추첨해 왔더라고요. 그러면 서버에 물어볼 것 없이 날짜에서 바로 계산할 수 있습니다.

drawCalendar.tsts
/** 지금 뽑은 번호가 들어가는 회차. 토 20:00 판매 마감 뒤에는 다음 회차. */
export function targetRound(now: number = Date.now()): number {
  const firstClose = ROUND1_MIDNIGHT + SALES_CLOSE_OFFSET;
  return Math.floor((now - firstClose) / WEEK) + 2;
}

바깥 일정이 규칙적이면 계산으로 끝낸다

  • 1회 추첨일인 2002년 12월 7일을 기준으로 7일씩 더하면 어느 회차든 날짜가 나옵니다.
  • 토요일 저녁 8시에 판매가 마감되니까, 그 뒤에 뽑은 번호는 다음 회차로 넘깁니다. 이걸 빼먹으면 이미 끝난 회차에 번호가 들어가요.
  • 시간은 전부 한국 시간 기준으로 계산합니다. 기기 시간대를 따르면 해외에 있는 사람은 회차가 어긋납니다.
함께 읽기앱인토스 미니앱 4 – 보석 광산앱인토스 미니앱 보석 광산 제작기입니다. 타일을 눌러 보석을 캐는 게임에 부적, 제련소, 주말 이벤트를 붙인 과정과 날짜로 광산을 만드는…

등수 매기기

채점은 로또 규칙을 그대로 옮긴 겁니다.

grading.tsts
export function gradeSet(numbers: number[], draw: Draw): Grade {
  // 같은 번호가 두 번 들어와도 한 번만 센다.
  const matched = [...new Set(numbers)].filter((n) => draw.numbers.includes(n));
  const matchCount = matched.length;
  const bonusMatched = numbers.includes(draw.bonus);
  let rank: Rank = 0;
  if (matchCount === 6) rank = 1;
  else if (matchCount === 5 && bonusMatched) rank = 2;
  else if (matchCount === 5) rank = 3;
  else if (matchCount === 4) rank = 4;
  else if (matchCount === 3) rank = 5;
  return { rank, matchCount, matched, bonusMatched };
}

보너스 번호는 다섯 개가 맞았을 때만 의미가 있어서 2등 판정에만 쓰고, 같은 번호가 두 번 들어와도 한 번만 세도록 해 뒀습니다.

당첨번호는 이렇게 받아온다

당첨번호는 동행복권의 공개 조회에서 먼저 받아옵니다. 정식으로 계약된 API가 아니어서 언제든 주소가 바뀔 수 있다는 점을 염두에 두고 만들었어요. 그래서 기획 단계에서 응답 형식과 이용 조건부터 확인하기로 정해 뒀습니다.

받아오는 코드에서 신경 쓴 건 요청 방식입니다.

drawResult.tsts
async function fetchJson(url: string): Promise<unknown> {
  const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
  const timer = window.setTimeout(() => controller?.abort(), TIMEOUT_MS);
  try {
    // 헤더를 붙이면 프리플라이트가 생기고 동행복권은 OPTIONS에 400을 준다. 단순 GET만 쓴다.
    const res = await fetch(url, { method: 'GET', credentials: 'omit', signal: controller?.signal });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } finally {
    window.clearTimeout(timer);
  }
}

남의 데이터로 채점할 때는 틀리느니 안 하는 쪽으로

  • 요청에 별도 헤더를 붙이면 브라우저가 사전 확인 요청을 먼저 보내는데, 그 요청이 거절됩니다. 그래서 아무것도 붙이지 않은 단순 요청만 씁니다.
  • 응답이 8초 안에 안 오면 끊습니다.
  • 동행복권 조회가 안 되면 공개된 다른 기록에서 한 번 더 받아 봅니다. 그것도 실패하면 채점을 하지 않고 “결과 대기”로만 보여줘요. 앱에 내장된 옛 데이터로는 절대 채점하지 않습니다. 틀린 등수를 보여주는 것보다 못 보여주는 게 낫습니다.

한 번 받아온 회차 결과는 바뀔 일이 없으니 기기에 저장해 두고 다시 요청하지 않고요.

알림은 목요일과 토요일에

알림은 한 주의 흐름에 맞춰 두 번으로 잡았습니다. 목요일 저녁 7시에는 이번 주 번호를 뽑으라는 알림이 나가요. 여기에 토요일 밤 9시 반쯤 “이번 주 번호 결과를 확인해 보세요”를 보내는 알림을 더하려고 합니다.

문구에서 “결과가 나왔어요”라고 단정하지 않은 데는 이유가 있습니다. 당첨번호 조회가 늦어지는 날에도 거짓말이 되지 않는 문장이어야 하니까요.

9월 30일부터 10월 6일까지는 하루 평균 13명쯤이 이 앱을 썼습니다.

프로젝트를 어떤 식으로 진행하는지는 프로젝트 진행 방식에, 매일 열 이유를 만든 다른 앱 이야기는 카드값 페이스 글에 있습니다.

로또 번호 생성기 자주 묻는 질문

로또 번호 생성기가 당첨 번호를 예측해 주나요?

아닙니다. 모든 번호 조합의 당첨 확률은 같습니다. 이 앱은 번호를 뽑아 보관하고 추첨 결과와 맞춰보는 것까지만 합니다. 실제 당첨 여부는 구입한 복권으로 확인해야 합니다.

당첨번호는 어디서 가져오나요?

동행복권의 공개 조회 결과를 먼저 받아오고, 안 되면 공개된 다른 기록에서 한 번 더 받아 봅니다. 둘 다 실패하면 채점하지 않고 결과 대기로만 표시합니다.

뽑은 번호는 따로 저장해야 하나요?

저장 버튼이 따로 없습니다. 번호를 뽑으면 그 회차에 자동으로 보관되고, 토요일 저녁 판매 마감 뒤에 뽑은 번호는 다음 회차로 들어갑니다.

이 글은 앱인토스 미니앱 「로또 번호 생성기」의 기록입니다. 앱인토스는 토스 앱 안에서 미니앱을 서비스하는 플랫폼이고, 공식 안내는 앱인토스 개발자센터에 있습니다.

이 글은 직접 만들고 운영하며 남긴 기록입니다. 적힌 수치는 작성 시점의 제 계정 기준이며, 같은 결과나 수익을 보장하지 않습니다.

Similar Posts

One Comment

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다