Skip to content

Instantly share code, notes, and snippets.

@atoko
Created November 18, 2016 17:20
Show Gist options
  • Save atoko/120bc12b357b0c8959c5c225e4f4a84f to your computer and use it in GitHub Desktop.
Save atoko/120bc12b357b0c8959c5c225e4f4a84f to your computer and use it in GitHub Desktop.
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