Created
November 18, 2016 17:20
-
-
Save atoko/120bc12b357b0c8959c5c225e4f4a84f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import groovyjarjarantlr.collections.List | |
class BriscaData { | |
static Map suits = [ | |
0: "Coins", | |
1: "Staffs", | |
2: "Goblets", | |
3: "Swords" | |
] | |
static Map faces = [ | |
0: "Ace", | |
1: "Two", | |
2: "Three", | |
3: "Four", | |
4: "Five", | |
5: "Six", | |
6: "Seven", | |
7: "Page", | |
8: "Knight", | |
9: "King" | |
] | |
static Map pointValues = [ | |
0: 11, | |
2: 10, | |
7: 1, | |
8: 2, | |
9: 3 | |
] | |
} | |
class Card { | |
int index | |
Card(int index) { | |
this.index = index | |
} | |
int getSuit() { | |
Math.floor(this.index / 10) | |
} | |
int getFaceNumber() { | |
this.index - (this.suit * 10) | |
} | |
String getSuitName() { | |
BriscaData.suits[this.suit] | |
} | |
String getFaceName() { | |
BriscaData.faces[this.faceNumber] | |
} | |
int getPointValue() { | |
BriscaData.pointValues[this.faceNumber] ?: 0 | |
} | |
String getFullName() { | |
"${this.faceName} of ${this.suitName}" | |
} | |
} | |
class BriscaCard extends Card { | |
def thrownBy | |
boolean isLife | |
BriscaCard(Card c, int thrownBy, int lifeSuit) { | |
super(c.index); | |
this.thrownBy = thrownBy; | |
this.isLife = lifeSuit == this.suit; | |
} | |
boolean WinsAgainst(BriscaCard opponent) { | |
if (!this.isLife && opponent.isLife) { | |
return false | |
} | |
if (opponent.isLife || (this.suit == opponent.suit)) { | |
if (opponent.pointValue > this.pointValue) { | |
return false | |
} | |
if (opponent.pointValue == this.pointValue) { | |
if (this.faceNumber > opponent.faceNumber) { | |
return true | |
} else { | |
return false | |
} | |
} | |
} | |
return true | |
} | |
} | |
class Player { | |
def name = "Fulanito" | |
def hand = [] | |
def grave = [] | |
int points = 0 | |
def Player(name) { | |
this.name = name | |
} | |
def PlayCard(index) { | |
def card = this.hand[index] | |
this.hand.remove(card) | |
return card | |
} | |
def DrawCard(card) { | |
this.hand << card | |
} | |
def WinCards(cards) { | |
cards.forEach() { card -> | |
this.points += card.pointValue | |
this.grave << card | |
} | |
} | |
} | |
class BriscaEngine { | |
Stack deck = [] as Stack | |
def players = [] | |
def table = [] | |
int nextToDraw = 0 | |
int nextToPlay = 0 | |
BriscaCard roundWinner | |
String message = "" | |
BriscaEngine() { | |
this.LoadDeck() | |
} | |
def AddPlayer(playerName) { | |
this.players << new Player(playerName); | |
if (players.size == 2) { | |
for (_ in 1..3) { | |
this.DealCards() | |
} | |
} | |
} | |
def IsTableFull() { | |
return this.players.size() == 2 | |
} | |
private LoadDeck() { | |
for (i in 0..39) { | |
deck << new Card(i) | |
} | |
Collections.shuffle(deck) | |
} | |
private Cycle(n) { | |
(n + 1) % players.size() | |
} | |
private DealCards() { | |
def playerCount = players.size(); | |
for (def i = 0; i < playerCount; i++) { | |
def card = deck.pop() | |
players[this.nextToDraw].DrawCard(card) | |
this.nextToDraw = Cycle(this.nextToDraw) | |
} | |
} | |
private getLifeCard() { | |
deck[0] | |
} | |
def getLifeName() { | |
this.lifeCard.suitName | |
} | |
def getCardsRemaining() { | |
"${this.deck.size()}" | |
} | |
def getCurrentPlayer() { | |
this.players[this.nextToPlay] | |
} | |
def getTable() { | |
this.table | |
} | |
def FormatMessage(def message) { | |
"${this.players[roundWinner.thrownBy].name} wins this round: \n ${message}" | |
} | |
def Play(int cardIndex) { | |
def card = this.players[this.nextToPlay].PlayCard(cardIndex) | |
def briscaCard = new BriscaCard(card, this.nextToPlay, this.lifeCard.suit) | |
this.table << briscaCard | |
this.nextToPlay = Cycle(this.nextToPlay) | |
if (this.table.size() > 1) { | |
if(!roundWinner.WinsAgainst(briscaCard)) { | |
roundWinner = briscaCard | |
message = FormatMessage("Wins because reasons") | |
} else { | |
message = FormatMessage("Card not matched") | |
} | |
} else { | |
roundWinner = briscaCard | |
message = "" | |
} | |
} | |
def Turn() { | |
if (this.table.size() == this.players.size()) { | |
this.players[this.roundWinner.thrownBy].WinCards(this.table); | |
this.nextToPlay = this.roundWinner.thrownBy; | |
this.table.clear() | |
this.roundWinner = null | |
this.DealCards(); | |
} | |
} | |
} | |
interface CommandApp { | |
def Render() | |
def Command(command) | |
} | |
class BriscaGame implements CommandApp { | |
enum states { | |
PENDING, | |
SHOWING | |
} | |
private def engine; | |
private def state = states.PENDING; | |
static def commands = ["a", "b", "c"] | |
BriscaGame(def engine) { | |
this.engine = engine | |
} | |
private def renderTable() { | |
println "--DECK-------------" | |
println "${engine.cardsRemaining} cards remain" | |
println "Life is ${engine.lifeName}" | |
println "--TABLE------------" | |
if (engine.table.size() > 0) { | |
for (card in engine.table) { | |
def isWinCard = card.index == engine.roundWinner.index | |
println card.fullName + (isWinCard ? " <-- Winning" : "") | |
} | |
} else { | |
println "No cards on the table" | |
} | |
} | |
private def renderHand() { | |
def options = ["a", "b", "c"]; | |
def index = 0; | |
def player = engine.currentPlayer; | |
println "--${player.name.toUpperCase()}-----------" | |
println "You have ${player.points} point(s)" | |
for (card in player.hand) { | |
println "${options[index]}) ${card.fullName}" | |
index++; | |
} | |
println "Which card will you play? (q to end game)" | |
} | |
def renderMessage() { | |
println "*------------------*" | |
println this.engine.message | |
println "Press enter to continue.." | |
} | |
def Render() { | |
renderTable(); | |
//renderPlayers(); | |
switch (this.state) { | |
case states.PENDING: | |
renderHand() | |
break | |
case states.SHOWING: | |
renderMessage() | |
break | |
} | |
} | |
static validCommands = ["a", "b", "c"]; | |
def Command(command) { | |
if (state == states.PENDING && validCommands.contains(command)) { | |
engine.Play(commands.indexOf(command)); | |
state = states.SHOWING | |
return "game" | |
} | |
if (state == states.SHOWING) { | |
engine.Turn() | |
state = states.PENDING | |
return "game" | |
} | |
} | |
} | |
class BriscaSignup implements CommandApp { | |
enum states { | |
WELCOME, | |
INPUT | |
} | |
def state = states.WELCOME | |
BriscaEngine engine | |
def BriscaSignup(engine) { | |
this.engine = engine | |
} | |
def Render() { | |
switch (state) { | |
case states.WELCOME: | |
println "Hello and welcome to GroovyBriscas! \nPress enter to begin" | |
break | |
case states.INPUT: | |
println "Please enter a name for player ${this.engine.players.size() + 1}: " | |
break | |
} | |
} | |
def Command(command) { | |
switch (state) { | |
case states.WELCOME: | |
state = states.INPUT | |
return "signup" | |
break | |
case states.INPUT: | |
engine.AddPlayer(command) | |
if (engine.IsTableFull()) { | |
return "game" | |
} | |
return "signup" | |
break | |
} | |
return "signup" | |
} | |
} | |
def engine = new BriscaEngine(); | |
def library = [signup:new BriscaSignup(engine), game:new BriscaGame(engine)] | |
def current = library.get("signup"); | |
def on = true; | |
while (on) { | |
println "Groovy Briscas v0 by atoko" | |
current.Render(); | |
def command = System.in.newReader().readLine(); | |
switch (command) { | |
case "q": | |
println "Goodbye!" | |
on = false | |
break | |
default: | |
current = library.get(current.Command(command)); | |
break | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment