Skip to content

Commit

Permalink
Merge pull request #4 from jimmyale3102/imprv/exp
Browse files Browse the repository at this point in the history
Imprv/exp
  • Loading branch information
jimmyale3102 committed May 27, 2024
2 parents 4f2057e + 1c5319e commit 935fe6b
Show file tree
Hide file tree
Showing 65 changed files with 350 additions and 138 deletions.
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
android:name=".MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.Triqui">
android:theme="@style/LaunchTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.alejo.triqui.data.network

import android.util.Log
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.snapshots
import dev.alejo.triqui.data.network.model.GameData
Expand Down Expand Up @@ -29,6 +30,7 @@ class FirebaseService @Inject constructor(private val databaseRef: DatabaseRefer
}

fun updateGame(gameData: GameData) {
Log.d("=======UPDATE->", gameData.toString())
if (gameData.gameId != null) {
databaseRef.child(PATH).child(gameData.gameId).setValue(gameData)
}
Expand Down
21 changes: 12 additions & 9 deletions app/src/main/java/dev/alejo/triqui/data/network/model/GameData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,32 @@ import java.util.Calendar
data class GameData(
val board: List<Int>? = null,
val gameId: String? = null,
val player1: PlayerData? = null,
val player2: PlayerData? = null,
val mainPlayer: PlayerData? = null,
val secondPlayer: PlayerData? = null,
val playerTurn: PlayerData? = null,
val player1PlayAgain: Boolean = false,
val player2PlayAgain: Boolean = false
val victories: GameVictories? = null,
val mainPlayerPlayAgain: Boolean = false,
val secondPlayerPlayAgain: Boolean = false
)

fun GameData.toModel(): GameModel = GameModel(
board = board?.map { playerId -> PlayerType.getPlayerTypeById(playerId) } ?: mutableListOf(),
gameId = gameId.orEmpty(),
player1 = player1!!.toModel(),
player2 = player2?.toModel(),
mainPlayer = mainPlayer!!.toModel(),
secondPlayer = secondPlayer?.toModel(),
playerTurn = playerTurn!!.toModel(),
player1PlayAgain = player1PlayAgain,
player2PlayAgain = player2PlayAgain
victories = victories ?: GameVictories(),
mainPlayerPlayAgain = mainPlayerPlayAgain,
secondPlayerPlayAgain = secondPlayerPlayAgain
)

data class PlayerData(
val userId: String? = Calendar.getInstance().timeInMillis.hashCode().toString(),
val playerType: Int? = null
)
data class GameVictories(val mainPlayer: Int = 0, val secondPlayer: Int = 0, val draw: Int = 0)

fun PlayerData.toModel(): PlayerModel = PlayerModel(
id = userId!!,
playerType = PlayerType.getPlayerTypeById(playerType)
)
)
95 changes: 21 additions & 74 deletions app/src/main/java/dev/alejo/triqui/ui/game/GameScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dev.alejo.triqui.ui.game

