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),
|
discard_pile: std.ArrayListUnmanaged(Card),
|
||||||
hands: []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() {
|
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));
|
||||||
|
@ -968,10 +968,11 @@ fn playerTurnHandler(arena: std.mem.Allocator, request: Request) HandlerError!Re
|
||||||
|
|
||||||
var new_game_state = try request.game_state.clone(arena);
|
var new_game_state = try request.game_state.clone(arena);
|
||||||
if (new_game_state.marked_cards.contains(card)) {
|
if (new_game_state.marked_cards.contains(card)) {
|
||||||
_ = new_game_state.marked_cards.remove(card);
|
_ = new_game_state.marked_cards.swapRemove(card);
|
||||||
} else {
|
} else {
|
||||||
try new_game_state.marked_cards.put(arena, card, {});
|
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 = .{
|
return Response{ .transition = .{
|
||||||
.game_state = new_game_state,
|
.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, .{
|
var new_meld_text = try TextElement.create(arena, .{
|
||||||
.text = "New Meld",
|
.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);
|
var melds_hbox = try HBox.create(arena);
|
||||||
try melds_hbox.addElement(new_meld_text.element());
|
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() };
|
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 {
|
fn glfw_framebuffer_size_callback(window: ?*seizer.backend.glfw.c.GLFWwindow, width: c_int, height: c_int) callconv(.C) void {
|
||||||
_ = window;
|
_ = window;
|
||||||
gl.viewport(
|
gl.viewport(
|
||||||
|
|
Loading…
Reference in New Issue