types: PlayCard and DropCard now require Card and Slot
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
3762856813
commit
098ce3a1d8
2 changed files with 67 additions and 8 deletions
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::types::{Action, Color, ColorDigit, Digit, GameAction, ReplAction, Slot, Slots};
|
use crate::types::{Action, Card, Color, ColorDigit, Digit, GameAction, ReplAction, Slot, Slots};
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::tag,
|
bytes::complete::tag,
|
||||||
|
@ -23,6 +23,7 @@ use nom::{
|
||||||
multi::many0,
|
multi::many0,
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
fn parse_color(i: &str) -> IResult<&str, ColorDigit> {
|
fn parse_color(i: &str) -> IResult<&str, ColorDigit> {
|
||||||
|
@ -61,9 +62,24 @@ fn parse_digit(i: &str) -> IResult<&str, ColorDigit> {
|
||||||
Ok((i, digit.into()))
|
Ok((i, digit.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_card(i: &str) -> IResult<&str, Card> {
|
||||||
|
let (i, color) = parse_color(i)?;
|
||||||
|
let (i, _) = space0(i)?;
|
||||||
|
let (i, digit) = parse_digit(i)?;
|
||||||
|
Ok((
|
||||||
|
i,
|
||||||
|
Card {
|
||||||
|
digit: Digit::try_from(digit).unwrap(),
|
||||||
|
color: Color::try_from(color).unwrap(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_play(i: &str) -> IResult<&str, GameAction> {
|
fn parse_play(i: &str) -> IResult<&str, GameAction> {
|
||||||
let (i, _) = alt((tag("play"), tag("p")))(i)?;
|
let (i, _) = alt((tag("play"), tag("p")))(i)?;
|
||||||
let (i, _) = space1(i)?;
|
let (i, _) = space1(i)?;
|
||||||
|
let (i, card) = parse_card(i)?;
|
||||||
|
let (i, _) = space1(i)?;
|
||||||
let (i, slot) = digit1(i)?;
|
let (i, slot) = digit1(i)?;
|
||||||
|
|
||||||
let slot = slot
|
let slot = slot
|
||||||
|
@ -74,7 +90,7 @@ fn parse_play(i: &str) -> IResult<&str, GameAction> {
|
||||||
return Err(nom::Err::Error(NomError::new("", ErrorKind::IsA)));
|
return Err(nom::Err::Error(NomError::new("", ErrorKind::IsA)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((i, GameAction::PlayCard(slot)))
|
Ok((i, GameAction::PlayCard(card, slot)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_slot(i: &str) -> IResult<&str, Slot> {
|
fn parse_slot(i: &str) -> IResult<&str, Slot> {
|
||||||
|
@ -110,9 +126,11 @@ fn parse_slots1(i: &str) -> IResult<&str, Slots> {
|
||||||
fn parse_drop(i: &str) -> IResult<&str, GameAction> {
|
fn parse_drop(i: &str) -> IResult<&str, GameAction> {
|
||||||
let (i, _) = alt((tag("drop"), tag("d")))(i)?;
|
let (i, _) = alt((tag("drop"), tag("d")))(i)?;
|
||||||
let (i, _) = space1(i)?;
|
let (i, _) = space1(i)?;
|
||||||
|
let (i, card) = parse_card(i)?;
|
||||||
|
let (i, _) = space1(i)?;
|
||||||
let (i, slot) = parse_slot(i)?;
|
let (i, slot) = parse_slot(i)?;
|
||||||
|
|
||||||
Ok((i, GameAction::DropCard(slot)))
|
Ok((i, GameAction::DropCard(card, slot)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_hint(i: &str) -> IResult<&str, GameAction> {
|
fn parse_hint(i: &str) -> IResult<&str, GameAction> {
|
||||||
|
|
51
src/types.rs
51
src/types.rs
|
@ -13,6 +13,7 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -150,11 +151,51 @@ impl From<Digit> for ColorDigit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<ColorDigit> for Digit {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(cd: ColorDigit) -> Result<Digit, Self::Error> {
|
||||||
|
Ok(match cd {
|
||||||
|
ColorDigit::Digit(d) => d,
|
||||||
|
ColorDigit::Color(c) => return Err(Error::ParseDigitError(c.to_string())),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<ColorDigit> for Color {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(cd: ColorDigit) -> Result<Color, Self::Error> {
|
||||||
|
Ok(match cd {
|
||||||
|
ColorDigit::Color(c) => c,
|
||||||
|
ColorDigit::Digit(d) => return Err(Error::ParseColorError(d.to_string())),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A card
|
/// A card
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Card {
|
pub struct Card {
|
||||||
pub digit: Digit,
|
pub digit: Digit,
|
||||||
pub color: Option<Color>,
|
pub color: Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Card {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{}{}",
|
||||||
|
match self.color {
|
||||||
|
Color::Blue => "b",
|
||||||
|
Color::Green => "g",
|
||||||
|
Color::Purple => "p",
|
||||||
|
Color::Red => "r",
|
||||||
|
Color::White => "w",
|
||||||
|
Color::Yellow => "y",
|
||||||
|
},
|
||||||
|
self.digit
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Position in a player's hand
|
/// Position in a player's hand
|
||||||
|
@ -197,8 +238,8 @@ impl fmt::Display for Slots {
|
||||||
/// Possible actions during the game
|
/// Possible actions during the game
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum GameAction {
|
pub enum GameAction {
|
||||||
PlayCard(Slot),
|
PlayCard(Card, Slot),
|
||||||
DropCard(Slot),
|
DropCard(Card, Slot),
|
||||||
ColorHint(Slots, Color),
|
ColorHint(Slots, Color),
|
||||||
DigitHint(Slots, Digit),
|
DigitHint(Slots, Digit),
|
||||||
}
|
}
|
||||||
|
@ -215,8 +256,8 @@ impl From<(ColorDigit, Slots)> for GameAction {
|
||||||
impl fmt::Display for GameAction {
|
impl fmt::Display for GameAction {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
GameAction::PlayCard(c) => write!(f, "play {}", c),
|
GameAction::PlayCard(card, slot) => write!(f, "play {} {}", card, slot),
|
||||||
GameAction::DropCard(c) => write!(f, "drop {}", c),
|
GameAction::DropCard(card, slot) => write!(f, "drop {} {}", card, slot),
|
||||||
GameAction::ColorHint(slots, c) => write!(f, "hint {} {}", c, slots),
|
GameAction::ColorHint(slots, c) => write!(f, "hint {} {}", c, slots),
|
||||||
GameAction::DigitHint(slots, d) => write!(f, "hint {} {}", d, slots),
|
GameAction::DigitHint(slots, d) => write!(f, "hint {} {}", d, slots),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue