wip cleanup
This commit is contained in:
+29
-44
@@ -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
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user