import android.content.Context
import android.content.Intent
import androidx.annotation.StringRes
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
Expand All @@ -11,7 +10,6 @@ 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.size
Expand All @@ -34,11 +32,11 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import dev.alejo.triqui.R
import dev.alejo.triqui.ui.game.components.GameResult
import dev.alejo.triqui.ui.game.components.GameVictories
import dev.alejo.triqui.ui.home.components.TriquiButton
import dev.alejo.triqui.ui.home.components.TriquiOutlinedButton
import dev.alejo.triqui.ui.model.GameModel
import dev.alejo.triqui.ui.model.PlayerType
import dev.alejo.triqui.ui.theme.Black80
import dev.alejo.triqui.ui.theme.Blue40
import dev.alejo.triqui.ui.theme.GeneralRoundCorner
import dev.alejo.triqui.ui.theme.Gold80
Expand All @@ -59,20 +57,27 @@ fun GameScreen(

val game: GameModel? by gameViewModel.game.collectAsState()
val winner: PlayerType? by gameViewModel.winner.collectAsState()
val playerType = game?.let {
if (it.isGameReady) {
gameViewModel.getPlayer()
} else {
PlayerType.Main
}
} ?: PlayerType.Main

if (winner != null) {
val playerType = gameViewModel.getPlayer()
WinnerResult(
GameResult(
game = game!!,
winner = winner!!,
playerType = playerType!!,
playerType = playerType,
onGoHome = { onGoHome() },
onPlayAgain = { gameViewModel.onPlayAgain() }
)
} else {
val context = LocalContext.current
Game(
game = game,
playerType = playerType,
shareGameId = {
shareGameId(context, game?.gameId)
}
Expand All @@ -82,19 +87,6 @@ fun GameScreen(
}
}

@Composable
fun WaitingToPlayAgain(@StringRes msg: Int) {
Row(
modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
CircularProgressIndicator(modifier = Modifier.size(24.dp))
Spacer(Modifier.width(8.dp))
Text(text = stringResource(msg))
}
}

private fun shareGameId(context: Context, gameId: String?) {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
Expand All @@ -107,69 +99,24 @@ private fun shareGameId(context: Context, gameId: String?) {
}

@Composable
fun WinnerResult(
game: GameModel,
winner: PlayerType,
fun Game(
game: GameModel?,
playerType: PlayerType,
onGoHome: () -> Unit,
onPlayAgain: () -> Unit
shareGameId: () -> Unit,
onPressed: (Int) -> Unit
) {
Column(
Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
val gameResult = if (winner == PlayerType.Empty) {
stringResource(R.string.draw)
} else {
if (winner == playerType) {
stringResource(R.string.you_won)
} else {
stringResource(R.string.you_lost)
}
}
Text(
modifier = Modifier.padding(16.dp),
text = gameResult,
fontSize = 28.sp,
color = Black80,
fontWeight = FontWeight.Bold
)

when {
(game.player1PlayAgain && (playerType == PlayerType.Main))
|| (game.player2PlayAgain && (playerType == PlayerType.Second)) -> {
WaitingToPlayAgain(R.string.waiting_for_your_opponent)
}

(game.player1PlayAgain && (playerType == PlayerType.Second))
|| (game.player2PlayAgain && (playerType == PlayerType.Main)) -> {
WaitingToPlayAgain(R.string.opponent_wants_to_play_again)
}
}

Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
TriquiOutlinedButton(icon = R.drawable.ic_home, text = R.string.go_home) {
onGoHome()
}
Spacer(Modifier.width(16.dp))
TriquiButton(icon = R.drawable.ic_restart, text = R.string.play_again) {
onPlayAgain()
}
}
}
}

@Composable
fun Game(game: GameModel?, shareGameId: () -> Unit, onPressed: (Int) -> Unit) {
if (game == null) return
Column(Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
Spacer(modifier = Modifier.weight(0.5f))
GameStatus(game)
Spacer(modifier = Modifier.weight(1f))
GameVictories(gameVictories = game.victories, playerType = playerType)
Spacer(modifier = Modifier.weight(1f))
Board(game) { position -> onPressed(position) }
Spacer(modifier = Modifier.weight(1f))
ShareGame { shareGameId() }
if (playerType == PlayerType.Main) {
ShareGame { shareGameId() }
}
Spacer(modifier = Modifier.weight(0.5f))
}
}
Expand Down
49 changes: 33 additions & 16 deletions app/src/main/java/dev/alejo/triqui/ui/game/GameViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class GameViewModel @Inject constructor(private val firebaseService: FirebaseSer
firebaseService.joinToGame(gameId).take(1).collect { game ->
game?.let {
val gameResult = it.copy(
player2 = PlayerModel(
secondPlayer = PlayerModel(
id = playerId,
playerType = PlayerType.Second
)
Expand All @@ -55,15 +55,15 @@ class GameViewModel @Inject constructor(private val firebaseService: FirebaseSer
viewModelScope.launch {
firebaseService.joinToGame(gameId).collect { game ->
val gameResult = game?.copy(
isGameReady = game.player2 != null,
isGameReady = game.secondPlayer != null,
isMyTurn = isMyTurn(game.playerTurn)
)
_game.value = gameResult
gameResult?.let {
if (it.player1PlayAgain && it.player2PlayAgain) {
onRestartGame()
when {
(it.mainPlayerPlayAgain && it.secondPlayerPlayAgain) -> resetGameData()
(!it.mainPlayerPlayAgain && !it.secondPlayerPlayAgain) -> verifyWinner()
}
verifyWinner()
}
}
}
Expand Down Expand Up @@ -97,14 +97,31 @@ class GameViewModel @Inject constructor(private val firebaseService: FirebaseSer
if (boardData.size == 9) {
when {
isGameWon(board, PlayerType.Main) -> {
val mainVictories = _game.value!!.victories.mainPlayer
val victoriesUpdated = _game.value!!.victories.copy(
mainPlayer = mainVictories + 1
)
_game.value = _game.value!!.copy(victories = victoriesUpdated)
_winner.value = PlayerType.Main
}

isGameWon(board, PlayerType.Second) -> {
val secondVictories = _game.value!!.victories.secondPlayer
val victoriesUpdated = _game.value!!.victories.copy(
secondPlayer = secondVictories + 1
)
_game.value = _game.value!!.copy(victories = victoriesUpdated)
_winner.value = PlayerType.Second
}

!boardIsNotComplete -> _winner.value = PlayerType.Empty
!boardIsNotComplete -> {
val drawVictories = _game.value!!.victories.draw
val victoriesUpdated = _game.value!!.victories.copy(
draw = drawVictories + 1
)
_game.value = _game.value!!.copy(victories = victoriesUpdated)
_winner.value = PlayerType.Empty
}
}
}
} ?: return
Expand Down Expand Up @@ -132,37 +149,37 @@ class GameViewModel @Inject constructor(private val firebaseService: FirebaseSer
}

fun getPlayer(): PlayerType? = when {
(game.value?.player1?.id == playerId) -> PlayerType.Main
(game.value?.player2?.id == playerId) -> PlayerType.Second
(game.value?.mainPlayer?.id == playerId) -> PlayerType.Main
(game.value?.secondPlayer?.id == playerId) -> PlayerType.Second
else -> null
}

private fun getOpponentPlayer(): PlayerModel? {
return if (game.value?.player1?.id == playerId) game.value?.player2 else game.value?.player1
return if (game.value?.mainPlayer?.id == playerId) game.value?.secondPlayer else game.value?.mainPlayer
}

fun onPlayAgain() {
viewModelScope.launch {
val gameUpdated = if (getPlayer() == PlayerType.Main) {
game.value!!.copy(
player1PlayAgain = true,
_game.value!!.copy(
mainPlayerPlayAgain = true,
)
} else {
game.value!!.copy(
player2PlayAgain = true,
_game.value!!.copy(
secondPlayerPlayAgain = true,
)
}
firebaseService.updateGame(gameUpdated.toData())
}
}

private fun onRestartGame() {
private fun resetGameData() {
_winner.value = null
val boardUpdated = _game.value!!.board.toMutableList().map { PlayerType.Empty }
_game.value = _game.value!!.copy(
board = boardUpdated,
player1PlayAgain = false,
player2PlayAgain = false
mainPlayerPlayAgain = false,
secondPlayerPlayAgain = false
)
}

Expand Down
Loading

0 comments on commit 935fe6b

Please sign in to comment.