only activate "New Meld" when a valid meld is marked
parent
f0e6bc4e0d
commit
6f42b35e14
52
src/main.zig
52
src/main.zig
|
@ -23,7 +23,7 @@ const GameState = struct {
|
|||
discard_pile: std.ArrayListUnmanaged(Card),
|
||||
hands: []std.ArrayListUnmanaged(Card),
|
||||
|
||||
marked_cards: std.AutoHashMapUnmanaged(Card, void),
|
||||
marked_cards: std.AutoArrayHashMapUnmanaged(Card, void),
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, seed: u64, num_players: usize) !@This() {
|
||||
var draw_pile = std.ArrayListUnmanaged(Card).fromOwnedSlice(try makeStandardDeck(allocator));
|
||||
|
@ -968,10 +968,11 @@ fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Re
|
|||
|
||||
var new_game_state = try request.game_state.clone(arena);
|
||||
if (new_game_state.marked_cards.contains(card)) {
|
||||
_ = new_game_state.marked_cards.remove(card);
|
||||
_ = new_game_state.marked_cards.swapRemove(card);
|
||||
} else {
|
||||
try new_game_state.marked_cards.put(arena, card, {});
|
||||
}
|
||||
new_game_state.marked_cards.sort(ArrayHashMapRummyHandSort{ .keys = new_game_state.marked_cards.keys() });
|
||||
|
||||
return Response{ .transition = .{
|
||||
.game_state = new_game_state,
|
||||
|
@ -982,8 +983,11 @@ fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Re
|
|||
|
||||
var new_meld_text = try TextElement.create(arena, .{
|
||||
.text = "New Meld",
|
||||
.command = "new-meld",
|
||||
.command = null,
|
||||
});
|
||||
if (isValidRummyMeld(request.game_state.marked_cards.keys())) {
|
||||
new_meld_text.command = "new-meld";
|
||||
}
|
||||
|
||||
var melds_hbox = try HBox.create(arena);
|
||||
try melds_hbox.addElement(new_meld_text.element());
|
||||
|
@ -1015,6 +1019,48 @@ fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Re
|
|||
return Response{ .page = page.element() };
|
||||
}
|
||||
|
||||
fn isValidRummyMeld(cards: []const Card) bool {
|
||||
std.debug.assert(std.sort.isSorted(Card, cards, {}, rummyHandSort));
|
||||
if (cards.len < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const expected_rank = cards[0].rank;
|
||||
var is_valid_set = true;
|
||||
for (cards) |card| {
|
||||
if (card.rank != expected_rank) {
|
||||
is_valid_set = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const expected_suit = cards[0].suit;
|
||||
var is_valid_run = true;
|
||||
for (cards[0 .. cards.len - 1], cards[1..]) |prev_card, card| {
|
||||
if (card.suit != expected_suit or card.rank != (prev_card.rank + 1)) {
|
||||
is_valid_run = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return is_valid_set or is_valid_run;
|
||||
}
|
||||
|
||||
pub fn rummyHandSort(_: void, lhs: Card, rhs: Card) bool {
|
||||
if (lhs.rank < rhs.rank) return true;
|
||||
if (lhs.rank > rhs.rank) return false;
|
||||
|
||||
return @intFromEnum(lhs.suit) < @intFromEnum(rhs.suit);
|
||||
}
|
||||
|
||||
const ArrayHashMapRummyHandSort = struct {
|
||||
keys: []const Card,
|
||||
|
||||
pub fn lessThan(this: @This(), lhs_index: usize, rhs_index: usize) bool {
|
||||
return rummyHandSort({}, this.keys[lhs_index], this.keys[rhs_index]);
|
||||
}
|
||||
};
|
||||
|
||||
fn glfw_framebuffer_size_callback(window: ?*seizer.backend.glfw.c.GLFWwindow, width: c_int, height: c_int) callconv(.C) void {
|
||||
_ = window;
|
||||
gl.viewport(
|
||||
|
|
Loading…
Reference in New Issue