render draw/discard/hand
parent
695c4d6280
commit
45bc09b612
128
src/main.zig
128
src/main.zig
|
@ -15,6 +15,79 @@ const Card = packed struct(u6) {
|
||||||
rank: u4,
|
rank: u4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const GameState = struct {
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
prng: std.rand.DefaultPrng,
|
||||||
|
draw_pile: std.ArrayListUnmanaged(Card),
|
||||||
|
discard_pile: std.ArrayListUnmanaged(Card),
|
||||||
|
hands: []std.ArrayListUnmanaged(Card),
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator, seed: u64, num_players: usize) !@This() {
|
||||||
|
var draw_pile = std.ArrayListUnmanaged(Card).fromOwnedSlice(try makeStandardDeck(allocator));
|
||||||
|
errdefer draw_pile.deinit(allocator);
|
||||||
|
|
||||||
|
var prng = std.rand.DefaultPrng.init(seed);
|
||||||
|
|
||||||
|
prng.random().shuffle(Card, draw_pile.items);
|
||||||
|
|
||||||
|
const cards_per_player: usize = switch (num_players) {
|
||||||
|
1, 2 => 7,
|
||||||
|
3, 4 => 6,
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
|
const hands = try allocator.alloc(std.ArrayListUnmanaged(Card), num_players);
|
||||||
|
errdefer allocator.free(hands);
|
||||||
|
for (hands) |*hand| {
|
||||||
|
hand.* = try std.ArrayListUnmanaged(Card).initCapacity(allocator, cards_per_player);
|
||||||
|
for (0..cards_per_player) |_| {
|
||||||
|
hand.appendAssumeCapacity(draw_pile.pop());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var discard_pile = try std.ArrayListUnmanaged(Card).initCapacity(allocator, 52);
|
||||||
|
errdefer discard_pile.deinit(allocator);
|
||||||
|
|
||||||
|
// start game with one card in the discard pile
|
||||||
|
discard_pile.appendAssumeCapacity(draw_pile.pop());
|
||||||
|
|
||||||
|
return @This(){
|
||||||
|
.allocator = allocator,
|
||||||
|
.prng = prng,
|
||||||
|
.draw_pile = draw_pile,
|
||||||
|
.discard_pile = discard_pile,
|
||||||
|
.hands = hands,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(this: *@This()) void {
|
||||||
|
this.draw_pile.deinit(this.allocator);
|
||||||
|
this.discard_pile.deinit(this.allocator);
|
||||||
|
for (this.hands) |*hand| {
|
||||||
|
hand.deinit(this.allocator);
|
||||||
|
}
|
||||||
|
this.allocator.free(this.hands);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn makeStandardDeck(allocator: std.mem.Allocator) ![]Card {
|
||||||
|
var deck = try allocator.alloc(Card, 52);
|
||||||
|
errdefer allocator.free(deck);
|
||||||
|
|
||||||
|
var next_index: usize = 0;
|
||||||
|
for (0..4) |suit| {
|
||||||
|
for (1..14) |rank| {
|
||||||
|
deck[next_index] = Card{
|
||||||
|
.suit = @enumFromInt(suit),
|
||||||
|
.rank = @intCast(rank),
|
||||||
|
};
|
||||||
|
next_index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return deck;
|
||||||
|
}
|
||||||
|
|
||||||
/// A texture with a regular grid of sprites
|
/// A texture with a regular grid of sprites
|
||||||
const TileSheet = struct {
|
const TileSheet = struct {
|
||||||
texture: seizer.Texture,
|
texture: seizer.Texture,
|
||||||
|
@ -167,6 +240,10 @@ pub fn main() !void {
|
||||||
var canvas = try seizer.Canvas.init(gpa.allocator(), .{});
|
var canvas = try seizer.Canvas.init(gpa.allocator(), .{});
|
||||||
defer canvas.deinit(gpa.allocator());
|
defer canvas.deinit(gpa.allocator());
|
||||||
|
|
||||||
|
// game state
|
||||||
|
var game_state = try GameState.init(gpa.allocator(), std.crypto.random.int(u64), 1);
|
||||||
|
defer game_state.deinit();
|
||||||
|
|
||||||
while (seizer.backend.glfw.c.glfwWindowShouldClose(window) != seizer.backend.glfw.c.GLFW_TRUE) {
|
while (seizer.backend.glfw.c.glfwWindowShouldClose(window) != seizer.backend.glfw.c.GLFW_TRUE) {
|
||||||
seizer.backend.glfw.c.glfwPollEvents();
|
seizer.backend.glfw.c.glfwPollEvents();
|
||||||
|
|
||||||
|
@ -209,31 +286,40 @@ pub fn main() !void {
|
||||||
1001...std.math.maxInt(c_int) => card_tilemap_large.?,
|
1001...std.math.maxInt(c_int) => card_tilemap_large.?,
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
for (0..4) |suit| {
|
|
||||||
for (1..14) |rank| {
|
|
||||||
const card = Card{ .suit = @enumFromInt(suit), .rank = @intCast(rank) };
|
|
||||||
const tile_index = deck_sprites.getTileForCard(card);
|
|
||||||
deck_sprites.tilesheet.renderTile(&canvas, @intCast(tile_index), .{
|
|
||||||
@floatFromInt(rank * deck_sprites.tilesheet.tile_size[0]),
|
|
||||||
@floatFromInt(suit * deck_sprites.tilesheet.tile_size[1]),
|
|
||||||
}, .{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deck_sprites.tilesheet.renderTile(&canvas, deck_sprites.blank, .{
|
const draw_pile_pos = [2]f32{
|
||||||
@floatFromInt(1 * deck_sprites.tilesheet.tile_size[0]),
|
canvas.window_size[0] / 2 - @as(f32, @floatFromInt(deck_sprites.tilesheet.tile_size[0])),
|
||||||
@floatFromInt(5 * deck_sprites.tilesheet.tile_size[1]),
|
canvas.window_size[1] / 2,
|
||||||
}, .{});
|
};
|
||||||
deck_sprites.tilesheet.renderTile(&canvas, deck_sprites.back, .{
|
const discard_pile_pos = [2]f32{
|
||||||
@floatFromInt(2 * deck_sprites.tilesheet.tile_size[0]),
|
canvas.window_size[0] / 2 + @as(f32, @floatFromInt(deck_sprites.tilesheet.tile_size[0])),
|
||||||
@floatFromInt(5 * deck_sprites.tilesheet.tile_size[1]),
|
canvas.window_size[1] / 2,
|
||||||
}, .{});
|
};
|
||||||
|
const hand_pos = [2]f32{
|
||||||
|
(canvas.window_size[0] - @as(f32, @floatFromInt(game_state.hands[0].items.len * deck_sprites.tilesheet.tile_size[0]))) / 2,
|
||||||
|
canvas.window_size[1] - @as(f32, @floatFromInt(deck_sprites.tilesheet.tile_size[1])),
|
||||||
|
};
|
||||||
|
|
||||||
for (0..52) |i| {
|
for (game_state.draw_pile.items, 0..) |_, i| {
|
||||||
const oy = -@as(f32, @floatFromInt(i)) * (@as(f32, @floatFromInt(deck_sprites.tilesheet.tile_size[1])) / (52.0 * 4));
|
const oy = -@as(f32, @floatFromInt(i)) * (@as(f32, @floatFromInt(deck_sprites.tilesheet.tile_size[1])) / (52.0 * 4));
|
||||||
deck_sprites.tilesheet.renderTile(&canvas, deck_sprites.back, .{
|
deck_sprites.tilesheet.renderTile(&canvas, deck_sprites.back, .{
|
||||||
@floatFromInt(4 * deck_sprites.tilesheet.tile_size[0]),
|
draw_pile_pos[0],
|
||||||
@as(f32, @floatFromInt(5 * deck_sprites.tilesheet.tile_size[1])) + oy,
|
draw_pile_pos[1] + oy,
|
||||||
|
}, .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (game_state.discard_pile.items, 0..) |card, i| {
|
||||||
|
const oy = -@as(f32, @floatFromInt(i)) * (@as(f32, @floatFromInt(deck_sprites.tilesheet.tile_size[1])) / (52.0 * 4));
|
||||||
|
deck_sprites.tilesheet.renderTile(&canvas, deck_sprites.getTileForCard(card), .{
|
||||||
|
discard_pile_pos[0],
|
||||||
|
discard_pile_pos[1] + oy,
|
||||||
|
}, .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (game_state.hands[0].items, 0..) |card, i| {
|
||||||
|
deck_sprites.tilesheet.renderTile(&canvas, deck_sprites.getTileForCard(card), .{
|
||||||
|
hand_pos[0] + @as(f32, @floatFromInt(i)) * @as(f32, @floatFromInt(deck_sprites.tilesheet.tile_size[0])),
|
||||||
|
hand_pos[1],
|
||||||
}, .{});
|
}, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue