Adventure: NATS Jetstream KV Store - Part 5
Welcome! Welcome to Part 5 of our series on the NATS JetStream KV Store! This time, we're going to build a little something - nothing too big just yet, but we're making progress. Stay tuned, because we'll get there! Where did we leave off? We did a bunch of CLI commands but let's try to put them to some actual use. We're going to make Tic Tac Toe in the bash shell! Terminal Tic Tac Toe Say that five times fast… actually, it's not that hard. I just did it - did you? You did. Admit it, you totally did. Alright, enough fun - let's move on! Time to get our setup ready. First things first let's start fresh again. # Start NATS Jetstream if you haven't already. $ ./nats-server -js # Delete all your buckets! $ nats kv del # Create the bucket named tictactoe $ nats kv add tictactoe It's time to design the main game loop for our Tic-Tac-Toe shell game. While you can simply copy the code, I'll also walk you through how it works. We'll implement five key functions: Main The main game loop. Initialize Board Resets the game board to its initial state. Display Board Displays the current state of the board. Make Move Handles moves for players X and O. Check Winner Determines if there's a winner. (Pretty self-explanatory!) Let's get started! Main Loop Let's go over the main game loop. # Main game loop main() { # Displays the main menu and handles user input. echo "Welcome to Tic-Tac-Toe with NATS JetStream KV!" echo "1. Initialize/Reset Board" echo "2. Play Game" echo "3. Exit" echo "-------------------" while :; do # Infinite loop to keep showing the menu until the user exits. echo -n "Choose an option: " read choice # Reads the user's menu choice. case $choice in 1) initialize_board ;; 2) while :; do echo "Player $current_player's turn." echo "Enter your move (e.g., A1) or press 3 to display the board." echo -n "Your input: " read cell # Handle special commands if [[ $cell == "3" ]]; then # If the user enters "3", display the board. display_board continue fi # Make the move if input is not a special command if make_move $cell; then if check_winner; then # Check if there is a winner and respond if there is. current_player="X" # Reset the current player break # Exit to the main menu fi fi done ;; 3) echo "Goodbye!" exit 0 ;; *) echo "Invalid option. Try again." ;; esac done } This process is fairly straightforward. Here's how it works: We start with an outer loop that continues until the user makes a choice between options 1–3: Clear the board for a new game. Start the game. Quit the program. Once the game starts, we enter an inner loop, which serves as the main game loop. Here's what happens: The loop pauses at the read command, waiting for the user to provide input. If the input is the special character 3, it displays the board. Otherwise, the input is passed to make_move. If the input is valid, it checks for a winner. Depending on the input and the result the loop either restarts to process more moves, or it exits if a winner is detected. Initialize the Board Now we get to use some good ol' fashioned NATS Jetstream KV Store! # KV bucket name BUCKET="tictactoe" # Resets the Tic-Tac-Toe board by initializing all cells in the bucket. initialize_board() { echo "Initializing board..." for cell in A1 A2 A3 B1 B2 B3 C1 C2 C3; do # Sets each cell in the KV store to an empty space (" "). nats kv put $BUCKET $cell " " >/dev/null 2>&1 done echo "Board initialized." # Displays the newly initialized board. display_board } Alright, buckle up - this is where the magic happens, and it's simpler than you think! We're going to loop through every cell of our Tic-Tac-Toe board and use the nats kv put command to stash an empty space for each one. Think of it like setting up a fresh board where every cell is just waiting for someone to make a move. Each cell gets its own key-value pair in the bucket, like key=A1, Value=" ". Boom, instant empty board! >/dev/null: This sneaky bit shushes the success messages from the nats kv put command. No bragging allowed here! 2>&1: And this? It's like saying, "Oh, you messed up? Cool, but we're not telling anyone." Any errors get tossed into the void too. Once the board is all set up, we'll proudly display it like a freshly baked cake. Display Board Oh, this one's a piece of cake!
![Adventure: NATS Jetstream KV Store - Part 5](https://media2.dev.to/dynamic/image/width%3D1000,height%3D500,fit%3Dcover,gravity%3Dauto,format%3Dauto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hsz5ikvsemhqzo8hbsr.png)
Welcome!
Welcome to Part 5 of our series on the NATS JetStream KV Store! This time, we're going to build a little something - nothing too big just yet, but we're making progress. Stay tuned, because we'll get there!
Where did we leave off?
We did a bunch of CLI commands but let's try to put them to some actual use.
We're going to make Tic Tac Toe in the bash shell!
Terminal Tic Tac Toe
Say that five times fast… actually, it's not that hard. I just did it - did you? You did. Admit it, you totally did.
Alright, enough fun - let's move on! Time to get our setup ready.
First things first let's start fresh again.
# Start NATS Jetstream if you haven't already.
$ ./nats-server -js
# Delete all your buckets!
$ nats kv del
# Create the bucket named tictactoe
$ nats kv add tictactoe
It's time to design the main game loop for our Tic-Tac-Toe shell game. While you can simply copy the code, I'll also walk you through how it works. We'll implement five key functions:
Main
The main game loop.
Initialize Board
Resets the game board to its initial state.
Display Board
Displays the current state of the board.
Make Move
Handles moves for players X and O.
Check Winner
Determines if there's a winner. (Pretty self-explanatory!)
Let's get started!
Main Loop
Let's go over the main game loop.
# Main game loop
main() {
# Displays the main menu and handles user input.
echo "Welcome to Tic-Tac-Toe with NATS JetStream KV!"
echo "1. Initialize/Reset Board"
echo "2. Play Game"
echo "3. Exit"
echo "-------------------"
while :; do
# Infinite loop to keep showing the menu until the user exits.
echo -n "Choose an option: "
read choice
# Reads the user's menu choice.
case $choice in
1)
initialize_board
;;
2)
while :; do
echo "Player $current_player's turn."
echo "Enter your move (e.g., A1) or press 3 to display the board."
echo -n "Your input: "
read cell
# Handle special commands
if [[ $cell == "3" ]]; then
# If the user enters "3", display the board.
display_board
continue
fi
# Make the move if input is not a special command
if make_move $cell; then
if check_winner; then
# Check if there is a winner and respond if there is.
current_player="X" # Reset the current player
break # Exit to the main menu
fi
fi
done
;;
3)
echo "Goodbye!"
exit 0
;;
*)
echo "Invalid option. Try again."
;;
esac
done
}
This process is fairly straightforward. Here's how it works:
We start with an outer loop that continues until the user makes a choice between options 1–3:
- Clear the board for a new game.
- Start the game.
- Quit the program.
Once the game starts, we enter an inner loop, which serves as the main game loop. Here's what happens:
The loop pauses at the read command, waiting for the user to provide input.
If the input is the special character 3, it displays the board.
Otherwise, the input is passed to make_move
. If the input is valid, it checks for a winner.
Depending on the input and the result the loop either restarts to process more moves, or it exits if a winner is detected.
Initialize the Board
Now we get to use some good ol' fashioned NATS Jetstream KV Store!
# KV bucket name
BUCKET="tictactoe"
# Resets the Tic-Tac-Toe board by initializing all cells in the bucket.
initialize_board() {
echo "Initializing board..."
for cell in A1 A2 A3 B1 B2 B3 C1 C2 C3; do
# Sets each cell in the KV store to an empty space (" ").
nats kv put $BUCKET $cell " " >/dev/null 2>&1
done
echo "Board initialized."
# Displays the newly initialized board.
display_board
}
Alright, buckle up - this is where the magic happens, and it's simpler than you think!
We're going to loop through every cell of our Tic-Tac-Toe board and use the nats kv put command to stash an empty space for each one. Think of it like setting up a fresh board where every cell is just waiting for someone to make a move.
Each cell gets its own key-value pair in the bucket, like key=A1, Value=" "
. Boom, instant empty board!
-
>/dev/null
: This sneaky bit shushes the success messages from the nats kv put command. No bragging allowed here! -
2>&1
: And this? It's like saying, "Oh, you messed up? Cool, but we're not telling anyone." Any errors get tossed into the void too.
Once the board is all set up, we'll proudly display it like a freshly baked cake.
Display Board
Oh, this one's a piece of cake!