fix transmutation bug
This commit is contained in:
+30
-37
@@ -4,58 +4,51 @@ import "core:fmt"
|
||||
import "core:net"
|
||||
|
||||
Client_View :: struct {
|
||||
num_hints: int,
|
||||
num_lives: int,
|
||||
players: []Player,
|
||||
num_players: int,
|
||||
num_hints: int,
|
||||
num_lives: int,
|
||||
other_players: []Player,
|
||||
}
|
||||
|
||||
unpack_card :: proc(c: Bit_Card) -> Card {
|
||||
return {value = c.value, color = c.color}
|
||||
}
|
||||
|
||||
recv_payload :: proc(sock: net.TCP_Socket, allocator := context.allocator) -> Payload {
|
||||
header: [3]byte
|
||||
recv_payload :: proc(sock: net.TCP_Socket, allocator := context.allocator) -> (pl: Payload) {
|
||||
header: [4]u8
|
||||
net.recv(sock, header[:])
|
||||
num_cards := header[2]
|
||||
body := make([]byte, num_cards)
|
||||
num_cards := header[3]
|
||||
body := make([]u8, num_cards)
|
||||
net.recv(sock, body)
|
||||
return {header[0], header[1], header[2], transmute([]Bit_Card)body}
|
||||
}
|
||||
|
||||
num_players :: proc(num_cards: int) -> int {
|
||||
switch num_cards {
|
||||
case 5:
|
||||
return 2
|
||||
case 10:
|
||||
return 3
|
||||
case 12:
|
||||
return 4
|
||||
case 16:
|
||||
return 5
|
||||
case:
|
||||
return -1
|
||||
}
|
||||
pl = {header[0], header[1], header[2], header[3], transmute([]Card)body}
|
||||
// sanity checks
|
||||
assert(2 <= pl.num_players && pl.num_players <= 5)
|
||||
assert(pl.num_hints >= 0 && pl.num_lives >= 0)
|
||||
for c in pl.cards do assert(1 <= c.value && c.value <= 5)
|
||||
return
|
||||
}
|
||||
|
||||
create_view :: proc(pl: Payload, allocator := context.allocator) -> Client_View {
|
||||
n := num_players(int(pl.num_cards))
|
||||
assert(n > 0)
|
||||
players := make([]Player, n)
|
||||
for i in 0 ..< n - 1 {
|
||||
cards_per_hand := int(pl.num_cards) / (n - 1)
|
||||
cards_per_hand := pl.num_cards / (pl.num_players - 1)
|
||||
players: [dynamic]Player
|
||||
i := 0
|
||||
for cast(u8)len(players) < pl.num_players - 1 {
|
||||
hand: [dynamic]Card
|
||||
for c in 0 ..< cards_per_hand {
|
||||
append(&hand, unpack_card(pl.cards[i * cards_per_hand + c]))
|
||||
for cast(u8)len(hand) < cards_per_hand {
|
||||
append(&hand, pl.cards[i])
|
||||
i += 1
|
||||
}
|
||||
players[i].hand = hand
|
||||
append(&players, Player{hand = hand})
|
||||
}
|
||||
|
||||
return {
|
||||
num_players = int(pl.num_players),
|
||||
num_hints = int(pl.num_hints),
|
||||
num_lives = int(pl.num_lives),
|
||||
other_players = players[:],
|
||||
}
|
||||
return {num_hints = int(pl.num_hints), num_lives = int(pl.num_lives), players = players}
|
||||
}
|
||||
|
||||
render_view :: proc(view: Client_View) {
|
||||
fmt.println("number of hints left:", view.num_hints)
|
||||
fmt.println("number of lives left:", view.num_lives)
|
||||
for p in view.players {
|
||||
for p in view.other_players {
|
||||
fmt.println()
|
||||
for c in p.hand {
|
||||
fmt.println(c.value, c.color)
|
||||
|
||||
+12
-12
@@ -3,21 +3,21 @@ package hanabi
|
||||
import "core:fmt"
|
||||
import "core:math/rand"
|
||||
|
||||
COLORS :: enum {
|
||||
RED,
|
||||
GREEN,
|
||||
WHITE,
|
||||
BLUE,
|
||||
YELLOW,
|
||||
RAINBOW,
|
||||
COLORS :: enum u8 {
|
||||
RED = 0b000,
|
||||
GREEN = 0b001,
|
||||
WHITE = 0b010,
|
||||
BLUE = 0b011,
|
||||
YELLOW = 0b100,
|
||||
RAINBOW = 0b101,
|
||||
}
|
||||
|
||||
Card :: struct {
|
||||
value: int,
|
||||
color: COLORS,
|
||||
Card :: bit_field u8 {
|
||||
value: u8 | 3,
|
||||
color: COLORS | 3,
|
||||
}
|
||||
|
||||
VALUES: []int : {1, 1, 1, 2, 2, 3, 3, 4, 4, 5}
|
||||
VALUES: []u8 : {1, 1, 1, 2, 2, 3, 3, 4, 4, 5}
|
||||
|
||||
Player :: struct {
|
||||
hand: [dynamic]Card,
|
||||
@@ -38,7 +38,7 @@ hand_size :: proc(g: Game) -> int {
|
||||
create_deck :: proc() -> (deck: [dynamic]Card) {
|
||||
for c in COLORS {
|
||||
for v in VALUES {
|
||||
append(&deck, Card{v, c})
|
||||
append(&deck, Card{value = v, color = c})
|
||||
}
|
||||
}
|
||||
rand.shuffle(deck[:])
|
||||
|
||||
+11
-24
@@ -30,47 +30,34 @@ delete_comm_world :: proc(w: ^Comm_World) {
|
||||
delete(w.sockets)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
emulates Card, but packs the fields more neatly
|
||||
*/
|
||||
Bit_Card :: bit_field u8 {
|
||||
value: int | 3,
|
||||
color: COLORS | 3,
|
||||
}
|
||||
|
||||
pack_card :: proc(c: Card) -> Bit_Card {
|
||||
return {value = c.value, color = c.color}
|
||||
}
|
||||
|
||||
Payload :: struct #packed {
|
||||
num_hints: u8,
|
||||
num_lives: u8,
|
||||
num_cards: u8,
|
||||
cards: []Bit_Card,
|
||||
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]Bit_Card
|
||||
cards: [dynamic]Card
|
||||
for i in 0 ..< g.num_players {
|
||||
if i == player do continue
|
||||
hand := g.players[i].hand[:]
|
||||
for c in hand {
|
||||
append(&cards, pack_card(c))
|
||||
}
|
||||
for c in hand do append(&cards, c)
|
||||
}
|
||||
return {u8(g.hint_tokens), u8(g.lives_left), u8(len(cards)), cards[:]}
|
||||
return {u8(g.num_players), u8(g.hint_tokens), u8(g.lives_left), u8(len(cards)), cards[:]}
|
||||
}
|
||||
|
||||
send_payload :: proc(sock: net.TCP_Socket, pl: Payload) -> net.Network_Error {
|
||||
data: [dynamic]byte
|
||||
data: [dynamic]u8
|
||||
defer delete(data)
|
||||
append(&data, pl.num_hints, pl.num_lives, pl.num_cards)
|
||||
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
|
||||
}
|
||||
|
||||
// TODO: add cli input for these
|
||||
DEFAULT_HINT_TOKENS :: 8
|
||||
DEFAULT_LIVES :: 3
|
||||
|
||||
|
||||
Reference in New Issue
Block a user