pub fn play(&mut self, entry: GameTransition) -> Result<TransitionSuccess, TransitionError> {
        match entry {
            GameTransition::Bet(bet) => {
                match self.state {
                    State::NotStarted => {
                        return Err(TransitionError::NotStarted); 
                    },
                    State::Trick(_rotation_status) => {
                        return Err(TransitionError::BetInTrickStage);
                    },
                    State::Completed => {
                        return Err(TransitionError::CompletedGame);
                    },
                    State::Betting(rotation_status) => {
                        self.scoring.add_bet(self.current_player_index,bet);
                        if rotation_status == 3 {
                            self.scoring.bet();
                            self.state = State::Trick((rotation_status + 1) % 4);
                            self.current_player_index = 0;
                            return Ok(TransitionSuccess::BetComplete);
                        } else {
                            self.current_player_index = (self.current_player_index + 1) % 4;
                            self.state = State::Betting((rotation_status + 1) % 4);
                        }

                        return Ok(TransitionSuccess::Bet);
                    },
                };
            },
            GameTransition::Card(card) => {
                match self.state {
                    State::NotStarted => {
                        return Err(TransitionError::NotStarted); 
                    },
                    State::Completed => {
                        return Err(TransitionError::CompletedGame);
                    },
                    State::Betting(_rotation_status) => {
                        return Err(TransitionError::CardInBettingStage)
                    },
                    State::Trick(rotation_status) => {
                        {
                            let player_hand = &mut match self.current_player_index {
                                0 => &mut self.player_a,
                                1 => &mut self.player_b,
                                2 => &mut self.player_c,
                                3 => &mut self.player_d,
                                _ => &mut self.player_d,
                            }.hand;

                            if !player_hand.contains(&card) {
                                return Err(TransitionError::CardNotInHand);
                            }
                            let leading_suit = self.leading_suit;
                            if rotation_status == 0 {
                                self.leading_suit = card.suit;
                            }
                            if self.leading_suit != card.suit && player_hand.iter().any(|ref x| x.suit == leading_suit) {
                                return Err(TransitionError::CardIncorrectSuit);
                            }

                            let card_index = player_hand.iter().position(|x| x == &card).unwrap();
                            self.deck.push(player_hand.remove(card_index));
                        }
                        
                        self.hands_played.last_mut().unwrap()[self.current_player_index] = card;
                        
                        if rotation_status == 3 {
                            let winner = self.scoring.trick(self.current_player_index, self.hands_played.last().unwrap());
                            if self.scoring.is_over {
                                self.state = State::Completed;
                                return Ok(TransitionSuccess::GameOver);
                            }
                            if self.scoring.in_betting_stage {
                                self.current_player_index = 0;
                                self.state = State::Betting((rotation_status + 1) % 4);
                                self.deal_cards();
                            } else {
                                self.current_player_index = winner;
                                self.state = State::Trick((rotation_status + 1) % 4);
                                self.hands_played.push(new_pot());
                            }
                            return Ok(TransitionSuccess::Trick);
                        } else {
                            self.current_player_index = (self.current_player_index + 1) % 4;
                            self.state = State::Trick((rotation_status + 1) % 4);
                            return Ok(TransitionSuccess::PlayCard);
                        }
                    }
                };
            },
            GameTransition::Start => {
                if self.state != State::NotStarted {
                    return Err(TransitionError::AlreadyStarted);
                }
                self.deal_cards();
                self.state = State::Betting(0);
                return Ok(TransitionSuccess::Start);
            }
        }
    }
/// The primary function used to progress the game state. The first `GameTransition` argument must always be 
/// [`GameTransition::Start`](enum.GameTransition.html#variant.Start). The stages and player rotations are managed
/// internally. The order of `GameTransition` arguments should be:
/// 
/// Start -> Bet * 4 -> Card * 13 -> Bet * 4 -> Card * 13 -> Bet * 4 -> ...
The primary function used to progress the game state.


