Is there something I'm missing about Zig for loops

Well I’m getting a weird bug in my code and from what I can tell it has to do with a single for loop section in the code.

pub fn main() !void {
    try start_game();
}

pub fn start_game() !void {
    var trie = try load_dictionary();
    defer trie.deinit(gpa_allocator);
    var n: usize = 0;
    while (n < 6) : (n += 1) {
        print("Make guess {d}: ", .{n + 1});
        var guess = try make_guesses();
        //print("The type of guess: {any}\n", .{@TypeOf(guess)});
        //print("guess letter at 0: {any}\n", .{guess[0]});
        if (std.mem.eql(u8, guess, winning_word)) {
            print("You win!\n", .{});
            break;
        } else {
            if (guess.len != 5) {
                print("Invalid guess\n", .{});
            } else if (!trie.search(guess)) {
                print("Not a wordle word\n", .{});
            } else {
                for (guess, 0..) |char, i| { //bug seems to occur in this loop
                    print("guess letter: {}\n", .{guess[i]}); 
                    print("winning word letter: {}\n", .{winning_word[i]});
                    if (guess[i] == winning_word[i]) {
                        wordle_grid[n][i] = Cell{ .value = char, .color = color.green };
                        print("{any}\n", .{wordle_grid[n][i]});
                    } else if (valueInArray(guess[i], winning_word)) {
                        wordle_grid[n][i] = Cell{ .value = char, .color = color.yellow };
                        print("{any}\n", .{wordle_grid[n][i]});
                    } else {
                        wordle_grid[n][i] = Cell{ .value = char, .color = color.gray };
                        print("{any}\n", .{wordle_grid[n][i]});
                    }
                }
            }
        }
    }
    print("This is the wordle grid: {any}\n", .{wordle_grid});
}

pub fn load_dictionary() !Trie {
    var trie = Trie{};
    const file = try fs.cwd().openFile("/home/clinton/Developer/Zig_projects/wordle/dictionary.txt", .{});
    defer file.close();

    var buffered_reader = std.io.bufferedReader(file.reader());
    const reader = buffered_reader.reader();

    var buf: [2048]u8 = undefined;

    while (try reader.readUntilDelimiterOrEof(&buf, '\n')) |line| {
        if (line.len == 5) {
            try trie.insert(line, gpa_allocator);
        }
    }
    return trie;
}

pub fn make_guesses() ![]const u8 {
    //var n: usize = 0;
    var reader = std.io.getStdIn().reader();
    var buf: [1024]u8 = undefined;
    const user_guess = try reader.readUntilDelimiter(&buf, '\n');
    print("Your guess: {any}\n", .{user_guess});
    return user_guess;
}

pub var winning_word: *const [5]u8 = "sunny";


Note the winning word is hard coded as “sunny”. Yet when run the code and enter “bunny”, I get this:

Make guess 1: bunny
Your guess: { 98, 117, 110, 110, 121 }
guess letter: 98
winning word letter: 115
wordle.Cell{ .value = 98, .color = wordle.color.gray }
guess letter: 0
winning word letter: 117
wordle.Cell{ .value = 0, .color = wordle.color.gray }
guess letter: 0
winning word letter: 110
wordle.Cell{ .value = 0, .color = wordle.color.gray }
guess letter: 0
winning word letter: 110
wordle.Cell{ .value = 0, .color = wordle.color.gray }
guess letter: 0
winning word letter: 121
wordle.Cell{ .value = 0, .color = wordle.color.gray }
Make guess 2: 

for some reason the for loop doesn’t loop through the characters in guess, but is able to do so for the winning word. It only loops for the first letter in guess and then returns 0s for the rest.

You’re returning from a local buffer in the function call here. That buffer goes out of scope when the function closes. You can take the buffer in as an argument or use an allocator to create a buffer, but the memory cannot be contained to the function body because it will go out of scope.

6 Likes

make_guesses function returns a pointer to the buf. But this storage lifetime ends with make_guesses function and is overwritten.
A solution is to extend buf lifetime by passing buf as a parameter to make_guesses.

2 Likes

Thank you for the help

2 Likes