Wersja Zig
enemy.zig
const std = @import("std");
pub const Enemy = struct {
name: []const u8,
max_health: u32,
current_health: u32,
level: u8,
damage: u32,
pub fn init() Enemy {
return Enemy{
.name = "",
.max_health = 0,
.current_health = 0,
.level = 1,
.damage = 0,
};
}
pub fn createEnemy(self: *Enemy, enemy_type: u8) void {
switch (enemy_type) {
0 => {
self.name = "Zombie";
self.max_health = 30;
self.damage = 5;
},
1 => {
self.name = "Szkieletor";
self.max_health = 25;
self.damage = 6;
},
2 => {
self.name = "Goblin";
self.max_health = 20;
self.damage = 4;
},
else => {
self.name = "Zombie";
self.max_health = 30;
self.damage = 5;
},
}
self.current_health = self.max_health;
}
pub fn setLevel(self: *Enemy, level: u8) void {
self.level = level;
self.max_health += (@as(u32, level) - 1) * 10;
self.current_health = self.max_health;
self.damage += (@as(u32, level) - 1) * 2;
}
};
player.zig
const std = @import("std");
const Print = @import("print.zig").Print;
const Color = @import("print.zig").Color;
pub const PlayerClass = enum {
Warrior,
Rogue,
Mage,
};
pub const Player = struct {
name: []const u8,
class: PlayerClass,
strength: u32,
intelligence: u32,
vitality: u32,
max_health: u32,
current_health: u32,
damage: u32,
pub fn init() Player {
return Player{
.name = "",
.class = .Warrior,
.strength = 0,
.intelligence = 0,
.vitality = 0,
.max_health = 0,
.current_health = 0,
.damage = 0,
};
}
pub fn setClass(
self: *Player,
choice: u8,
) void {
self.name = "Bohater";
switch (choice) {
1 => {
self.class = .Warrior;
self.strength = 10;
self.intelligence = 2;
self.vitality = 8;
},
2 => {
self.class = .Rogue;
self.strength = 6;
self.intelligence = 5;
self.vitality = 6;
},
3 => {
self.class = .Mage;
self.strength = 2;
self.intelligence = 10;
self.vitality = 5;
},
else => {
self.class = .Warrior;
self.strength = 10;
self.intelligence = 2;
self.vitality = 8;
},
}
self.calculateStats();
}
fn calculateStats(
self: *Player,
) void {
self.max_health =
50 + self.vitality * 10;
self.current_health =
self.max_health;
self.damage = switch (self.class) {
.Warrior => self.strength * 2,
.Rogue => self.strength * 2 + 2,
.Mage => self.intelligence * 2,
};
}
pub fn display(
self: Player,
) void {
Print.clear();
Print.write("Wybrałeś ");
const class_name = switch (self.class) {
.Warrior => "Wojownik",
.Rogue => "Łotrzyk",
.Mage => "Mag",
};
Print.writeColor(
class_name,
Color.Cyan,
);
Print.write("\n\n");
std.debug.print(
"Siła: {}\n",
.{self.strength},
);
std.debug.print(
"Inteligencja: {}\n",
.{self.intelligence},
);
std.debug.print(
"Witalność: {}\n",
.{self.vitality},
);
Print.write("Zdrowie: ");
Print.drawHpBar(
self.current_health,
self.max_health,
20,
Color.Green,
);
}
};
print.zig
const std = @import("std");
pub const Color = enum {
Default,
Red,
Green,
Yellow,
Cyan,
Blue,
Magenta,
White,
Black,
};
pub const Print = struct {
pub fn write(text: []const u8) void {
std.debug.print("{s}", .{text});
}
pub fn writeColor(text: []const u8, color: Color) void {
const code = switch (color) {
.Red => "\x1b[31m",
.Green => "\x1b[32m",
.Yellow => "\x1b[33m",
.Cyan => "\x1b[36m",
.Blue => "\x1b[34m",
.Magenta => "\x1b[35m",
.White => "\x1b[37m",
.Black => "\x1b[30m",
.Default => "\x1b[0m",
};
std.debug.print("{s}{s}\x1b[0m", .{
code,
text,
});
}
pub fn clear() void {
std.debug.print("\x1b[2J\x1b[H", .{});
}
pub fn drawHpBar(
current: u32,
max: u32,
width: usize,
color: Color,
) void {
const filled = (current * width) / max;
const empty = width - filled;
Print.writeColor(
"[",
color,
);
for (0..filled) |_| {
Print.write("█");
}
for (0..empty) |_| {
Print.write(" ");
}
std.debug.print("] {}/{}\n", .{
current,
max,
});
}
};
main.zig
const std = @import("std");
const Player = @import("player.zig").Player;
const Enemy = @import("enemy.zig").Enemy;
const Print = @import("print.zig").Print;
const Color = @import("print.zig").Color;
var random_counter: u32 = 0;
fn readNumber() u8 {
var buffer: [32]u8 = undefined;
const size = std.posix.read(
0,
&buffer,
) catch return 0;
var end: usize = 0;
while (end < size and buffer[end] != '\n') {
end += 1;
}
return std.fmt.parseInt(
u8,
buffer[0..end],
10,
) catch 0;
}
fn waitEnter() void {
var buffer: [8]u8 = undefined;
_ = std.posix.read(
0,
&buffer,
) catch {};
}
fn getEnemyType() u8 {
random_counter += 1;
return @intCast(
random_counter % 3,
);
}
fn getEnemyCount() usize {
random_counter += 1;
return switch (random_counter % 4) {
0 => 1,
1 => 2,
2 => 3,
else => 4,
};
}
fn getEnemyLevel() u8 {
random_counter += 1;
return @intCast(
(random_counter % 3) + 1,
);
}
pub fn main() !void {
var player = Player.init();
while (true) {
Print.clear();
Print.writeColor(
"==== UpiornePotyczki Zig ====\n\n",
Color.Red,
);
Print.write(
"1. Nowa Gra\n",
);
Print.write(
"2. Wyjście\n\n",
);
Print.writeColor(
"Wybierz: ",
Color.Yellow,
);
const menu = readNumber();
if (menu == 2) {
break;
}
if (menu != 1) {
continue;
}
Print.clear();
Print.writeColor(
"Wybierz klasę:\n\n",
Color.Yellow,
);
Print.write(
"1. Wojownik\n",
);
Print.write(
"2. Łotrzyk\n",
);
Print.write(
"3. Mag\n\n",
);
Print.writeColor(
"Wybierz: ",
Color.Yellow,
);
player.setClass(
readNumber(),
);
player.display();
waitEnter();
var enemies: [4]Enemy = undefined;
var enemy_count =
getEnemyCount();
var i: usize = 0;
while (i < enemy_count) {
enemies[i] =
Enemy.init();
enemies[i].createEnemy(
getEnemyType(),
);
enemies[i].setLevel(
getEnemyLevel(),
);
i += 1;
}
var fighting = true;
while (fighting) {
Print.clear();
Print.writeColor(
"=== WALKA ===\n\n",
Color.Red,
);
i = 0;
while (i < enemy_count) {
std.debug.print(
"{}. {s} lvl {}\n",
.{
i + 1,
enemies[i].name,
enemies[i].level,
},
);
Print.drawHpBar(
enemies[i].current_health,
enemies[i].max_health,
20,
Color.Green,
);
i += 1;
}
Print.write(
"\nTwoje HP:\n",
);
Print.drawHpBar(
player.current_health,
player.max_health,
20,
Color.Green,
);
Print.write(
"\n1. Atak\n",
);
Print.write(
"2. Ucieczka\n\n",
);
Print.writeColor(
"Wybierz: ",
Color.Yellow,
);
const action =
readNumber();
if (action == 2) {
Print.writeColor(
"\nUciekasz!\n",
Color.Yellow,
);
fighting = false;
continue;
}
if (action == 1) {
Print.write(
"\nWybierz przeciwnika: ",
);
const target =
readNumber();
if (target == 0 or target > enemy_count) {
continue;
}
const index =
target - 1;
enemies[index].current_health =
if (enemies[index].current_health > player.damage)
enemies[index].current_health - player.damage
else
0;
std.debug.print(
"\nZadajesz {} obrażeń {s}\n",
.{
player.damage,
enemies[index].name,
},
);
if (enemies[index].current_health == 0) {
Print.writeColor(
"Pokonany!\n",
Color.Green,
);
enemies[index] =
enemies[enemy_count - 1];
enemy_count -= 1;
}
if (enemy_count == 0) {
Print.writeColor(
"\nWygrałeś walkę!\n",
Color.Green,
);
fighting = false;
continue;
}
i = 0;
while (i < enemy_count) {
player.current_health =
if (player.current_health > enemies[i].damage)
player.current_health - enemies[i].damage
else
0;
std.debug.print(
"{s} zadaje {} obrażeń!\n",
.{
enemies[i].name,
enemies[i].damage,
},
);
if (player.current_health == 0) {
Print.writeColor(
"\nZostałeś pokonany!\n",
Color.Red,
);
fighting = false;
break;
}
i += 1;
}
waitEnter();
}
}
Print.write(
"\nENTER aby wrócić do menu...\n",
);
waitEnter();
}
Print.writeColor(
"\nDzięki za grę!\n",
Color.Magenta,
);
}
Kompilujemy za pomocą zig run.