Skip to content

Commit

Permalink
basics done!!!
Browse files Browse the repository at this point in the history
  • Loading branch information
chouzar committed Feb 7, 2024
1 parent 83b0f09 commit 78a7a8e
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 121 deletions.
10 changes: 8 additions & 2 deletions priv/assets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,19 @@ button {
justify-content: space-between;
}

.board>.field>.scores>.score.player-1 {
.board>.field>.scores.totals>.score.player-1 {
outline: 3px solid var(--dark-blue);
}

.board>.field>.scores.totals>.score.player-2 {
outline: 3px solid var(--dark-red);
}

.board>.field>.scores>.score.player-1 {
color: var(--font-blue);
}

.board>.field>.scores>.score.player-2 {
outline: 3px solid var(--dark-red);
color: var(--font-red);
}

Expand Down
2 changes: 1 addition & 1 deletion src/luster/games/three_line_poker.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import gleam/result.{try}

pub const max_hand_size = 8

const plays_per_turn = 4
pub const plays_per_turn = 4

const straight_flush = 19

Expand Down
5 changes: 2 additions & 3 deletions src/luster/systems/comp.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn handle_init(

let session_id = session.id(session)

process.send_after(self, 5000, AssessMove)
process.send(self, AssessMove)

actor.Ready(
State(self, session_id, player, session, pubsub),
Expand All @@ -72,8 +72,7 @@ fn handle_message(message: Message, state: State) -> actor.Next(Message, State)
Ok(Nil)
}

let _timer =
process.send_after(state.self, between(1000, 2500), AssessMove)
let _timer = process.send_after(state.self, between(50, 50), AssessMove)

actor.continue(state)
}
Expand Down
49 changes: 37 additions & 12 deletions src/luster/systems/session.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@ import gleam/erlang/process
import gleam/function.{identity}
import gleam/option.{None}
import gleam/otp/actor
import luster/games/three_line_poker as tlp
import luster/games/three_line_poker as g
import luster/systems/store

pub opaque type Message {
Id(caller: process.Subject(String))
Set(tlp.GameState)
Get(caller: process.Subject(Result(tlp.GameState, Nil)))
Set(g.GameState)
Get(caller: process.Subject(Result(g.GameState, Nil)))
Next(caller: process.Subject(Result(g.GameState, g.Errors)), g.Message)
Stop
}

type State {
State(id: String, store: process.Subject(store.Message(tlp.GameState)))
State(id: String, store: process.Subject(store.Message(g.GameState)))
}

pub fn start(
store: process.Subject(store.Message(tlp.GameState)),
store: process.Subject(store.Message(g.GameState)),
session_registry: process.Subject(chip.Message(String, Message)),
) -> Result(process.Subject(Message), actor.StartError) {
actor.start_spec(actor.Spec(
Expand All @@ -32,20 +33,27 @@ pub fn id(session: process.Subject(Message)) -> String {
actor.call(session, Id(_), 100)
}

pub fn set(session: process.Subject(Message), gamestate: tlp.GameState) -> Nil {
pub fn next(
session: process.Subject(Message),
message: g.Message,
) -> Result(g.GameState, g.Errors) {
actor.call(session, Next(_, message), 100)
}

pub fn set(session: process.Subject(Message), gamestate: g.GameState) -> Nil {
actor.send(session, Set(gamestate))
}

pub fn get(session: process.Subject(Message)) -> Result(tlp.GameState, Nil) {
pub fn get(session: process.Subject(Message)) -> Result(g.GameState, Nil) {
actor.call(session, Get(_), 100)
}

fn handle_init(
store: process.Subject(store.Message(tlp.GameState)),
store: process.Subject(store.Message(g.GameState)),
session_registry: process.Subject(chip.Message(String, Message)),
) -> actor.InitResult(State, Message) {
let self = process.new_subject()
let session_id = store.create(store, tlp.new())
let session_id = store.create(store, g.new())
let _ = chip.register_as(session_registry, session_id, fn() { Ok(self) })

actor.Ready(
Expand All @@ -59,20 +67,37 @@ fn handle_message(message: Message, state: State) -> actor.Next(Message, State)
case message {
Id(caller) -> {
process.send(caller, state.id)
actor.Continue(state, None)
actor.continue(state)
}

Set(gamestate) -> {
let _ = store.update(state.store, state.id, gamestate)
actor.Continue(state, None)
actor.continue(state)
}

Get(caller) -> {
state.store
|> store.one(state.id)
|> process.send(caller, _)

actor.Continue(state, None)
actor.continue(state)
}

Next(caller, message) -> {
let assert Ok(gamestate) = store.one(state.store, state.id)

case g.next(gamestate, message) {
Ok(gamestate) -> {
let _ = store.update(state.store, state.id, gamestate)
let _ = process.send(caller, Ok(gamestate))
actor.continue(state)
}

Error(error) -> {
let _ = process.send(caller, Error(error))
actor.continue(state)
}
}
}

Stop -> {
Expand Down
10 changes: 5 additions & 5 deletions src/luster/web.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ pub fn router(
}

http.Post, ["battleline"] -> {
let assert Ok(_session) = session.start(store, session_registry)
//let assert Ok(_comp_1) = comp.start(tlp.Player1, session, socket_registry)
//let assert Ok(_comp_2) = comp.start(tlp.Player2, session, socket_registry)
let assert Ok(session) = session.start(store, session_registry)
let assert Ok(_comp_1) = comp.start(tlp.Player1, session, socket_registry)
let assert Ok(_comp_2) = comp.start(tlp.Player2, session, socket_registry)

redirect("/")
}

http.Get, ["battleline", id] -> {
case store.one(store, id) {
Ok(gamestate) ->
tea_game.init(gamestate)
|> tea_game.view()
tea_game.init()
|> tea_game.view(gamestate)
|> render(with: fn(body) { layout(id, body) })

Error(_) -> redirect("/")
Expand Down
101 changes: 36 additions & 65 deletions src/luster/web/socket.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import gleam/http/response.{type Response}
import gleam/int
import gleam/io
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/option.{type Option, Some}
import gleam/otp/actor
import gleam/result.{try}
import luster/games/three_line_poker as g
Expand Down Expand Up @@ -70,26 +70,14 @@ fn build_init(
pubsub: PubSub,
) -> #(State, Option(process.Selector(Message))) {
let self = process.new_subject()

let _ = chip.register_as(pubsub, session_id, fn() { Ok(self) })
let model = tea.init()
let state = State(self, session_id, session, pubsub, model)
let selector =
process.new_selector()
|> process.selecting(self, identity)

let assert Ok(gamestate) = session.get(session)

let model =
tea.Model(
alert: None,
selected_card: None,
toggle_scoring: False,
gamestate: gamestate,
)

#(
State(self, session_id, session, pubsub, model),
Some(
process.new_selector()
|> process.selecting(self, identity),
),
)
#(state, Some(selector))
}

fn on_close(state: State) -> Nil {
Expand All @@ -104,60 +92,45 @@ fn handle_message(
) -> actor.Next(a, State) {
case message {
Binary(bits) -> {
let result = {
use action <- try(parse_message(bits))
use gamestate <- try(session.get(state.session))

case action {
Play(message) -> {
case g.next(gamestate, message) {
Ok(gamestate) -> {
let Nil = session.set(state.session, gamestate)
let Nil =
broadcast(state.pubsub, state.session_id, UpdateGameState)
Ok(state)
case parse_message(bits) {
Ok(action) -> {
let model = case action {
Play(message) -> {
case session.next(state.session, message) {
Ok(_gamestate) -> {
state.model
}
Error(error) -> {
tea.update(state.model, tea.Alert(error))
}
}
}

Error(error) -> {
let model = tea.update(state.model, tea.Alert(error))
let state = State(..state, model: model)

model
|> tea.view()
|> nakai.to_inline_string()
|> tap(mist.send_text_frame(conn, _))

Ok(state)
}
Select(message) -> {
tea.update(state.model, message)
}
}

Select(message) -> {
io.debug(message)
let model = tea.update(state.model, message)
let state = State(..state, model: model)

model
|> tea.view()
|> nakai.to_inline_string()
|> tap(mist.send_text_frame(conn, _))
let Nil = broadcast(state.pubsub, state.session_id, UpdateGameState)

Ok(state)
}
let state = State(..state, model: model)
actor.continue(state)
}
}

case result {
Ok(state) -> actor.continue(state)
Error(Nil) -> actor.continue(state)
Error(Nil) -> {
io.println("out of bound message:")
io.debug(bits)

actor.continue(state)
}
}
}

Custom(UpdateGameState) -> {
case session.get(state.session) {
Ok(gamestate) -> {
tea.update(state.model, tea.Next(gamestate))
|> tea.view()
state.model
|> tea.view(gamestate)
|> nakai.to_inline_string()
|> tap(mist.send_text_frame(conn, _))

Expand Down Expand Up @@ -202,13 +175,11 @@ fn parse_message(bits: BitArray) -> Result(Action, Nil) {
Ok(Select(tea.SelectCard(card)))
}

<<"popuptoggle":utf8, _rest:bytes>> -> {
<<"popup-toggle":utf8, _rest:bytes>> -> {
Ok(Select(tea.ToggleScoring))
}

_other -> {
io.println("out of bound message:")
io.debug(bits)
Error(Nil)
}
}
Expand All @@ -230,8 +201,8 @@ fn decode_play_card(bits: BitArray) -> Result(#(g.Player, g.Slot, g.Card), Nil)
<<
player:bytes-size(2),
slot:bytes-size(1),
suit:bytes-size(2),
rank:bytes-size(1),
suit:bytes-size(3),
rank:bytes-size(2),
>> -> {
use player <- try(decode_player(player))
use slot <- try(decode_slot(slot))
Expand All @@ -246,7 +217,7 @@ fn decode_play_card(bits: BitArray) -> Result(#(g.Player, g.Slot, g.Card), Nil)

fn decode_select_card(bits: BitArray) -> Result(#(g.Card), Nil) {
case bits {
<<suit:bytes-size(3), rank:bytes-size(1)>> -> {
<<suit:bytes-size(3), rank:bytes-size(2)>> -> {
use suit <- try(decode_suit(suit))
use rank <- try(decode_rank(rank))
Ok(#(g.Card(rank, suit)))
Expand Down
Loading

0 comments on commit 78a7a8e

Please sign in to comment.