Skip to content

Commit

Permalink
refactor: Change from a function to an extension method
Browse files Browse the repository at this point in the history
  • Loading branch information
Apricot-S committed Sep 25, 2024
1 parent 2234eba commit 3f99211
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 46 deletions.
93 changes: 50 additions & 43 deletions src/bingpai.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,36 +66,43 @@ pub(crate) enum InvalidBingpaiError {
InvalidTileFor3Player(usize),
}

pub(crate) fn count_bingpai(bingpai: &Bingpai) -> Result<u8, InvalidBingpaiError> {
let num_bingpai = bingpai.iter().try_fold(0, |acc, &num_tile| {
if num_tile > MAX_NUM_SAME_TILE {
return Err(InvalidBingpaiError::ExceedsMaxNumSameTile(num_tile));
pub(crate) trait BingpaiExt {
fn count(&self) -> Result<u8, InvalidBingpaiError>;
fn count_3_player(&self) -> Result<u8, InvalidBingpaiError>;
}

impl BingpaiExt for Bingpai {
fn count(&self) -> Result<u8, InvalidBingpaiError> {
let num_bingpai = self.iter().try_fold(0, |acc, &num_tile| {
if num_tile > MAX_NUM_SAME_TILE {
return Err(InvalidBingpaiError::ExceedsMaxNumSameTile(num_tile));
}
Ok(acc + num_tile)
})?;

if num_bingpai > MAX_NUM_SHOUPAI {
return Err(InvalidBingpaiError::ExceedsMaxNumBingpai(num_bingpai));
}
if num_bingpai == 0 {
return Err(InvalidBingpaiError::EmptyBingpai);
}
if num_bingpai % 3 == 0 {
return Err(InvalidBingpaiError::InvalidNumBingpai(num_bingpai));
}
Ok(acc + num_tile)
})?;

if num_bingpai > MAX_NUM_SHOUPAI {
return Err(InvalidBingpaiError::ExceedsMaxNumBingpai(num_bingpai));
}
if num_bingpai == 0 {
return Err(InvalidBingpaiError::EmptyBingpai);
}
if num_bingpai % 3 == 0 {
return Err(InvalidBingpaiError::InvalidNumBingpai(num_bingpai));
Ok(num_bingpai)
}

Ok(num_bingpai)
}
fn count_3_player(&self) -> Result<u8, InvalidBingpaiError> {
self[1..8].iter().enumerate().try_for_each(|(i, &t)| {
if t > 0 {
return Err(InvalidBingpaiError::InvalidTileFor3Player(i + 1));
}
Ok(())
})?;

pub(crate) fn count_bingpai_3_player(bingpai: &Bingpai) -> Result<u8, InvalidBingpaiError> {
bingpai[1..8].iter().enumerate().try_for_each(|(i, &t)| {
if t > 0 {
return Err(InvalidBingpaiError::InvalidTileFor3Player(i + 1));
}
Ok(())
})?;

count_bingpai(bingpai)
self.count()
}
}

#[cfg(test)]
Expand Down Expand Up @@ -123,9 +130,9 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, // z
];

let num_bingpai_1 = count_bingpai(&bingpai_1).unwrap();
let num_bingpai_2 = count_bingpai(&bingpai_2).unwrap();
let num_bingpai_3 = count_bingpai(&bingpai_3).unwrap();
let num_bingpai_1 = bingpai_1.count().unwrap();
let num_bingpai_2 = bingpai_2.count().unwrap();
let num_bingpai_3 = bingpai_3.count().unwrap();

assert_eq!(num_bingpai_1, bingpai_1.iter().sum());
assert_eq!(num_bingpai_2, bingpai_2.iter().sum());
Expand All @@ -140,7 +147,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 0, 0, 0, 0, 0, 0, // z
];
let result = count_bingpai(&bingpai).unwrap_err();
let result = bingpai.count().unwrap_err();
assert!(matches!(result, InvalidBingpaiError::EmptyBingpai));
}

