Deadline: 11th of Ordibehesht - 23:59 o'clock
Welcome to your BONUS project on implementing the Pig Game! This document outlines the core objectives of the project, providing you with essential information and guidelines to help you successfully complete the game's functionality using JavaScript. Before diving into the development aspects, let's understand the game itself.
Pig Game is a popular dice game involving rounds of rolling dice to accumulate points, with the risk of losing all points in a round if a player rolls a 1. Here’s a brief overview:
- Gameplay: Players take turns to roll a single dice as many times as they wish, accumulating points. However, if a player rolls a 1, their turn ends, and they lose all points accumulated in that turn.
- Winning: The first player to reach 100 points or more across all turns wins the game.
Welcome to the JavaScript implementation phase of the Pig Game! This section outlines the specific tasks and objectives you must achieve to make the provided HTML and CSS functional. Follow these steps carefully to ensure your game behaves as expected.
Your main goal is to develop the JavaScript functionality that allows two players to play the Pig game. This includes handling dice rolls, updating scores, managing game state changes, and initializing the game correctly.
- Objective: Set up the initial game state when the page loads or when the "New Game" button is pressed.
- Tasks:
- Reset all scores to 0 and set the initial player (First Player) as active.
- Ensure the dice image is hidden, at the beginning of the game. (You can add a "hidden" class to its classList)
- Update the UI to reflect these initial states using DOM manipulation.
- Objective: Implement the dice roll functionality when the "Roll Dice" button is clicked.
- Tasks:
- Generate a random number between 1 and 6 to simulate a dice roll.
- Update the dice image to match the roll result.
- If the dice roll is 1:
- Reset the current score of the active player to 0.
- Switch to the other player.
- If the dice roll is anything other than 1:
- Add the roll value to the active player's current score.
- Update the current score display in the UI.
- Objective: Allow players to "hold" their current score, which adds it to their total and switches the turn.
- Tasks:
- Add the current score to the active player's total score.
- Update the total score display on the UI.
- Reset the current score of the active player to 0.
- Switch the active player and update the UI to reflect this change.
- Objective: Define what happens when a player reaches the winning score (typically 100 points).
- Tasks:
- Check the player's total score after the "hold" action to see if it reaches or exceeds 100.
- If a player wins:
- Display a celebration icon (🎉) in place of their current score.
- Change the background color of the page to #E64980.
- Disable the "Roll Dice" and "Hold" buttons to prevent further play.
- Allow only the "New Game" button to function to restart the game.
- Objective: Ensure the "New Game" button resets the game entirely.
- Tasks:
- Call the initial game setup function to reset all scores, player states, and UI elements like the dice image and background color.
- Objective: Verify that all functionalities work seamlessly and handle all edge cases.
- Tasks:
- Test each functionality individually and in sequence.
- Check responsiveness of the UI to game state changes.
- Use console logs to debug and ensure that score calculations and player switches are handled correctly.
- Code Modularity: Keep your functions small and focused. Each function should perform one task.
- Use Comments: Comment your code to explain why you are doing something, not what you are doing.
- Consistent Naming Convention: Use clear and descriptive names for variables and functions to make your code readable and maintainable.
In this section, we explore the foundational elements of JavaScript crucial for building interactive games and applications like the Pig game. Understanding these basics will enable you to write more effective and error-free code.
What is Strict Mode?
Strict Mode is a feature in JavaScript that makes your code more robust by enabling a stricter set of rules. Activating Strict Mode helps in catching common coding bloopers, preventing potentially problematic actions, and alerting developers by throwing errors.
Why Use Strict Mode?
- Catches Common Errors: Helps in identifying typos in variable names, unsafe actions, etc.
- Prevents Bad Syntax: Stops you from using parts of JavaScript that are not advisable or that are obsolete.
- Secures JavaScript: It provides a layer of security by correcting mistakes that make it difficult for JavaScript engines to perform optimizations.
How to Enable Strict Mode?
To enable Strict Mode, add the string 'use strict';
at the beginning of your JavaScript files or functions. This tells the JavaScript engine to evaluate the code more rigorously.
Understanding Variables
Variables are fundamental in any programming language. They are used to store data values. In JavaScript, variables can be declared using let
, const
, or var
(though var
is mostly historical and its use is generally discouraged in modern JavaScript practices).
let
vs. const
let
: Allows you to declare variables that can be changed later. Uselet
when you expect the variable to be reassigned later in your program.const
: Allows you to declare variables with a constant value, meaning the value assigned toconst
cannot be changed (though objects and arrays defined withconst
can still be mutated).
Examples
let playerName = "John";
const maxScore = 100;
playerName = "Doe"; // This is allowed
maxScore = 200; // This will throw an error because const values cannot be reassigned
Best Practices
- Prefer
const
by default; only uselet
if you know the variable's value will change. - Avoid
var
to reduce scope-related issues.
In this section, we explore functions in JavaScript, which are essential for structuring and organizing code, especially when building interactive applications like the Pig game. Understanding functions allows you to create reusable code and implement game logic effectively.
What is a Function?
A function in JavaScript is a reusable block of code designed to perform a particular task. Functions are executed when they are called or invoked. This is useful in games for tasks that need to be repeated with slight variations.
Why Use Functions?
- Code Reusability: Write code once, use it multiple times.
- Modularity: Break down complex problems into smaller, manageable tasks.
- Maintainability: Easier to debug and update individual sections of the code.
Function Declaration
A function declaration defines a function without running it. It's one of the ways to create a function. Here's the basic syntax:
function myFunction() {
// Code to execute
}
Function Expression
Alternatively, you can define a function using a function expression, which allows you to create anonymous functions (functions without a name).
const myFunction = function () {
// Code to execute
};
Parameters vs. Arguments
- Parameters: Variables listed as part of the function's definition.
- Arguments: Values passed to the function when it is invoked.
Example
function addNumbers(a, b) {
return a + b;
}
const sum = addNumbers(5, 3); // 5 and 3 are arguments
Default Parameters
You can also set default values for parameters that are used if no argument is passed during the function call.
function greet(name = "Guest") {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // Output: Hello, Alice!
console.log(greet()); // Output: Hello, Guest!
What is a Return Statement?
The return statement ends function execution and specifies a value to be returned to the function caller.
Why Use Return Statements?
- To output a result from a function.
- To stop the execution of a function at a specific point and send the control back to the place it was called.
Example
function multiply(x, y) {
return x * y; // Returns the product of x and y
}
const result = multiply(4, 3); // result is 12
No Return Statement
If no return statement is used, the function returns undefined
by default.
- Naming: Use clear, descriptive names for functions.
- Single Responsibility: Each function should perform one task or function.
- Commenting: Use comments to describe what the function does, especially if the logic is complex.
Control structures are fundamental in programming, allowing you to dictate the flow of control through your code. In this section, we'll explore how to use conditional statements and logical operators in JavaScript to implement game logic effectively.
What are Conditional Statements?
Conditional statements execute different parts of code based on whether a specified condition is true or false. They are crucial for decision-making in programming.
Types of Conditional Statements
if
Statement: Executes a block of code if a specified condition is true.else
Statement: Executes a block of code if the associatedif
condition is false.else if
Statement: Specifies a new condition to test if the first condition is false.
Syntax and Example
if (condition1) {
// Code to execute if condition1 is true
} else if (condition2) {
// Code to execute if condition1 is false and condition2 is true
} else {
// Code to execute if both condition1 and condition2 are false
}
Practical Use Case
Imagine checking if a player has enough points to win a game:
let score = 95;
if (score >= 100) {
console.log("You won!");
} else {
console.log("Keep trying, you need more points to win!");
}
What are Logical Operators?
Logical operators are used to combine multiple conditions. They are essential for creating complex logical expressions.
Common Logical Operators
- AND (
&&
): Returns true if both operands are true. - OR (
||
): Returns true if at least one operand is true. - NOT (
!
): Returns true if the operand is false (and vice versa).
Example
let score = 120;
let timeLeft = 5;
if (score >= 100 && timeLeft > 0) {
console.log("You won!");
} else {
console.log("Game over!");
}
In this example, the player wins only if they have scored 100 points or more and there is still time left.
Alternative to Multiple if
Statements
The switch
statement is used for performing different actions based on different conditions. It's particularly useful when comparing the same variable to different values.
Syntax and Example
let fruit = "apple";
switch (fruit) {
case "apple":
console.log("Apples are $0.65 per pound.");
break;
case "banana":
console.log("Bananas are $0.35 per pound.");
break;
default:
console.log("Sorry, we are out of " + fruit + ".");
}
- Clear Conditions: Write conditions that are simple and clear to understand.
- Limit Logical Complexity: Avoid overly complex expressions in if conditions.
- Use
switch
Sparingly: Whileswitch
is useful, it can lead to harder-to-maintain code if overused, especially with large sets of conditions.
DOM manipulation is a critical skill for any web developer. It allows you to interact with and change the content and structure of a webpage dynamically. In this section, we will cover how to select elements, manipulate classes, and change attributes and text content in the context of building interactive web applications like the Pig game.
What is DOM Selection?
DOM selection is the process of selecting elements from the HTML document using JavaScript, which then allows you to manipulate those elements.
Methods of Selection
-
By ID:
getElementById()
: Selects an element by its ID. It's a fast and efficient way to access elements if you know their ID.- Example:
let playerScore = document.getElementById('score--1');
-
By Class Name:
getElementsByClassName()
: Selects all elements that have a specified class name. This method returns a live HTMLCollection.- Example:
let buttons = document.getElementsByClassName('btn');
-
Query Selector:
querySelector()
: Uses CSS selectors to select the first matching element. It's very versatile.querySelectorAll()
: Selects all elements that match the CSS selector. It returns a static NodeList.- Examples:
let diceImage = document.querySelector('.dice');
let allPlayers = document.querySelectorAll('.player');
Using classList
The classList
property provides methods to add, remove, and toggle CSS classes on an element.
add()
: Adds a specified class to an element.remove()
: Removes a specified class from an element.toggle()
: Toggles a class on an element (adds it if it doesn't exist, removes it if it does).
Examples
let player = document.querySelector(".player--active");
// Adding an active class
player.classList.add("active");
// Removing an active class
player.classList.remove("active");
// Toggling a class
player.classList.toggle("active");
Changing Text Content
textContent
: Sets or returns the text content of the specified node and all its descendants.- Example:
document.getElementById('score--0').textContent = '50';
Manipulating Attributes
setAttribute()
: Adds a new attribute or changes the value of an existing attribute on the specified element.getAttribute()
: Returns the current value of an attribute on the element.src
Attribute: Commonly used to set the source of an image element.
Examples
// Setting the source of an image
let dice = document.querySelector(".dice");
dice.src = "dice-3.png";
// Changing attributes
dice.setAttribute("alt", "Dice three");
- Minimize DOM Manipulations: Each manipulation can affect performance, so minimize direct DOM manipulation where possible.
- Use IDs for Single Elements: When you need to select a single element, use an ID if possible for faster selection.
- Cache DOM References: Store DOM references in variables if you need to access the same element multiple times.
Event handling is a cornerstone of interactive web development, allowing your applications to respond to user actions such as clicks, keyboard input, and more. This section explains how to implement event handling in JavaScript, which is crucial for creating dynamic behaviors in games like the Pig game.
What is an Event?
An event in JavaScript is any interaction that a user can have with a webpage. Common events include clicks, hovering over elements, pressing keys, and loading pages.
Why Handle Events?
Handling events allows your web applications to be interactive and responsive to user actions, making them more engaging and functional.
What is an Event Listener?
An event listener is a function in JavaScript that will be called whenever the specified event fires on the target element.
Syntax of addEventListener()
element.addEventListener(event, function, useCapture);
- element: The DOM element to listen on.
- event: The name of the event to listen for.
- function: The handler function to run when the event occurs.
- useCapture: Optional boolean value that specifies whether to handle the event in the capturing or in the bubbling phase.
Example
const button = document.querySelector(".btn--roll");
button.addEventListener("click", function () {
console.log("Button was clicked!");
});
What is an Event Handler?
An event handler is a function that is triggered when the event it listens to occurs. This function can perform any number of actions, from updating HTML content to modifying CSS styles or triggering other events.
Example of an Event Handler
function rollDice() {
// Simulate rolling a dice
const diceValue = Math.floor(Math.random() * 6) + 1;
console.log(`You rolled a ${diceValue}!`);
}
Using the Event Handler
button.addEventListener("click", rollDice);
What is the Event Object?
The event object is a parameter that is automatically passed to event handlers by the browser. It contains properties and methods related to the event, such as the type of event, the target element, and more.
Using the Event Object
button.addEventListener("click", function (event) {
console.log(event.type); // Logs 'click'
});
Although not as commonly required in simple games, knowing how to remove event listeners is important for avoiding memory leaks in larger applications.
Syntax
element.removeEventListener(event, handler);
Example
button.removeEventListener("click", rollDice);
- Don’t Overuse Inline Event Handlers: Inline event handlers (e.g.,
<button onclick="alert('Clicked!')">Click me!</button>
) are harder to maintain and debug compared toaddEventListener
. - Use Named Functions for Clarity: Named functions make your code more readable and easier to debug than anonymous functions in your event listeners.
- Debounce and Throttle: Use debouncing and throttling techniques to limit the rate at which a function is executed, particularly useful in handling events like resizing or scrolling.
In the final section of our JavaScript fundamentals course for the Pig game, we delve into some debugging techniques that enhance debugging, dynamic styling, and efficient gameplay logic. These skills are essential for creating robust, maintainable, and dynamic web applications.
What is Console Logging?
Logging is a debugging method that outputs messages or variables to the console, providing insight into the code's behavior at runtime.
Using console.log()
- Purpose: Primarily used for general debugging and information logging.
- Example:
console.log("This is a log message.");
Using console.error()
- Purpose: Specifically used for logging error messages, making them easily distinguishable in the console.
- Example:
console.error("This is an error message.");
Dynamic Styling
Changing styles through JavaScript allows for interactive and responsive design changes based on user interactions or other conditions.
Modifying Styles
- Syntax:
element.style.property = 'value';
- Example:
document.body.style.backgroundColor = "#ff0000"; // Changes background color to red
Adding and Removing Background Images
- Setting a Background Image:
document.body.style.backgroundImage = 'url("background.jpg")';
- Removing a Background Image:
document.body.style.backgroundImage = "none";
Using the Modulo Operator for Toggling
The modulo operator (%
) is useful for toggling between values within a range, particularly common in games for switching turns.
- Example:
let currentPlayer = 1; currentPlayer = (currentPlayer + 1) % 2; // Toggles between 0 and 1
This method is efficient for cycling through a series of values without needing conditional statements.
Scope and Usage of Global Variables
Global variables are accessible from anywhere in your JavaScript code. While they can be very useful, especially in shared game states, they should be used sparingly due to potential conflicts and debugging complexity.
Defining Global Variables
- Declare outside any function to make them accessible universally.
- Example:
let gameActive = true;
Best Practices for Global Variables
- Minimize Use: Try to keep global variables to a minimum. Use local variables or function parameters where possible.
- Naming Convention: Use clear, descriptive names to avoid conflicts and enhance readability.
For your assignment, please replace only the JavaScript code with your own implementation based on the guidelines provided. Once you have completed your version, submit your results on your course page for evaluation. Make sure your implementation adheres to the project requirements and functions as expected. Good luck!
Best Regards, Hamidi