Ever dreamt of building your own game, even a simple one? It might sound complicated, but with the right tools and a step-by-step approach, you can create something fun and interactive. In this blog post, we’re going to combine the power of Flask (a friendly Python web framework) with JavaScript (the language that brings websites to life) to build a simple “Guess the Number” game.
This project is perfect for beginners who want to dip their toes into web development and see how different technologies work together to create a dynamic experience. We’ll keep the explanations clear and simple, making sure you understand each step along the way.
Let’s get started and build our first interactive game!
Understanding the Tools
Before we dive into coding, let’s briefly understand the two main technologies we’ll be using.
What is Flask?
Flask is what we call a “micro web framework” for Python.
* Web Framework: Think of a web framework as a toolkit that provides all the necessary components and structure to build web applications faster and more efficiently. Instead of writing everything from scratch, Flask gives you a starting point.
* Micro: This means Flask is lightweight and doesn’t come with many built-in features, giving you the flexibility to choose the tools you need. It’s excellent for smaller projects or for learning the fundamentals of web development.
In our game, Flask will act as the “backend” – the part of our application that runs on a server. It will handle logic like generating the secret number, checking the user’s guess, and sending responses back to the browser.
What is JavaScript?
JavaScript is a programming language that makes web pages interactive.
* Client-Side Scripting: Unlike Flask, which runs on a server, JavaScript typically runs directly in your web browser (the “client-side”).
* Interactivity: It allows you to create dynamic content, control multimedia, animate images, and much more. Without JavaScript, web pages would be mostly static text and images.
For our game, JavaScript will be the “frontend” – what the user sees and interacts with. It will take the user’s guess, send it to our Flask backend, and then display the result back to the user without reloading the entire page.
Setting Up Your Environment
First, you’ll need to make sure you have Python installed on your computer. If not, head over to the official Python website (python.org) and follow the installation instructions.
Once Python is ready, open your terminal or command prompt and install Flask:
pip install Flask
Now, let’s create a new folder for our game project. You can call it guess_the_number_game. Inside this folder, we’ll create the following structure:
guess_the_number_game/
├── app.py
├── templates/
│ └── index.html
└── static/
├── style.css
└── script.js
app.py: This will contain our Flask backend code.templates/: This folder is where Flask looks for HTML files (our web pages).static/: This folder holds static files like CSS (for styling) and JavaScript (for interactivity).
Building the Backend (Flask)
Let’s start by writing the Python code for our game logic in app.py.
app.py – The Brains of the Game
This file will:
1. Initialize our Flask application.
2. Generate a random secret number.
3. Define a “route” (a specific web address) for our homepage.
4. Handle the user’s guess submitted from the frontend.
import random
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
SECRET_NUMBER = random.randint(1, 100)
print(f"Secret number is: {SECRET_NUMBER}") # For debugging purposes
@app.route('/')
def index():
# render_template: Flask function to load and display an HTML file
return render_template('index.html')
@app.route('/guess', methods=['POST'])
def guess():
# request.json: Accesses the JSON data sent from the frontend
user_guess = request.json.get('guess')
# Basic validation
if not isinstance(user_guess, int):
return jsonify({'message': 'Please enter a valid number!'}), 400
message = ""
if user_guess < SECRET_NUMBER:
message = "Too low! Try a higher number."
elif user_guess > SECRET_NUMBER:
message = "Too high! Try a lower number."
else:
message = f"Congratulations! You guessed the number {SECRET_NUMBER}!"
# For simplicity, we won't reset the number here, but you could add that logic.
# jsonify: Flask function to convert a Python dictionary into a JSON response
return jsonify({'message': message})
if __name__ == '__main__':
# app.run(debug=True): Runs the Flask development server.
# debug=True: Automatically reloads the server on code changes and shows helpful error messages.
app.run(debug=True)
Explanation:
* import random: Used to generate our secret number.
* from flask import Flask, render_template, request, jsonify: We import necessary components from Flask.
* app = Flask(__name__): This line creates our Flask application instance.
* SECRET_NUMBER = random.randint(1, 100): We generate a random integer between 1 and 100, which is our target number.
* @app.route('/'): This is a “decorator” that tells Flask what function to run when someone visits the root URL (e.g., http://localhost:5000/).
* render_template('index.html'): This function looks for index.html inside the templates folder and sends it to the user’s browser.
* @app.route('/guess', methods=['POST']): This route specifically handles guesses. We specify methods=['POST'] because the frontend will “POST” data (send it to the server) when the user makes a guess.
* request.json.get('guess'): When the frontend sends data as JSON, Flask’s request.json object allows us to easily access that data. We’re looking for a key named 'guess'.
* jsonify({'message': message}): This is how our Flask backend sends a response back to the frontend. It takes a Python dictionary and converts it into a JSON string, which JavaScript can easily understand.
* app.run(debug=True): This starts the web server. debug=True is useful during development.
Building the Frontend (HTML & JavaScript)
Now, let’s create the user interface and the interactive logic that runs in the browser.
templates/index.html – The Game Board
This HTML file will define the structure of our game page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Guess The Number Game</title>
<!-- Link to our CSS file for styling (optional but good practice) -->
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="game-container">
<h1>Guess The Number!</h1>
<p>I'm thinking of a number between 1 and 100.</p>
<p>Can you guess what it is?</p>
<input type="number" id="guessInput" placeholder="Enter your guess">
<button id="submitGuess">Guess</button>
<!-- This paragraph will display messages to the user -->
<p id="message" class="game-message"></p>
</div>
<!-- Link to our JavaScript file, defer makes sure the HTML loads first -->
<script src="{{ url_for('static', filename='script.js') }}" defer></script>
</body>
</html>
Explanation:
* <!DOCTYPE html>: Declares the document as an HTML5 file.
* <head>: Contains metadata about the page, like its title and links to stylesheets.
* url_for('static', filename='style.css'): This is a Jinja2 template function provided by Flask. It generates the correct URL for our static style.css file.
* <body>: Contains the visible content of the web page.
* <h1>, <p>: Standard HTML headings and paragraphs.
* <input type="number" id="guessInput">: An input field where the user can type their guess. id="guessInput" gives it a unique identifier so JavaScript can easily find it.
* <button id="submitGuess">: The button the user clicks to submit their guess.
* <p id="message">: An empty paragraph where we will display “Too high!”, “Too low!”, or “Correct!” messages using JavaScript.
* <script src="..." defer></script>: This links our JavaScript file. The defer attribute tells the browser to parse the HTML before executing the script, ensuring all HTML elements are available when the script runs.
static/script.js – Making it Interactive
This JavaScript file will handle user interactions and communicate with our Flask backend.
// Get references to HTML elements by their IDs
const guessInput = document.getElementById('guessInput');
const submitButton = document.getElementById('submitGuess');
const messageParagraph = document.getElementById('message');
// Add an event listener to the submit button
// When the button is clicked, the 'handleGuess' function will run
submitButton.addEventListener('click', handleGuess);
// Function to handle the user's guess
async function handleGuess() {
const userGuess = parseInt(guessInput.value); // Get the value from the input and convert it to an integer
// Clear previous message
messageParagraph.textContent = '';
messageParagraph.className = 'game-message'; // Reset class for styling
// Basic client-side validation
if (isNaN(userGuess) || userGuess < 1 || userGuess > 100) {
messageParagraph.textContent = 'Please enter a number between 1 and 100.';
messageParagraph.classList.add('error');
return; // Stop the function if the input is invalid
}
try {
// Send the user's guess to the Flask backend using the Fetch API
// fetch: A modern JavaScript function to make network requests (like sending data to a server)
const response = await fetch('/guess', {
method: 'POST', // We are sending data, so it's a POST request
headers: {
'Content-Type': 'application/json' // Tell the server we're sending JSON data
},
body: JSON.stringify({ guess: userGuess }) // Convert our JavaScript object to a JSON string
});
// Check if the response was successful
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Something went wrong on the server.');
}
// Parse the JSON response from the server
// await response.json(): Reads the response body and parses it as JSON
const data = await response.json();
// Update the message paragraph with the response from the server
messageParagraph.textContent = data.message;
// Add specific classes for styling based on the message
if (data.message.includes("Congratulations")) {
messageParagraph.classList.add('correct');
} else {
messageParagraph.classList.add('hint');
}
} catch (error) {
console.error('Error:', error);
messageParagraph.textContent = `An error occurred: ${error.message}`;
messageParagraph.classList.add('error');
}
// Clear the input field after submitting
guessInput.value = '';
}
Explanation:
* document.getElementById(): This is how JavaScript selects specific HTML elements using their id attribute.
* addEventListener('click', handleGuess): This line “listens” for a click event on the submit button. When a click happens, it executes the handleGuess function.
* async function handleGuess(): The async keyword allows us to use await inside the function, which is useful for waiting for network requests to complete.
* parseInt(guessInput.value): Gets the text from the input field and converts it into a whole number.
* fetch('/guess', { ... }): This is the core of our interaction! The fetch API sends an HTTP request to our Flask backend at the /guess route.
* method: 'POST': Specifies that we are sending data.
* headers: { 'Content-Type': 'application/json' }: Tells the server that the body of our request contains JSON data.
* body: JSON.stringify({ guess: userGuess }): Converts our JavaScript object { guess: userGuess } into a JSON string, which is then sent as the body of the request.
* const data = await response.json(): Once the Flask backend responds, this line parses the JSON response back into a JavaScript object.
* messageParagraph.textContent = data.message;: We take the message from the Flask response and display it in our HTML paragraph.
* classList.add('correct') etc.: These lines dynamically add CSS classes to the message paragraph, allowing us to style “correct” or “error” messages differently.
static/style.css – Making it Pretty (Optional)
You can add some basic styling to make your game look nicer. Create style.css inside the static folder.
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #f4f4f4;
color: #333;
}
.game-container {
background-color: #fff;
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
text-align: center;
max-width: 400px;
width: 90%;
}
h1 {
color: #007bff;
margin-bottom: 20px;
}
input[type="number"] {
width: calc(100% - 20px);
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
}
button {
background-color: #28a745;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #218838;
}
.game-message {
margin-top: 20px;
font-size: 1.1em;
font-weight: bold;
}
.game-message.correct {
color: #28a745; /* Green for correct guess */
}
.game-message.hint {
color: #007bff; /* Blue for too high/low */
}
.game-message.error {
color: #dc3545; /* Red for errors */
}
Putting It All Together & Running Your Game
You’ve built all the pieces! Now, let’s run our application.
- Open your terminal or command prompt.
- Navigate to your
guess_the_number_gamefolder using thecdcommand:
bash
cd guess_the_number_game - Run your Flask application:
bash
python app.py
You should see output similar to this, indicating your Flask app is running:
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: XXX-XXX-XXX
Secret number is: 42 # (Your secret number will be different each time)
Now, open your web browser and go to http://127.0.0.1:5000/ (or http://localhost:5000/).
You should see your “Guess The Number!” game. Try entering numbers and clicking “Guess.” Watch how the message changes instantly without the entire page reloading – that’s Flask and JavaScript working together!
Next Steps & Ideas
This is just a starting point! You can enhance your game in many ways:
- Add a “New Game” button: Implement a button that resets the
SECRET_NUMBERon the server and clears the messages on the client. - Track guesses: Keep a count of how many guesses the user has made.
- Difficulty levels: Allow users to choose a range for the secret number (e.g., 1-10, 1-1000).
- Visual feedback: Use CSS animations or different styling to make the feedback more engaging.
- Leaderboard: Store high scores or fastest guessers using a simple database.
Conclusion
Congratulations! You’ve successfully built an interactive “Guess the Number” game using Flask for the backend logic and JavaScript for the frontend interactivity. You’ve learned how Flask serves HTML pages, handles requests, and sends JSON responses, and how JavaScript makes those pages dynamic by sending data to the server and updating the UI without a full page reload.
This project demonstrates a fundamental pattern in web development: how a backend server and a frontend client communicate to create a rich user experience. Keep experimenting, and don’t be afraid to try out new features!
Leave a Reply
You must be logged in to post a comment.