phase-10-tracker/phase10.odin

117 lines
3 KiB
Odin

package phase10
import "core:strconv"
import "core:fmt"
import "core:slice"
// Struct to hold all information about a game
Game :: struct {
names: [dynamic]string,
scores: [dynamic][dynamic]int,
phases: [dynamic]int
}
// Clean up memory allocated for a Game struct
deleteGameData :: proc(game: ^Game) {
for scorelist in game.scores {
delete(scorelist)
}
delete(game.scores)
delete(game.names)
delete(game.phases)
}
// Prompt user to enter scores for each player
addScores :: proc(game: ^Game) {
buf: [2048]byte
fmt.print(" ")
for name in game.names {
fmt.print(name, "")
}
fmt.println()
fmt.print("Scores: ")
newScores := getSpaceDelimetedItems(buf[:])
if len(newScores) != len(game.names) {
fmt.println("[ERROR] == Invalid number of scores")
return
}
defer delete(newScores)
for score, index in newScores {
intScore, _ := strconv.parse_int(score)
append(&(game.scores[index]), intScore)
}
}
// Update the status of each player's phase in a game based on scores each round
updatePhasesByScores :: proc(game: ^Game) {
for name, index in game.names {
phase: int = 1
for score in game.scores[index] {
if score < 50 {
phase += 1
}
}
game.phases[index] = phase
}
}
// Add a player to the game
addPlayer :: proc(game: ^Game, name: string, score: int = 0, phase: int = 1) {
append(&game.names, name)
append(&game.phases, phase)
// Calculate necesasry score sheet to result in score and phase
scores: [dynamic]int
for i := 1; i < phase - 1; i += 1 {
append(&scores, 0)
}
if score >= 50 {
append(&scores, 0)
}
if (phase != 1) {
append(&scores, score)
}
append(&game.scores, scores)
}
// Get aggregate score of player by index
getScore :: proc(game: ^Game, playerIndex: int) -> int {
sum: int = 0
for score in game.scores[playerIndex] {
sum += score
}
return sum
}
// Returns the index of the player who wins, or -1 if there is no winner
checkWinner :: proc(game: ^Game) -> int {
winners: [dynamic]int
defer delete(winners)
for player, index in game.names {
if game.phases[index] > 10 {
append(&winners, index)
}
}
if len(winners) > 0 {
// sort by lowest points
context.user_ptr = game
point_order :: proc(lhs, rhs: int) -> bool {
game: ^Game = (^Game)(context.user_ptr)
return getScore(game, lhs) < getScore(game, rhs)
}
slice.sort_by(winners[:], point_order)
return winners[0]
}
return -1
}
// Print state of the game as a nice table
printGame :: proc(game: ^Game) {
fmt.printf("Name\tScore\tPhase\n")
fmt.printf("----\t-----\t-----\n")
for name, index in game.names {
fmt.printf("%v\t%v\t%v\n", name, getScore(game, index),
game.phases[index])
}
}