The primary function used to progress the game state .
pub fn play(&mut self, entry: GameTransition) -> Result<TransitionSuccess, TransitionError> {
        match entry {
            GameTransition::Bet(bet) => {
                match self.state {
                    State::NotStarted => {
                        return Err(TransitionError::NotStarted); 
                    },
                    State::Trick(_rotation_status) => {
                        return Err(TransitionError::BetInTrickStage);
                    },
                    State::Completed => {
                        return Err(TransitionError::CompletedGame);
                    },
                    State::Betting(rotation_status) => {
                        self.scoring.add_bet(self.current_player_index,bet);
                        if rotation_status == 3 {
                            self.scoring.bet();
                            self.state = State::Trick((rotation_status + 1) % 4);
                            self.current_player_index = 0;
                            return Ok(TransitionSuccess::BetComplete);
                        } else {
                            self.current_player_index = (self.current_player_index + 1) % 4;
                            self.state = State::Betting((rotation_status + 1) % 4);
                        }
                        return Ok(TransitionSuccess::Bet);
                    },
                };
            },
            GameTransition::Card(card) => {
                match self.state {
                    State::NotStarted => {
                        return Err(TransitionError::NotStarted); 
                    },
                    State::Completed => {
                        return Err(TransitionError::CompletedGame);
                    },
                    State::Betting(_rotation_status) => {
                        return Err(TransitionError::CardInBettingStage)
                    },
                    State::Trick(rotation_status) => {
                        {
                            let player_hand = &mut match self.current_player_index {
                                0 => &mut self.player_a,
                                1 => &mut self.player_b,
                                2 => &mut self.player_c,
                                3 => &mut self.player_d,
                                _ => &mut self.player_d,
                            }.hand;
                            if !player_hand.contains(&card) {
                                return Err(TransitionError::CardNotInHand);
                            }
                            let leading_suit = self.leading_suit;
                            if rotation_status == 0 {
                                self.leading_suit = card.suit;
                            }
                            if self.leading_suit != card.suit && player_hand.iter().any(|ref x| x.suit == leading_suit) {
                                return Err(TransitionError::CardIncorrectSuit);
                            }
                            let card_index = player_hand.iter().position(|x| x == &card).unwrap();
                            self.deck.push(player_hand.remove(card_index));
                        }
                        self.hands_played.last_mut().unwrap()[self.current_player_index] = card;
                        if rotation_status == 3 {
                            let winner = self.scoring.trick(self.current_player_index, self.hands_played.last().unwrap());
                            if self.scoring.is_over {
                                self.state = State::Completed;
                                return Ok(TransitionSuccess::GameOver);
                            }
                            if self.scoring.in_betting_stage {
                                self.current_player_index = 0;
                                self.state = State::Betting((rotation_status + 1) % 4);
                                self.deal_cards();
                            } else {
                                self.current_player_index = winner;
                                self.state = State::Trick((rotation_status + 1) % 4);
                                self.hands_played.push(new_pot());
                            }
                            return Ok(TransitionSuccess::Trick);
                        } else {
                            self.current_player_index = (self.current_player_index + 1) % 4;
                            self.state = State::Trick((rotation_status + 1) % 4);
                            return Ok(TransitionSuccess::PlayCard);
                        }
                    }
                };
            },
            GameTransition::Start => {
                if self.state != State::NotStarted {
                    return Err(TransitionError::AlreadyStarted);
                }
                self.deal_cards();
                self.state = State::Betting(0);
                return Ok(TransitionSuccess::Start);
            }
        }
    }
pub fn play ( & mut self , entry : GameTransition ) -> Result < TransitionSuccess , TransitionError > { match entry { GameTransition :: Bet ( bet ) => { match self . state { State :: NotStarted => { return Err ( TransitionError :: NotStarted ) ; } , State :: Trick ( _rotation_status ) => { return Err ( TransitionError :: BetInTrickStage ) ; } , State :: Completed => { return Err ( TransitionError :: CompletedGame ) ; } , State :: Betting ( rotation_status ) => { self . scoring . add_bet ( self . current_player_index , bet ) ; if rotation_status == 3 { self . scoring . bet ( ) ; self . state = State :: Trick ( ( rotation_status + 1 ) % 4 ) ; self . current_player_index = 0 ; return Ok ( TransitionSuccess :: BetComplete ) ; } else { self . current_player_index = ( self . current_player_index + 1 ) % 4 ; self . state = State :: Betting ( ( rotation_status + 1 ) % 4 ) ; } return Ok ( TransitionSuccess :: Bet ) ; } , } ; } , GameTransition :: Card ( card ) => { match self . state { State :: NotStarted => { return Err ( TransitionError :: NotStarted ) ; } , State :: Completed => { return Err ( TransitionError :: CompletedGame ) ; } , State :: Betting ( _rotation_status ) => { return Err ( TransitionError :: CardInBettingStage ) } , State :: Trick ( rotation_status ) => { { let player_hand = & mut match self . current_player_index { 0 => & mut self . player_a , 1 => & mut self . player_b , 2 => & mut self . player_c , 3 => & mut self . player_d , _ => & mut self . player_d , } . hand ; if ! player_hand . contains ( & card ) { return Err ( TransitionError :: CardNotInHand ) ; } let leading_suit = self . leading_suit ; if rotation_status == 0 { self . leading_suit = card . suit ; } if self . leading_suit != card . suit && player_hand . iter ( ) . any ( | ref x | x . suit == leading_suit ) { return Err ( TransitionError :: CardIncorrectSuit ) ; } let card_index = player_hand . iter ( ) . position ( | x | x == & card ) . unwrap ( ) ; self . deck . push ( player_hand . remove ( card_index ) ) ; } self . hands_played . last_mut ( ) . unwrap ( ) [ self . current_player_index ] = card ; if rotation_status == 3 { let winner = self . scoring . trick ( self . current_player_index , self . hands_played . last ( ) . unwrap ( ) ) ; if self . scoring . is_over { self . state = State :: Completed ; return Ok ( TransitionSuccess :: GameOver ) ; } if self . scoring . in_betting_stage { self . current_player_index = 0 ; self . state = State :: Betting ( ( rotation_status + 1 ) % 4 ) ; self . deal_cards ( ) ; } else { self . current_player_index = winner ; self . state = State :: Trick ( ( rotation_status + 1 ) % 4 ) ; self . hands_played . push ( new_pot ( ) ) ; } return Ok ( TransitionSuccess :: Trick ) ; } else { self . current_player_index = ( self . current_player_index + 1 ) % 4 ; self . state = State :: Trick ( ( rotation_status + 1 ) % 4 ) ; return Ok ( TransitionSuccess :: PlayCard ) ; } } } ; } , GameTransition :: Start => { if self . state != State :: NotStarted { return Err ( TransitionError :: AlreadyStarted ) ; } self . deal_cards ( ) ; self . state = State :: Betting ( 0 ) ; return Ok ( TransitionSuccess :: Start ) ; } } }
The primary function used to progress the game state.
The primary function used to progress the game state .
&mut self
entry
GameTransition
&mut self
entry
GameTransition