use crate::symbols::Symbols;
#[derive(Debug, Clone)]
pub enum Paylines {
HorSM(Symbols, Vec<(usize, usize)>),
AboveSM(Symbols, Vec<(usize, usize)>),
BelowSM(Symbols, Vec<(usize, usize)>),
ZigSM(Symbols, Vec<(usize, usize)>),
ZagSM(Symbols, Vec<(usize, usize)>),
HorXL(Symbols, Vec<(usize, usize)>),
Zig(Symbols, Vec<(usize, usize)>),
Zag(Symbols, Vec<(usize, usize)>),
Above(Symbols, Vec<(usize, usize)>),
Below(Symbols, Vec<(usize, usize)>),
Eye(Symbols, Vec<(usize, usize)>),
}
impl Paylines {
pub fn get_payout(&self, bet: i32) -> i32 {
match self {
Paylines::HorSM(symbol, _)
| Paylines::AboveSM(symbol, _)
| Paylines::BelowSM(symbol, _) => symbol.get_value() * bet,
Paylines::ZigSM(symbol, _) | Paylines::ZagSM(symbol, _) => symbol.get_value() * 2 * bet,
Paylines::HorXL(symbol, _) => symbol.get_value() * 3 * bet,
Paylines::Zig(symbol, _) | Paylines::Zag(symbol, _) => symbol.get_value() * 4 * bet,
Paylines::Above(symbol, _) | Paylines::Below(symbol, _) => symbol.get_value() * 8 * bet,
Paylines::Eye(symbol, _) => symbol.get_value() * 10 * bet,
}
}
pub fn display_name(&self) -> &'static str {
match self {
Paylines::HorSM(..) => "HorSM",
Paylines::AboveSM(..) => "AboveSM",
Paylines::BelowSM(..) => "BelowSM",
Paylines::ZigSM(..) => "ZigSM",
Paylines::ZagSM(..) => "ZagSM",
Paylines::HorXL(..) => "HorXL",
Paylines::Zig(..) => "Zig",
Paylines::Zag(..) => "Zag",
Paylines::Above(..) => "Above",
Paylines::Below(..) => "Below",
Paylines::Eye(..) => "Eye",
}
}
pub fn symbol(&self) -> &Symbols {
match self {
Paylines::HorSM(s, _)
| Paylines::AboveSM(s, _)
| Paylines::BelowSM(s, _)
| Paylines::ZigSM(s, _)
| Paylines::ZagSM(s, _)
| Paylines::HorXL(s, _)
| Paylines::Zig(s, _)
| Paylines::Zag(s, _)
| Paylines::Above(s, _)
| Paylines::Below(s, _)
| Paylines::Eye(s, _) => s,
}
}
pub fn positions(&self) -> &[(usize, usize)] {
match self {
Paylines::HorSM(_, p)
| Paylines::AboveSM(_, p)
| Paylines::BelowSM(_, p)
| Paylines::ZigSM(_, p)
| Paylines::ZagSM(_, p)
| Paylines::HorXL(_, p)
| Paylines::Zig(_, p)
| Paylines::Zag(_, p)
| Paylines::Above(_, p)
| Paylines::Below(_, p)
| Paylines::Eye(_, p) => p,
}
}
}
fn check_payline(visible_reels: &[&[Symbols]], positions: &[(usize, usize)]) -> Option<Symbols> {
let target = positions
.iter()
.map(|&(row, col)| &visible_reels[row][col])
.find(|s| **s != Symbols::Wild);
let target = target?;
if positions.iter().all(|&(row, col)| {
visible_reels[row][col] == *target || visible_reels[row][col] == Symbols::Wild
}) {
Some(target.clone())
} else {
None
}
}
pub type PaylineCheckerFn = fn(&[&[Symbols]]) -> Option<Paylines>;
pub fn check_hor_sm(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 3] = [(1, 1), (1, 2), (1, 3)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::HorSM(symbols, positions_vec))
}
pub fn check_above_sm(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 3] = [(0, 1), (0, 2), (0, 3)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions)
.map(|symbols| Paylines::AboveSM(symbols, positions_vec))
}
pub fn check_below_sm(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 3] = [(2, 1), (2, 2), (2, 3)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions)
.map(|symbols| Paylines::BelowSM(symbols, positions_vec))
}
pub fn check_zig_sm(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 3] = [(2, 1), (1, 2), (0, 3)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::ZigSM(symbols, positions_vec))
}
pub fn check_zag_sm(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 3] = [(0, 1), (1, 2), (2, 3)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::ZagSM(symbols, positions_vec))
}
pub fn check_hor_xl(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 5] = [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::HorXL(symbols, positions_vec))
}
pub fn check_zig(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 5] = [(2, 0), (1, 1), (0, 2), (1, 3), (2, 4)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::Zig(symbols, positions_vec))
}
pub fn check_zag(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 5] = [(0, 0), (1, 1), (2, 2), (1, 3), (0, 4)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::Zag(symbols, positions_vec))
}
pub fn check_above(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 5] = [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::Above(symbols, positions_vec))
}
pub fn check_below(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 5] = [(2, 0), (2, 1), (2, 2), (2, 3), (2, 4)];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::Below(symbols, positions_vec))
}
pub fn check_eye(visible_reels: &[&[Symbols]]) -> Option<Paylines> {
let positions: [(usize, usize); 8] = [
(1, 0),
(0, 1),
(2, 1),
(0, 2),
(2, 2),
(0, 3),
(2, 3),
(1, 4),
];
let positions_vec = positions.to_vec();
check_payline(visible_reels, &positions).map(|symbols| Paylines::Eye(symbols, positions_vec))
}