feat: mark/unmark cards after drawing
parent
c5526ba229
commit
2dde105a58
56
src/main.zig
56
src/main.zig
|
@ -23,6 +23,8 @@ const GameState = struct {
|
||||||
discard_pile: std.ArrayListUnmanaged(Card),
|
discard_pile: std.ArrayListUnmanaged(Card),
|
||||||
hands: []std.ArrayListUnmanaged(Card),
|
hands: []std.ArrayListUnmanaged(Card),
|
||||||
|
|
||||||
|
marked_cards: std.AutoHashMapUnmanaged(Card, void),
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, seed: u64, num_players: usize) !@This() {
|
pub fn init(allocator: std.mem.Allocator, seed: u64, num_players: usize) !@This() {
|
||||||
var draw_pile = std.ArrayListUnmanaged(Card).fromOwnedSlice(try makeStandardDeck(allocator));
|
var draw_pile = std.ArrayListUnmanaged(Card).fromOwnedSlice(try makeStandardDeck(allocator));
|
||||||
errdefer draw_pile.deinit(allocator);
|
errdefer draw_pile.deinit(allocator);
|
||||||
|
@ -59,6 +61,7 @@ const GameState = struct {
|
||||||
.draw_pile = draw_pile,
|
.draw_pile = draw_pile,
|
||||||
.discard_pile = discard_pile,
|
.discard_pile = discard_pile,
|
||||||
.hands = hands,
|
.hands = hands,
|
||||||
|
.marked_cards = .{},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +72,7 @@ const GameState = struct {
|
||||||
hand.deinit(this.allocator);
|
hand.deinit(this.allocator);
|
||||||
}
|
}
|
||||||
this.allocator.free(this.hands);
|
this.allocator.free(this.hands);
|
||||||
|
this.marked_cards.deinit(this.allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone(this: @This(), allocator: std.mem.Allocator) !@This() {
|
pub fn clone(this: @This(), allocator: std.mem.Allocator) !@This() {
|
||||||
|
@ -84,6 +88,7 @@ const GameState = struct {
|
||||||
.draw_pile = try this.draw_pile.clone(allocator),
|
.draw_pile = try this.draw_pile.clone(allocator),
|
||||||
.discard_pile = try this.discard_pile.clone(allocator),
|
.discard_pile = try this.discard_pile.clone(allocator),
|
||||||
.hands = hands,
|
.hands = hands,
|
||||||
|
.marked_cards = try this.marked_cards.clone(allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -262,6 +267,9 @@ pub fn main() !void {
|
||||||
history.clearRetainingCapacity();
|
history.clearRetainingCapacity();
|
||||||
}
|
}
|
||||||
try history.append(try transition.game_state.clone(gpa.allocator()));
|
try history.append(try transition.game_state.clone(gpa.allocator()));
|
||||||
|
|
||||||
|
if (request_command) |command| gpa.allocator().free(command);
|
||||||
|
request_command = null;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -734,13 +742,14 @@ pub const CardElement = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
visual: Visual,
|
visual: Visual,
|
||||||
command: ?[]const u8,
|
command: ?[]const u8,
|
||||||
|
marked: bool,
|
||||||
|
|
||||||
const Visual = union(enum) {
|
const Visual = union(enum) {
|
||||||
back,
|
back,
|
||||||
card: Card,
|
card: Card,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(allocator: std.mem.Allocator, options: struct { visual: Visual, command: ?[]const u8 }) !*@This() {
|
pub fn create(allocator: std.mem.Allocator, options: struct { visual: Visual, command: ?[]const u8, marked: ?bool = null }) !*@This() {
|
||||||
const this = try allocator.create(@This());
|
const this = try allocator.create(@This());
|
||||||
errdefer allocator.destroy(this);
|
errdefer allocator.destroy(this);
|
||||||
|
|
||||||
|
@ -748,6 +757,7 @@ pub const CardElement = struct {
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.visual = options.visual,
|
.visual = options.visual,
|
||||||
.command = options.command,
|
.command = options.command,
|
||||||
|
.marked = options.marked orelse false,
|
||||||
};
|
};
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -776,24 +786,32 @@ pub const CardElement = struct {
|
||||||
pub fn element_render(pointer: ?*anyopaque, canvas: *seizer.Canvas, render_resources: RenderResources, min: [2]f32, max: [2]f32) void {
|
pub fn element_render(pointer: ?*anyopaque, canvas: *seizer.Canvas, render_resources: RenderResources, min: [2]f32, max: [2]f32) void {
|
||||||
const this: *@This() = @ptrCast(@alignCast(pointer));
|
const this: *@This() = @ptrCast(@alignCast(pointer));
|
||||||
|
|
||||||
|
const mark_offset = if (this.marked)
|
||||||
|
[2]f32{
|
||||||
|
0,
|
||||||
|
@as(f32, @floatFromInt(render_resources.deck.tilesheet.tile_size[1])) * -0.4,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
[2]f32{ 0, 0 };
|
||||||
|
|
||||||
switch (this.visual) {
|
switch (this.visual) {
|
||||||
.back => render_resources.deck.tilesheet.renderTile(
|
.back => render_resources.deck.tilesheet.renderTile(
|
||||||
canvas,
|
canvas,
|
||||||
render_resources.deck.back,
|
render_resources.deck.back,
|
||||||
.{ min[0], min[1] },
|
.{ min[0] + mark_offset[0], min[1] + mark_offset[1] },
|
||||||
.{},
|
.{},
|
||||||
),
|
),
|
||||||
.card => |card| render_resources.deck.tilesheet.renderTile(
|
.card => |card| render_resources.deck.tilesheet.renderTile(
|
||||||
canvas,
|
canvas,
|
||||||
render_resources.deck.getTileForCard(card),
|
render_resources.deck.getTileForCard(card),
|
||||||
.{ min[0], min[1] },
|
.{ min[0] + mark_offset[0], min[1] + mark_offset[1] },
|
||||||
.{},
|
.{},
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (render_resources.hovered != null and this.command != null and std.mem.eql(u8, render_resources.hovered.?, this.command.?)) {
|
if (render_resources.hovered != null and this.command != null and std.mem.eql(u8, render_resources.hovered.?, this.command.?)) {
|
||||||
canvas.rect(
|
canvas.rect(
|
||||||
min,
|
.{ min[0] + mark_offset[0], min[1] + mark_offset[1] },
|
||||||
.{ max[0] - min[0], max[1] - min[1] },
|
.{ max[0] - min[0], max[1] - min[1] },
|
||||||
.{ .color = .{ 0xAA, 0xFF, 0xAA, 0x60 } },
|
.{ .color = .{ 0xAA, 0xFF, 0xAA, 0x60 } },
|
||||||
);
|
);
|
||||||
|
@ -867,6 +885,33 @@ fn drawCardHandler(arena: std.mem.Allocator, request: Request) HandlerError!Resp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Response {
|
fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Response {
|
||||||
|
if (request.command) |command| handle_command: {
|
||||||
|
if (std.mem.startsWith(u8, command, "mark ")) {
|
||||||
|
var iter = std.mem.tokenizeScalar(u8, command, ' ');
|
||||||
|
_ = iter.next() orelse break :handle_command;
|
||||||
|
const rank_str = iter.next() orelse break :handle_command;
|
||||||
|
_ = iter.next() orelse break :handle_command;
|
||||||
|
const suit_str = iter.next() orelse break :handle_command;
|
||||||
|
|
||||||
|
const card = Card{
|
||||||
|
.suit = std.meta.stringToEnum(assets.Suit, suit_str) orelse break :handle_command,
|
||||||
|
.rank = std.fmt.parseInt(u4, rank_str, 10) catch break :handle_command,
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
try new_game_state.marked_cards.put(arena, card, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response{ .transition = .{
|
||||||
|
.game_state = new_game_state,
|
||||||
|
.can_undo = true,
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var draw_pile = try Pile.create(arena, request.game_state.draw_pile.items);
|
var draw_pile = try Pile.create(arena, request.game_state.draw_pile.items);
|
||||||
draw_pile.hidden = true;
|
draw_pile.hidden = true;
|
||||||
|
|
||||||
|
@ -876,7 +921,8 @@ fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Re
|
||||||
for (request.game_state.hands[0].items) |card| {
|
for (request.game_state.hands[0].items) |card| {
|
||||||
var card_element = try CardElement.create(arena, .{
|
var card_element = try CardElement.create(arena, .{
|
||||||
.visual = .{ .card = card },
|
.visual = .{ .card = card },
|
||||||
.command = "mark",
|
.command = try std.fmt.allocPrint(arena, "mark {} of {s}", .{ card.rank, @tagName(card.suit) }),
|
||||||
|
.marked = request.game_state.marked_cards.contains(card),
|
||||||
});
|
});
|
||||||
try hand.addElement(card_element.element());
|
try hand.addElement(card_element.element());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue