Structs

Con los structs definimos estructuras de datos compuestas por campos nombrados con tipos concretos. Usamos esta sintaxis para definir un struct:


const NombreDelStruct = struct {

     nombre_campo: tipo,

      …

     nombre_campoN: tipo,

}; 


Al mirar alrededor, el jugador se da cuenta: esto es casi un vertedero en medio del mar. No ayudan los restos de los drones rotos, desensamblados, cables sueltos entre módulos esparcidos y colocados según él, en su “caos ordenado”. A su lado, 1KR - su “hijo” y fiel acompañante en una de sus múltiples reencarnaciones. Todavía recuerda cuando el chico era perro hace unos años. Escapar de la isla no va a ser fácil.

Hace un par de horas el plan funcionó casi a la perfección y usando el pulso electromagnético, el par de ARP1 que vigilaban el acceso a la playa cayeron como dos moscas enormes, chocando en pleno vuelo. Claro que tanto el pulso como el impacto de la caída han dejado secuelas.  

- ¿Chafados un poquito más de lo que queríamos, no pa?

- Si, has hecho muy buen trabajo bebé. En cualquier caso hay que comprobar hasta qué punto valen para sacarnos de aquí.

El laberinto cambiante de las cuevas quedó atrás, escondiendo sus terrores y la criatura hostil cabreadísima por no haberles matado. Pretender hacer prisionero del Laberinto, al propio creador del mismo, es como poco estúpido, y dice bastante de la capacidad intelectual del Gobernante. La criatura de las cuevas tal vez, al contrario de lo que se cree, heredó su estupidez extrema del mandatario incompetente, su “padre” humano… jaja y los cuernos los heredó también - ahora que lo pienso. Tiene gracia - piensa el jugador mientras pone en marcha el test. Tenía que haber sido cómico… para círculos muy reducidos.

Los struct pueden contener cualquier tipo de datos, incluidos otros struct y enum. Aquí usamos el enum EngineStatus, previamente definido, para describir el estado actual de un motor.

struct_engine.zig

const std = @import("std");

const print = std.debug.print;

const EngineStatus = enum(i8) {

    failure = -1, off = 0, on = 1, testing = 2, autorepairing = 3,

};

const DroneEngine = struct {

    var n_total_failed: u8 = 0;

    const N_MAX_RPM: u32 = 3500;

    const N_MIN_HEALTH: u32 = 75;

    e_status: EngineStatus,

    n_health: u8,

    s_key: []const u8,

    n_rpm: u32,

    // el botón de encendido/ apagado del motor

    fn toggle(self: *DroneEngine) void {

        self.e_status = sw: switch (self.e_status) {

            EngineStatus.off => self.turn_on(),

            // si está encendido apagamos

            EngineStatus.on => {

                self.e_status = EngineStatus.off;

                self.n_rpm = 0;

                break :sw self.e_status;

            },

            EngineStatus.testing => EngineStatus.off,

            EngineStatus.autorepairing => EngineStatus.off,

            EngineStatus.failure => EngineStatus.failure,

        };

    }

    // función que comprueba si se cumplen las condiciones

    // para poder encender el motor

    fn turn_on(self: *DroneEngine) EngineStatus {

        if (self.n_health > DroneEngine.N_MIN_HEALTH) {

            // el motor enciende

            self.e_status = EngineStatus.on;

            self.n_rpm = DroneEngine.N_MAX_RPM * self.n_health / 100;

        } else if (self.n_health > 20) {

            // el motor intenta autorepararse

            self.e_status = EngineStatus.autorepairing;

            self.n_rpm = DroneEngine.N_MAX_RPM * self.n_health / 100;

            DroneEngine.n_total_failed += 1;

        } else {

            // fallo

            self.e_status = EngineStatus.failure;

            self.n_rpm = 0;

            DroneEngine.n_total_failed += 1;

        }

        return self.e_status;

    }

    // método que formatea el struct y se invoca

    // automáticamente cuando lo imprimimos

    pub fn format(self: DroneEngine, writer: anytype) !void {

        try writer.print(

            \\Motor {s}:

            \\  * rpm: {}

            \\  * health: {}

            \\  * status: {s}

        , .{

            self.s_key,

            self.n_rpm,

            self.n_health,

            @tagName(self.e_status),

        });

    }

};

