Skip to content

Commit 503d339

Browse files
Article: R1.D6
1 parent 5408b8b commit 503d339

File tree

4 files changed

+149
-9
lines changed

4 files changed

+149
-9
lines changed

.github/workflows/crosspost.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ name: CrossPost
33
on:
44
push:
55
branches:
6-
- master
6+
- master
77
paths:
8-
- 'content/articles/*.md'
8+
- 'content/articles/*.md'
99

1010
jobs:
1111
crosspost:
1212
runs-on: ubuntu-latest
1313
steps:
14-
- name: Checkout Code
15-
uses: actions/checkout@v2
14+
- name: Checkout Code
15+
uses: actions/checkout@v2
1616

17-
- uses: basicBrogrammer/crosspost-markdown@v0.1.2
18-
with:
19-
content-dir: 'content/articles/'
20-
dev-to-token: ${{ secrets.DEV_TO }}
21-
github-token: ${{ secrets.GITHUB_TOKEN }}
17+
- uses: basicBrogrammer/crosspost-markdown@v0.1.3
18+
with:
19+
content-dir: 'content/articles/'
20+
dev-to-token: ${{ secrets.DEV_TO }}
21+
github-token: ${{ secrets.GITHUB_TOKEN }}
22+
medium-token: ${{ secrets.MEDIUM_TOKEN }}
23+
medium-author-id: ${{ secrets.MEDIUM_AUTHOR_ID }}

components/ArticleTag.vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,12 @@ a::before {
5959
background-color: #4a245d;
6060
color: #fff;
6161
}
62+
.webdev {
63+
background-color: #562765;
64+
color: #fff;
65+
}
66+
.productivity {
67+
background-color: #2a0798;
68+
color: #fff;
69+
}
6270
</style>

content/articles/round-1-day-3.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description: Finished https://elixirschool.com/en/lessons/basics
55
tags: 100daysofcode, elixir
66
cover_image: https://cdn.hashnode.com/res/hashnode/image/upload/v1613355044450/ggGLGvRqH.png?auto=compress
77
datePosted: '2021-02-14'
8+
devToId: 603919
89
---
910

1011
# Keep Moving Forward

content/articles/round-1-day-5.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: '[WIP] Creating a Blackjack CLI game with Elixir'
3+
published: true
4+
description: On day 6 of my 100 days of code, I was able to make some head way with my CLI Blackjack game with elixir.
5+
tags: 100daysofcode, webdev, elixir
6+
cover_image:
7+
datePosted: '2021-02-19'
8+
---
9+
10+
## Day 6 of 100 Days of Code
11+
12+
Today I was able to work on my [Blackjack CLI](https://github.com/basicBrogrammer/blackjack_cli) written in elixir. It's starting to shape up, but it still feels a little off. Here's a quick demo:
13+
14+
![blackjack demo](https://cdn.hashnode.com/res/hashnode/image/upload/v1613759602886/OZjw9gwhJ.gif?auto=compress)
15+
16+
## Update to the user experience
17+
18+
First I took advantage of elixir's pattern matching in functions to create a set of functions to calculate the value for a given card.
19+
20+
```elixir
21+
defmodule Card do
22+
...
23+
def value(%{value: "J"}), do: 10
24+
def value(%{value: "Q"}), do: 10
25+
def value(%{value: "K"}), do: 10
26+
def value(%{value: "A"}), do: 11
27+
def value(%{value: value}), do: value
28+
...
29+
end
30+
```
31+
32+
Next, I added a flash to displaying the cards by adding a white background and painting the card according to the suit.
33+
34+
```elixir
35+
defmodule Card do
36+
...
37+
def display(%{suit: suit, value: value}) do
38+
IO.ANSI.color_background(15) <> IO.ANSI.color(color_code(suit)) <> "#{suit}#{value}" <> IO.ANSI.reset()
39+
end
40+
41+
defp color_code(""), do: 9
42+
defp color_code(""), do: 9
43+
defp color_code(""), do: 0
44+
defp color_code(""), do: 0
45+
end
46+
```
47+
48+
Another bit of flare I added was chaning out the `Deck @suits` constant with the unicode icons for each suit. It's the little things you know?
49+
50+
Now, let's take a look at the changes to the Game module.
51+
52+
```elixir
53+
defmodule Game do
54+
# Added the "finished_players" attribute to the %Game struct. When a user
55+
# finishes their turn, they will be removed from the players list and placed
56+
# into the finished_players list.
57+
defstruct players: [%Player{name: "player_one"}, %Player{name: "dealer"}], cards: Deck.generate(), finished_players: []
58+
59+
# After all users are removed from the players list, we can pattern match on
60+
# an empty players attr and finish the game.
61+
def play(%{players: []} = game) do
62+
game |> inspect_table()
63+
end
64+
65+
# If there are still players, the play function logic will be a little
66+
# different, but with the pipe operator its pretty easy to follow.
67+
def play(game) do
68+
game
69+
|> deal()
70+
|> inspect_table()
71+
|> turn()
72+
|> play
73+
end
74+
75+
# To handle a players turn, we just ask them if they want to Hit or Stay, and
76+
# build a new game struct accordingly.
77+
def turn(%{players: [current | players]} = game) do
78+
IO.puts "\n#{current.name} your move."
79+
case IO.gets("(H)it or (S)tay\n") |> String.downcase |> String.trim do
80+
"hit" -> deal_card(game, current)
81+
"h" -> deal_card(game, current)
82+
"stay" -> %{game | players: players, finished_players: [current | game.finished_players]}
83+
"s" -> %{game | players: players, finished_players: [current | game.finished_players]}
84+
_ -> game
85+
end
86+
end
87+
88+
# Inspecting the table clears out the terminal, then displays info about for
89+
# the current state of the game
90+
defp inspect_table(%{players: players, finished_players: f_players} = game) do
91+
IO.write IO.ANSI.reset() <> IO.ANSI.clear() <> IO.ANSI.home()
92+
if length(players) == 0 do
93+
IO.puts "Game Over."
94+
end
95+
for player <- f_players ++ players do
96+
IO.puts "#{player.name}'s\n hand: #{Player.display_hand(player)} | #{player.total}"
97+
end
98+
game
99+
end
100+
end
101+
```
102+
103+
## Implement the Dealer logic
104+
105+
In regular Blackjack, the deal has to hit if they have less than 17. I decided to replace `%Player{name: "dealer"}` with a `%Dealer` struct. With that in place I can use pattern matching again for the `Game.turn/1` function which looks a little like this:
106+
107+
```elixir
108+
def turn(%{players: [%Dealer{} = dealer | players]} = game) do
109+
cond do
110+
dealer.total >= 17 -> %{game | players: players, finished_players: [dealer | game.finished_players]}
111+
true -> deal_card(game, dealer)
112+
end
113+
|> inspect_table()
114+
|> (fn (game) ->
115+
IO.gets("Press enter to continue.")
116+
game
117+
end).()
118+
end
119+
```
120+
121+
## What's next?
122+
123+
If I want to finish Blackjack CLI, I would have to handle Aces. Aces can have a value of 1 or 11. This shouldn't be to hard, but might take some time. Other than that, It would be nice to choose how many decks could be played, and play to a certain percentage of the deck before regenerating the game.
124+
125+
I will prolly move on to the advance section of elixirschool.com, and come back to this repo later on.
126+
127+
## Follow Me @
128+
129+
[Twitter](https://twitter.com/basicbrogrammer) | [Instagram](https://instagram.com/basicbrogrammer)

0 commit comments

Comments
 (0)