summaryrefslogtreecommitdiff
path: root/webapp/src/components/game.rs
blob: 0f25fc3940dc138c47181e8bf772ecdcaaca96cc (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
use crate::bridge_engine::{self, Contract, Player};
use crate::card;
use crate::card::Suit;
use crate::components::{Bidding, Hand, HandProps, ShowBid};
use yew::prelude::*;

pub const SUIT_DISPLAY_ORDER: [Suit; 4] = [Suit::Diamond, Suit::Club, Suit::Heart, Suit::Spade];

#[derive(Debug)]
enum Phase {
    Bidding,
    Cardplay,
}

#[function_component(Game)]
pub fn game() -> Html {
    let mut rng = rand::thread_rng();
    let mut deal = card::deal(&mut rng);
    deal.sort(&SUIT_DISPLAY_ORDER, card::RankOrder::Descending);

    let north = use_state(|| HandProps::from_iter(deal.north.into_iter()));
    let west = use_state(|| HandProps::from_iter(deal.west.into_iter()));
    let south = use_state(|| HandProps::from_iter(deal.south.into_iter()));
    let east = use_state(|| HandProps::from_iter(deal.east.into_iter()));

    let dealer = use_state(|| Player::East);

    let contract: UseStateHandle<Option<(Contract, bridge_engine::Bidding)>> = use_state(|| None);
    let on_contract = {
        let contract = contract.clone();
        Callback::from(move |c| contract.set(Some(c)))
    };

    let phase = if contract.is_none() {
        Phase::Bidding
    } else {
        Phase::Cardplay
    };

    let shuffle = {
        let north = north.clone();
        let west = west.clone();
        let south = south.clone();
        let east = east.clone();
        let dealer = dealer.clone();
        let contract = contract.clone();

        Callback::from(move |_| {
            let mut rng = rand::thread_rng();
            let mut deal = card::deal(&mut rng);
            deal.sort(&SUIT_DISPLAY_ORDER, card::RankOrder::Descending);
            north.set(deal.north.into_iter().collect());
            west.set(deal.west.into_iter().collect());
            south.set(deal.south.into_iter().collect());
            east.set(deal.east.into_iter().collect());

            dealer.set(dealer.next());
            contract.set(None);
        })
    };

    html! {
        <>
            <div class="nav">
              if let Some((contract, bidding)) = &*contract {
                  <ShowBid contract={contract.clone()} bidding={bidding.clone()}/>
              }
              <p>{ format!("Phase: {:?}", phase) }</p>
              <button onclick={shuffle}>{ "Shuffle" }</button>
            </div>
            <div class="center">
                <p>{ format!("Dealer: {:?}", *dealer) }</p>
                if let Some(_) = &*contract {
                    { "Let's play" }
                } else {
                    <Bidding {on_contract} dealer={ *dealer } />
                }
            </div>
            <div class="hand west">
                <Hand ..(*west).clone() />
            </div>
            <div class="hand north">
                <Hand ..(*north).clone() />
            </div>
            <div class="hand east">
                <Hand ..(*east).clone() />
            </div>
            <div class="hand south">
                <Hand ..(*south).clone() />
            </div>
        </>
    }
}