wip cleanup

This commit is contained in:
2026-05-31 16:38:35 +02:00
parent b1182e5488
commit bd778f4c56
2 changed files with 132 additions and 131 deletions
+29 -44
View File
@@ -1,8 +1,9 @@
package hanabi
import "core:fmt"
import "core:math/rand"
VALUES :: []u8{1, 1, 1, 2, 2, 3, 3, 4, 4, 5}
COLORS :: enum u8 {
RED,
GREEN,
@@ -13,26 +14,20 @@ COLORS :: enum u8 {
}
Card :: bit_field u8 {
value: u8 | 3,
color: COLORS | 3,
value: u8 | 3,
color: COLORS | 3,
_player: u8 | 2,
}
VALUES: []u8 : {1, 1, 1, 2, 2, 3, 3, 4, 4, 5}
Player :: struct {
hand: [dynamic]Card,
}
Hand :: distinct []Card
Game :: struct {
num_players: int,
hint_tokens: int,
lives_left: int,
players: [dynamic]Player,
deck: [dynamic]Card,
}
hand_size :: proc(g: Game) -> int {
return g.num_players <= 3 ? 5 : 4
num_players: int,
num_hints: int,
num_lives: int,
hand_size: int,
player_hands: [dynamic]Hand,
deck: [dynamic]Card,
}
create_deck :: proc() -> (deck: [dynamic]Card) {
@@ -45,9 +40,18 @@ create_deck :: proc() -> (deck: [dynamic]Card) {
return
}
create_player :: proc(g: ^Game) -> (p: Player) {
for i in 0 ..< hand_size(g^) {
append(&p.hand, pop(&g.deck))
deal_hands :: proc(
deck: ^[dynamic]Card,
num_players: int,
hand_size: int,
) -> (
player_hands: [dynamic]Hand,
) {
for i in 0 ..< num_players {
start := len(deck) - hand_size
hand := Hand(deck[start:])
append(&player_hands, hand)
resize(deck, start)
}
return
}
@@ -55,35 +59,16 @@ create_player :: proc(g: ^Game) -> (p: Player) {
create_game :: proc(hint_tokens, lives_left, num_players: int) -> (s: Game) {
assert(num_players >= 2 && num_players <= 5)
s.num_players = num_players
s.hint_tokens = hint_tokens
s.lives_left = lives_left
s.num_hints = hint_tokens
s.num_lives = lives_left
s.hand_size = num_players <= 3 ? 5 : 4
s.deck = create_deck()
for i in 0 ..< num_players {
append(&s.players, create_player(&s))
}
s.player_hands = deal_hands(&s.deck, num_players, s.hand_size)
return
}
delete_game :: proc(g: ^Game) {
delete(g.deck)
for &p in g.players {
delete(p.hand)
}
delete(g.players)
}
print_game :: proc(g: Game) {
for p in g.players {
fmt.println("---")
for c in p.hand {
fmt.println(c.value, c.color)
}
}
// fmt.println("---")
// for c in s.deck {
// fmt.println(c.value, c.color)
// }
// fmt.println("---")
// fmt.println(len(s.deck))
delete(g.player_hands)
}
+103 -87
View File
@@ -5,91 +5,6 @@ import "core:math/rand"
import "core:mem"
import "core:net"
Comm_World :: struct {
sockets: [dynamic]net.TCP_Socket,
}
create_comm_world :: proc(
listener: net.TCP_Socket,
num_conn: int,
) -> (
w: Comm_World,
err: net.Network_Error,
) {
fmt.printfln("waiting for players (%d)...", num_conn)
for len(w.sockets) < num_conn {
client_sock, source := net.accept_tcp(listener) or_return
append(&w.sockets, client_sock)
fmt.println("player connected:", net.to_string(source))
}
return
}
delete_comm_world :: proc(w: ^Comm_World) {
for sock in w.sockets {
net.close(sock)
}
delete(w.sockets)
}
Payload :: struct #packed {
num_players: u8,
num_hints: u8,
num_lives: u8,
num_cards: u8,
cards: []Card,
}
create_payload :: proc(g: Game, player: int, allocator := context.allocator) -> Payload {
cards: [dynamic]Card
for i in 0 ..< g.num_players {
if i == player do continue
hand := g.players[i].hand[:]
for c in hand do append(&cards, c)
}
return {u8(g.num_players), u8(g.hint_tokens), u8(g.lives_left), u8(len(cards)), cards[:]}
}
Msg_Type :: enum u8 {
State_Update,
Poke,
}
send_payload :: proc(sock: net.TCP_Socket, pl: Payload) -> net.Network_Error {
header := Msg_Type.State_Update
net.send(sock, mem.ptr_to_bytes(&header))
data: [dynamic]u8
defer delete(data)
append(&data, pl.num_players, pl.num_hints, pl.num_lives, pl.num_cards)
for c in pl.cards do append(&data, transmute(u8)c)
net.send(sock, data[:]) or_return
return nil
}
send_poke :: proc(sock: net.TCP_Socket) -> net.Network_Error {
header := Msg_Type.Poke
net.send(sock, mem.ptr_to_bytes(&header)) or_return
return nil
}
Play_Action :: distinct Card
Discard_Action :: distinct Card
Hint_Action :: distinct Card
Action :: union {
Play_Action,
Discard_Action,
Hint_Action,
}
receive_action :: proc(player: net.TCP_Socket) -> (action: Action, is_valid: bool) {
unimplemented()
}
perform_action :: proc(game: ^Game, action: Action) {
unimplemented()
}
run_server :: proc(listen_addr: net.Endpoint, num_players: int, num_hints: int, num_lives: int) {
listener, list_err := net.listen_tcp(listen_addr)
if list_err != nil do panic(fmt.tprintln("failed to listen:", net.to_string(listen_addr)))
@@ -127,8 +42,8 @@ run_server :: proc(listen_addr: net.Endpoint, num_players: int, num_hints: int,
POKE: for {
poke_err := send_poke(w.sockets[current_player])
if poke_err != nil do panic(fmt.tprintfln("failed to poke player %d; %s", current_player, poke_err))
action, is_valid := receive_action(w.sockets[current_player])
if is_valid do break POKE
// action, is_valid := receive_action(w.sockets[current_player])
// if is_valid do break POKE
fmt.println("invalid action received. try again.")
}
perform_action(&g, action)
@@ -138,3 +53,104 @@ run_server :: proc(listen_addr: net.Endpoint, num_players: int, num_hints: int,
}
}
/*********************
COMM
**********************/
Comm_World :: struct {
sockets: [dynamic]net.TCP_Socket,
}
create_comm_world :: proc(
listener: net.TCP_Socket,
num_conn: int,
) -> (
w: Comm_World,
err: net.Network_Error,
) {
fmt.printfln("waiting for players (%d)...", num_conn)
for len(w.sockets) < num_conn {
client_sock, source := net.accept_tcp(listener) or_return
append(&w.sockets, client_sock)
fmt.println("player connected:", net.to_string(source))
}
return
}
delete_comm_world :: proc(w: ^Comm_World) {
for sock in w.sockets {
net.close(sock)
}
delete(w.sockets)
}
/******************************
MESSAGE (PAYLOAD/POKE)
*******************************/
Msg_Type :: enum u8 {
State_Update,
Poke,
}
Payload :: struct #packed {
num_players: u8,
num_hints: u8,
num_lives: u8,
num_cards: u8,
cards: []Card,
}
create_payload :: proc(g: Game, player: int, allocator := context.allocator) -> Payload {
cards: [dynamic]Card
for i in 0 ..< g.num_players {
if i == player do continue
hand := g.players[i].hand[:]
for c in hand do append(&cards, c)
}
return {u8(g.num_players), u8(g.num_hints), u8(g.linum_lives u8(len(cards)), cards[:]}
}
send_payload :: proc(sock: net.TCP_Socket, pl: Payload) -> net.Network_Error {
header := Msg_Type.State_Update
net.send(sock, mem.ptr_to_bytes(&header))
data: [dynamic]u8
defer delete(data)
append(&data, pl.num_players, pl.num_hints, pl.num_lives, pl.num_cards)
for c in pl.cards do append(&data, transmute(u8)c)
net.send(sock, data[:]) or_return
return nil
}
send_poke :: proc(sock: net.TCP_Socket) -> net.Network_Error {
header := Msg_Type.Poke
net.send(sock, mem.ptr_to_bytes(&header)) or_return
return nil
}
/*************************
ACTION RESOLUTION
**************************/
Play_Action :: distinct Card
Discard_Action :: distinct Card
Hint_Action :: distinct Card
Action :: union {
Play_Action,
Discard_Action,
Hint_Action,
}
receive_action :: proc(player: net.TCP_Socket) -> Action {
unimplemented()
}
validate_action :: proc(action: Action) -> bool {
unimplemented()
}
perform_action :: proc(game: ^Game, action: Action) {
unimplemented()
}