SudokuAndroid Tutorial
Sudoku für Android in Kotlin mit Jetpack Compose — 2D- und 3D-Sudoku auf dem Smartphone
Zuletzt aktualisiert: 13.04.2026
Zielgruppe: Anfänger ohne Android-Vorkenntnisse
Inhaltsverzeichnis
1. Was ist SudokuAndroid?
SudokuAndroid ist eine native Android-App für 2D- und 3D-Sudoku. Sie wurde in Kotlin mit Jetpack Compose geschrieben — dem modernen UI-Framework für Android-Entwicklung.
| Feature | Beschreibung |
|---|---|
| 2D-Sudoku (9×9) | Das bekannte Puzzle auf dem Smartphone-Bildschirm |
| 3D-Sudoku | Sudoku auf einem Würfel — 3D-Darstellung mit SceneView |
| Touch-Steuerung | Zellen per Fingertipp auswählen, Zahlen über Zahlen-Pad eingeben |
| Schwierigkeitsstufen | Verschiedene Schwierigkeitsgrade zur Auswahl |
| Automatischer Löser | Das Rätsel auf Knopfdruck lösen lassen |
| Undo/Redo | Züge rückgängig machen und wiederherstellen |
| Fehlerhervorhebung | Ungültige Eingaben werden farblich markiert |
2. Kotlin statt Java
Android-Apps können in Java oder Kotlin geschrieben werden. Seit 2019 ist Kotlin die offizielle Programmiersprache für Android. Kotlin ist moderner, kürzer und sicherer als Java:
// Dasselbe in Java (verbose):
public class SudokuCell {
private Integer value;
private boolean isFixed;
public SudokuCell(Integer value, boolean isFixed) {
this.value = value;
this.isFixed = isFixed;
}
public Integer getValue() { return value; }
public boolean isFixed() { return isFixed; }
}
// Dasselbe in Kotlin (kompakt):
data class SudokuCell(
val value: Int?, // Int? bedeutet: Int oder null
val isFixed: Boolean
)
null sein, was oft zu NullPointerException-Fehlern führt. In Kotlin muss man explizit mit ? angeben, ob eine Variable null sein darf — der Compiler verhindert viele Fehler schon beim Schreiben des Codes.
3. Voraussetzungen & Setup
| Software | Version | Zweck |
|---|---|---|
| Android Studio | Neueste stabile Version | IDE für Android-Entwicklung (enthält alles) |
| Android SDK | API 26+ (Android 8.0), Target/Compile SDK 34 | Wird von Android Studio automatisch installiert |
| JDK | 17+ | Wird von Android Studio mitgeliefert |
| Android-Gerät oder Emulator | — | Zum Testen der App |
git clone https://github.com/CavdarKemal/SudokuAndroid.git
# Dann: Android Studio → "Open" → SudokuAndroid-Ordner auswählen
4. Bauen und Installieren
Option 1: Android Studio (empfohlen)
- Projekt in Android Studio öffnen
- Emulator starten (oder Android-Gerät per USB verbinden)
- Grünen „Run“-Button klicken (→)
- App installiert sich automatisch und startet
Option 2: Kommandozeile (Gradle)
# Debug-APK bauen:
./gradlew assembleDebug
# Die fertige APK befindet sich in:
# app/build/outputs/apk/debug/app-debug.apk
# APK auf verbundenem Gerät installieren:
adb install app/build/outputs/apk/debug/app-debug.apk
build.gradle.kts-Dateien (Kotlin DSL) und baut daraus eine APK-Datei (Android Package). ./gradlew ist ein „Gradle Wrapper“ — er lädt automatisch die richtige Gradle-Version herunter. SudokuAndroid verwendet AGP 8.13.2 und Kotlin 1.9.22.
5. Android-App-Grundlagen
Wer mit Desktop-Java-Entwicklung vertraut ist, findet hier die wichtigsten Unterschiede:
| Konzept | Desktop Java | Android (Kotlin) |
|---|---|---|
| Hauptfenster | JFrame | Activity |
| Bildschirme | JPanel | Composable Screens |
| Layout | Im Code (Swing) | Jetpack Compose (deklarativ im Code) |
| Navigation | Manuell (Fenster) | Navigation Compose (NavGraph) |
| Build-Tool | Maven | Gradle (Kotlin DSL) |
| Paketformat | JAR | APK |
| Eingabe | Maus + Tastatur | Touchscreen |
| DI-Framework | — | Hilt (Dagger) |
Was ist eine Activity?
Eine Activity ist der Grundbaustein einer Android-App — vergleichbar mit einem JFrame-Fenster. SudokuAndroid hat eine MainActivity, die als Einstiegspunkt dient und Jetpack Compose für die UI verwendet:
// Activity mit Jetpack Compose (statt XML-Layouts):
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SudokuTheme {
// Navigation zwischen Screens
NavGraph()
}
}
}
}
@Composable-Funktionen definiert. Das ist deklarativ, typsicher und benötigt kein findViewById.
6. Projektstruktur
SudokuAndroid/
├── app/ ← Android-App-Modul
│ ├── src/main/
│ │ ├── java/com/sudoku/android/ ← Kotlin-Quellcode
│ │ │ ├── MainActivity.kt ← Einstiegspunkt (Activity)
│ │ │ ├── SudokuApplication.kt ← Hilt Application-Klasse
│ │ │ ├── di/
│ │ │ │ └── AppModule.kt ← Dependency Injection (Hilt)
│ │ │ ├── navigation/
│ │ │ │ ├── NavGraph.kt ← Compose-Navigation
│ │ │ │ └── Screen.kt ← Screen-Definitionen
│ │ │ ├── viewmodel/
│ │ │ │ ├── Sudoku2DViewModel.kt ← ViewModel für 2D
│ │ │ │ └── Sudoku3DViewModel.kt ← ViewModel für 3D
│ │ │ └── ui/
│ │ │ ├── components/
│ │ │ │ └── NumberPad.kt ← Zahlen-Pad Composable
│ │ │ ├── screens/
│ │ │ │ ├── home/HomeScreen.kt ← Startbildschirm
│ │ │ │ ├── sudoku2d/Sudoku2DScreen.kt ← 2D-Spielfeld
│ │ │ │ └── sudoku3d/Sudoku3DScreen.kt ← 3D-Spielfeld
│ │ │ └── theme/ ← Material 3 Theme
│ │ ├── res/ ← Ressourcen (Strings, Icons)
│ │ └── AndroidManifest.xml ← App-Konfiguration
│ └── build.gradle.kts ← App Build-Konfiguration
├── core/ ← Reines Kotlin-Modul (ohne Android)
│ ├── src/main/kotlin/com/sudoku/core/
│ │ ├── generator/
│ │ │ ├── Generator2D.kt ← 2D-Rätsel generieren
│ │ │ └── Generator3D.kt ← 3D-Rätsel generieren
│ │ ├── solver/
│ │ │ ├── Solver2D.kt ← 2D-Backtracking-Löser
│ │ │ └── Solver3D.kt ← 3D-Backtracking-Löser
│ │ ├── model/
│ │ │ ├── Difficulty.kt ← Schwierigkeitsstufen
│ │ │ ├── SudokuSize.kt ← Würfelgrößen
│ │ │ └── SolveStep.kt ← Einzelne Lösungsschritte
│ │ └── history/
│ │ └── UndoRedoManager.kt ← Undo/Redo-Logik
│ └── build.gradle.kts
└── build.gradle.kts ← Globale Build-Konfiguration
app (Android-UI mit Compose) und core (reine Kotlin-Logik ohne Android-Abhängigkeiten). Das core-Modul enthält Generator, Solver und Spielmodelle — diese könnten auch in einer Desktop-Anwendung wiederverwendet werden.
7. Das Spielfeld zeichnen
Das 9×9-Sudoku-Gitter wird als Composable mit Canvas implementiert — Jetpack Compose zeichnet das Spielfeld deklarativ:
// Sudoku-Spielfeld als Composable:
@Composable
fun SudokuBoard(
board: Array<IntArray>,
selectedCell: Pair<Int, Int>?,
onCellClick: (Int, Int) -> Unit
) {
Canvas(modifier = Modifier.fillMaxWidth().aspectRatio(1f)
.pointerInput(Unit) {
detectTapGestures { offset ->
val row = (offset.y / cellSize).toInt()
val col = (offset.x / cellSize).toInt()
onCellClick(row, col)
}
}
) {
drawGrid() // Gitterlinien zeichnen
drawNumbers() // Zahlen einsetzen
drawHighlight() // Ausgewählte Zelle hervorheben
}
}
// Gitterlinien mit dickeren 3x3-Block-Grenzen:
private fun DrawScope.drawGrid() {
for (i in 0..9) {
val strokeWidth = if (i % 3 == 0) 4f else 1f
drawLine(Color.Black, Offset(0f, i * cellSize), Offset(size.width, i * cellSize), strokeWidth)
drawLine(Color.Black, Offset(i * cellSize, 0f), Offset(i * cellSize, size.height), strokeWidth)
}
}
Canvas als Composable verwendet statt einer Custom View mit onDraw(). Der Vorteil: Die UI reagiert automatisch auf State-Änderungen und wird neu gezeichnet (Recomposition), ohne manuelles invalidate().
8. Spiellogik
Die Spiellogik (Generator und Solver) liegt im separaten core-Modul und ist in reinem Kotlin geschrieben — ohne Android-Abhängigkeiten. Die Algorithmen sind vergleichbar mit den Desktop-Versionen (SudokuApp):
// Backtracking-Solver in Kotlin:
fun solve(board: Array<IntArray>): Boolean {
val emptyCell = findEmptyCell(board) ?: return true // ?: = Elvis-Operator
val (row, col) = emptyCell // Destructuring
for (num in 1..9) {
if (isValid(board, row, col, num)) {
board[row][col] = num
if (solve(board)) return true
board[row][col] = 0 // Backtrack
}
}
return false
}
•
?: return true (Elvis-Operator): Falls findEmptyCell null zurückgibt, direkt return true — spart eine If-Anweisung
•
val (row, col) = emptyCell (Destructuring): Mehrere Werte gleichzeitig in Variablen entpacken
•
1..9: Range-Ausdruck — entspricht einer for-Schleife von 1 bis 9
9. Eingabe auf dem Touchscreen
Auf dem Smartphone gibt es keine Maus — die Eingabe erfolgt per Touch. In Compose wird die Touch-Erkennung deklarativ mit pointerInput realisiert:
// Touch-Erkennung direkt im Canvas-Modifier:
Canvas(modifier = Modifier
.pointerInput(Unit) {
detectTapGestures { offset ->
// Welche Zelle wurde angetippt?
val row = (offset.y / cellSize).toInt()
val col = (offset.x / cellSize).toInt()
if (row in 0..8 && col in 0..8) {
viewModel.selectCell(row, col)
// Kein invalidate() nötig — Compose erkennt State-Änderungen automatisch
}
}
}
) { /* zeichnen ... */ }
Zahleneingabe
Nach der Zellauswahl gibt der Spieler die Zahl über ein NumberPad-Composable (1–9-Buttons) ein:
// NumberPad als eigenes Composable (ui/components/NumberPad.kt):
@Composable
fun NumberPad(onNumberClick: (Int) -> Unit, onDelete: () -> Unit) {
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
for (num in 1..9) {
Button(onClick = { onNumberClick(num) }) {
Text("$num", fontSize = 20.sp)
}
}
}
}
// Verwendung im Screen:
NumberPad(
onNumberClick = { num -> viewModel.enterNumber(num) },
onDelete = { viewModel.deleteNumber() }
)
10. Vergleich: Android vs. Desktop
| Aspekt | Desktop (Java Swing) | Android (Kotlin) |
|---|---|---|
| Sprache | Java | Kotlin 1.9 |
| UI-Framework | Swing + JavaFX | Jetpack Compose + Material 3 |
| Layout | Im Java-Code | Deklarativ in Kotlin (Composables) |
| Architektur | MDI (MainFrame) | MVVM (ViewModel + Compose) |
| DI | — | Hilt (Dagger) |
| Build | Maven | Gradle (Kotlin DSL) |
| Distribution | JAR-Datei | APK → Google Play Store |
| Eingabe | Maus + Tastatur | Touchscreen |
| Bildschirmgröße | Groß (beliebig skalierbar) | Klein (DP-Einheiten statt Pixel) |
| Lifecycle | Einfach (open → close) | Komplex (onCreate, onPause, onResume...) |
onPause() (App kommt in Hintergrund), onResume() (App kommt wieder in Vordergrund) und onDestroy() (App wird beendet). Spielstand und Daten müssen entsprechend gespeichert/wiederhergestellt werden.
11. Nächste Schritte
Die App kennenlernen
- Android Studio installieren und Projekt öffnen
- Emulator starten und App laufen lassen
- Quellcode lesen — Einstiegspunkt ist
MainActivity.kt
Weiterentwickeln
- Timer: Zeit messen und anzeigen
- Highscore: Bestzeiten lokal speichern (mit Room-Datenbank oder DataStore)
- Animations: Compose-Animationen für Lösungsschritte und Zellauswahl
- Widgets: Android-Widget für den Homescreen mit Glance
- Tests: UI-Tests mit Compose Testing Framework erweitern
Links
- Quellcode auf GitHub
- Kotlin für Android (Google Docs)
- SudokuApp Tutorial (die Desktop-Version)