开发一个Android App: 打牌计分器

package com.example.myapplication
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.tooling.preview.Preview
import com.example.myapplication.ui.theme.MyApplicationTheme
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
                    ScoreCounterApp()
                }
            }
        }
    }
}
// 数据类:表示一个玩家
data class Player(
    val id: Int,
    var name: String,
    var totalScore: Int = 0
)
// 数据类:表示一轮得分
data class RoundScore(
    val roundNumber: Int,
    val scores: Map<Int, Int> // 玩家ID -> 得分
)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ScoreCounterApp() {
    var players by remember { mutableStateOf(listOf<Player>()) }
    var currentRound by remember { mutableStateOf(1) }
    var currentRoundScores by remember { mutableStateOf(mapOf<Int, String>()) }
    var scoreHistory by remember { mutableStateOf(listOf<RoundScore>()) }
    var newPlayerName by remember { mutableStateOf("") }
    var showHistory by remember { mutableStateOf(false) }
    var showAddPlayerDialog by remember { mutableStateOf(false) }

    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        Text(text = "计分器", style = MaterialTheme.typography.headlineLarge, modifier = Modifier.padding(bottom = 16.dp))
        // 玩家初始化部分
        if (players.isEmpty()) {
            Card(modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.secondaryContainer)) {
                Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
                    Text(text = "添加玩家", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(bottom = 8.dp))
                    OutlinedTextField(
                        value = newPlayerName,
                        onValueChange = { newPlayerName = it },
                        label = { Text("玩家姓名") },
                        modifier = Modifier.fillMaxWidth(),
                        singleLine = true
                    )
                    Spacer(modifier = Modifier.height(8.dp))
                    Button(
                        onClick = {
                            if (newPlayerName.isNotBlank()) {
                                val newPlayer = Player(id = players.size + 1, name = newPlayerName)
                                players = players + newPlayer
                                newPlayerName = ""
                            }
                        },
                        modifier = Modifier.fillMaxWidth()
                    ) { Text("添加玩家") }
                }
            }
        } else {
            // 显示当前总分
            Card(modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primaryContainer)) {
                Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
                    Text(
                        text = "当前总分 (第${currentRound}轮)",
                        style = MaterialTheme.typography.headlineSmall,
                        modifier = Modifier.padding(bottom = 8.dp)
                    )
                    LazyColumn {
                        items(players.sortedBy { it.id }) { player ->
                            Row(modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), horizontalArrangement = Arrangement.SpaceBetween) {
                                Text(text = player.name, style = MaterialTheme.typography.bodyLarge)
                                Text(
                                    text = "${player.totalScore} 分",
                                    style = MaterialTheme.typography.bodyLarge,
                                    color = if (player.totalScore >= 0)
                                        MaterialTheme.colorScheme.primary
                                    else
                                        MaterialTheme.colorScheme.error
                                )
                            }
                        }
                    }
                }
            }

            Spacer(modifier = Modifier.height(16.dp))

            // 当前轮次得分输入
            Card(modifier = Modifier.fillMaxWidth()) {
                Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
                    Text(text = "第${currentRound}轮得分", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(bottom = 8.dp))
                    LazyColumn {
                        items(players.sortedBy { it.id }) { player ->
                            Column(modifier = Modifier.padding(vertical = 4.dp)) {
                                Text(text = player.name, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.padding(bottom = 4.dp))
                                OutlinedTextField(
                                    value = currentRoundScores[player.id] ?: "",
                                    onValueChange = { newValue ->
                                        // 只允许数字和负号
                                        if (newValue.matches(Regex("-?\\d*"))) {
                                            currentRoundScores = currentRoundScores.toMutableMap().apply { put(player.id, newValue) }
                                        }
                                    },
                                    label = { Text("得分") },
                                    modifier = Modifier.fillMaxWidth(),
                                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                                    singleLine = true
                                )
                            }
                        }
                    }
                    Spacer(modifier = Modifier.height(16.dp))
                    // 计算当前轮次总分
                    val currentTotal = currentRoundScores.values.sumOf { it.toIntOrNull() ?: 0 }
                    Text(
                        text = "当前轮次总分: $currentTotal",
                        style = MaterialTheme.typography.bodyLarge,
                        color = if (currentTotal == 0)
                            MaterialTheme.colorScheme.primary
                        else
                            MaterialTheme.colorScheme.error,
                        modifier = Modifier.padding(bottom = 8.dp)
                    )

                    Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                        Button(
                            onClick = {
                                if (currentTotal != 0) {
                                    // 可以在这里显示错误提示
                                    return@Button
                                }
                                // 更新玩家总分
                                players = players.map { player ->
                                    val roundScore = currentRoundScores[player.id]?.toIntOrNull() ?: 0
                                    player.copy(totalScore = player.totalScore + roundScore)
                                }
                                // 保存历史记录
                                val scoresMap = currentRoundScores.mapValues { it.value.toIntOrNull() ?: 0 }
                                val newRoundScore = RoundScore(currentRound, scoresMap)
                                scoreHistory = scoreHistory + newRoundScore
                                // 重置当前轮次
                                currentRound++
                                currentRoundScores = players.associate { it.id to "" }
                            },
                            modifier = Modifier.weight(1f),
                            enabled = currentTotal == 0
                        ) { Text("确认本轮得分") }
                        OutlinedButton(onClick = { currentRoundScores = players.associate { it.id to "" } }, modifier = Modifier.weight(1f)) { Text("重置输入") }
                    }
                }
            }
            Spacer(modifier = Modifier.height(16.dp))
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                Button(onClick = { showHistory = !showHistory }, modifier = Modifier.weight(1f)) { Text(if (showHistory) "隐藏历史" else "查看历史") }
                OutlinedButton(onClick = { showAddPlayerDialog = true }, modifier = Modifier.weight(1f)) { Text("添加玩家") }
                OutlinedButton(
                    onClick = {
                        // 重置整个游戏
                        players = emptyList()
                        currentRound = 1
                        currentRoundScores = emptyMap()
                        scoreHistory = emptyList()
                    },
                    modifier = Modifier.weight(1f),
                    colors = ButtonDefaults.outlinedButtonColors(contentColor = MaterialTheme.colorScheme.error)
                ) { Text("重置游戏") }
            }

            // 历史记录
            if (showHistory && scoreHistory.isNotEmpty()) {
                Spacer(modifier = Modifier.height(16.dp))
                Card(modifier = Modifier.fillMaxWidth()) {
                    Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
                        Text(text = "历史得分记录", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(bottom = 8.dp))
                        LazyColumn {
                            items(scoreHistory.reversed()) { round ->
                                Card(modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) {
                                    Column(modifier = Modifier.fillMaxWidth().padding(12.dp)) {
                                        Text(text = "第${round.roundNumber}轮", style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(bottom = 4.dp))
                                        round.scores.forEach { (playerId, score) ->
                                            val player = players.find { it.id == playerId }
                                            Row(modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp), horizontalArrangement = Arrangement.SpaceBetween) {
                                                Text(text = player?.name ?: "玩家$playerId")
                                                Text(
                                                    text = "$score 分",
                                                    color = if (score >= 0)
                                                        MaterialTheme.colorScheme.primary
                                                    else
                                                        MaterialTheme.colorScheme.error
                                                )
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // 添加玩家对话框
    if (showAddPlayerDialog) {
        AlertDialog(
            onDismissRequest = { showAddPlayerDialog = false },
            title = { Text("添加新玩家") },
            text = { Column { OutlinedTextField(value = newPlayerName, onValueChange = { newPlayerName = it }, label = { Text("玩家姓名") }, modifier = Modifier.fillMaxWidth(), singleLine = true) } },
            confirmButton = {
                Button(
                    onClick = {
                        if (newPlayerName.isNotBlank()) {
                            val newPlayer = Player(id = players.size + 1, name = newPlayerName)
                            players = players + newPlayer
                            currentRoundScores = currentRoundScores.toMutableMap().apply { put(newPlayer.id, "") }
                            newPlayerName = ""
                        }
                        showAddPlayerDialog = false
                    }
                ) { Text("添加") }
            },
            dismissButton = { TextButton(onClick = { showAddPlayerDialog = false }) { Text("取消") } }
        )
    }
}

@Preview(showBackground = true)
@Composable
fun ScoreCounterAppPreview() {
    MyApplicationTheme {
        ScoreCounterApp()
    }
}
posted @ 2026-02-01 22:24  肉肉的男朋友  阅读(1)  评论(0)    收藏  举报