summaryrefslogtreecommitdiff
path: root/webapp/src/components/game.rs
blob: 02774e76a010bc2e146909b5e63bd855e6ef67ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use protocol::bridge_engine::{DealInPlay, DealInPlayResult, Player, GameState, deal};
use crate::components::{Bidding, Hand, ShowBid, TrickInPlay, TricksPlayed};
use log::{error, info};
use yew::prelude::*;

fn init_state() -> GameState {
    let dealer = Player::East;
    let deal = deal();
    GameState::Bidding { dealer, deal }
}

#[function_component(Game)]
pub fn game() -> Html {
    let state = use_state(|| init_state());

    let shuffle = {
        let state = state.clone();
        Callback::from(move |_| {
            state.set(init_state());
        })
    };

    let on_card_clicked = {
        let state = state.clone();
        Callback::from(move |card| {
            if let GameState::Play {
                playing_deal,
                contract,
                bidding,
            } = (*state).clone()
            {
                info!("Card clicked: {}", card);
                match playing_deal.play(card) {
                    Err(err) => error!("Could not play card: {:?}", err),
                    Ok(DealInPlayResult::InProgress(playing_deal)) => state.set(GameState::Play {
                        playing_deal,
                        contract,
                        bidding,
                    }),
                    Ok(DealInPlayResult::PlayFinished(_tricks)) => todo!(),
                };
            }
        })
    };

    let center = match &*state {
        GameState::Bidding { dealer, deal } => {
            let on_contract = {
                let state = state.clone();
                let dealer = dealer.clone();
                let deal = deal.clone();
                Callback::from(move |(contract, bidding)| {
                    state.set(match contract {
                        Some(contract) => GameState::Play {
                            playing_deal: DealInPlay::new(dealer, deal.clone()),
                            contract,
                            bidding,
                        },
                        None => GameState::PassedOut {
                            dealer: dealer,
                            deal: deal.clone(),
                            bidding: bidding,
                        },
                    });
                })
            };
            html! {
                <Bidding {on_contract} dealer={dealer.clone()} />
            }
        }
        GameState::Play {
            playing_deal,
            contract: _,
            bidding: _,
        } => {
            html! {
                <>
                    <TricksPlayed tricks={ playing_deal.tricks().clone() } />
                    <TrickInPlay in_progress={ playing_deal.trick_in_play().clone() } />
                </>
            }
        }
        GameState::PassedOut { .. } => html! { <p>{ "Everyone passed" }</p> },
    };

    html! {
        <>
            <div class="nav">
                if let GameState::Play { contract, bidding, .. } = &*state {
                  <ShowBid contract={contract.clone()} bidding={bidding.clone()}/>
               }
              <button onclick={shuffle}>{ "Shuffle" }</button>
            </div>
            <div class="center">
                { center }
            </div>
            <div class="hand west">
              <Hand cards={ state.deal().west.clone() }
                    on_card_clicked={ on_card_clicked.clone() }
              />
            </div>
            <div class="hand north">
              <Hand cards={ state.deal().north.clone() }
                    on_card_clicked={ on_card_clicked.clone() }
              />
            </div>
            <div class="hand east">
              <Hand cards={ state.deal().east.clone() }
                    on_card_clicked={ on_card_clicked.clone() }
              />
            </div>
            <div class="hand south">
              <Hand cards={ state.deal().south.clone() }
                    on_card_clicked={ on_card_clicked.clone() }
              />
            </div>
        </>
    }
}