반응형

전체 글 157

나이프 히트 — 각도 정규화와 충돌 임계값

오프라인 인디팩 · 개발일지나이프 히트 — 각도 정규화와 충돌 임계값2026-06-12 · v1.0 · 아케이드 / 각도 계산요약 — 회전하는 통나무에 칼을 던져 박는 게임. 이미 박힌 칼과 너무 가까운 각도에 또 박으면 게임오버. 스테이지가 올라갈수록 회전 속도가 빨라지고 방향이 반전되기도 한다.월드 각도를 통나무 로컬 각도로 변환칼은 항상 화면 아래(월드 기준 고정 각도)에 박히지만, 통나무는 계속 회전하고 있다. 그래서 "칼이 박힌 각도"를 통나무 기준 로컬 각도로 바꾸려면 회전값을 빼줘야 한다.final newLocal = _normalize(impactAngle - logRotation);for (final a in stuckAngles) { if (_angularDistance(a, ..

사이먼 게임 — 시퀀스 재생과 사용자 입력 인덱스 매칭

오프라인 인디팩 · 개발일지사이먼 게임 — 시퀀스 재생과 사용자 입력 인덱스 매칭2026-06-08 · v1.0 · 두뇌 트레이닝 / 패턴 기억요약 — 점점 길어지는 색깔 패턴을 보고 그대로 따라 누르는 사이먼 게임. 매 라운드 시퀀스에 색을 하나씩 추가하고, 사용자는 처음부터 순서대로 눌러야 한다.Record 타입으로 (정답 여부, 라운드 완료 여부) 동시 반환Dart의 레코드 타입을 활용해서 탭 결과를 튜플로 반환한다. UI 쪽에서는 이 두 값만 보고 "정답 애니메이션"과 "다음 라운드 진행"을 각각 처리하면 된다.(bool correct, bool roundComplete) tap(SimonPad pad) { final expected = sequence[userInputIndex]; i..

스택 타워 — 자동 왕복 블록과 겹침 잘라내기

오프라인 인디팩 · 개발일지스택 타워 — 자동 왕복 블록과 겹침 잘라내기2026-06-08 · v1.0 · 아케이드 / 정밀 타이밍요약 — 좌우로 자동 왕복하는 블록을 탭으로 떨어뜨려 쌓는 게임. 아래 블록과 겹치는 부분만 남기고 나머지는 잘려나가며, 완전히 벗어나면 게임오버다.겹침 구간만 남기는 사각형 교집합현재 블록과 아래 탑 꼭대기 블록의 x범위 교집합을 구해서, 겹치는 부분(overlap)이 0보다 크면 그만큼만 새 블록으로 쌓는다. 겹침이 없으면 완전히 빗나간 것이므로 게임오버.final left = max(current.x, top.x);final right = min(current.x + current.width, top.x + top.width);final overlap = righ..

프리셀 — 이동 가능한 최대 카드 수 공식

오프라인 인디팩 · 개발일지프리셀 — 이동 가능한 최대 카드 수 공식2026-06-09 · v1.0 · 카드 솔리테어 / 알고리즘요약 — 8개 캐스케이드 + 4개 프리셀 + 4개 파운데이션으로 구성된 프리셀 솔리테어. 한 번에 옮길 수 있는 카드 시퀀스 길이가 빈 프리셀과 빈 캐스케이드 수에 따라 정해지는 공식이 핵심이다.(빈 프리셀+1) × 2^(빈 캐스케이드)프리셀 솔리테어의 유명한 공식. 빈 프리셀 하나마다 카드 한 장을 임시 보관할 수 있고, 빈 캐스케이드 하나는 시퀀스를 절반씩 나눠 옮기는 걸 반복할 수 있어 실질적으로 2배 효과를 낸다.int maxMoveSize({required bool destIsEmptyCascade}) { final freeBuffers = emptyFreeC..

퐁 — 패들 타격 위치 기반 반사각과 랠리 가속

오프라인 인디팩 · 개발일지퐁 — 패들 타격 위치 기반 반사각과 랠리 가속2026-05-27 · v1.0 · 아케이드 / 물리요약 — 가장 오래된 비디오 게임 중 하나인 퐁을 세로 방향으로 구현. AI 패들은 공을 완벽히 따라가지 않고 속도를 78%로 제한해서 봐주기 요소를 넣었다.AI에 일부러 넣은 속도 제한AI 패들이 공을 100% 따라가면 절대 못 이기는 게임이 된다. aiSpeedFraction = 0.78로 AI의 최대 이동 속도를 제한해서, 빠른 공에는 못 따라가는 틈을 의도적으로 만든다.final aiMaxStep = speed * aiSpeedFraction * dt;final dx = aiTargetX - aiX;if (dx.abs() 패들 충돌마다 가속, 득점마다 더 크게 가속랠..

오델로 — 코너/엣지 가중치 테이블

오프라인 인디팩 · 개발일지오델로 — 코너/엣지 가중치 테이블2026-05-22 · v1.0 · 보드게임 / AI 알고리즘요약 — 8×8 보드에서 돌을 뒤집어가는 오델로. hard AI는 단순히 돌 개수가 아니라, 코너가 압도적으로 유리하고 코너 옆 칸은 오히려 불리하다는 포지션 가중치 표로 평가한다.코너는 +120, 코너 옆은 -40오델로 이론에서 코너는 절대 뒤집히지 않는 안전한 자리라 최고 가중치를 주고, 그 대각선 옆(X-square)은 상대에게 코너를 내줄 위험이 커서 오히려 마이너스 점수를 준다. 8×8 전체를 이런 식으로 미리 계산한 표를 갖고 있다.static const List _weights = [ [120, -20, 20, 5, 5, 20, -20, 120], [-20,..

반응속도 테스트 — 5회 평균과 성급한 탭 감지

오프라인 인디팩 · 개발일지반응속도 테스트 — 5회 평균과 성급한 탭 감지2026-05-29 · v1.0 · 두뇌 트레이닝요약 — 빨간 화면이 초록으로 바뀌는 순간 탭하는 반응속도 게임. 5회 시행의 평균을 최종 기록으로 삼고, 초록으로 바뀌기 전에 탭하면 "너무 빠름"으로 그 시행을 무효 처리한다.무작위 대기시간으로 예측 탭 방지대기 시간을 1.2~3.5초 사이 무작위로 잡아서, 사용자가 박자를 외워 타이밍만으로 탭하는 걸 막는다. 이 범위 자체가 게임의 핵심 밸런스 포인트다.int randomWaitMs() => minWaitMs + _random.nextInt(maxWaitMs - minWaitMs);상태 기반 부정 탭 처리waiting(빨강) 상태에서 탭하면 markTooEarly()가 호..

숫자 기억 게임 — 자릿수 비례 표시 시간과 상태 머신

오프라인 인디팩 · 개발일지숫자 기억 게임 — 자릿수 비례 표시 시간과 상태 머신2026-06-08 · v1.0 · 두뇌 트레이닝요약 — 점점 길어지는 숫자를 외웠다가 그대로 입력하는 게임. 라운드가 올라갈수록 자릿수가 늘고, 보여주는 시간도 자릿수에 비례해서 늘어난다.5가지 상태를 명시적으로 관리idle → showing → inputting → result → gameOver로 이어지는 상태 머신이다. 각 메서드가 자기 상태에서만 동작하도록 가드를 걸어두면, 화면(UI) 쪽에서 실수로 잘못된 타이밍에 호출해도 조용히 무시된다.enum NumberMemoryState { idle, showing, inputting, result, gameOver }Duration get showDuration ..

피아노 타일 — 실제 악보 기반 타일 생성

오프라인 인디팩 · 개발일지피아노 타일 — 실제 악보 기반 타일 생성2026-06-08 · v1.0 · 리듬 게임요약 — 내려오는 검은 타일을 순서대로 탭하는 리듬 게임. 절차적 무작위 생성 대신, 실제 동요/클래식 악보 데이터를 순서대로 재생하며 타일을 만드는 "곡 모드"가 기본이다.악보 노트를 컬럼에 매핑곡 데이터의 각 음(note)을 note % 열개수로 컬럼에 매핑한다. 짧은 음은 일반 타일, 긴 음(len > 1)은 눌러서 유지해야 하는 롱 노트가 된다. 곡이 끝나면 다음 곡을 무작위로 골라 이어붙인다.PianoSongNote _nextSongNote() { if (_currentSong == null || _songNoteIndex >= _currentSong!.notes.length..

15퍼즐 — 풀이 가능성을 보장하는 셔플 방식

오프라인 인디팩 · 개발일지15퍼즐 — 풀이 가능성을 보장하는 셔플 방식2026-06-08 · v1.0 · 퍼즐 게임 / 알고리즘요약 — 4×4 슬라이딩 퍼즐. 타일을 완전 무작위로 배치하면 절반의 확률로 풀 수 없는 배치가 나오기 때문에, 항상 완성 상태에서 시작해 유효한 이동만 반복해서 섞는다.완성 상태에서 거꾸로 섞기15퍼즐은 무작위 순열의 절반이 풀이 불가능하다(치환의 우기성 때문). 이걸 수학적으로 검증하는 대신, 애초에 항상 풀 수 있는 완성 상태에서 시작해 빈 칸과 인접한 타일을 400번 무작위로 교환한다 — 실제 게임처럼 손으로 섞는 것과 같은 원리다.for (int i = 0; i n != lastSwapped).toList(); final pick = neighbors[_ra..

반응형