From 7562fd3043e460d535a77a4d6a81ed09f6c54085 Mon Sep 17 00:00:00 2001 From: Hayden Johnson Date: Wed, 18 Feb 2026 17:51:19 -0800 Subject: [PATCH] Refactor and add exportGame --- .gitignore | 1 + main.odin | 4 ++++ phase10.odin | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/.gitignore b/.gitignore index 065b0f7..d8b368a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ phase-10-tracker +*.csv diff --git a/main.odin b/main.odin index d1944c1..8dba82b 100644 --- a/main.odin +++ b/main.odin @@ -40,9 +40,13 @@ main :: proc() { winner = checkWinner(&game) } + // Print winner fmt.printfln( "%v wins! They had %v points!", game.names[winner], getScore(&game, winner) ) + + exportGame(&game, "game.csv") + } diff --git a/phase10.odin b/phase10.odin index a2cdbc8..34cc561 100644 --- a/phase10.odin +++ b/phase10.odin @@ -1,5 +1,7 @@ package phase10 +import "core:io" +import "core:encoding/csv" import "core:os" import "core:strings" import "core:strconv" @@ -131,3 +133,63 @@ getNames :: proc(backingBuffer: []byte) -> []string { fmt.print("Enter Names: ") return getSpaceDelimetedItems(backingBuffer) } + +// export a game as a csv +exportGame :: proc(game: ^Game, filename: string) { + // Open handle to file + handle, err := os.open(filename, flags = os.O_CREATE | os.O_WRONLY | os.O_TRUNC, mode = 0o666) + if err != nil { + fmt.eprintln("Could not open file:", filename) + return + } + defer os.close(handle) + + // create stream from file handle + stream := os.stream_from_handle(handle) + defer io.destroy(stream) + + // Create CSV Writer + w: csv.Writer + csv.writer_init(&w, stream) + + records: [dynamic][]string + defer { + for record in records { + for col in record { + delete(col) + } + delete(record) + } + delete(records) + } + + // First row is all the names, each subsequent row is the score for a + // particular round. It is important that we create a new array for each of + // these so we don't accidentally free the actual data in the game struct. + nameRow: [dynamic]string + for name in game.names { + s := strings.clone(name) + append(&nameRow, s) + } + append(&records, nameRow[:]) + + for i := 0 ; i < len(game.scores[0]); i += 1 { + scoreRowString: [dynamic]string + for playerScores in game.scores { + s := strings.builder_make() + strings.write_int(&s, playerScores[i]) + scoreCol := strings.to_string(s) + append(&scoreRowString, scoreCol) + } + append(&records, scoreRowString[:]) + } + + // Write the records to the file + csv.write_all(&w, records[:]) +} + +// import an existing game from a csv file +importGame :: proc(filename: string) -> ^Game { + // TODO + return nil +}