pub fn main() void {

    // todos los motores conectados para la prueba

    var a_engines: [6]DroneEngine = .{

        DroneEngine{ .s_key = "E1", .n_health = 100, 

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E2", .n_health = 95, 

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E3", .n_health = 100,

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E4", .n_health = 98, 

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E5", .n_health = 60, 

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E6", .n_health = 0, 

          .n_rpm = 0, .e_status = .off },

    };

    // prueba de encendido de motores

    for (&a_engines) |*o_engine| {

        if (o_engine.e_status == .off)

            o_engine.toggle();

        // usando {f} se usará de manera automática

        // el método format que hemos definido

        print("{f}\n", .{o_engine});

    }

    print("\nHa habido {} fallos\n", .{DroneEngine.n_total_failed});

}

$ zig run struct_engines.zig

Motor E1:

  * rpm: 3500

  * health: 100

  * status: on

Motor E2:

  * rpm: 3325

  * health: 95

  * status: on

Motor E3:

  * rpm: 3500

  * health: 100

  * status: on

Motor E4:

  * rpm: 3430

  * health: 98

  * status: on

Motor E5:

  * rpm: 2100

  * health: 60

  * status: autorepairing

Motor E6:

  * rpm: 0

  * health: 0

  * status: failure

Ha habido 2 fallos

El jugador se sienta en la arena por un momento. Está cansado y cubierto de polvo,... la ropa sucia y rota. La huida de las cuevas, a pesar de seguir un plan que incluía engañar al tauroide que vive encerrado en ellas, y encontrar una salida empleando un algoritmo modificado, almacenado en la memoria de 1KR,... tuvo momentos tensos.

- Y tan tensos - piensa -. Casi nos pilla.

Ahora, después de tantas horas sin dormir, tenía sueño.

- Vale, hay que volver al trabajo. Veamos…

Entre los dos drones ARP1 desensamblados hay seis motores en total: uno está completamente estropeado, otro a medio gas, y cuatro funcionan perfectamente. Hay que construir un “ala” usando esos cuatro motores. Debe de  ser lo bastante potente como para salir, junto a 1KR, de esta prisión.

Los dos ARP1 fueron un “regalo”, igual que otros tantos del mismo modelo, producidos a pequeña escala, en los talleres del propio inventor, para el señor de la isla: un gobernante cuestionado y supuestamente hijo de una divinidad local.

Las creencias son como esas nubes que pasan delante del sol. Por enormes que parezcan, solo son vapor y quimeras a luz de la verdad. Se van y el sol queda.

No tenemos mucho tiempo, hay que ensamblar el “ala” con el material que tenemos, antes de que descubran que nos hemos escapado. Ellos tienen la ley de su parte, hecha a su medida, pero en realidad, no tienen conocimiento profundo de cómo funciona nada. Se creen que nos han vencido y eso nos da cierta ventaja.

Sobrevuelan las olas del mar profundo, que de noche, en la oscuridad, reflejan la luz de la luna, como una enorme cota de malla hecha de plata. Nota la brisa caprichosa, - momento caricia, momento látigo - en la cara y los pies helados que, a veces, casi tocan la superficie del mar. A ratos planean; a ratos se encienden los motores con zumbido salvaje, olor a metal quemado, sufriendo para mantenerse en el aire. Se apagan cuando el viento les lleva a favor, y así siguen una ruta que ahora mismo solo 1KR conoce y visualiza desde dentro del ala.

Al aterrizar en la costa pedregosa, después del largo vuelo, siente el dolor en las manos agarrotadas, molido por el cansancio. Desenchufa y arranca la cabeza metálica desde el ala.

Enums
© 2025 Zen of Zig