Spock Web Console

subscribe to the feed Subscribe
War (via #spockwebconsole)
tweet this script Tweet

War

Published 1 week ago by Eric
Actions  ➤ Edit In Console Back To Console Show/Hide Line Numbers View Recent Scripts
package war

import spock.lang.Specification

class WarSpec extends Specification {
    def "Play Game"() {
        expect: "Play the game!"
        game()
    }

    def "Deck"() {
        given:
        def deck = new Deck().generate()
        expect:
        deck.cards.size() == 52
        and: "Index is not 0 based"
        !deck.cards.suit.contains(0)
        !deck.cards.card.contains(0)
    }

    def "Card Display"() {
        expect:
        new Card(suit: 1, card: 3).toString() == "3 ♥"
        new Card(suit: 2, card: 11).toString() == "Jack ♦"
    }

    def totalNumberOfHands = 0
    def totalWarsPlayed = 0
    def numberOfGamesToPlay = 1
    def p1Wins = 0
    def p2Wins = 0
    def p1Points = 0
    def p2Points = 0

    def game() {
        for (def games = 0; games < numberOfGamesToPlay; games++) {
            Deck playingDeck = new Deck().generate().shuffle()
            def cards = playingDeck.cards.collate(playingDeck.deckSize.intdiv(2))

            Deck player1Deck = new Deck().withCards(cards[0])
            Deck player2Deck = new Deck().withCards(cards[1])

            while (true) {
                if (player1Deck.cards.size() == 0 || player2Deck.cards.size() == 0)
                    break
                war(player1Deck, player2Deck)
            }
            if (player1Deck.cards.size() == 0) {
                p1Wins++
                println "Player 1 wins war!"
            } else {
                p2Wins++
                println "Player 2 wins war!"
            }
            totalNumberOfHands += (p1Points + p2Points)
        }

        println "-" * 80
        println "Total Number of Hands: $totalNumberOfHands"
        println "Hands/Games: ${totalNumberOfHands / numberOfGamesToPlay}"
        println "Total Wars Played: $totalWarsPlayed"
        println "Avg Wars per Game: ${totalWarsPlayed / numberOfGamesToPlay}"
        println "P1Wins: $p1Wins, P2Wins: $p2Wins"
        println "-" * 80
        true
    }

    enum Player { ONE, TWO, DRAW }

    def war(Deck player1Deck, Deck player2Deck) {
        Card player1Card = player1Deck.cards.pop()
        Card player2Card = player2Deck.cards.pop()

        println player1Card
        println player2Card

        if(player1Card.card == player2Card.card) {
            println "Draw"
            totalWarsPlayed++
            if(player1Deck.cards.size() > 0 && player2Deck.cards.size() > 0) {
                def who = war(player1Deck, player2Deck)
                if(who == Player.ONE) {
                    player1Deck.cards.addAll(player2Card,player1Card)
                } else {
                    player2Deck.cards.addAll(player2Card, player1Card)
                }
            }

            return Player.DRAW
        }
        if(player1Card.card > player2Card.card) {
            println "Player 1 wins hand!"
            player1Deck.cards.addAll(player2Card, player1Card)
            p1Points++
            return Player.ONE
        }
        if(player1Card.card < player2Card.card) {
            println "Player 2 wins hand!"
            player2Deck.cards.addAll(player1Card, player2Card)
            p2Points++
            return Player.TWO
        }
    }

    class Deck {
        final Integer suits = 4
        final Integer numOfCardsInSuit = 13
        final Integer jokers = 0
        final Integer deckSize = suits * numOfCardsInSuit + jokers

        List<Card> cards = []

        Deck() {
            this
        }

        Deck generate() {
            (0..(deckSize - 1)).each { cardNum ->
                def suit = (cardNum % suits) + 1
                def value = (Math.floor(cardNum / suits)) + 1

                def card = new Card(suit:suit, card:value.toInteger())
                cards.push(card)
            }
            this
        }

        Deck withCards(List<Card> theCards) {
            cards = theCards
            this
        }

        Deck shuffle() {
            1..100.each {
                Collections.shuffle(cards)
            }
            this
        }

        String toString() {
            cards.each { card ->
                card
            }
        }
    }

    class Card {
        Integer suit
        Integer card

        String toString() {
            def display = ""
            switch (card) {
                case 1:
                    display += "Ace"
                    break
                case 11:
                    display += "Jack"
                    break
                case 12:
                    display += "Queen"
                    break
                case 13:
                    display += "King"
                    break
                case 14:
                    display += "🃏"
                    break
                default:
                    display += card
            }

            switch (suit) {
                case 1:
                    display += " ♥"
                    break
                case 2:
                    display += " ♦"
                    break
                case 3:
                    display += " ♣"
                    break
                case 4:
                    display += " ♠"
                    break
            }

            display
        }
    }
}