|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Git Terminology Matching Game</title> |
|
<style> |
|
body { |
|
font-family: Arial, sans-serif; |
|
line-height: 1.6; |
|
color: #333; |
|
max-width: 1000px; |
|
margin: 0 auto; |
|
padding: 20px; |
|
} |
|
h1 { |
|
color: #0078D4; |
|
} |
|
#score { |
|
font-size: 18px; |
|
font-weight: bold; |
|
margin-bottom: 20px; |
|
} |
|
.game-container { |
|
display: flex; |
|
justify-content: space-between; |
|
} |
|
.column { |
|
padding: 10px; |
|
} |
|
#elements { |
|
width: 30%; |
|
} |
|
#descriptions { |
|
width: 65%; |
|
} |
|
.item { |
|
background-color: #f0f0f0; |
|
border: 1px solid #ddd; |
|
padding: 10px; |
|
margin-bottom: 10px; |
|
cursor: pointer; |
|
border-radius: 4px; |
|
transition: background-color 0.3s ease; |
|
} |
|
.item:hover { |
|
background-color: #e0e0e0; |
|
} |
|
.item.selected { |
|
background-color: #0078D4; |
|
color: white; |
|
} |
|
.item.correct { |
|
background-color: #107C10; |
|
color: white; |
|
} |
|
.item.incorrect { |
|
background-color: #D83B01; |
|
color: white; |
|
} |
|
#result { |
|
margin-top: 20px; |
|
font-weight: bold; |
|
} |
|
button { |
|
background-color: #0078D4; |
|
color: white; |
|
border: none; |
|
padding: 10px 20px; |
|
cursor: pointer; |
|
font-size: 16px; |
|
margin-top: 20px; |
|
margin-right: 10px; |
|
border-radius: 4px; |
|
transition: background-color 0.3s ease; |
|
} |
|
button:hover { |
|
background-color: #106EBE; |
|
} |
|
.modal { |
|
display: none; |
|
position: fixed; |
|
z-index: 1; |
|
left: 0; |
|
top: 0; |
|
width: 100%; |
|
height: 100%; |
|
overflow: auto; |
|
background-color: rgba(0,0,0,0.4); |
|
} |
|
.modal-content { |
|
background-color: #fefefe; |
|
margin: 15% auto; |
|
padding: 20px; |
|
border: 1px solid #888; |
|
width: 80%; |
|
max-width: 800px; |
|
border-radius: 8px; |
|
} |
|
.close { |
|
color: #aaa; |
|
float: right; |
|
font-size: 28px; |
|
font-weight: bold; |
|
cursor: pointer; |
|
} |
|
.close:hover, |
|
.close:focus { |
|
color: black; |
|
text-decoration: none; |
|
cursor: pointer; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<h1>Git Terminology Matching Game</h1> |
|
<div id="score">Score: 0 / 15</div> |
|
<p>Match the Git terms with their descriptions. Click on an item from each column to make a match.</p> |
|
<div class="game-container"> |
|
<div class="column" id="elements"></div> |
|
<div class="column" id="descriptions"></div> |
|
</div> |
|
<div id="result"></div> |
|
<button id="replay">Replay Game</button> |
|
<button id="showSolution">Show Solution</button> |
|
|
|
<div id="solutionModal" class="modal"> |
|
<div class="modal-content"> |
|
<span class="close">×</span> |
|
<h2>Solution</h2> |
|
<div id="solutionContent"></div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
const gameData = [ |
|
{ element: "Working Tree", description: "A directory structure that contains all of the project's files." }, |
|
{ element: "Repository (Repo)", description: "The directory located at the top level of a working tree, hosting all of the project's files along with their version history." }, |
|
{ element: "Clone", description: "The action of creating a copy of a remote repository on a local machine to work on a project to which you have access." }, |
|
{ element: "Fork", description: "The action of creating a GitHub-hosted copy of a remote repository to work on a project to which you don't have access." }, |
|
{ element: "Commit", description: "A snapshot of the changes made to the files in a repository at a specific point in time." }, |
|
{ element: "Staging Area", description: "An intermediate location where changes to files in the working tree are prepared before being committed." }, |
|
{ element: "Branch", description: "A named series of linked commits representing a distinct version of a project." }, |
|
{ element: "Merge", description: "The process of combining changes from one branch (or commit) into another." }, |
|
{ element: "Object", description: "One of four types of entities in a repo: blobs, trees, commits, and tags." }, |
|
{ element: "Hash", description: "A unique, fixed-length identifier representing the contents of an object." }, |
|
{ element: "Remote", description: "A reference to another repository, typically pointing to a service-hosted instance of the repo." }, |
|
{ element: "Pull", description: "The action that fetches changes from a remote repository and merges them into the current branch." }, |
|
{ element: "Push", description: "The action that sends local commits to a remote repository, updating it with local changes." }, |
|
{ element: "Fetch", description: "The action that retrieves changes from a remote repository without automatically merging them." }, |
|
{ element: "Pull Request", description: "A feature in Git-based hosting platforms allowing developers to propose changes to be merged into a target branch." } |
|
]; |
|
let selectedElement = null; |
|
let selectedDescription = null; |
|
let correctMatches = 0; |
|
function shuffleArray(array) { |
|
for (let i = array.length - 1; i > 0; i--) { |
|
const j = Math.floor(Math.random() * (i + 1)); |
|
[array[i], array[j]] = [array[j], array[i]]; |
|
} |
|
} |
|
function createGameBoard() { |
|
const elementsContainer = document.getElementById('elements'); |
|
const descriptionsContainer = document.getElementById('descriptions'); |
|
elementsContainer.innerHTML = ''; |
|
descriptionsContainer.innerHTML = ''; |
|
const shuffledElements = [...gameData]; |
|
const shuffledDescriptions = [...gameData]; |
|
shuffleArray(shuffledElements); |
|
shuffleArray(shuffledDescriptions); |
|
shuffledElements.forEach((item, index) => { |
|
const elementDiv = document.createElement('div'); |
|
elementDiv.className = 'item'; |
|
elementDiv.textContent = item.element; |
|
elementDiv.dataset.index = index; |
|
elementDiv.onclick = () => selectItem(elementDiv, 'element'); |
|
elementsContainer.appendChild(elementDiv); |
|
}); |
|
shuffledDescriptions.forEach((item, index) => { |
|
const descriptionDiv = document.createElement('div'); |
|
descriptionDiv.className = 'item'; |
|
descriptionDiv.textContent = item.description; |
|
descriptionDiv.dataset.index = index; |
|
descriptionDiv.onclick = () => selectItem(descriptionDiv, 'description'); |
|
descriptionsContainer.appendChild(descriptionDiv); |
|
}); |
|
} |
|
function selectItem(item, type) { |
|
if (type === 'element') { |
|
if (selectedElement && selectedElement.classList) { |
|
selectedElement.classList.remove('selected'); |
|
} |
|
selectedElement = item; |
|
} else { |
|
if (selectedDescription && selectedDescription.classList) { |
|
selectedDescription.classList.remove('selected'); |
|
} |
|
selectedDescription = item; |
|
} |
|
item.classList.add('selected'); |
|
if (selectedElement && selectedDescription) { |
|
checkMatch(); |
|
} |
|
} |
|
function checkMatch() { |
|
const elementIndex = gameData.findIndex(item => item.element === selectedElement.textContent); |
|
const descriptionIndex = gameData.findIndex(item => item.description === selectedDescription.textContent); |
|
if (elementIndex === descriptionIndex) { |
|
selectedElement.classList.add('correct'); |
|
selectedDescription.classList.add('correct'); |
|
correctMatches++; |
|
updateScore(); |
|
if (correctMatches === gameData.length) { |
|
document.getElementById('result').textContent = 'Congratulations! You\'ve matched all items correctly!'; |
|
} |
|
} else { |
|
selectedElement.classList.add('incorrect'); |
|
selectedDescription.classList.add('incorrect'); |
|
setTimeout(() => { |
|
if (selectedElement && selectedElement.classList) { |
|
selectedElement.classList.remove('incorrect'); |
|
} |
|
if (selectedDescription && selectedDescription.classList) { |
|
selectedDescription.classList.remove('incorrect'); |
|
} |
|
}, 1000); |
|
} |
|
if (selectedElement && selectedElement.classList) { |
|
selectedElement.classList.remove('selected'); |
|
} |
|
if (selectedDescription && selectedDescription.classList) { |
|
selectedDescription.classList.remove('selected'); |
|
} |
|
selectedElement = null; |
|
selectedDescription = null; |
|
} |
|
function updateScore() { |
|
document.getElementById('score').textContent = `Score: ${correctMatches} / ${gameData.length}`; |
|
} |
|
function replayGame() { |
|
correctMatches = 0; |
|
selectedElement = null; |
|
selectedDescription = null; |
|
createGameBoard(); |
|
updateScore(); |
|
document.getElementById('result').textContent = ''; |
|
} |
|
function showSolution() { |
|
const modal = document.getElementById('solutionModal'); |
|
const solutionContent = document.getElementById('solutionContent'); |
|
solutionContent.innerHTML = ''; |
|
gameData.forEach(item => { |
|
solutionContent.innerHTML += `<p><strong>${item.element}:</strong> ${item.description}</p>`; |
|
}); |
|
modal.style.display = 'block'; |
|
} |
|
document.getElementById('replay').onclick = replayGame; |
|
document.getElementById('showSolution').onclick = showSolution; |
|
document.querySelector('.close').onclick = function() { |
|
document.getElementById('solutionModal').style.display = 'none'; |
|
} |
|
window.onclick = function(event) { |
|
if (event.target == document.getElementById('solutionModal')) { |
|
document.getElementById('solutionModal').style.display = 'none'; |
|
} |
|
} |
|
createGameBoard(); |
|
updateScore(); |
|
</script> |
|
</body> |
|
</html> |
|
|