Expand All @@ -152,7 +159,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 1, 1, 1, 1, 1, 1, // z
];
let result = count_bingpai(&bingpai).unwrap_err();
let result = bingpai.count().unwrap_err();
assert!(matches!(
result,
InvalidBingpaiError::ExceedsMaxNumBingpai(15)
Expand All @@ -167,7 +174,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 0, 0, 0, 0, 0, 0, // z
];
let result_1 = count_bingpai(&bingpai_1).unwrap_err();
let result_1 = bingpai_1.count().unwrap_err();
assert!(matches!(
result_1,
InvalidBingpaiError::ExceedsMaxNumSameTile(5)
Expand All @@ -179,7 +186,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 0, 0, 0, 0, 0, 0, // z
];
let result_2 = count_bingpai(&bingpai_2).unwrap_err();
let result_2 = bingpai_2.count().unwrap_err();
assert!(matches!(
result_2,
InvalidBingpaiError::ExceedsMaxNumSameTile(5)
Expand All @@ -194,7 +201,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 0, 0, 0, 1, 1, 1, // z
];
let result = count_bingpai(&bingpai).unwrap_err();
let result = bingpai.count().unwrap_err();
assert!(matches!(result, InvalidBingpaiError::InvalidNumBingpai(12)));
}

Expand All @@ -219,9 +226,9 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, // z
];

let num_bingpai_1 = count_bingpai_3_player(&bingpai_1).unwrap();
let num_bingpai_2 = count_bingpai_3_player(&bingpai_2).unwrap();
let num_bingpai_3 = count_bingpai_3_player(&bingpai_3).unwrap();
let num_bingpai_1 = bingpai_1.count_3_player().unwrap();
let num_bingpai_2 = bingpai_2.count_3_player().unwrap();
let num_bingpai_3 = bingpai_3.count_3_player().unwrap();

assert_eq!(num_bingpai_1, bingpai_1.iter().sum());
assert_eq!(num_bingpai_2, bingpai_2.iter().sum());
Expand All @@ -236,7 +243,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 0, 0, 0, 0, 0, 0, // z
];
let result = count_bingpai_3_player(&bingpai).unwrap_err();
let result = bingpai.count_3_player().unwrap_err();
assert!(matches!(result, InvalidBingpaiError::EmptyBingpai));
}

Expand All @@ -248,7 +255,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 1, 1, 1, 1, 1, 1, // z
];
let result = count_bingpai_3_player(&bingpai).unwrap_err();
let result = bingpai.count_3_player().unwrap_err();
assert!(matches!(
result,
InvalidBingpaiError::ExceedsMaxNumBingpai(15)
Expand All @@ -263,7 +270,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 0, 0, 0, 0, 0, 0, // z
];
let result_1 = count_bingpai_3_player(&bingpai_1).unwrap_err();
let result_1 = bingpai_1.count_3_player().unwrap_err();
assert!(matches!(
result_1,
InvalidBingpaiError::ExceedsMaxNumSameTile(5)
Expand All @@ -275,7 +282,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 0, 0, 0, 0, 0, 0, // z
];
let result_2 = count_bingpai_3_player(&bingpai_2).unwrap_err();
let result_2 = bingpai_2.count_3_player().unwrap_err();
assert!(matches!(
result_2,
InvalidBingpaiError::ExceedsMaxNumSameTile(5)
Expand All @@ -290,7 +297,7 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, 0, 0, // s
0, 0, 0, 0, 1, 1, 1, // z
];
let result = count_bingpai_3_player(&bingpai).unwrap_err();
let result = bingpai.count_3_player().unwrap_err();
assert!(matches!(result, InvalidBingpaiError::InvalidNumBingpai(12)));
}

Expand All @@ -309,8 +316,8 @@ mod tests {
0, 0, 0, 0, 0, 0, 0, // z
];

let result_2m = count_bingpai_3_player(&bingpai_2m).unwrap_err();
let result_8m = count_bingpai_3_player(&bingpai_8m).unwrap_err();
let result_2m = bingpai_2m.count_3_player().unwrap_err();
let result_8m = bingpai_8m.count_3_player().unwrap_err();

assert!(matches!(
result_2m,
Expand Down
6 changes: 3 additions & 3 deletions src/calculate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use super::qiduizi;
use super::shisanyao;
use super::standard;
use crate::bingpai::{count_bingpai, count_bingpai_3_player, Bingpai};
use crate::bingpai::{Bingpai, BingpaiExt};
use crate::shoupai::{
validate_shoupai, validate_shoupai_3_player, FuluMianziList, InvalidShoupaiError,
};
Expand Down Expand Up @@ -84,7 +84,7 @@ pub fn calculate_replacement_number(
bingpai: &Bingpai,
fulu_mianzi_list: &Option<FuluMianziList>,
) -> Result<u8, InvalidShoupaiError> {
let num_bingpai = count_bingpai(bingpai)?;
let num_bingpai = bingpai.count()?;

if let Some(f) = fulu_mianzi_list {
validate_shoupai(bingpai, f)?;
Expand Down Expand Up @@ -174,7 +174,7 @@ pub fn calculate_replacement_number_3_player(
bingpai: &Bingpai,
fulu_mianzi_list: &Option<FuluMianziList>,
) -> Result<u8, InvalidShoupaiError> {
let num_bingpai = count_bingpai_3_player(bingpai)?;
let num_bingpai = bingpai.count_3_player()?;

if let Some(f) = fulu_mianzi_list {
validate_shoupai_3_player(bingpai, f)?;
Expand Down

0 comments on commit 3f99211

Please sign in to comment.