2026/04/27

오늘의 이야기

 



🎾 Kotlin으로 복식 경기 Round-Robin 매칭 구성하기


라운드 로빈 구현해 보기



 


이 글은 Kotlin과 Jetpack Compose를 사용하는 Android 앱에서 복식 경기 매칭을 어떻게 구성할 수 있는지 기록한 개발자 경험 공유입니다. 예제 코드는 초보자도 이해할 수 있도록 주석과 함께 설명합니다.


🧩 사용 시나리오


앱 사용자는 4명 이상의 참여자를 등록한 후, 복식 경기 방식으로 매칭을 자동 생성합니다.



  • 경기 방식은 Round-Robin 방식 (모든 가능한 조합을 구성)

  • 같은 팀 또는 상대가 중복되지 않도록 구성

  • 선수 수가 홀수인 경우 마지막 한 명을 제외

  • 참가자 수가 4명일 경우에도 다양한 팀 구성을 고려


🧠 핵심 데이터 구조



// 경기 참가자
data class Contestant(
val pk: String, // 고유 ID
val tokenId: String,
val enterTime: Long,
val exitTime: Long
)

// 경기 매칭
data class Match(
val pk: String, // "Round_0", "Round_1" 등
val startTime: Long,
val endTime: Long,
val teamA: List, // 2인 1조
val teamB: List,
val isDoubles: Boolean = true
)

⚙️ 매칭 로직 구현


복식 경기를 위한 모든 가능한 조합을 만들고, 이전 경기에 바로 참여한 선수는 다음 경기에서 쉬도록 구성합니다.



// 복식 팀 조합을 생성하는 함수
fun generateDoublesTeamPairs(players: List): List<List<Contestant>> {
val validPlayers = if (players.size % 2 != 0) players.dropLast(1) else players
val teamPairs = mutableListOf<List<Contestant>>()

// 모든 2명 조합 생성
for (i in validPlayers.indices) {
for (j in i + 1 until validPlayers.size) {
teamPairs.add(listOf(validPlayers[i], validPlayers[j]))
}
}

return teamPairs
}

이후 이 조합으로 가능한 모든 2팀 매칭을 구성합니다.



// 복식 경기를 위한 가능한 Match 조합 생성
fun generateDoublesMatches(players: List<Contestant>): List<Match> {
val validPlayers = if (players.size % 2 != 0) players.dropLast(1) else players
val teamPairs = generateDoublesTeamPairs(validPlayers)
val matchList = mutableListOf<Match>()
var idx = 0

val usedMatches = mutableSetOf<Set<String>>()

for (i in teamPairs.indices) {
for (j in i + 1 until teamPairs.size) {
val teamA = teamPairs[i]
val teamB = teamPairs[j]

// 팀원이 겹치지 않는지 확인
if (teamA.intersect(teamB.toSet()).isEmpty()) {
val allPlayers = (teamA + teamB).map { it.pk }.toSet()

// 동일한 구성의 경기인지 중복 확인
if (allPlayers !in usedMatches) {
usedMatches.add(allPlayers)

// 실제 Match 객체 생성
val match = Match(
pk = "Round_${idx++}",
startTime = System.currentTimeMillis(),
endTime = System.currentTimeMillis() + 10 * 60 * 1000,
teamA = teamA,
teamB = teamB,
isDoubles = true
)

matchList.add(match)
}
}
}
}

return matchList
}

✨ 위 함수는 4명이 참여했을 때도 3가지 가능한 조합 중 1경기로 끝나는 일이 없도록 팀 구성 중복 여부를 고려해 최소 2경기 이상이 생성될 수 있도록 보완하였습니다.

🔍 로그 출력 예시 (디버깅용)



Log.e("MatchGen", "Valid players (${validPlayers.size}): ${validPlayers.map { it.pk }}")
Log.e("MatchGen", "Generated ${teamPairs.size} teams")

for (match in matchList) {
Log.e("MatchGen", "Match: ${match.teamA.map { it.pk }} vs ${match.teamB.map { it.pk }}")
}

✅ 결과 예시 (4명일 때)



Match: A, B vs C, D
Match: A, C vs B, D

📌 마무리


이 방식은 경기 운영 자동화라운드로빈 방식의 배치 자동화에 유용하며, 참여자 수의 변화에 따라 유연하게 대응할 수 있는 점이 큰 장점입니다.


필요에 따라 매칭 조건(예: 직전 경기 제외, 최소 휴식 시간 보장 등)을 더 정교하게 설계해 나갈 수 있습니다.




문의나 개선 아이디어가 있다면 댓글로 남겨주세요! 😊


 


어디까지나... chatGPT 의 의견은 아직 100% 신뢰도를 보장 하지 않습니다. 





댓글 없음:

댓글 쓰기

오늘의 이야기

  🎾 Kotlin으로 복식 경기 Round-Robin 매칭 구성하기 라운드 로빈 구현해 보기   이 글은 Kotlin과 Jetpack Compose를 사용하는 Android 앱에서 복식 경기 매...