schnapsen_rs/
client.rs

1use std::sync::{Arc, Mutex, RwLock};
2
3use crate::{
4    models::{Announcement, Card, Player},
5    PlayerError, SchnapsenDuo,
6};
7
8pub struct SchnapsenDuoClient {
9    player: Arc<RwLock<Player>>,
10    instance: Arc<Mutex<SchnapsenDuo>>,
11}
12
13impl SchnapsenDuoClient {
14    pub fn new(player: Arc<RwLock<Player>>, instance: Arc<Mutex<SchnapsenDuo>>) -> Self {
15        Self { player, instance }
16    }
17
18    #[inline]
19    pub fn cutt_deck(&self, cards_to_take: usize) -> Result<(), crate::PlayerError> {
20        self.instance
21            .lock()
22            .unwrap()
23            .cutt_deck(self.player.clone(), cards_to_take)
24    }
25
26    #[inline]
27    pub fn get_player_id(&self) -> String {
28        self.player.read().unwrap().id.clone()
29    }
30
31    #[inline]
32    pub fn is_active(&self) -> bool {
33        self.instance
34            .lock()
35            .unwrap()
36            .is_active(&self.player.read().unwrap())
37    }
38
39    pub fn draw_card(&self) -> Result<(), crate::PlayerError> {
40        let card = self
41            .instance
42            .lock()
43            .unwrap()
44            .draw_card_after_trick(self.player.clone())?;
45        self.player.write().unwrap().cards.push(card);
46
47        self.update_player_state();
48        Ok(())
49    }
50
51    pub fn close_talon(&self) -> Result<(), crate::PlayerError> {
52        self.instance
53            .lock()
54            .unwrap()
55            .close_talon(self.player.clone())
56    }
57
58    pub fn take_cards_til(&self, idx: usize) -> Result<(), crate::PlayerError> {
59        let cards = self
60            .instance
61            .lock()
62            .unwrap()
63            .take_cards_til(self.player.clone(), idx)?;
64
65        self.player.write().unwrap().cards.extend(cards);
66        Ok(())
67    }
68
69    pub fn play_card(&self, card: crate::Card) -> Result<(), crate::PlayerError> {
70        self.instance
71            .lock()
72            .unwrap()
73            .play_card(self.player.clone(), card.clone())?;
74        Ok(())
75    }
76
77    pub fn swap_trump(&self, card: crate::Card) -> Result<(), crate::PlayerError> {
78        let swap = self
79            .instance
80            .lock()
81            .unwrap()
82            .swap_trump(self.player.clone(), card.clone())?;
83
84        self.player.write().unwrap().cards.retain(|x| *x != card);
85        self.player.write().unwrap().cards.push(swap);
86
87        self.update_player_state();
88
89        Ok(())
90    }
91
92    pub fn announce_40(&self) -> Result<(), crate::PlayerError> {
93        let announcement = self
94            .instance
95            .lock()
96            .unwrap()
97            .announce_40(&self.player.read().unwrap())?;
98
99        self.announce_state_changes(announcement)?;
100        Ok(())
101    }
102
103    pub fn announce_20(&self, cards: [Card; 2]) -> Result<(), crate::PlayerError> {
104        let announcement = self
105            .instance
106            .lock()
107            .unwrap()
108            .announce_20(&self.player.read().unwrap(), cards)?;
109
110        self.announce_state_changes(announcement)?;
111        Ok(())
112    }
113
114    fn announce_state_changes(&self, announcement: Announcement) -> Result<(), PlayerError> {
115        self.player
116            .write()
117            .unwrap()
118            .announcements
119            .push(announcement.clone());
120
121        self.player
122            .write()
123            .unwrap()
124            .announcable
125            .retain(|x| *x == announcement);
126
127        let mut instance_lock = self.instance.lock().unwrap();
128        instance_lock
129            .notify_changes_playable_cards(&self.player.read().unwrap(), &announcement.cards);
130
131        self.player.write().unwrap().playable_cards = announcement.cards.to_vec();
132        instance_lock.update_announcable_props(self.player.clone());
133        instance_lock.update_finish_round(self.player.clone())?;
134        Ok(())
135    }
136
137    fn update_player_state(&self) {
138        let instance_lock = self.instance.lock().unwrap();
139        let (_, announcable) = instance_lock.notify_announcable_props(&self.player.read().unwrap());
140        self.player.write().unwrap().announcable = announcable;
141
142        let (_, can_swap) = instance_lock.notify_swap_trump_check(&self.player.read().unwrap());
143        self.player.write().unwrap().possible_trump_swap = can_swap;
144
145        let playable_cards = instance_lock.find_playable_cards(self.player.clone());
146        instance_lock.notify_changes_playable_cards(&self.player.read().unwrap(), &playable_cards);
147
148        self.player.write().unwrap().playable_cards = playable_cards.to_vec();
149    }
150}