diff --git a/build.zig b/build.zig index f11df6f..0911881 100644 --- a/build.zig +++ b/build.zig @@ -40,7 +40,7 @@ const exercises = [_]Exercise{ .{ .main_file = "01_hello.zig", .output = "Hello world", - .hint = "Note the error: the source file has a hint for fixing 'main'.", + .hint = "DON'T PANIC!\nRead the error above.\nSee how it has something to do with 'main'?\nOpen up the source file as noted and read the comments.\nYou can do this!", }, .{ .main_file = "02_std.zig", @@ -243,9 +243,13 @@ const exercises = [_]Exercise{ .{ .main_file = "46_optionals2.zig", .output = "Elephant A. Elephant B. Elephant C.", - .hint = "Elephants!", + .hint = "Elephants again!", + }, + .{ + .main_file = "47_methods.zig", + .output = "5 aliens. 4 aliens. 1 aliens. 0 aliens. Earth is saved!", + .hint = "Use the heat ray. And the method!", }, - // super-simple struct method // use struct method for elephant tails // quiz: add elephant trunk (like tail)! }; diff --git a/exercises/47_methods.zig b/exercises/47_methods.zig new file mode 100644 index 0000000..c8e5c17 --- /dev/null +++ b/exercises/47_methods.zig @@ -0,0 +1,94 @@ +// +// Help! Evil alien creatures have hidden eggs all over the Earth +// and they're starting to hatch! +// +// Before you jump into battle, you'll need to know four things: +// +// 1. You can attach functions to structs: +// +// const Foo = struct{ +// pub fn hello() void { +// std.debug.print("Foo says hello!\n", .{}); +// } +// } +// +// 2. A function that is a member of a struct is a "method" and is +// called with the "dot syntax" like so: +// +// Foo.hello(); +// +// 3. The NEAT feature of methods is the special parameter named +// "self" that takes an instance of that type of struct: +// +// const Bar = struct{ +// number: u32, +// +// pub fn printMe(self: *Bar) void { +// std.debug.print("{}\n", .{self.number}); +// } +// } +// +// 4. Now when you call the method on an INSTANCE of that struct +// with the "dot syntax", the instance will be automatically +// passed as the "self" parameter: +// +// const my_bar = Bar{ .number = 2000 }; +// my_bar.printMe(); // prints "2000" +// +// Okay, you're armed. +// +// Now, please zap the alien structs until they're all gone or +// Earth will be doomed! +// +const std = @import("std"); + +// Look at this hideous Alien struct. Know your enemy! +const Alien = struct { + health: u8, + + // We hate this method: + pub fn hatch(strength: u8) Alien { + return Alien{ + .health = strength * 5, + }; + } + + // We love this method: + pub fn zap(self: *Alien, damage: u8) void { + self.health -= if (damage >= self.health) self.health else damage; + } +}; + +pub fn main() void { + // Look at all of these aliens of various strengths! + var aliens = [_]Alien{ + Alien.hatch(2), + Alien.hatch(1), + Alien.hatch(3), + Alien.hatch(3), + Alien.hatch(5), + Alien.hatch(3), + }; + + var aliens_alive = aliens.len; + var heat_ray_strength: u8 = 7; // We've been given a heat ray weapon. + + // We'll keep checking to see if we've killed all the aliens yet. + while (aliens_alive > 0) { + aliens_alive = 0; + + // Loop through every alien... + for (aliens) |*alien| { + + // *** Zap the Alien Here! *** + ???.zap(heat_ray_strength); + + // If the alien's health is still above 0, it's still alive. + if (alien.health > 0) aliens_alive += 1; + } + + std.debug.print("{} aliens. ", .{aliens_alive}); + } + + std.debug.print("Earth is saved!\n", .{}); +} diff --git a/patches/patches/47_methods.patch b/patches/patches/47_methods.patch new file mode 100644 index 0000000..cde93af --- /dev/null +++ b/patches/patches/47_methods.patch @@ -0,0 +1,4 @@ +84c84 +< ???.zap(heat_ray_strength); +--- +> alien.zap(heat_ray_strength);