kinda working client
This commit is contained in:
+70
-5
@@ -3,13 +3,78 @@ package hanabi
|
||||
import "core:fmt"
|
||||
import "core:net"
|
||||
|
||||
Client_View :: struct {
|
||||
num_hints: int,
|
||||
num_lives: int,
|
||||
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
|
||||
net.recv(sock, header[:])
|
||||
num_cards := header[2]
|
||||
body := make([]byte, 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
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
hand: [dynamic]Card
|
||||
for c in 0 ..< cards_per_hand {
|
||||
append(&hand, unpack_card(pl.cards[i * cards_per_hand + c]))
|
||||
}
|
||||
players[i].hand = hand
|
||||
}
|
||||
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 {
|
||||
fmt.println()
|
||||
for c in p.hand {
|
||||
fmt.println(c.value, c.color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
run_client :: proc(host_addr: net.Endpoint) {
|
||||
sock, list_err := net.dial_tcp(host_addr)
|
||||
serv, list_err := net.dial_tcp(host_addr)
|
||||
if list_err != nil do panic(fmt.tprintln("failed to dial:", net.to_string(host_addr)))
|
||||
defer net.close(sock)
|
||||
buf: [256]byte
|
||||
net.recv(sock, buf[:])
|
||||
fmt.println(transmute(string)buf[:])
|
||||
defer net.close(serv)
|
||||
|
||||
pl := recv_payload(serv, context.temp_allocator)
|
||||
fmt.println("received payload")
|
||||
|
||||
view := create_view(pl, context.temp_allocator)
|
||||
render_view(view)
|
||||
|
||||
free_all(context.temp_allocator)
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -53,7 +53,8 @@ create_player :: proc(g: ^Game) -> (p: Player) {
|
||||
}
|
||||
|
||||
create_game :: proc(hint_tokens, lives_left, num_players: int) -> (s: Game) {
|
||||
assert(num_players > 1 && num_players < 6)
|
||||
assert(num_players >= 2 && num_players <= 5)
|
||||
s.num_players = num_players
|
||||
s.hint_tokens = hint_tokens
|
||||
s.lives_left = lives_left
|
||||
s.deck = create_deck()
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ main :: proc() {
|
||||
if !endpoint_ok do panic(fmt.tprintln("failed to parse endpoint:", os.args[2]))
|
||||
num_players, int_ok := strconv.parse_int(os.args[3])
|
||||
if !int_ok do panic(fmt.tprintln("failed to parse number of players:", os.args[3]))
|
||||
if num_players < 1 || num_players > 5 do return
|
||||
if num_players < 2 || num_players > 5 do return
|
||||
run_server(addr, num_players)
|
||||
case:
|
||||
return
|
||||
|
||||
+15
-3
@@ -39,6 +39,10 @@ Bit_Card :: bit_field u8 {
|
||||
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,
|
||||
@@ -52,7 +56,7 @@ create_payload :: proc(g: Game, player: int, allocator := context.allocator) ->
|
||||
if i == player do continue
|
||||
hand := g.players[i].hand[:]
|
||||
for c in hand {
|
||||
append(&cards, Bit_Card{value = c.value, color = c.color})
|
||||
append(&cards, pack_card(c))
|
||||
}
|
||||
}
|
||||
return {u8(g.hint_tokens), u8(g.lives_left), u8(len(cards)), cards[:]}
|
||||
@@ -88,19 +92,27 @@ run_server :: proc(
|
||||
defer delete_game(&g)
|
||||
|
||||
current_player := rand.int_max(num_players)
|
||||
game_loop: for {
|
||||
GAME_LOOP: for {
|
||||
for i in 0 ..< num_players {
|
||||
pl := create_payload(g, i, context.temp_allocator)
|
||||
send_err := send_payload(w.sockets[i], pl)
|
||||
if send_err != nil do panic("failed to send payload")
|
||||
}
|
||||
|
||||
fmt.printfln("player %s's turn!", current_player)
|
||||
fmt.printfln("player %d's turn!", current_player)
|
||||
|
||||
for p in g.players {
|
||||
fmt.println()
|
||||
for c in p.hand {
|
||||
fmt.println(c.value, c.color)
|
||||
}
|
||||
}
|
||||
|
||||
// body
|
||||
|
||||
current_player = (current_player + 1) % num_players
|
||||
free_all(context.temp_allocator)
|
||||
break GAME_LOOP
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user