Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 81 additions & 49 deletions script.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const defaultWords = [
'DEVOPS', 'AGILE', 'VERSION', 'BRANCH', 'GITHUB',
'DEVOPS', 'AGILE', 'VERSION', 'BRANCH', 'GITHUB',
'CHANGES', 'FEATURES', 'HOTFIX', 'CONTINUOUS', 'INTEGRATION',
'DEPLOYMENT', 'TESTING', 'COMMIT', 'SNAPSHOT', 'CULTURE',
'PIPELINE', 'DOCKER', 'SCRUM', 'KANBAN', 'MERGE'
Expand All @@ -10,6 +10,7 @@ let gameState = {
player2: { name: '', score: 0 },
currentPlayer: 1,
currentWord: '',
lastWord: '', // ✅ add this
guessedLetters: [],
wrongGuesses: 0,
maxWrong: 6,
Expand All @@ -19,14 +20,14 @@ let gameState = {

let wordBank = [];

document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('DOMContentLoaded', function () {
loadWordBank();
generateKeyboard();
});

function toggleTheme() {
const themeIcon = document.querySelector('.theme-icon');

if (themeIcon.textContent === '🌙') {
themeIcon.textContent = '☀️';
} else {
Expand All @@ -37,10 +38,10 @@ function toggleTheme() {
function switchTab(tabName) {
const tabs = document.querySelectorAll('.tab-content');
tabs.forEach(tab => tab.classList.remove('active'));

const tabButtons = document.querySelectorAll('.tab');
tabButtons.forEach(btn => btn.classList.remove('active'));

document.getElementById(tabName).classList.add('active');
event.target.classList.add('active');
}
Expand All @@ -63,9 +64,9 @@ function saveWordBank() {
function displayWordBank() {
const wordList = document.getElementById('wordList');
const wordCount = document.getElementById('wordCount');

wordCount.textContent = wordBank.length;

if (wordBank.length === 0) {
wordList.innerHTML = `
<div class="empty-state">
Expand All @@ -75,7 +76,7 @@ function displayWordBank() {
`;
return;
}

wordList.innerHTML = '';
wordBank.forEach((word, index) => {
const wordItem = document.createElement('div');
Expand Down Expand Up @@ -120,7 +121,7 @@ function deleteWord(index) {
function generateKeyboard() {
const keyboard = document.getElementById('keyboard');
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

keyboard.innerHTML = '';
for (let letter of letters) {
const button = document.createElement('button');
Expand All @@ -131,35 +132,66 @@ function generateKeyboard() {
keyboard.appendChild(button);
}
}

function startGame() {
const p1Name = document.getElementById('player1Name').value.trim();
const p2Name = document.getElementById('player2Name').value.trim();

gameState.player1.name = p1Name || 'Player 1';
gameState.player2.name = p2Name || 'Player 2';

document.getElementById('player1Display').textContent = gameState.player1.name;
document.getElementById('player2Display').textContent = gameState.player2.name;

const p1Input = document.getElementById('player1Name');
const p2Input = document.getElementById('player2Name');

const p1Name = p1Input.value.trim();
const p2Name = p2Input.value.trim();

const nameRegex = /^[A-Za-z]{2,}$/; // letters only, min 2 chars

// Validate Player 1
if (!nameRegex.test(p1Name)) {
alert('Player 1 name must contain only letters and be at least 2 characters long.');
p1Input.focus();
return;
}

// Validate Player 2
if (!nameRegex.test(p2Name)) {
alert('Player 2 name must contain only letters and be at least 2 characters long.');
p2Input.focus();
return;
}

// If valid, set names
gameState.player1.name = p1Name;
gameState.player2.name = p2Name;

document.getElementById('player1Display').textContent = p1Name;
document.getElementById('player2Display').textContent = p2Name;

document.getElementById('gameArea').style.display = 'block';

nextRound();
}


function nextRound() {
if (wordBank.length === 0) {
alert('No words in the word bank! Add some words first.');
return;
}

gameState.guessedLetters = [];
gameState.wrongGuesses = 0;
gameState.gameActive = true;

const randomIndex = Math.floor(Math.random() * wordBank.length);
gameState.currentWord = wordBank[randomIndex];


let newWord;

if (wordBank.length === 1) {
newWord = wordBank[0]; // Only one word available
} else {
do {
const randomIndex = Math.floor(Math.random() * wordBank.length);
newWord = wordBank[randomIndex];
} while (newWord === gameState.lastWord);
}

gameState.currentWord = newWord;
gameState.lastWord = newWord;

document.getElementById('gameStatus').classList.remove('show');
document.getElementById('gameStatus').className = 'game-status';
resetHangman();
Expand All @@ -172,18 +204,18 @@ function nextRound() {

function guessLetter(letter) {
if (!gameState.gameActive) return;

if (gameState.guessedLetters.includes(letter)) {
return;
}

gameState.guessedLetters.push(letter);

if (!gameState.currentWord.includes(letter)) {
gameState.wrongGuesses++;
updateHangman();
}

updateWordDisplay();
updateWrongLetters();
updateLives();
Expand All @@ -193,24 +225,24 @@ function guessLetter(letter) {
function updateWordDisplay() {
const display = document.getElementById('wordDisplay');
let displayText = '';

for (let letter of gameState.currentWord) {
if (gameState.guessedLetters.includes(letter)) {
displayText += letter + ' ';
} else {
displayText += '_ ';
}
}

display.textContent = displayText.trim();
}

function updateWrongLetters() {
const wrongLettersDiv = document.getElementById('wrongLetters');
const wrong = gameState.guessedLetters.filter(letter =>
const wrong = gameState.guessedLetters.filter(letter =>
!gameState.currentWord.includes(letter)
);

if (wrong.length === 0) {
wrongLettersDiv.textContent = 'None yet';
} else {
Expand All @@ -219,16 +251,16 @@ function updateWrongLetters() {
}

function updateLives() {
const livesLeft = gameState.maxWrong - gameState.wrongGuesses + 1;
const livesLeft = gameState.maxWrong - gameState.wrongGuesses;
document.getElementById('livesLeft').textContent = livesLeft;
}

function updateHangman() {
const parts = ['head', 'body', 'leftArm', 'rightArm', 'leftLeg', 'rightLeg'];

const wrongOrder = ['head', 'leftArm', 'rightArm', 'body', 'leftLeg', 'rightLeg'];
const partIndex = gameState.wrongGuesses - 1;

if (partIndex >= 0 && partIndex < wrongOrder.length) {
const partToShow = wrongOrder[partIndex];
document.getElementById(partToShow).style.display = 'block';
Expand All @@ -255,7 +287,7 @@ function resetKeyboard() {
function updateCurrentPlayer() {
const player1Div = document.getElementById('player1Score');
const player2Div = document.getElementById('player2Score');

if (gameState.currentPlayer === 1) {
player1Div.classList.add('active');
player2Div.classList.remove('active');
Expand All @@ -269,12 +301,12 @@ function checkGameStatus() {
const allLettersGuessed = [...gameState.currentWord].every(letter =>
gameState.guessedLetters.includes(letter)
);

if (allLettersGuessed) {
gameWon();
return;
}

if (gameState.wrongGuesses >= gameState.maxWrong) {
gameLost();
return;
Expand All @@ -283,36 +315,36 @@ function checkGameStatus() {

function gameWon() {
gameState.gameActive = false;

if (gameState.currentPlayer === 1) {
gameState.player2.score += 10;
document.getElementById('score2').textContent = gameState.player2.score;
} else {
gameState.player1.score += 10;
document.getElementById('score1').textContent = gameState.player1.score;
}

const statusDiv = document.getElementById('gameStatus');
const statusMsg = document.getElementById('statusMessage');
const winnerName = gameState.currentPlayer === 1 ?

const winnerName = gameState.currentPlayer === 1 ?
gameState.player2.name : gameState.player1.name;

statusMsg.textContent = `🎉 ${winnerName} won! The word was: ${gameState.currentWord}`;
statusDiv.classList.add('show', 'winner');
}

function gameLost() {
gameState.gameActive = false;

const statusDiv = document.getElementById('gameStatus');
const statusMsg = document.getElementById('statusMessage');
const currentPlayerName = gameState.currentPlayer === 1 ?

const currentPlayerName = gameState.currentPlayer === 1 ?
gameState.player1.name : gameState.player2.name;

statusMsg.textContent = `😢 ${currentPlayerName} lost! The word was: ${gameState.currentWord}`;
statusDiv.classList.add('show', 'loser');

gameState.currentPlayer = gameState.currentPlayer === 1 ? 2 : 1;
}