Hello,
I’ve recently completed a mathematics project in Zig, aimed at calculating probabilities in the game of Yams. Now that it’s fully operational and yielding the expected results, I’m looking to refine and improve it. This project marks my inaugural journey with Zig, and I’m particularly interested in enhancing the parsing aspect.
The program currently parses command line arguments to appropriately supply values to the computation functions. I’m seeking advice on how to make this parsing process more efficient or elegant. Any insights or suggestions from the community would be greatly appreciated!
Thank you in advance for your time and help.
here are some usage example:
./201yams 0 0 0 0 0 yams_4
Chances to get a 4 yams: 0.01%
./201yams 1 2 3 4 5 four_4
Chances to get a 4 four-of-a-kind: 1.62%
./201yams 2 2 5 4 6 straight_6
Chances to get a 6 straight: 16.67%
./201yams 0 0 0 0 0 full_2_3
Chances to get a 2 full of 3: 0.13%
./201yams 2 3 2 3 2 full_2_3
Chances to get a 2 full of 3: 100.00%
here is the code (yes it’s long)
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
defer _ = gpa.deinit();
const args = std.process.argsAlloc(allocator) catch {
std.debug.print("failed to allocate args\n", .{});
return 84;
};
defer std.process.argsFree(allocator, args);
if (args.len != 2 and args.len != 7) {
std.debug.print("wrong number of arguments\n", .{});
return 84;
}
if (std.mem.eql(u8, args[1], "-h")) {
const help = "USAGE\n\t./201yams d1 d2 d3 d4 d5 c\n\nDESCRIPTION\n\td1\tvalue of the first die (0 if not thrown)\n\td2\tvalue of the second die (0 if not thrown)\n\td3\tvalue of the third die (0 if not thrown)\n\td4\tvalue of the fourth die (0 if not thrown)\n\td5\tvalue of the fifth die (0 if not thrown)\n\tc\tcombination to be obtained\n";
std.io.getStdOut().writeAll(help) catch {
std.debug.print("failed to write to stdout\n", .{});
return 84;
};
return 0;
}
var dice_numbers: [5]u8 = undefined;
var dice_count: u8 = 0;
var combination: combinations = undefined;
var combination_nb: [2]u8 = undefined;
for (args[1..]) |arg| {
if (dice_count < 5) {
if (arg.len != 1) {
std.debug.print("wrong dice number, too long\n", .{});
return 84;
}
dice_numbers[dice_count] = std.fmt.charToDigit(arg[0], 7) catch {
std.debug.print("wrong dice number, not a digit or digit > 6\n", .{});
return 84;
};
dice_count += 1;
} else {
if (std.mem.startsWith(u8, arg, "pair_")) {
if (arg.len != 6) {
std.debug.print("invalid combination\n", .{});
return 84;
}
combination = combinations.pair;
combination_nb[0] = std.fmt.charToDigit(arg[5], 7) catch {
std.debug.print("wrong pair number, not a digit or digit > 6\n", .{});
return 84;
};
} else if (std.mem.startsWith(u8, arg, "three_")) {
if (arg.len != 7) {
std.debug.print("invalid combination\n", .{});
return 84;
}
combination = combinations.three;
combination_nb[0] = std.fmt.charToDigit(arg[6], 7) catch {
std.debug.print("wrong three number, not a digit or digit > 6\n", .{});
return 84;
};
} else if (std.mem.startsWith(u8, arg, "four_")) {
if (arg.len != 6) {
std.debug.print("invalid combination\n", .{});
return 84;
}
combination = combinations.four;
combination_nb[0] = std.fmt.charToDigit(arg[5], 7) catch {
std.debug.print("wrong four number, not a digit or digit > 6\n", .{});
return 84;
};
} else if (std.mem.startsWith(u8, arg, "full_")) {
if (arg.len != 8) {
std.debug.print("invalid combination\n", .{});
return 84;
}
combination = combinations.full;
combination_nb[0] = std.fmt.charToDigit(arg[5], 7) catch {
std.debug.print("wrong full first number, not a digit or digit > 6\n", .{});
return 84;
};
combination_nb[1] = std.fmt.charToDigit(arg[7], 7) catch {
std.debug.print("wrong full second number, not a digit or digit > 6\n", .{});
return 84;
};
if (arg[6] != '_') {
std.debug.print("invalid full syntax\n", .{});
return 84;
}
} else if (std.mem.startsWith(u8, arg, "straight_")) {
if (arg.len != 10) {
std.debug.print("invalid combination\n", .{});
return 84;
}
combination = combinations.straight;
combination_nb[0] = std.fmt.charToDigit(arg[9], 7) catch {
std.debug.print("wrong straight number, not a digit or digit > 6\n", .{});
return 84;
};
if (combination_nb[0] != 5 and combination_nb[0] != 6) {
std.debug.print("wrong straight number, it can only be 5 or 6\n", .{});
return 84;
}
} else if (std.mem.startsWith(u8, arg, "yams_")) {
if (arg.len != 6) {
std.debug.print("invalid combination\n", .{});
return 84;
}
combination = combinations.yams;
combination_nb[0] = std.fmt.charToDigit(arg[5], 7) catch {
std.debug.print("wrong yams number, not a digit or digit > 6\n", .{});
return 84;
};
} else {
std.debug.print("wrong combination\n", .{});
return 84;
}
}
}
if (combination_nb[0] == 0 or combination_nb[1] == 0) {
std.debug.print("combination number cannot be 0\n", .{});
return 84;
}