Skip to content

Instantly share code, notes, and snippets.

@evilthreads669966
Last active November 8, 2023 19:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evilthreads669966/99fd867215f6b4c388bbf5a4f23a886f to your computer and use it in GitHub Desktop.
Save evilthreads669966/99fd867215f6b4c388bbf5a4f23a886f to your computer and use it in GitHub Desktop.
heads up blackjack game
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.koin.core.context.startKoin
import org.koin.core.qualifier.named
import org.koin.dsl.module
fun main(){
startKoin {
modules(appModule)
}
Game.start()
}
val appModule = module {
factory<Hand>{ Hand() }
factory<Deck> { Deck() }
factory<Participant>(named("player")) { Player.createParticipant(get()) }
factory<Participant>(named("dealer")) { Dealer.createParticipant(get(), get()) }
}
enum class TableState{
PLAY, LOSE, WIN
}
enum class Suite{
CLUBS, SPADE, HEARTS, DIAMOND
}
enum class Request{
HIT, FOLD, DEAL
}
class Card(val value: Int, val suite: Suite){
val score: Int
get() {
val range = IntRange(11,13)
if(value in 11..13)
return 10
else if(value == 14)
return 11
return value
}
override fun toString(): String {
return when(value){
11 -> "${suite} Jack"
12 -> "${suite} Queen"
13 -> "${suite} King"
14 -> "${suite} Ace"
1 -> "${suite} ACE"
else -> "${suite} ${value}"
}
}
}
class Hand{
private val _cards = mutableListOf<Card>()
val cards: List<Card>
get() = _cards
val score: Int
get() {
val score = _cards.fold(0){ score, card ->
score + card.score
}
return score
}
fun addCard(card: Card){
_cards.add(card)
}
fun removeCard(card: Card): Boolean{
return _cards.remove(card)
}
override fun toString(): String {
return _cards.joinToString(" ") { it.toString() }
}
}
interface Participant{
val hand: Hand
val score: Int
}
interface ParticipantFactory{
fun createParticipant(hand: Hand, deck: Deck? = null): Participant
}
class Player(override val hand: Hand): Participant{
companion object: ParticipantFactory{
override fun createParticipant(hand: Hand, deck: Deck?): Participant = Player(hand)
}
override val score: Int
get() = hand.score
}
class Table: KoinComponent{
val dealer: Participant by inject(qualifier = named("dealer"))
val player: Participant by inject(qualifier = named("player"))
fun request(request: Request): TableState{
return when(request){
Request.HIT -> (dealer as Dealer).hit(player.hand)
Request.FOLD -> (dealer as Dealer).fold(player.hand)
Request.DEAL -> (dealer as Dealer).deal(player.hand)
}
}
fun showHandsAndScores(){
println("Player Score: ${player.score}")
println("Dealer Score: ${dealer.score}")
println("Player hand ${player.hand}")
println("Dealer hand ${dealer.hand}")
}
}
class Deck{
private val _cards = mutableListOf<Card>()
val cards: List<Card>
get() = _cards
init {
Suite.values().forEach { suite ->
val cards = mutableListOf(Card(2,suite),Card(3,suite),Card(4,suite),Card(5,suite),Card(6,suite),Card(7,suite),Card(8,suite),Card(9,suite),Card(10,suite),Card(11,suite),Card(12,suite),Card(13,suite),Card(14,suite))
_cards.addAll(cards)
}
_cards.shuffle()
}
fun drawCard(): Card = _cards.removeLast()
}
class Dealer(override val hand: Hand, val deck: Deck): Participant{
override val score: Int
get() = hand.score
companion object: ParticipantFactory{
override fun createParticipant(hand: Hand, deck: Deck?): Participant = Dealer(hand, deck!!)
}
fun deal(playerHand: Hand): TableState{
var cardOne = deck.drawCard()
var cardTwo = deck.drawCard()
hand.addCard(cardOne)
hand.addCard(cardTwo)
cardOne = deck.drawCard()
cardTwo = deck.drawCard()
playerHand.addCard(cardOne)
playerHand.addCard(cardTwo)
return TableState.PLAY
}
fun hit(playerHand: Hand): TableState {
var card = deck.drawCard()
playerHand.addCard(card)
if(playerHand.score > 21 && card.value == 14){
playerHand.removeCard(card)
playerHand.addCard(Card(1, card.suite))
}
if(hand.score < 17){
card = deck.drawCard()
hand.addCard(card)
if(hand.score > 21 && card.value == 14){
hand.removeCard(card)
hand.addCard(Card(1, card.suite))
}
}
if(playerHand.score > 21)
return TableState.LOSE
if(hand.score == 21 && playerHand.score < 21)
return TableState.LOSE
if(hand.score > 21 && playerHand.score <= 21)
return TableState.WIN
return TableState.PLAY
}
fun fold(playerHand: Hand): TableState{
if(playerHand.score > 21)
return TableState.LOSE
if(hand.score == 21 && playerHand.score < 21)
return TableState.LOSE
if(hand.score > 21 && playerHand.score <= 21)
return TableState.WIN
if(hand.score < playerHand.score)
return TableState.WIN
return TableState.LOSE
}
}
class Game{
companion object{
@JvmStatic
fun start(){
var count = 1
loop@while(true){
val table = Table()
println("Dealing cards")
table.request(Request.DEAL)
print("Your hand is: ")
println(table.player.hand)
println("Your score is ${table.player.score}")
hitfold@while(true){
println("HIT OR FOLD")
var input = readlnOrNull()?.trim()!!.lowercase()
if(input.isNullOrBlank())
continue@hitfold
if(input == "hit"){
val state = table.request(Request.HIT)
if(state == TableState.LOSE){
table.showHandsAndScores()
println("You lose!")
break@hitfold
}
if(state == TableState.WIN){
table.showHandsAndScores()
println("You win!")
break@hitfold
}
if(state == TableState.PLAY){
println("Player Score: ${table.player.score}")
println("Player hand ${table.player.hand}")
continue@hitfold
}
}
if(input == "fold"){
table.showHandsAndScores()
val state = table.request(Request.FOLD)
if(state == TableState.WIN)
println("You win!")
else
println("You lose!")
break@hitfold
}
}
println()
println()
count++
if(count % 10 == 0)
System.gc()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment