diff --git a/src/client.odin b/src/client.odin index 4b7fdd9..c8bd070 100644 --- a/src/client.odin +++ b/src/client.odin @@ -15,7 +15,8 @@ run_client :: proc(host_addr: net.Endpoint) { // player input from stdin scanner: bufio.Scanner - // bufio.scanner_init(&scanner, io.to_reader(transmute(io.Stream)os.stdin.stream)) + bufio.scanner_init(&scanner, os.to_stream(os.stdin)) + defer bufio.scanner_destroy(&scanner) LISTEN: for { msg_header: Msg_Type @@ -23,9 +24,10 @@ run_client :: proc(host_addr: net.Endpoint) { switch msg_header { case .Poke: fmt.println("action:") - bufio.scanner_scan(&scanner) - action := bufio.scanner_text(&scanner) - net.send(serv, transmute([]byte)action) + if !bufio.scan(&scanner) do panic("failed to scan") + raw_action := transmute([]byte)bufio.scanner_text(&scanner) + net.send(serv, []byte{byte(len(raw_action))}) + net.send(serv, raw_action) case .State_Update: view, recv_err := receive_view(serv, context.temp_allocator) if recv_err != nil do panic(fmt.tprintln("failed to receive view", recv_err)) diff --git a/src/server.odin b/src/server.odin index fe6f93a..10a9d8a 100644 --- a/src/server.odin +++ b/src/server.odin @@ -38,15 +38,9 @@ run_server :: proc(listen_addr: net.Endpoint, num_players: int, num_hints: int, } } - // action: Action - // POKE: for { - // poke_err := send_poke(comm[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 - // fmt.println("invalid action received. try again.") - // } - // perform_action(&g, action) + action := receive_action(comm[current_player]) + + perform_action(&g, action) current_player = (current_player + 1) % num_players free_all(context.temp_allocator) break GAME_LOOP @@ -212,8 +206,43 @@ Action :: union { Hint_Action, } -receive_action :: proc(player: net.TCP_Socket) -> Action { - // validates user input and creates correct action +ACTION_GUIDE :: `write an action of the form: + - p[lay] + - d[iscard] + - h[int] +where color is one of + - r[ed] + - g[reen] + - w[hite] + - b[lue] + - y[ellow] + - r[ainbow] +and value is one of 1, 2, 3, 4, 5. + +whitespace does not matter, so you could write shorthands like "play1" or "d3". + +example: + $ hint 2 red + $ play 5 + $ hint 3 5` + +receive_action :: proc(player: net.TCP_Socket) -> (action: Action) { + POKE: for { + poke_err := send_poke(player) + if poke_err != nil do panic(fmt.tprintfln("failed to poke player %d: %s", player, poke_err)) + length: [1]u8 + net.recv(player, length[:]) + raw_action := make([]byte, length[0]) + net.recv(player, raw_action) + action = parse_action(transmute(string)raw_action) + if action != nil do break POKE + fmt.println("invalid action.") + fmt.println(ACTION_GUIDE) + } + return +} + +parse_action :: proc(raw_action: string) -> Action { unimplemented() }