diff --git a/src/main.zig b/src/main.zig index fabaecd..43f3d88 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1080,6 +1080,31 @@ fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Re .can_undo = true, .reset_selection = false, } }; + } else if (std.mem.eql(u8, command, "discard")) { + if (request.game_state.marked_cards.count() == 1) { + var new_game_state = try request.game_state.clone(arena); + + try new_game_state.discard_pile.ensureUnusedCapacity(arena, 1); + + new_game_state.hands[0].clearRetainingCapacity(); + new_game_state.marked_cards.clearRetainingCapacity(); + + for (request.game_state.hands[0].items) |card| { + if (request.game_state.marked_cards.contains(card)) { + new_game_state.discard_pile.appendAssumeCapacity(card); + } else { + new_game_state.hands[0].appendAssumeCapacity(card); + } + } + + new_game_state.handler = &endOfTurnConfirmHandler; + + return Response{ .transition = .{ + .game_state = new_game_state, + .can_undo = true, + .reset_selection = false, + } }; + } } } @@ -1098,6 +1123,9 @@ fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Re draw_pile.hidden = true; var discard_pile = try Pile.create(arena, request.game_state.discard_pile.items); + if (request.game_state.marked_cards.count() == 1) { + discard_pile.command = "discard"; + } var hand = try HBox.create(arena); for (request.game_state.hands[0].items) |card| { @@ -1121,6 +1149,60 @@ fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Re return Response{ .page = page.element() }; } +fn endOfTurnConfirmHandler(arena: std.mem.Allocator, request: Request) HandlerError!Response { + if (request.command) |command| { + if (std.mem.eql(u8, command, "end_turn")) { + var new_game_state = try request.game_state.clone(arena); + new_game_state.handler = &drawCardHandler; + + return Response{ .transition = .{ + .game_state = new_game_state, + .can_undo = false, + } }; + } + } + + var new_meld_text = try TextElement.create(arena, .{ + .text = "New Meld", + .command = null, + }); + + var melds_hbox = try HBox.create(arena); + try melds_hbox.addElement(new_meld_text.element()); + + var draw_pile = try Pile.create(arena, request.game_state.draw_pile.items); + draw_pile.hidden = true; + + var discard_pile = try Pile.create(arena, request.game_state.discard_pile.items); + + var hand = try HBox.create(arena); + for (request.game_state.hands[0].items) |card| { + var card_element = try CardElement.create(arena, .{ + .visual = .{ .card = card }, + .command = null, + .marked = false, + }); + try hand.addElement(card_element.element()); + } + + var draw_discard_hbox = try HBox.create(arena); + try draw_discard_hbox.addElement(draw_pile.element()); + try draw_discard_hbox.addElement(discard_pile.element()); + + var end_turn_text = try TextElement.create(arena, .{ + .text = "End Turn", + .command = "end_turn", + }); + + var page = try Page.create(arena); + try page.addElement(.{ 0.5, 0.5 }, .{ 0.5, 0.5 }, draw_discard_hbox.element()); + try page.addElement(.{ 0.5, 1 }, .{ 0.5, 1 }, hand.element()); + try page.addElement(.{ 0.5, 0 }, .{ 0.5, 0 }, melds_hbox.element()); + try page.addElement(.{ 0.5, 0.5 }, .{ 0.5, 0.5 }, end_turn_text.element()); + + return Response{ .page = page.element() }; +} + fn isValidRummyMeld(cards: []const Card) bool { std.debug.assert(std.sort.isSorted(Card, cards, {}, rummyHandSort)); if (cards.len < 3) {