Phase 7 (Core): chemistry v2, expanded card pool & search filters
CI / Build, lint & test (push) Failing after 1m46s
CI / Build, lint & test (push) Failing after 1m46s
- Chemistry v2: FUT-style link scoring with per-player breakdown (club +3/link cap 6, league +1/link cap 4, nation +1/link cap 3; player cap 10, team cap 100); chemistry response now includes per-player breakdown with club/league/nation link counts and pts - Card pool: 34 new cards across Premier League, La Liga, Bundesliga with overlapping clubs/nations for meaningful chemistry testing - Card search: extended GET /cards with nation, league, club, min_overall, max_overall, limit query params; results sorted by overall descending - Match opponent: added "ultimate" difficulty band (85+ OVR); random formation selection from 6 tactical formations; falls back to lower OVR pool when not enough cards at the requested band - Tests: 9 new integration tests (28 total, all passing) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+40
-10
@@ -16,6 +16,12 @@ use crate::{
|
||||
pub struct CardQuery {
|
||||
pub rarity: Option<String>,
|
||||
pub position: Option<String>,
|
||||
pub nation: Option<String>,
|
||||
pub league: Option<String>,
|
||||
pub club: Option<String>,
|
||||
pub min_overall: Option<u8>,
|
||||
pub max_overall: Option<u8>,
|
||||
pub limit: Option<usize>,
|
||||
}
|
||||
|
||||
pub async fn get_card(
|
||||
@@ -33,25 +39,49 @@ pub async fn get_cards(
|
||||
State(state): State<AppState>,
|
||||
Query(query): Query<CardQuery>,
|
||||
) -> AppResult<Json<Value>> {
|
||||
let cards = state
|
||||
let mut cards: Vec<_> = state
|
||||
.card_db
|
||||
.all()
|
||||
.into_iter()
|
||||
.filter(|c| {
|
||||
query
|
||||
let rarity_ok = query
|
||||
.rarity
|
||||
.as_ref()
|
||||
.map(|r| format!("{:?}", c.rarity).to_lowercase() == r.to_lowercase())
|
||||
.unwrap_or(true)
|
||||
&& query
|
||||
.position
|
||||
.as_ref()
|
||||
.map(|p| c.position.to_lowercase() == p.to_lowercase())
|
||||
.unwrap_or(true)
|
||||
.unwrap_or(true);
|
||||
let pos_ok = query
|
||||
.position
|
||||
.as_ref()
|
||||
.map(|p| c.position.eq_ignore_ascii_case(p))
|
||||
.unwrap_or(true);
|
||||
let nation_ok = query
|
||||
.nation
|
||||
.as_ref()
|
||||
.map(|n| c.nation.eq_ignore_ascii_case(n))
|
||||
.unwrap_or(true);
|
||||
let league_ok = query
|
||||
.league
|
||||
.as_ref()
|
||||
.map(|l| c.league.eq_ignore_ascii_case(l))
|
||||
.unwrap_or(true);
|
||||
let club_ok = query
|
||||
.club
|
||||
.as_ref()
|
||||
.map(|cl| c.club.eq_ignore_ascii_case(cl))
|
||||
.unwrap_or(true);
|
||||
let min_ok = query.min_overall.map(|m| c.overall >= m).unwrap_or(true);
|
||||
let max_ok = query.max_overall.map(|m| c.overall <= m).unwrap_or(true);
|
||||
rarity_ok && pos_ok && nation_ok && league_ok && club_ok && min_ok && max_ok
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
.collect();
|
||||
|
||||
Ok(Json(json!({ "cards": cards, "total": cards.len() })))
|
||||
cards.sort_by_key(|c| std::cmp::Reverse(c.overall));
|
||||
let total = cards.len();
|
||||
if let Some(limit) = query.limit {
|
||||
cards.truncate(limit);
|
||||
}
|
||||
|
||||
Ok(Json(json!({ "cards": cards, "total": total, "returned": cards.len() })))
|
||||
}
|
||||
|
||||
pub async fn get_collection(State(state): State<AppState>) -> AppResult<Json<Value>> {
|
||||
|
||||
Reference in New Issue
Block a user