---
# System prepended metadata

title: 'Android App 設計開發課程 #4'

---


## 剪刀石頭布遊戲三戰兩勝版

```kotlin=
package com.example.hellokotlin

enum class Choice {
    ROCK, PAPER, SCISSORS
}

fun main() {
    var playerWins = 0
    var computerWins = 0
    var round = 0

    while (playerWins < 2 && computerWins < 2) {
        round++
        println("現在是第 $round 局")

        var result = 0
        do {
            println("請出拳：Rock, Paper, Scissors")
            val playerInput = readln().trim().lowercase()

            val playerChoice = when (playerInput) {
                "rock", "r" -> Choice.ROCK
                "paper", "p" -> Choice.PAPER
                "scissors", "s" -> Choice.SCISSORS
                else -> {
                    println("輸入錯誤，請重新輸入\n")
                    continue
                }
            }
            val computerChoice = Choice.entries.random()
            result = (playerChoice.ordinal - computerChoice.ordinal + 3) % 3
            println("玩家出拳：$playerChoice")
            println("電腦出拳：$computerChoice")
            println(
                "結果：${
                    when (result) {
                        0 -> "平手"
                        1 -> {
                            playerWins++
                            "你贏了"
                        }
                        else -> {
                            computerWins++
                            "你輸了"
                        }
                    }
                }\n"
            )
        } while (result == 0)
    }

    if (playerWins > computerWins) {
        println("恭喜你獲得最終勝利！")
    } else {
        println("很遺憾，最終是電腦獲勝了。")
    }
}
```
## 名人語錄 App 素材
![quote-background-1](https://hackmd.io/_uploads/BJ51hhXeR.png)

把檔名改為 `quote-background-1.png`

## 名人語錄加上背景圖
```kotlin=
package com.example.myfirstcomposeapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.myfirstcomposeapp.ui.theme.MyFirstComposeAppTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyFirstComposeAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    QuoteText(message = "Life is like a box of chocolates.", from = "Forrest Gump")
                }
            }
        }
    }
}

@Composable
fun QuoteText(message: String, from: String, modifier: Modifier = Modifier) {
    // Create a column so that texts don't overlap
    Column(
        verticalArrangement = Arrangement.Center,
        modifier = modifier
    ) {
        Text(
            text = message,
            fontSize = 48.sp,
            lineHeight = 55.sp,
            textAlign = TextAlign.Center,
            modifier = Modifier.padding(top = 16.dp),
        )
        Text(
            text = from,
            fontSize = 36.sp,
            modifier = Modifier
                .padding(top = 16.dp)
                .padding(end = 16.dp)
                .align(alignment = Alignment.End)

        )
    }
}

@Composable
fun QuoteImage(message: String, from: String, modifier: Modifier = Modifier) {
    Box(modifier) {
        Image(
            painter = painterResource(R.drawable.quote_background_1),
            contentDescription = null,
            contentScale = ContentScale.Crop,
            alpha = 0.5f,
            modifier = Modifier
                .fillMaxSize()
        )
        QuoteText(
            message = message,
            from = from,
            modifier = Modifier
                .fillMaxSize()
                .padding(8.dp)
        )
    }
}

@Preview(showBackground = true)
@Composable
fun QuotePreview() {
    MyFirstComposeAppTheme {
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colorScheme.background
        ) {
            QuoteImage(message = "Life is like a box of chocolates.", from = "Forrest Gump")
        }
    }
}
```

增加更多名人語錄
```kotlin=
data class Quote(val message: String, val from: String)

val quotes = listOf(
    Quote("Life is like a box of chocolates.", "Forrest Gump"),
    Quote("Imagination is more important than knowledge.", "Albert Einstein"),
    Quote("Time you enjoy wasting, was not wasted.", "John Lennon"),
)
```

點擊螢幕可以隨機更換名人語錄
```kotlin=
package com.example.myfirstcomposeapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.myfirstcomposeapp.ui.theme.MyFirstComposeAppTheme

data class Quote(val message: String, val from: String)

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val quotes = listOf(
                Quote("Life is like a box of chocolates.", "Forrest Gump"),
                Quote("Imagination is more important than knowledge.", "Albert Einstein"),
                Quote("Time you enjoy wasting, was not wasted.", "John Lennon"),
            )

            var currentQuote by remember { mutableStateOf(quotes.random()) }

            MyFirstComposeAppTheme {
                Surface(
                    modifier = Modifier
                        .fillMaxSize()
                        .clickable {
                            currentQuote = quotes.random()
                        },
                    color = MaterialTheme.colorScheme.background
                ) {
                    QuoteImage(message = currentQuote.message, from = currentQuote.from)
                }
            }
        }
    }
}

@Composable
fun QuoteText(message: String, from: String, modifier: Modifier = Modifier) {
    // Create a column so that texts don't overlap
    Column(
        verticalArrangement = Arrangement.Center,
        modifier = modifier
    ) {
        Text(
            text = "\"" + message + "\"",
            fontSize = 48.sp,
            lineHeight = 55.sp,
            textAlign = TextAlign.Center,
            modifier = Modifier.padding(top = 16.dp),
        )
        Text(
            text = from,
            fontSize = 36.sp,
            fontStyle = FontStyle.Italic,
            modifier = Modifier
                .padding(top = 16.dp)
                .padding(end = 16.dp)
                .align(alignment = Alignment.End)

        )
    }
}

@Composable
fun QuoteImage(message: String, from: String, modifier: Modifier = Modifier) {
    Box(modifier) {
        Image(
            painter = painterResource(R.drawable.quote_background_1),
            contentDescription = null,
            contentScale = ContentScale.Crop,
            alpha = 0.5f,
            modifier = Modifier.fillMaxSize()
        )
        QuoteText(
            message = message,
            from = from,
            modifier = Modifier
                .fillMaxSize()
                .padding(8.dp)
        )
    }
}

@Preview(showBackground = true)
@Composable
fun QuotePreview() {

    val quotes = listOf(
        Quote("Life is like a box of chocolates.", "Forrest Gump"),
        Quote("Imagination is more important than knowledge.", "Albert Einstein"),
        Quote("Time you enjoy wasting, was not wasted.", "John Lennon"),
    )

    var currentQuote by remember { mutableStateOf(quotes.random()) }

    MyFirstComposeAppTheme {
        Surface(
            modifier = Modifier
                .fillMaxSize()
                .clickable {
                    currentQuote = quotes.random()
                },
            color = MaterialTheme.colorScheme.background
        ) {
            QuoteImage(message = currentQuote.message, from = currentQuote.from)
        }
    }
}
```

## 課後練習
點擊螢幕可以更換不同的名人語錄，不會點擊了之後還是相同的名人語錄