import Testing @testable import SoliCards @Suite("Spider Rules Tests") struct SpiderRulesTests { let rules = SpiderRules() @Test("Deal creates correct layout with 2 decks") func dealLayout() { let deck = Deck.double() let snapshot = rules.deal(deck: deck) #expect(snapshot.tableaus.count == 10) // First 4 get 6 cards, last 6 get 5 cards for i in 0..<4 { #expect(snapshot.tableaus[i].count == 6) } for i in 4..<10 { #expect(snapshot.tableaus[i].count == 5) } // Total dealt: 4*6 + 6*5 = 24 + 30 = 54 let totalDealt = snapshot.tableaus.reduce(0) { $0 + $1.count } #expect(totalDealt == 54) // Remaining in stock: 104 - 54 = 50 #expect(snapshot.stock.count == 50) // 8 empty foundations #expect(snapshot.foundations.count == 8) } @Test("Can place any card on descending rank in tableau") func tableauStacking() { let ten = Card(suit: .spades, rank: .ten, isFaceUp: true) let nine = Card(suit: .hearts, rank: .nine, isFaceUp: true) // different suit OK var snapshot = emptySpiderSnapshot() snapshot.tableaus[0] = [ten] snapshot.tableaus[1] = [nine] #expect(rules.canMove(cards: [nine], from: .tableau(1), to: .tableau(0), state: snapshot)) } @Test("Complete K-A same-suit sequence detected") func completeSequence() { var tableau: [Card] = [] for rank in Rank.allCases.reversed() { tableau.append(Card(suit: .spades, rank: rank, isFaceUp: true)) } #expect(rules.isCompleteSequence(in: tableau)) } @Test("Mixed-suit sequence not complete") func mixedSuitSequence() { var tableau: [Card] = [] for (i, rank) in Rank.allCases.reversed().enumerated() { let suit: Suit = i == 5 ? .hearts : .spades tableau.append(Card(suit: suit, rank: rank, isFaceUp: true)) } #expect(!rules.isCompleteSequence(in: tableau)) } @Test("Cannot pick up mixed-suit sequence") func cannotPickUpMixedSuit() { let spade5 = Card(suit: .spades, rank: .five, isFaceUp: true) let heart4 = Card(suit: .hearts, rank: .four, isFaceUp: true) var snapshot = emptySpiderSnapshot() snapshot.tableaus[0] = [spade5, heart4] #expect(!rules.canPickUp(cards: [spade5, heart4], from: .tableau(0), state: snapshot)) } // MARK: - Helpers private func emptySpiderSnapshot() -> GameSnapshot { GameSnapshot( tableaus: Array(repeating: [], count: 10), foundations: Array(repeating: [], count: 8), stock: [], waste: [], freeCells: [], moves: 0, score: 0 ) } }