diff --git a/CLAUDE.md b/CLAUDE.md index 7cbe5ec..2c815ce 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,8 +9,10 @@ No `java`/`gradle` on PATH — use Android Studio's bundled JDK: ```bash export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" -./gradlew :engine:jvmTest # evaluator + engine tests -./gradlew :sim:run --args="50000" # simulate 50k hands, print bot stats +./gradlew :engine:jvmTest # engine tests (JVM) +./gradlew :engine:testAndroidHostTest # same suite, Android variant +./gradlew :sim:run --args="50000" # simulate 50k hands, print bot stats +./gradlew :app:assembleDebug # build the APK ``` ## Layout @@ -21,7 +23,9 @@ export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" | `engine/src/commonMain/.../bot/` | Skill/style profiles, `MathBot` | | `engine/src/commonMain/.../game/` | `Table` — betting rounds, side pots, showdown | | `sim/` | JVM-only headless simulator used to **tune** bot profiles | -| `assets/cards/` | 52 CC0 card faces + generated backs | +| `app/` | Android app: Compose table, `PokerViewModel` | +| `assets/cards/` | 52 CC0 card faces + generated backs (**source of truth**) | +| `tools/generate_card_assets.sh` | Rasterises those SVGs into `app/.../drawable-*` | `engine` is pure Kotlin with no platform APIs, so `androidTarget()` / `iosArm64()` slot in without touching `commonMain`. diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..894be11 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,47 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.compose) +} + +android { + namespace = "com.jsjdesigns.poker" + compileSdk = 37 + + defaultConfig { + applicationId = "com.jsjdesigns.poker" + minSdk = 26 + targetSdk = 37 + versionCode = 1 + versionName = "0.1.0" + } + + buildTypes { + release { isMinifyEnabled = false } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + buildFeatures { compose = true } +} + +dependencies { + implementation(project(":engine")) + implementation(libs.kotlinx.coroutines.android) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.lifecycle.viewmodel.compose) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.lifecycle.runtime.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + debugImplementation(libs.androidx.compose.ui.tooling) + + testImplementation(libs.junit) + testImplementation(libs.kotlinx.coroutines.test) +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..5587b1b --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/app/src/main/java/com/jsjdesigns/poker/CardArt.kt b/app/src/main/java/com/jsjdesigns/poker/CardArt.kt new file mode 100644 index 0000000..ece56a4 --- /dev/null +++ b/app/src/main/java/com/jsjdesigns/poker/CardArt.kt @@ -0,0 +1,74 @@ +package com.jsjdesigns.poker + +import androidx.annotation.DrawableRes + +/** + * Maps a deck index (0..51) to its drawable. + * + * Generated by tools/generate_card_assets.sh's companion step — regenerate rather + * than hand-editing. References are static so R8 resource shrinking cannot strip + * the artwork, which `getIdentifier` lookups would risk. + * + * Order matches [com.jsjdesigns.poker.core.Card]: index = (rank - 2) * 4 + suit, + * suits ordered clubs, diamonds, hearts, spades. + */ +private val CARD_FACES = intArrayOf( + R.drawable.card_2_of_clubs, // 0 + R.drawable.card_2_of_diamonds, // 1 + R.drawable.card_2_of_hearts, // 2 + R.drawable.card_2_of_spades, // 3 + R.drawable.card_3_of_clubs, // 4 + R.drawable.card_3_of_diamonds, // 5 + R.drawable.card_3_of_hearts, // 6 + R.drawable.card_3_of_spades, // 7 + R.drawable.card_4_of_clubs, // 8 + R.drawable.card_4_of_diamonds, // 9 + R.drawable.card_4_of_hearts, // 10 + R.drawable.card_4_of_spades, // 11 + R.drawable.card_5_of_clubs, // 12 + R.drawable.card_5_of_diamonds, // 13 + R.drawable.card_5_of_hearts, // 14 + R.drawable.card_5_of_spades, // 15 + R.drawable.card_6_of_clubs, // 16 + R.drawable.card_6_of_diamonds, // 17 + R.drawable.card_6_of_hearts, // 18 + R.drawable.card_6_of_spades, // 19 + R.drawable.card_7_of_clubs, // 20 + R.drawable.card_7_of_diamonds, // 21 + R.drawable.card_7_of_hearts, // 22 + R.drawable.card_7_of_spades, // 23 + R.drawable.card_8_of_clubs, // 24 + R.drawable.card_8_of_diamonds, // 25 + R.drawable.card_8_of_hearts, // 26 + R.drawable.card_8_of_spades, // 27 + R.drawable.card_9_of_clubs, // 28 + R.drawable.card_9_of_diamonds, // 29 + R.drawable.card_9_of_hearts, // 30 + R.drawable.card_9_of_spades, // 31 + R.drawable.card_10_of_clubs, // 32 + R.drawable.card_10_of_diamonds, // 33 + R.drawable.card_10_of_hearts, // 34 + R.drawable.card_10_of_spades, // 35 + R.drawable.card_jack_of_clubs, // 36 + R.drawable.card_jack_of_diamonds, // 37 + R.drawable.card_jack_of_hearts, // 38 + R.drawable.card_jack_of_spades, // 39 + R.drawable.card_queen_of_clubs, // 40 + R.drawable.card_queen_of_diamonds, // 41 + R.drawable.card_queen_of_hearts, // 42 + R.drawable.card_queen_of_spades, // 43 + R.drawable.card_king_of_clubs, // 44 + R.drawable.card_king_of_diamonds, // 45 + R.drawable.card_king_of_hearts, // 46 + R.drawable.card_king_of_spades, // 47 + R.drawable.card_ace_of_clubs, // 48 + R.drawable.card_ace_of_diamonds, // 49 + R.drawable.card_ace_of_hearts, // 50 + R.drawable.card_ace_of_spades, // 51 +) + +@DrawableRes +fun cardFace(index: Int): Int = CARD_FACES[index] + +@DrawableRes +fun cardBack(): Int = R.drawable.card_back diff --git a/app/src/main/java/com/jsjdesigns/poker/MainActivity.kt b/app/src/main/java/com/jsjdesigns/poker/MainActivity.kt new file mode 100644 index 0000000..b8f5235 --- /dev/null +++ b/app/src/main/java/com/jsjdesigns/poker/MainActivity.kt @@ -0,0 +1,20 @@ +package com.jsjdesigns.poker + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.lifecycle.viewmodel.compose.viewModel + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + MaterialTheme(colorScheme = darkColorScheme()) { + val vm: PokerViewModel = viewModel() + TableScreen(vm) + } + } + } +} diff --git a/app/src/main/java/com/jsjdesigns/poker/PokerViewModel.kt b/app/src/main/java/com/jsjdesigns/poker/PokerViewModel.kt new file mode 100644 index 0000000..6aa84ec --- /dev/null +++ b/app/src/main/java/com/jsjdesigns/poker/PokerViewModel.kt @@ -0,0 +1,139 @@ +package com.jsjdesigns.poker + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.jsjdesigns.poker.bot.BotProfile +import com.jsjdesigns.poker.bot.MathBot +import com.jsjdesigns.poker.bot.PlayStyle +import com.jsjdesigns.poker.bot.SkillLevel +import com.jsjdesigns.poker.game.Action +import com.jsjdesigns.poker.game.ActionType +import com.jsjdesigns.poker.game.HumanAgent +import com.jsjdesigns.poker.game.Seat +import com.jsjdesigns.poker.game.Table +import com.jsjdesigns.poker.game.TableSnapshot +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import kotlin.random.Random + +const val HERO_SEAT = 0 +private const val STARTING_STACK = 200 +private const val SMALL_BLIND = 1 +private const val BIG_BLIND = 2 + +data class UiState( + val snapshot: TableSnapshot? = null, + val handsPlayed: Int = 0, + val message: String? = null, +) + +/** + * Drives a continuous cash game and publishes it to Compose. + * + * **Frames are queued, not conflated.** The engine can emit the flop, turn and + * river of an all-in runout within microseconds of each other. Pushing those + * straight into a `StateFlow` would collapse them — `StateFlow` keeps only the + * latest value — and the board would appear to jump from empty to complete. + * Instead the engine's suspending observer sends into a [Channel], a consumer + * paces each frame, and only then is `StateFlow` updated. Because the observer + * suspends when the channel is full, the engine cannot outrun the animation: + * backpressure does the pacing for us. + */ +class PokerViewModel : ViewModel() { + + private val human = HumanAgent() + private val frames = Channel(capacity = 32) + + private val _state = MutableStateFlow(UiState()) + val state: StateFlow = _state.asStateFlow() + + /** What the player is being asked to decide, or null when it isn't their turn. */ + val offer = human.offer + + private val roster = listOf( + BotProfile("You", SkillLevel.EXPERT, PlayStyle.TIGHT_AGGRESSIVE), + BotProfile("Ada", SkillLevel.EXPERT, PlayStyle.TIGHT_AGGRESSIVE, "Ice-cold. Punishes mistakes."), + BotProfile("Bruno", SkillLevel.ADVANCED, PlayStyle.LOOSE_AGGRESSIVE, "Relentless pressure."), + BotProfile("Cleo", SkillLevel.INTERMEDIATE, PlayStyle.TRAPPER, "Quiet until she has you."), + BotProfile("Dex", SkillLevel.INTERMEDIATE, PlayStyle.CALLING_STATION, "Pays to see it."), + BotProfile("Enzo", SkillLevel.BEGINNER, PlayStyle.MANIAC, "Chaos, and certain he's winning."), + ) + + private val seats: List + private val table: Table + + init { + val deckRandom = Random(System.nanoTime()) + seats = roster.mapIndexed { i, profile -> + val agent = if (i == HERO_SEAT) human else MathBot(profile, Random(deckRandom.nextLong())) + Seat(i, profile.name, STARTING_STACK, agent) + } + table = Table( + seats = seats, + smallBlind = SMALL_BLIND, + bigBlind = BIG_BLIND, + random = deckRandom, + observer = { frames.send(it) }, + ) + + viewModelScope.launch { consumeFrames() } + viewModelScope.launch(Dispatchers.Default) { playContinuously() } + } + + private suspend fun consumeFrames() { + for (frame in frames) { + _state.value = _state.value.copy(snapshot = frame.maskedFor(HERO_SEAT)) + delay(pacingMillis(frame)) + } + } + + /** + * How long to hold a frame on screen. Zero when the player is on the clock — + * never make someone wait to act — and longest for cards landing and for the + * showdown, which are the moments worth watching. + */ + private fun pacingMillis(frame: TableSnapshot): Long = when (frame.phase) { + TableSnapshot.Phase.DEALT -> 400 + TableSnapshot.Phase.BETTING -> + if (frame.toAct == HERO_SEAT) 0 else if (frame.toAct != null) 250 else 450 + TableSnapshot.Phase.STREET_COMPLETE -> 700 + TableSnapshot.Phase.SHOWDOWN -> 2200 + TableSnapshot.Phase.COMPLETE -> 1200 + } + + private suspend fun playContinuously() { + while (true) { + // Cash-game convention: top anyone back up who cannot cover a blind. + for (s in seats) if (s.stack < BIG_BLIND) s.stack = STARTING_STACK + table.advanceButton() + runCatching { table.playHand() } + .onSuccess { _state.value = _state.value.copy(handsPlayed = _state.value.handsPlayed + 1) } + .onFailure { return } // scope cancelled: the screen went away + } + } + + fun submit(action: Action) { + viewModelScope.launch { human.submit(action) } + } + + fun fold() = submit(Action(ActionType.FOLD)) + + fun checkOrCall() { + val o = offer.value ?: return + submit(if (o.canCheck) Action(ActionType.CHECK) else Action(ActionType.CALL, o.toCall)) + } + + fun raiseTo(amount: Int) = submit(Action(ActionType.RAISE, amount)) + + override fun onCleared() { + // Release a hand parked on human input so the coroutine can finish. + viewModelScope.launch { human.cancel() } + frames.close() + super.onCleared() + } +} diff --git a/app/src/main/java/com/jsjdesigns/poker/TableScreen.kt b/app/src/main/java/com/jsjdesigns/poker/TableScreen.kt new file mode 100644 index 0000000..2a83d19 --- /dev/null +++ b/app/src/main/java/com/jsjdesigns/poker/TableScreen.kt @@ -0,0 +1,260 @@ +package com.jsjdesigns.poker + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Slider +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.jsjdesigns.poker.game.SeatSnapshot +import com.jsjdesigns.poker.game.TableSnapshot + +private val Felt = Color(0xFF0B3D26) + +@Composable +fun TableScreen(vm: PokerViewModel) { + val state by vm.state.collectAsStateWithLifecycle() + val offer by vm.offer.collectAsStateWithLifecycle() + val snap = state.snapshot + + Column( + modifier = Modifier + .fillMaxSize() + .background(Felt) + .systemBarsPadding() + .padding(12.dp), + ) { + Text( + text = "Hand ${state.handsPlayed + 1} ${snap?.street ?: ""}", + color = Color.White.copy(alpha = 0.6f), + fontSize = 12.sp, + ) + + Spacer(Modifier.height(8.dp)) + + // Opponents + // Weighted rather than fixed-width: five opponents must all fit on a + // phone, and a horizontally scrolling table hides players from you. + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { + snap?.seats?.filter { it.index != HERO_SEAT }?.forEach { seat -> + Box(Modifier.weight(1f)) { + OpponentSeat(seat, isTurn = snap.toAct == seat.index) + } + } + } + + Spacer(Modifier.weight(1f)) + + // Board and pot + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = "POT ${snap?.pot ?: 0}", + color = Color(0xFFE3C179), + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + ) + Spacer(Modifier.height(8.dp)) + Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { + val board = snap?.board.orEmpty() + repeat(5) { i -> + if (i < board.size) { + CardImage(board[i], Modifier.size(54.dp, 81.dp)) + } else { + Box( + Modifier + .size(54.dp, 81.dp) + .clip(RoundedCornerShape(4.dp)) + .background(Color.White.copy(alpha = 0.06f)), + ) + } + } + } + } + + Spacer(Modifier.weight(1f)) + + // Hero + val hero = snap?.seats?.firstOrNull { it.index == HERO_SEAT } + HeroSeat(hero, isTurn = snap?.toAct == HERO_SEAT) + + Spacer(Modifier.height(12.dp)) + + ActionBar( + offer = offer, + onFold = vm::fold, + onCheckCall = vm::checkOrCall, + onRaise = vm::raiseTo, + ) + } +} + +@Composable +private fun OpponentSeat(seat: SeatSnapshot, isTurn: Boolean) { + Card( + colors = CardDefaults.cardColors( + containerColor = if (isTurn) Color(0xFF1D6B45) else Color.White.copy(alpha = 0.07f), + ), + modifier = Modifier.fillMaxWidth(), + ) { + Column( + modifier = Modifier.padding(6.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Row(horizontalArrangement = Arrangement.spacedBy(2.dp)) { + if (seat.folded) { + Box(Modifier.size(24.dp, 36.dp)) + } else { + val hole = seat.hole + repeat(2) { i -> + CardImage(hole?.getOrNull(i), Modifier.size(24.dp, 36.dp)) + } + } + } + Spacer(Modifier.height(4.dp)) + Text( + seat.name + if (seat.isButton) " ⏺" else "", + color = Color.White, + fontSize = 11.sp, + fontWeight = FontWeight.Medium, + modifier = Modifier.alpha(if (seat.folded) 0.4f else 1f), + ) + Text( + if (seat.allIn) "ALL IN" else "${seat.stack}", + color = if (seat.allIn) Color(0xFFE3C179) else Color.White.copy(alpha = 0.7f), + fontSize = 11.sp, + ) + if (seat.committedThisRound > 0) { + Text( + "bet ${seat.committedThisRound}", + color = Color(0xFFE3C179), + fontSize = 10.sp, + ) + } + } + } +} + +@Composable +private fun HeroSeat(seat: SeatSnapshot?, isTurn: Boolean) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(12.dp), + ) { + Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { + repeat(2) { i -> + CardImage(seat?.hole?.getOrNull(i), Modifier.size(64.dp, 96.dp)) + } + } + Column { + Text( + (seat?.name ?: "You") + if (seat?.isButton == true) " ⏺" else "", + color = if (isTurn) Color(0xFFE3C179) else Color.White, + fontWeight = FontWeight.Bold, + ) + Text("${seat?.stack ?: 0}", color = Color.White.copy(alpha = 0.75f)) + if ((seat?.committedThisRound ?: 0) > 0) { + Text("bet ${seat?.committedThisRound}", color = Color(0xFFE3C179), fontSize = 12.sp) + } + } + } +} + +@Composable +private fun ActionBar( + offer: com.jsjdesigns.poker.game.DecisionOffer?, + onFold: () -> Unit, + onCheckCall: () -> Unit, + onRaise: (Int) -> Unit, +) { + if (offer == null) { + Box(Modifier.fillMaxWidth().height(96.dp), contentAlignment = Alignment.Center) { + Text("Waiting…", color = Color.White.copy(alpha = 0.4f)) + } + return + } + + var raiseTo by remember { mutableIntStateOf(offer.minRaiseTo) } + // Reset the slider whenever a new decision arrives, or it keeps the old hand's value. + LaunchedEffect(offer) { raiseTo = offer.minRaiseTo } + + Column(Modifier.fillMaxWidth()) { + if (offer.canRaise && offer.maxRaiseTo > offer.minRaiseTo) { + Text("Raise to $raiseTo", color = Color.White, fontSize = 13.sp) + Slider( + value = raiseTo.toFloat(), + onValueChange = { raiseTo = it.toInt() }, + valueRange = offer.minRaiseTo.toFloat()..offer.maxRaiseTo.toFloat(), + ) + } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + Button( + onClick = onFold, + modifier = Modifier.weight(1f), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF8F1218)), + ) { Text("Fold") } + + Button( + onClick = onCheckCall, + modifier = Modifier.weight(1f), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2C6E49)), + ) { Text(if (offer.canCheck) "Check" else "Call ${offer.toCall}") } + + if (offer.canRaise && offer.maxRaiseTo > offer.minRaiseTo) { + Button( + onClick = { onRaise(raiseTo) }, + modifier = Modifier.weight(1f), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF14357A)), + ) { Text(if (raiseTo >= offer.maxRaiseTo) "All in" else "Raise") } + } + } + } +} + +@Composable +private fun CardImage(index: Int?, modifier: Modifier) { + Image( + painter = painterResource(if (index != null) cardFace(index) else cardBack()), + contentDescription = null, + modifier = modifier.clip(RoundedCornerShape(4.dp)), + ) +} diff --git a/app/src/main/res/drawable-hdpi/card_10_of_clubs.png b/app/src/main/res/drawable-hdpi/card_10_of_clubs.png new file mode 100644 index 0000000..061135f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_10_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_10_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_10_of_diamonds.png new file mode 100644 index 0000000..5c08e11 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_10_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_10_of_hearts.png b/app/src/main/res/drawable-hdpi/card_10_of_hearts.png new file mode 100644 index 0000000..1865743 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_10_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_10_of_spades.png b/app/src/main/res/drawable-hdpi/card_10_of_spades.png new file mode 100644 index 0000000..9ce8f60 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_10_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_2_of_clubs.png b/app/src/main/res/drawable-hdpi/card_2_of_clubs.png new file mode 100644 index 0000000..fb658b7 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_2_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_2_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_2_of_diamonds.png new file mode 100644 index 0000000..03b3aa8 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_2_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_2_of_hearts.png b/app/src/main/res/drawable-hdpi/card_2_of_hearts.png new file mode 100644 index 0000000..3cc7a38 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_2_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_2_of_spades.png b/app/src/main/res/drawable-hdpi/card_2_of_spades.png new file mode 100644 index 0000000..7a7f28f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_2_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_3_of_clubs.png b/app/src/main/res/drawable-hdpi/card_3_of_clubs.png new file mode 100644 index 0000000..7653eed Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_3_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_3_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_3_of_diamonds.png new file mode 100644 index 0000000..55aa313 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_3_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_3_of_hearts.png b/app/src/main/res/drawable-hdpi/card_3_of_hearts.png new file mode 100644 index 0000000..d569ae2 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_3_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_3_of_spades.png b/app/src/main/res/drawable-hdpi/card_3_of_spades.png new file mode 100644 index 0000000..c59ce01 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_3_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_4_of_clubs.png b/app/src/main/res/drawable-hdpi/card_4_of_clubs.png new file mode 100644 index 0000000..be0aa59 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_4_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_4_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_4_of_diamonds.png new file mode 100644 index 0000000..1e3e32d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_4_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_4_of_hearts.png b/app/src/main/res/drawable-hdpi/card_4_of_hearts.png new file mode 100644 index 0000000..86ef290 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_4_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_4_of_spades.png b/app/src/main/res/drawable-hdpi/card_4_of_spades.png new file mode 100644 index 0000000..b46575b Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_4_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_5_of_clubs.png b/app/src/main/res/drawable-hdpi/card_5_of_clubs.png new file mode 100644 index 0000000..ba55e9a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_5_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_5_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_5_of_diamonds.png new file mode 100644 index 0000000..4c331b0 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_5_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_5_of_hearts.png b/app/src/main/res/drawable-hdpi/card_5_of_hearts.png new file mode 100644 index 0000000..d5bec87 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_5_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_5_of_spades.png b/app/src/main/res/drawable-hdpi/card_5_of_spades.png new file mode 100644 index 0000000..d9c0165 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_5_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_6_of_clubs.png b/app/src/main/res/drawable-hdpi/card_6_of_clubs.png new file mode 100644 index 0000000..9d7c7b5 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_6_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_6_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_6_of_diamonds.png new file mode 100644 index 0000000..50290c3 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_6_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_6_of_hearts.png b/app/src/main/res/drawable-hdpi/card_6_of_hearts.png new file mode 100644 index 0000000..d91b312 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_6_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_6_of_spades.png b/app/src/main/res/drawable-hdpi/card_6_of_spades.png new file mode 100644 index 0000000..d225342 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_6_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_7_of_clubs.png b/app/src/main/res/drawable-hdpi/card_7_of_clubs.png new file mode 100644 index 0000000..eab9c85 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_7_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_7_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_7_of_diamonds.png new file mode 100644 index 0000000..40a3581 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_7_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_7_of_hearts.png b/app/src/main/res/drawable-hdpi/card_7_of_hearts.png new file mode 100644 index 0000000..88e1103 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_7_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_7_of_spades.png b/app/src/main/res/drawable-hdpi/card_7_of_spades.png new file mode 100644 index 0000000..c56c9c3 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_7_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_8_of_clubs.png b/app/src/main/res/drawable-hdpi/card_8_of_clubs.png new file mode 100644 index 0000000..9f39e34 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_8_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_8_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_8_of_diamonds.png new file mode 100644 index 0000000..51a434e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_8_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_8_of_hearts.png b/app/src/main/res/drawable-hdpi/card_8_of_hearts.png new file mode 100644 index 0000000..31e0417 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_8_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_8_of_spades.png b/app/src/main/res/drawable-hdpi/card_8_of_spades.png new file mode 100644 index 0000000..bcb5810 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_8_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_9_of_clubs.png b/app/src/main/res/drawable-hdpi/card_9_of_clubs.png new file mode 100644 index 0000000..c4de5da Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_9_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_9_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_9_of_diamonds.png new file mode 100644 index 0000000..4a32804 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_9_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_9_of_hearts.png b/app/src/main/res/drawable-hdpi/card_9_of_hearts.png new file mode 100644 index 0000000..4943fcd Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_9_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_9_of_spades.png b/app/src/main/res/drawable-hdpi/card_9_of_spades.png new file mode 100644 index 0000000..25f4f34 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_9_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_ace_of_clubs.png b/app/src/main/res/drawable-hdpi/card_ace_of_clubs.png new file mode 100644 index 0000000..6ab66b8 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_ace_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_ace_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_ace_of_diamonds.png new file mode 100644 index 0000000..f49f833 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_ace_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_ace_of_hearts.png b/app/src/main/res/drawable-hdpi/card_ace_of_hearts.png new file mode 100644 index 0000000..0460f39 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_ace_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_ace_of_spades.png b/app/src/main/res/drawable-hdpi/card_ace_of_spades.png new file mode 100644 index 0000000..521a7bd Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_ace_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_back.png b/app/src/main/res/drawable-hdpi/card_back.png new file mode 100644 index 0000000..a1a3590 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_back.png differ diff --git a/app/src/main/res/drawable-hdpi/card_back_blue.png b/app/src/main/res/drawable-hdpi/card_back_blue.png new file mode 100644 index 0000000..fd7a622 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_back_blue.png differ diff --git a/app/src/main/res/drawable-hdpi/card_back_red.png b/app/src/main/res/drawable-hdpi/card_back_red.png new file mode 100644 index 0000000..a1a3590 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_back_red.png differ diff --git a/app/src/main/res/drawable-hdpi/card_jack_of_clubs.png b/app/src/main/res/drawable-hdpi/card_jack_of_clubs.png new file mode 100644 index 0000000..5b02422 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_jack_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_jack_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_jack_of_diamonds.png new file mode 100644 index 0000000..8ddcff9 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_jack_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_jack_of_hearts.png b/app/src/main/res/drawable-hdpi/card_jack_of_hearts.png new file mode 100644 index 0000000..0fd51df Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_jack_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_jack_of_spades.png b/app/src/main/res/drawable-hdpi/card_jack_of_spades.png new file mode 100644 index 0000000..9a40209 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_jack_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_king_of_clubs.png b/app/src/main/res/drawable-hdpi/card_king_of_clubs.png new file mode 100644 index 0000000..8b16952 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_king_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_king_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_king_of_diamonds.png new file mode 100644 index 0000000..076d1c9 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_king_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_king_of_hearts.png b/app/src/main/res/drawable-hdpi/card_king_of_hearts.png new file mode 100644 index 0000000..68c6ad4 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_king_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_king_of_spades.png b/app/src/main/res/drawable-hdpi/card_king_of_spades.png new file mode 100644 index 0000000..8e9cb78 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_king_of_spades.png differ diff --git a/app/src/main/res/drawable-hdpi/card_queen_of_clubs.png b/app/src/main/res/drawable-hdpi/card_queen_of_clubs.png new file mode 100644 index 0000000..e644152 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_queen_of_clubs.png differ diff --git a/app/src/main/res/drawable-hdpi/card_queen_of_diamonds.png b/app/src/main/res/drawable-hdpi/card_queen_of_diamonds.png new file mode 100644 index 0000000..929a4ac Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_queen_of_diamonds.png differ diff --git a/app/src/main/res/drawable-hdpi/card_queen_of_hearts.png b/app/src/main/res/drawable-hdpi/card_queen_of_hearts.png new file mode 100644 index 0000000..055ac2c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_queen_of_hearts.png differ diff --git a/app/src/main/res/drawable-hdpi/card_queen_of_spades.png b/app/src/main/res/drawable-hdpi/card_queen_of_spades.png new file mode 100644 index 0000000..fb7ea2c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/card_queen_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_10_of_clubs.png b/app/src/main/res/drawable-mdpi/card_10_of_clubs.png new file mode 100644 index 0000000..f810aef Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_10_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_10_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_10_of_diamonds.png new file mode 100644 index 0000000..244a276 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_10_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_10_of_hearts.png b/app/src/main/res/drawable-mdpi/card_10_of_hearts.png new file mode 100644 index 0000000..e79fc00 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_10_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_10_of_spades.png b/app/src/main/res/drawable-mdpi/card_10_of_spades.png new file mode 100644 index 0000000..25b44a1 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_10_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_2_of_clubs.png b/app/src/main/res/drawable-mdpi/card_2_of_clubs.png new file mode 100644 index 0000000..6196347 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_2_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_2_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_2_of_diamonds.png new file mode 100644 index 0000000..5665fab Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_2_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_2_of_hearts.png b/app/src/main/res/drawable-mdpi/card_2_of_hearts.png new file mode 100644 index 0000000..52aacb5 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_2_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_2_of_spades.png b/app/src/main/res/drawable-mdpi/card_2_of_spades.png new file mode 100644 index 0000000..1a7e1f8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_2_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_3_of_clubs.png b/app/src/main/res/drawable-mdpi/card_3_of_clubs.png new file mode 100644 index 0000000..0340059 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_3_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_3_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_3_of_diamonds.png new file mode 100644 index 0000000..083f8db Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_3_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_3_of_hearts.png b/app/src/main/res/drawable-mdpi/card_3_of_hearts.png new file mode 100644 index 0000000..c69ba25 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_3_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_3_of_spades.png b/app/src/main/res/drawable-mdpi/card_3_of_spades.png new file mode 100644 index 0000000..3fbc644 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_3_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_4_of_clubs.png b/app/src/main/res/drawable-mdpi/card_4_of_clubs.png new file mode 100644 index 0000000..0750b1a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_4_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_4_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_4_of_diamonds.png new file mode 100644 index 0000000..e713af7 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_4_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_4_of_hearts.png b/app/src/main/res/drawable-mdpi/card_4_of_hearts.png new file mode 100644 index 0000000..13bfa45 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_4_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_4_of_spades.png b/app/src/main/res/drawable-mdpi/card_4_of_spades.png new file mode 100644 index 0000000..895ce53 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_4_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_5_of_clubs.png b/app/src/main/res/drawable-mdpi/card_5_of_clubs.png new file mode 100644 index 0000000..3a70e09 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_5_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_5_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_5_of_diamonds.png new file mode 100644 index 0000000..784249f Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_5_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_5_of_hearts.png b/app/src/main/res/drawable-mdpi/card_5_of_hearts.png new file mode 100644 index 0000000..cd0860b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_5_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_5_of_spades.png b/app/src/main/res/drawable-mdpi/card_5_of_spades.png new file mode 100644 index 0000000..267b625 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_5_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_6_of_clubs.png b/app/src/main/res/drawable-mdpi/card_6_of_clubs.png new file mode 100644 index 0000000..30f6c43 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_6_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_6_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_6_of_diamonds.png new file mode 100644 index 0000000..3fead69 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_6_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_6_of_hearts.png b/app/src/main/res/drawable-mdpi/card_6_of_hearts.png new file mode 100644 index 0000000..9e92cb6 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_6_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_6_of_spades.png b/app/src/main/res/drawable-mdpi/card_6_of_spades.png new file mode 100644 index 0000000..4c80a33 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_6_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_7_of_clubs.png b/app/src/main/res/drawable-mdpi/card_7_of_clubs.png new file mode 100644 index 0000000..36f0691 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_7_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_7_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_7_of_diamonds.png new file mode 100644 index 0000000..9ee63cc Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_7_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_7_of_hearts.png b/app/src/main/res/drawable-mdpi/card_7_of_hearts.png new file mode 100644 index 0000000..d6196aa Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_7_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_7_of_spades.png b/app/src/main/res/drawable-mdpi/card_7_of_spades.png new file mode 100644 index 0000000..c84847f Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_7_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_8_of_clubs.png b/app/src/main/res/drawable-mdpi/card_8_of_clubs.png new file mode 100644 index 0000000..7bb707b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_8_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_8_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_8_of_diamonds.png new file mode 100644 index 0000000..5d23a03 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_8_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_8_of_hearts.png b/app/src/main/res/drawable-mdpi/card_8_of_hearts.png new file mode 100644 index 0000000..ed7a3dc Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_8_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_8_of_spades.png b/app/src/main/res/drawable-mdpi/card_8_of_spades.png new file mode 100644 index 0000000..26629e0 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_8_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_9_of_clubs.png b/app/src/main/res/drawable-mdpi/card_9_of_clubs.png new file mode 100644 index 0000000..dddc915 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_9_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_9_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_9_of_diamonds.png new file mode 100644 index 0000000..f7aa8cd Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_9_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_9_of_hearts.png b/app/src/main/res/drawable-mdpi/card_9_of_hearts.png new file mode 100644 index 0000000..a97f227 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_9_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_9_of_spades.png b/app/src/main/res/drawable-mdpi/card_9_of_spades.png new file mode 100644 index 0000000..7103ba7 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_9_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_ace_of_clubs.png b/app/src/main/res/drawable-mdpi/card_ace_of_clubs.png new file mode 100644 index 0000000..86a1480 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_ace_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_ace_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_ace_of_diamonds.png new file mode 100644 index 0000000..d9a624b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_ace_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_ace_of_hearts.png b/app/src/main/res/drawable-mdpi/card_ace_of_hearts.png new file mode 100644 index 0000000..4891404 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_ace_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_ace_of_spades.png b/app/src/main/res/drawable-mdpi/card_ace_of_spades.png new file mode 100644 index 0000000..d7ecb3e Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_ace_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_back.png b/app/src/main/res/drawable-mdpi/card_back.png new file mode 100644 index 0000000..a33da9b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_back.png differ diff --git a/app/src/main/res/drawable-mdpi/card_back_blue.png b/app/src/main/res/drawable-mdpi/card_back_blue.png new file mode 100644 index 0000000..6da685a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_back_blue.png differ diff --git a/app/src/main/res/drawable-mdpi/card_back_red.png b/app/src/main/res/drawable-mdpi/card_back_red.png new file mode 100644 index 0000000..a33da9b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_back_red.png differ diff --git a/app/src/main/res/drawable-mdpi/card_jack_of_clubs.png b/app/src/main/res/drawable-mdpi/card_jack_of_clubs.png new file mode 100644 index 0000000..b603864 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_jack_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_jack_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_jack_of_diamonds.png new file mode 100644 index 0000000..df913c8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_jack_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_jack_of_hearts.png b/app/src/main/res/drawable-mdpi/card_jack_of_hearts.png new file mode 100644 index 0000000..12c9d2b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_jack_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_jack_of_spades.png b/app/src/main/res/drawable-mdpi/card_jack_of_spades.png new file mode 100644 index 0000000..eaf5efb Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_jack_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_king_of_clubs.png b/app/src/main/res/drawable-mdpi/card_king_of_clubs.png new file mode 100644 index 0000000..2f96435 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_king_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_king_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_king_of_diamonds.png new file mode 100644 index 0000000..508436a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_king_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_king_of_hearts.png b/app/src/main/res/drawable-mdpi/card_king_of_hearts.png new file mode 100644 index 0000000..6a6f380 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_king_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_king_of_spades.png b/app/src/main/res/drawable-mdpi/card_king_of_spades.png new file mode 100644 index 0000000..3a804fb Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_king_of_spades.png differ diff --git a/app/src/main/res/drawable-mdpi/card_queen_of_clubs.png b/app/src/main/res/drawable-mdpi/card_queen_of_clubs.png new file mode 100644 index 0000000..2d21630 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_queen_of_clubs.png differ diff --git a/app/src/main/res/drawable-mdpi/card_queen_of_diamonds.png b/app/src/main/res/drawable-mdpi/card_queen_of_diamonds.png new file mode 100644 index 0000000..7fde53a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_queen_of_diamonds.png differ diff --git a/app/src/main/res/drawable-mdpi/card_queen_of_hearts.png b/app/src/main/res/drawable-mdpi/card_queen_of_hearts.png new file mode 100644 index 0000000..a3e1810 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_queen_of_hearts.png differ diff --git a/app/src/main/res/drawable-mdpi/card_queen_of_spades.png b/app/src/main/res/drawable-mdpi/card_queen_of_spades.png new file mode 100644 index 0000000..ebad7fd Binary files /dev/null and b/app/src/main/res/drawable-mdpi/card_queen_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_10_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_10_of_clubs.png new file mode 100644 index 0000000..83925d4 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_10_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_10_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_10_of_diamonds.png new file mode 100644 index 0000000..e96bf59 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_10_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_10_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_10_of_hearts.png new file mode 100644 index 0000000..2fe0768 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_10_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_10_of_spades.png b/app/src/main/res/drawable-xhdpi/card_10_of_spades.png new file mode 100644 index 0000000..21f078d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_10_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_2_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_2_of_clubs.png new file mode 100644 index 0000000..6376d14 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_2_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_2_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_2_of_diamonds.png new file mode 100644 index 0000000..8c85d92 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_2_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_2_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_2_of_hearts.png new file mode 100644 index 0000000..689201a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_2_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_2_of_spades.png b/app/src/main/res/drawable-xhdpi/card_2_of_spades.png new file mode 100644 index 0000000..eab86a9 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_2_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_3_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_3_of_clubs.png new file mode 100644 index 0000000..bff6553 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_3_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_3_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_3_of_diamonds.png new file mode 100644 index 0000000..405711e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_3_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_3_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_3_of_hearts.png new file mode 100644 index 0000000..58973fa Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_3_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_3_of_spades.png b/app/src/main/res/drawable-xhdpi/card_3_of_spades.png new file mode 100644 index 0000000..cd7e619 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_3_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_4_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_4_of_clubs.png new file mode 100644 index 0000000..7ee8261 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_4_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_4_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_4_of_diamonds.png new file mode 100644 index 0000000..f453c91 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_4_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_4_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_4_of_hearts.png new file mode 100644 index 0000000..c551599 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_4_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_4_of_spades.png b/app/src/main/res/drawable-xhdpi/card_4_of_spades.png new file mode 100644 index 0000000..db596a2 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_4_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_5_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_5_of_clubs.png new file mode 100644 index 0000000..47a32e6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_5_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_5_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_5_of_diamonds.png new file mode 100644 index 0000000..e28b519 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_5_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_5_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_5_of_hearts.png new file mode 100644 index 0000000..321faac Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_5_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_5_of_spades.png b/app/src/main/res/drawable-xhdpi/card_5_of_spades.png new file mode 100644 index 0000000..322c612 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_5_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_6_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_6_of_clubs.png new file mode 100644 index 0000000..e155286 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_6_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_6_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_6_of_diamonds.png new file mode 100644 index 0000000..03bed89 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_6_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_6_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_6_of_hearts.png new file mode 100644 index 0000000..1da3496 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_6_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_6_of_spades.png b/app/src/main/res/drawable-xhdpi/card_6_of_spades.png new file mode 100644 index 0000000..8d25429 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_6_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_7_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_7_of_clubs.png new file mode 100644 index 0000000..1eef2a4 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_7_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_7_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_7_of_diamonds.png new file mode 100644 index 0000000..dcf486e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_7_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_7_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_7_of_hearts.png new file mode 100644 index 0000000..ca5a36c Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_7_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_7_of_spades.png b/app/src/main/res/drawable-xhdpi/card_7_of_spades.png new file mode 100644 index 0000000..adee0df Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_7_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_8_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_8_of_clubs.png new file mode 100644 index 0000000..3ab11b5 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_8_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_8_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_8_of_diamonds.png new file mode 100644 index 0000000..98751a6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_8_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_8_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_8_of_hearts.png new file mode 100644 index 0000000..97e4af6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_8_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_8_of_spades.png b/app/src/main/res/drawable-xhdpi/card_8_of_spades.png new file mode 100644 index 0000000..5f9ebfb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_8_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_9_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_9_of_clubs.png new file mode 100644 index 0000000..f41babb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_9_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_9_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_9_of_diamonds.png new file mode 100644 index 0000000..2161e0b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_9_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_9_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_9_of_hearts.png new file mode 100644 index 0000000..cad8e97 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_9_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_9_of_spades.png b/app/src/main/res/drawable-xhdpi/card_9_of_spades.png new file mode 100644 index 0000000..da1f0a3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_9_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_ace_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_ace_of_clubs.png new file mode 100644 index 0000000..02c7c0a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_ace_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_ace_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_ace_of_diamonds.png new file mode 100644 index 0000000..d1b6dea Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_ace_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_ace_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_ace_of_hearts.png new file mode 100644 index 0000000..22c25b2 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_ace_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_ace_of_spades.png b/app/src/main/res/drawable-xhdpi/card_ace_of_spades.png new file mode 100644 index 0000000..56622ba Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_ace_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_back.png b/app/src/main/res/drawable-xhdpi/card_back.png new file mode 100644 index 0000000..6cf2743 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_back.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_back_blue.png b/app/src/main/res/drawable-xhdpi/card_back_blue.png new file mode 100644 index 0000000..92dc440 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_back_blue.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_back_red.png b/app/src/main/res/drawable-xhdpi/card_back_red.png new file mode 100644 index 0000000..6cf2743 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_back_red.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_jack_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_jack_of_clubs.png new file mode 100644 index 0000000..28581ef Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_jack_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_jack_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_jack_of_diamonds.png new file mode 100644 index 0000000..2dddef3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_jack_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_jack_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_jack_of_hearts.png new file mode 100644 index 0000000..36af5e0 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_jack_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_jack_of_spades.png b/app/src/main/res/drawable-xhdpi/card_jack_of_spades.png new file mode 100644 index 0000000..5238a97 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_jack_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_king_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_king_of_clubs.png new file mode 100644 index 0000000..33723e7 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_king_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_king_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_king_of_diamonds.png new file mode 100644 index 0000000..9517967 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_king_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_king_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_king_of_hearts.png new file mode 100644 index 0000000..b3421e3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_king_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_king_of_spades.png b/app/src/main/res/drawable-xhdpi/card_king_of_spades.png new file mode 100644 index 0000000..c7432bf Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_king_of_spades.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_queen_of_clubs.png b/app/src/main/res/drawable-xhdpi/card_queen_of_clubs.png new file mode 100644 index 0000000..e2b3b52 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_queen_of_clubs.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_queen_of_diamonds.png b/app/src/main/res/drawable-xhdpi/card_queen_of_diamonds.png new file mode 100644 index 0000000..139bc29 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_queen_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_queen_of_hearts.png b/app/src/main/res/drawable-xhdpi/card_queen_of_hearts.png new file mode 100644 index 0000000..2f952d2 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_queen_of_hearts.png differ diff --git a/app/src/main/res/drawable-xhdpi/card_queen_of_spades.png b/app/src/main/res/drawable-xhdpi/card_queen_of_spades.png new file mode 100644 index 0000000..8b244b3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/card_queen_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_10_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_10_of_clubs.png new file mode 100644 index 0000000..02d7057 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_10_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_10_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_10_of_diamonds.png new file mode 100644 index 0000000..45e92df Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_10_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_10_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_10_of_hearts.png new file mode 100644 index 0000000..33545c1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_10_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_10_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_10_of_spades.png new file mode 100644 index 0000000..ea93a39 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_10_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_2_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_2_of_clubs.png new file mode 100644 index 0000000..e983203 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_2_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_2_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_2_of_diamonds.png new file mode 100644 index 0000000..400696e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_2_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_2_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_2_of_hearts.png new file mode 100644 index 0000000..7484860 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_2_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_2_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_2_of_spades.png new file mode 100644 index 0000000..2f1a489 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_2_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_3_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_3_of_clubs.png new file mode 100644 index 0000000..a21f9d2 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_3_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_3_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_3_of_diamonds.png new file mode 100644 index 0000000..4e28c0d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_3_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_3_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_3_of_hearts.png new file mode 100644 index 0000000..26a5081 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_3_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_3_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_3_of_spades.png new file mode 100644 index 0000000..a906fb6 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_3_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_4_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_4_of_clubs.png new file mode 100644 index 0000000..05409e0 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_4_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_4_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_4_of_diamonds.png new file mode 100644 index 0000000..1ad36fa Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_4_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_4_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_4_of_hearts.png new file mode 100644 index 0000000..09afe76 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_4_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_4_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_4_of_spades.png new file mode 100644 index 0000000..edd4731 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_4_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_5_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_5_of_clubs.png new file mode 100644 index 0000000..74a3fc3 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_5_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_5_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_5_of_diamonds.png new file mode 100644 index 0000000..eefa04d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_5_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_5_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_5_of_hearts.png new file mode 100644 index 0000000..d52d51c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_5_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_5_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_5_of_spades.png new file mode 100644 index 0000000..bffa28b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_5_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_6_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_6_of_clubs.png new file mode 100644 index 0000000..beb15c7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_6_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_6_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_6_of_diamonds.png new file mode 100644 index 0000000..59db265 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_6_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_6_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_6_of_hearts.png new file mode 100644 index 0000000..5e93d93 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_6_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_6_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_6_of_spades.png new file mode 100644 index 0000000..80cd1b4 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_6_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_7_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_7_of_clubs.png new file mode 100644 index 0000000..99720b0 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_7_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_7_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_7_of_diamonds.png new file mode 100644 index 0000000..056e195 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_7_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_7_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_7_of_hearts.png new file mode 100644 index 0000000..0c6294c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_7_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_7_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_7_of_spades.png new file mode 100644 index 0000000..b65b745 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_7_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_8_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_8_of_clubs.png new file mode 100644 index 0000000..bbda0f6 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_8_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_8_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_8_of_diamonds.png new file mode 100644 index 0000000..009dd1f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_8_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_8_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_8_of_hearts.png new file mode 100644 index 0000000..0729966 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_8_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_8_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_8_of_spades.png new file mode 100644 index 0000000..d13f0bc Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_8_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_9_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_9_of_clubs.png new file mode 100644 index 0000000..091909c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_9_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_9_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_9_of_diamonds.png new file mode 100644 index 0000000..d7daaea Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_9_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_9_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_9_of_hearts.png new file mode 100644 index 0000000..ab778a0 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_9_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_9_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_9_of_spades.png new file mode 100644 index 0000000..c4e6491 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_9_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_ace_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_ace_of_clubs.png new file mode 100644 index 0000000..e2e44f9 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_ace_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_ace_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_ace_of_diamonds.png new file mode 100644 index 0000000..6107768 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_ace_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_ace_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_ace_of_hearts.png new file mode 100644 index 0000000..c0d63c8 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_ace_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_ace_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_ace_of_spades.png new file mode 100644 index 0000000..22bacf8 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_ace_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_back.png b/app/src/main/res/drawable-xxhdpi/card_back.png new file mode 100644 index 0000000..8659897 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_back.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_back_blue.png b/app/src/main/res/drawable-xxhdpi/card_back_blue.png new file mode 100644 index 0000000..dcd083d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_back_blue.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_back_red.png b/app/src/main/res/drawable-xxhdpi/card_back_red.png new file mode 100644 index 0000000..8659897 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_back_red.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_jack_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_jack_of_clubs.png new file mode 100644 index 0000000..c260f94 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_jack_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_jack_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_jack_of_diamonds.png new file mode 100644 index 0000000..8b3e94a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_jack_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_jack_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_jack_of_hearts.png new file mode 100644 index 0000000..9cbc5fa Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_jack_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_jack_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_jack_of_spades.png new file mode 100644 index 0000000..b166e80 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_jack_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_king_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_king_of_clubs.png new file mode 100644 index 0000000..96eba0f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_king_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_king_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_king_of_diamonds.png new file mode 100644 index 0000000..ed15874 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_king_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_king_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_king_of_hearts.png new file mode 100644 index 0000000..317cf4b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_king_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_king_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_king_of_spades.png new file mode 100644 index 0000000..589f2cb Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_king_of_spades.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_queen_of_clubs.png b/app/src/main/res/drawable-xxhdpi/card_queen_of_clubs.png new file mode 100644 index 0000000..0be27f7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_queen_of_clubs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_queen_of_diamonds.png b/app/src/main/res/drawable-xxhdpi/card_queen_of_diamonds.png new file mode 100644 index 0000000..f996aed Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_queen_of_diamonds.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_queen_of_hearts.png b/app/src/main/res/drawable-xxhdpi/card_queen_of_hearts.png new file mode 100644 index 0000000..a3544ad Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_queen_of_hearts.png differ diff --git a/app/src/main/res/drawable-xxhdpi/card_queen_of_spades.png b/app/src/main/res/drawable-xxhdpi/card_queen_of_spades.png new file mode 100644 index 0000000..a477a91 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/card_queen_of_spades.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..6861825 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Hold\'em + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..de174d9 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,7 @@ + + + + diff --git a/build.gradle.kts b/build.gradle.kts index 58b2789..b9f09a2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,6 @@ plugins { alias(libs.plugins.kotlin.multiplatform) apply false alias(libs.plugins.kotlin.jvm) apply false - alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.kotlin.compose) apply false alias(libs.plugins.android.application) apply false alias(libs.plugins.android.kotlin.multiplatform.library) apply false diff --git a/engine/src/commonTest/kotlin/com/jsjdesigns/poker/game/SnapshotDeliveryTest.kt b/engine/src/commonTest/kotlin/com/jsjdesigns/poker/game/SnapshotDeliveryTest.kt new file mode 100644 index 0000000..9bda8aa --- /dev/null +++ b/engine/src/commonTest/kotlin/com/jsjdesigns/poker/game/SnapshotDeliveryTest.kt @@ -0,0 +1,104 @@ +package com.jsjdesigns.poker.game + +import com.jsjdesigns.poker.core.StackedDeck +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import kotlin.random.Random +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +private class Shoves : PlayerAgent { + override suspend fun act(ctx: DecisionContext): Action = when { + ctx.canRaise -> Action(ActionType.RAISE, ctx.maxRaiseTo) + ctx.toCall > 0 -> Action(ActionType.CALL, ctx.toCall) + else -> Action(ActionType.CHECK) + } +} + +/** + * How snapshots reach the UI matters as much as what is in them. + * + * An all-in runout emits flop, turn and river within microseconds. A consumer + * that keeps only the latest value will show the player an empty board and then a + * complete one, losing the runout entirely. + */ +class SnapshotDeliveryTest { + + private fun table(observer: suspend (TableSnapshot) -> Unit, seats: List) = Table( + seats = seats, + smallBlind = 5, + bigBlind = 10, + random = Random(1), + deck = StackedDeck.of(listOf("Ah Ad", "Kh Kd"), "2c 7d 9s Jc 3h"), + observer = observer, + ) + + @Test + fun `a channel preserves every runout frame`() = runTest { + val received = mutableListOf() + val channel = Channel(capacity = 32) + + val consumer = launch { + for (frame in channel) received += frame + } + + val seats = listOf(Seat(0, "A", 100, Shoves()), Seat(1, "B", 100, Shoves())) + table({ channel.send(it) }, seats).playHand() + channel.close() + consumer.join() + + val boardSizes = received.map { it.board.size }.distinct().sorted() + assertEquals( + listOf(0, 3, 4, 5), boardSizes, + "every stage of the board must survive delivery", + ) + } + + /** + * Documents *why* the channel is required: the same run through a conflating + * StateFlow drops intermediate frames. This is a characterisation test — if it + * ever starts preserving them, the reasoning above can be revisited. + */ + @Test + fun `a conflating StateFlow loses runout frames`() = runTest { + val flow = MutableStateFlow(null) + val observed = mutableListOf() + + val seats = listOf(Seat(0, "A", 100, Shoves()), Seat(1, "B", 100, Shoves())) + // A collector that is not actively suspended on every emission — exactly the + // situation a recomposing UI is in — sees only whatever the latest value is. + table({ flow.value = it; observed += flow.value!! }, seats).playHand() + + // The final value is all a late subscriber would ever see. + val lateSubscriberSees = flow.value + assertEquals(5, lateSubscriberSees?.board?.size, "only the river survives") + assertTrue( + observed.map { it.board.size }.distinct().size > 1, + "the engine did emit intermediate frames; conflation is what loses them", + ) + } + + @Test + fun `backpressure lets a slow consumer keep up without dropping frames`() = runTest { + val received = mutableListOf() + // Capacity 1 forces the engine to wait on nearly every emission. + val channel = Channel(capacity = 1) + + val consumer = launch { + for (frame in channel) received += frame + } + + val seats = listOf(Seat(0, "A", 100, Shoves()), Seat(1, "B", 100, Shoves())) + table({ channel.send(it) }, seats).playHand() + channel.close() + consumer.join() + + assertEquals( + listOf(0, 3, 4, 5), received.map { it.board.size }.distinct().sorted(), + "a suspending observer means the engine cannot outrun the UI", + ) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 76e27bf..088ce34 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,6 +16,7 @@ androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle" } androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" } +androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycle" } androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } diff --git a/settings.gradle.kts b/settings.gradle.kts index cf4fe76..fc20f0b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,4 +21,4 @@ dependencyResolutionManagement { } rootProject.name = "Poker" -include(":engine", ":sim") +include(":engine", ":sim", ":app") diff --git a/tools/generate_card_assets.sh b/tools/generate_card_assets.sh new file mode 100755 index 0000000..4304c19 --- /dev/null +++ b/tools/generate_card_assets.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Rasterises the card SVGs into Android density buckets. +# +# The SVGs in assets/cards/ stay the source of truth; this regenerates the +# drawables at any size. Uses macOS `sips`, which renders SVG directly — no +# librsvg or ImageMagick needed. +# +# Note the `card_` prefix: Android resource names may not start with a digit, so +# `10_of_clubs.svg` must become `card_10_of_clubs.png`. +# +# Usage: tools/generate_card_assets.sh +set -euo pipefail + +SRC="$(cd "$(dirname "$0")/.." && pwd)/assets/cards" +RES="$(cd "$(dirname "$0")/.." && pwd)/app/src/main/res" + +# Card art is 2:3. Widths are chosen so xxhdpi lands at a crisp 240x360. +declare -a BUCKETS=( + "mdpi:80:120" + "hdpi:120:180" + "xhdpi:160:240" + "xxhdpi:240:360" +) + +count=0 +for bucket in "${BUCKETS[@]}"; do + IFS=':' read -r density width height <<< "$bucket" + out="$RES/drawable-$density" + mkdir -p "$out" + for svg in "$SRC"/*.svg; do + base="$(basename "$svg" .svg)" + # playing_cards_deck is the 52-card contact sheet, not a usable game asset. + [ "$base" = "playing_cards_deck" ] && continue + sips -s format png -z "$height" "$width" "$svg" --out "$out/card_$base.png" >/dev/null 2>&1 + count=$((count + 1)) + done + echo " $density (${width}x${height}): $(ls "$out" | wc -l | tr -d ' ') files" +done + +echo "generated $count PNGs" +du -sh "$RES" | awk '{print " total: " $1}'