1#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
2#![cfg_attr(test, allow(clippy::needless_pass_by_value))]
3#![cfg_attr(test, allow(clippy::missing_panics_doc))]
4#![allow(clippy::wildcard_imports)]
5#![allow(unused_imports)]
6
7use std::{
8 any::Any,
9 borrow::Borrow,
10 cmp, convert, fmt, io, mem,
11 num::{ParseFloatError, ParseIntError},
12 ops, ptr,
13 rc::Rc,
14 str::FromStr,
15};
16
17use bitflags::bitflags;
18use derive_more::{Display, Into, TryInto};
19use openpql_macro::*;
20pub use openpql_pql_parser::parse_pql;
21use openpql_pql_parser::{Error as SyntaxError, Spanned, *};
22use openpql_prelude::{CardGen, HandN, ParseError, PlayerIdx};
23use openpql_range_parser::{
24 BoardRangeChecker, Error as RangeError, RangeChecker,
25};
26use runner_output::*;
27
28mod error;
29mod functions;
30mod helper_loc;
31mod output_aggregator;
32mod runner;
33mod runner_output;
34mod types;
35mod vm;
36
37pub use error::*;
38use functions::*;
39use helper_loc::*;
40use output_aggregator::*;
41pub use runner::*;
42#[cfg(test)]
43pub use tests::*;
44pub use types::*;
45use vm::{
46 Vm, VmBinOpCmp, VmCache, VmExecContext, VmProgram, VmSampledData,
47 VmStackValue,
48};
49
50type HeapIdx = usize;
51type FractionInner = i32;
52type RangeSrc = String;
53type FnCheckRange = Box<dyn Fn(&[PQLCard]) -> bool>;
54
55fn parse_cards(text: &str) -> Option<PQLCardSet> {
56 let mut res = PQLCardSet::default();
57 let mut iter = text.chars().filter(|c| !c.is_whitespace());
58
59 while let Some(rank) = iter.next() {
60 let suit = iter.next()?;
61
62 dbg!(suit);
63 res.set(PQLCard::new(
64 PQLRank::from_char(rank)?,
65 PQLSuit::from_char(suit)?,
66 ));
67 }
68
69 Some(res)
70}
71
72#[cfg(test)]
73pub mod tests {
74 pub use std::fmt::Write;
75
76 pub use itertools::Itertools;
77 use openpql_pql_parser::*;
78 pub use openpql_prelude::{CardN, c64, card, cards, r16};
79 pub use quickcheck::{Arbitrary, TestResult};
80 pub use quickcheck_macros::quickcheck;
81 pub use rand::{SeedableRng, prelude::*, rngs};
82
83 pub use super::{
84 PQLBoardRange, PQLGame, PQLHiRating, PQLRange,
85 functions::{PQLFnContext, TestPQLFnContext, rate_hi_hand},
86 };
87 use super::{PQLCard, PQLCardCount, PQLError, PQLErrorKind, PQLRank};
88
89 pub fn count_suits(cs: &[PQLCard]) -> PQLCardCount {
90 cs.iter().map(|c| c.suit).unique().count().to_le_bytes()[0]
91 }
92
93 pub fn get_ranks(cs: &[PQLCard]) -> Vec<PQLRank> {
94 cs.iter().map(|c| c.rank).collect()
95 }
96
97 pub fn mk_ranges(
98 game: PQLGame,
99 player: &[&str],
100 board: &str,
101 ) -> (Vec<PQLRange>, PQLBoardRange) {
102 let player_ranges = player
103 .iter()
104 .map(|&s| (game, s).try_into().unwrap())
105 .collect();
106
107 let board_range = (game, board).try_into().unwrap();
108
109 (player_ranges, board_range)
110 }
111
112 pub fn mk_rating(text: &str) -> PQLHiRating {
113 rate_hi_hand(&PQLFnContext::default(), &text.to_string()).unwrap()
114 }
115}