diff --git a/main.odin b/main.odin index a40e342..53dd225 100644 --- a/main.odin +++ b/main.odin @@ -17,7 +17,6 @@ package phase10 import "core:fmt" import "core:os" import "core:strings" -import "core:strconv" // Return a slice of space delimited strings from stdin getSpaceDelimetedItems :: proc(backingBuffer: []byte) -> []string { @@ -33,22 +32,6 @@ getNames :: proc(backingBuffer: []byte) -> []string { return getSpaceDelimetedItems(backingBuffer) } -// 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[:]) - defer delete(newScores) - for score, index in newScores { - intScore, _ := strconv.parse_int(score) - append(&(game.scores[index]), intScore) - } -} main :: proc() { // Prompt for names @@ -56,31 +39,24 @@ main :: proc() { names := getNames(buf[:]) defer delete(names) - // Show names to user - for name in names { - fmt.println("Name:", name) - } - // Create game game: Game for name in names { - if name == "hayden" { - addPlayer(&game, name, phase = 10, score = 40) - } else { - addPlayer(&game, name) - } + addPlayer(&game, name) } defer deleteGameData(&game) // Clean up game data - // Main loop of adding scores - fmt.println(game) - winner: string - for winner == "" { + // Main game loop + // fmt.println(game) + printGame(&game) + winner: int = -1 + for winner == -1 { addScores(&game) - updatePhases(&game) - fmt.println(game) + updatePhasesByScores(&game) + // fmt.println(game) + printGame(&game) winner = checkWinner(&game) } - fmt.println("The winner is:", winner) + fmt.printfln("%v wins! They had %v points!", game.names[winner], getScore(&game, winner)) } diff --git a/phase10.odin b/phase10.odin index bb7f11f..f06f80f 100644 --- a/phase10.odin +++ b/phase10.odin @@ -1,11 +1,17 @@ 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) @@ -15,7 +21,25 @@ deleteGameData :: proc(game: ^Game) { delete(game.phases) } -updatePhases :: proc(game: ^Game) { +// 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[:]) + 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] { @@ -27,6 +51,7 @@ updatePhases :: proc(game: ^Game) { } } +// 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) @@ -44,11 +69,43 @@ addPlayer :: proc(game: ^Game, name: string, score: int = 0, phase: int = 1) { append(&game.scores, scores) } -checkWinner :: proc(game: ^Game) -> string { +// 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 { - return player + append(&winners, index) } } - return "" + + 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 +} + +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]) + } }