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()
}
}