diff --git a/Games/Single_Player_Solitaire/README.md b/Games/Single_Player_Solitaire/README.md new file mode 100644 index 0000000000..6b6df37e7c --- /dev/null +++ b/Games/Single_Player_Solitaire/README.md @@ -0,0 +1,98 @@ +Hii!! This is a small single player solitaire game +The goal of the single-player card game is to get rid of your cards and build the deck into a sequence and by suit from ace through king. The game is won when the whole deck of cards is built into the foundation. +# What is Foundation? +The piles of the sequence the player is trying to build from the tableau, beginning with the King. The aces will go at the bottom of the foundation. +# The scoring System!! +Though not all players are in it to earn the most possible points, there is a definitive scoring system in Solitaire. +What are we offerring you as score? +So, till now ther's no scoring system, just the piles and you need to stack up the cards from Ace to King + +--------------------------------------------------------------------------------------------------------------------------- +There are total 52 cards in the game of Solitaire +13 of Clubs (Black) 3 face cards(King, Queen, Jack) and others forom Ace to 10 (1,2,3,4,5,6,7,8,9,10) +13 of Spades (Black) 3 face cards(King, Queen, Jack) and others forom Ace to 10 (1,2,3,4,5,6,7,8,9,10) +13 of Hearts (Red) 3 face cards(King, Queen, Jack) and others forom Ace to 10 (1,2,3,4,5,6,7,8,9,10) +13 of Diamonds (Red) 3 face cards(King, Queen, Jack) and others forom Ace to 10 (1,2,3,4,5,6,7,8,9,10) + +--------------------------------------------------------------------------------------------------------------------------- + So Once Again, I welcome you ^_^ + + Welcome to the Solitaire Game! This is a classic solitaire game implemented using HTML, CSS, and JavaScript. The game includes features such as a "Hint" button and a "New Game" button, and the win condition is met when any one foundation pile is completed from Ace to King. + +## Table of Contents + +-- [Description](#description) +- [Features](#features) +- [Technologies Used](#technologies-used) +- [Getting Started](#getting-started) + - [Prerequisites](#prerequisites) + - [Installation](#installation) +- [Gameplay](#gameplay) + - [Objective](#objective) + - [Controls](#controls) +- [Project Structure](#project-structure) +- [Contributing](#contributing) + + +## Features +- **New Game Button**: Start a new game at any time. +- **Hint Button**: Get a hint for a possible move. +- **Win Condition**: The game is won if any one foundation pile is completed from Ace to King. +- **Interactive UI**: Click and drag to move cards. + +## Technologies Used +- HTML +- CSS +- JavaScript + +## Getting Started + +### Prerequisites +- A modern web browser (Chrome, Firefox, Safari, etc.) + +### Installation + +To run the game locally, follow these steps: + +1. Clone the repository: + ```bash + git clone https://github.com/your-username/solitaire-game.git + ``` +2. Navigate to the project directory: + ```bash + cd solitaire-game + ``` + +## Usage + +Open the `newindex.html` file in your preferred web browser to start playing the game. + +## Game Rules + +1. **Objective:** The goal is to move all cards to the foundation piles, each pile from Ace to King of the same suit. +2. **Setup:** The game starts with seven tableau piles. The first pile has one + +# Objective +The goal of solitaire is to move all cards to the foundation piles, sorted by suit in ascending order from Ace to King. + +# Controls +New Game Button: Click to start a new game. +Hint Button: Click to receive a hint for a possible move. +Card Movement: Click and drag to move cards between piles. + +# Project Structure +newindex.html: The main HTML file containing the game layout. +newstyles.css: The CSS file for styling the game. +newscript.js: The JavaScript file containing the game logic. + +# Contributing +Contributions are welcome! Please follow these steps: + +Fork the repository. +Create a new branch (git checkout -b feature-branch). +Make your changes. +Commit your changes (git commit -m 'Add some feature'). +Push to the branch (git push origin feature-branch). +Open a pull request. + +--------------------------------ENJOY---------------------------- \ No newline at end of file diff --git a/Games/Single_Player_Solitaire/index.html b/Games/Single_Player_Solitaire/index.html new file mode 100644 index 0000000000..9ea13d5f0b --- /dev/null +++ b/Games/Single_Player_Solitaire/index.html @@ -0,0 +1,36 @@ + + + + + + Solitaire + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+ + + diff --git a/Games/Single_Player_Solitaire/script.js b/Games/Single_Player_Solitaire/script.js new file mode 100644 index 0000000000..080bceb8e5 --- /dev/null +++ b/Games/Single_Player_Solitaire/script.js @@ -0,0 +1,212 @@ +document.addEventListener('DOMContentLoaded', () => { + // Initialize the game + initGame(); + document.getElementById('hint-button').addEventListener('click', showHint); + document.getElementById('new-game-button').addEventListener('click', newGame); +}); + +function initGame() { + const deck = createDeck(); + shuffleDeck(deck); + dealCards(deck); + document.getElementById('win-message').classList.add('hidden'); +} +function newGame() { + // Reset the game board and start a new game + const tableauPiles = document.querySelectorAll('.tableau-pile'); + tableauPiles.forEach(pile => { + while (pile.firstChild) { + pile.removeChild(pile.firstChild); + } + }); + initGame(); +} +function checkWinCondition() { + const foundations = document.querySelectorAll('.foundation'); + let win = false; + + foundations.forEach(foundation => { + const cards = foundation.querySelectorAll('.card'); + if (cards.length === 13) { + win = true; + } + }); + + if (win) { + document.getElementById('win-message').classList.remove('hidden'); + } +} + +function createDeck() { + const suits = ['hearts', 'diamonds', 'clubs', 'spades']; + const ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']; + const deck = []; + + for (const suit of suits) { + for (const rank of ranks) { + deck.push({ suit, rank }); + } + } + + return deck; +} + +function shuffleDeck(deck) { + for (let i = deck.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [deck[i], deck[j]] = [deck[j], deck[i]]; + } +} + +function dealCards(deck) { + const tableauPiles = document.querySelectorAll('.tableau-pile'); + + tableauPiles.forEach((pile, pileIndex) => { + for (let cardIndex = 0; cardIndex <= pileIndex; cardIndex++) { + const card = deck.pop(); + const cardElement = createCardElement(card); + + if (cardIndex === pileIndex) { + cardElement.classList.add('face-up'); + } else { + cardElement.classList.add('face-down'); + } + + pile.appendChild(cardElement); + } + }); +} + +function createCardElement(card) { + const cardElement = document.createElement('div'); + cardElement.classList.add('card'); + cardElement.classList.add(card.suit === 'hearts' || card.suit === 'diamonds' ? 'red' : 'black'); + cardElement.dataset.suit = card.suit; + cardElement.dataset.rank = card.rank; + + const rankElement = document.createElement('div'); + rankElement.classList.add('rank'); + rankElement.innerText = card.rank; + + const suitElement = document.createElement('div'); + suitElement.classList.add('suit'); + suitElement.innerHTML = getSuitSymbol(card.suit); + + cardElement.appendChild(rankElement); + cardElement.appendChild(suitElement); + + // Make the card draggable + cardElement.draggable = true; + cardElement.addEventListener('dragstart', onDragStart); + cardElement.addEventListener('dragend', onDragEnd); + + return cardElement; +} + +function getSuitSymbol(suit) { + switch (suit) { + case 'hearts': + return '♥'; + case 'diamonds': + return '♦'; + case 'clubs': + return '♣'; + case 'spades': + return '♠'; + } +} + +function onDragStart(event) { + event.dataTransfer.setData('text/plain', event.target.dataset.suit + ' ' + event.target.dataset.rank); + event.target.classList.add('dragging'); +} + +function onDragEnd(event) { + event.target.classList.remove('dragging'); + checkWinCondition(); +} + +// Add drop event listeners to card piles +const cardPiles = document.querySelectorAll('.card-pile'); +cardPiles.forEach(pile => { + pile.addEventListener('dragover', onDragOver); + pile.addEventListener('drop', onDrop); +}); + +function onDragOver(event) { + event.preventDefault(); +} + +function onDrop(event) { + event.preventDefault(); + const data = event.dataTransfer.getData('text/plain'); + const [suit, rank] = data.split(' '); + const card = document.querySelector(`.card[data-suit="${suit}"][data-rank="${rank}"]`); + event.target.appendChild(card); + checkWinCondition(); +} + + + +function showHint() { + const moveableCard = findMoveableCard(); + if (moveableCard) { + highlightCard(moveableCard); + } else { + alert('No hints available!'); + } +} + +function findMoveableCard() { + const tableauPiles = document.querySelectorAll('.tableau-pile'); + for (const pile of tableauPiles) { + const cards = pile.querySelectorAll('.card.face-up'); + if (cards.length > 0) { + const topCard = cards[cards.length - 1]; + if (canMoveCard(topCard)) { + return topCard; + } + } + } + return null; +} + +function canMoveCard(card) { + const suit = card.dataset.suit; + const rank = card.dataset.rank; + const foundations = document.querySelectorAll('.foundation'); + + for (const foundation of foundations) { + const cards = foundation.querySelectorAll('.card'); + if (cards.length === 0 && rank === 'A') { + return true; + } + const topCard = cards[cards.length - 1]; + if (topCard && isNextRank(topCard.dataset.rank, rank) && topCard.dataset.suit === suit) { + return true; + } + } + return false; +} + +function isNextRank(topRank, currentRank) { + const ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']; + return ranks.indexOf(currentRank) === ranks.indexOf(topRank) + 1; +} + +function highlightCard(card) { + card.classList.add('highlight'); + setTimeout(() => { + card.classList.remove('highlight'); + }, 2000); +} + +// Add necessary CSS for highlighting +const style = document.createElement('style'); +style.innerHTML = ` + .highlight { + border: 3px solid yellow; + box-shadow: 0 0 10px yellow; + } +`; +document.head.appendChild(style); \ No newline at end of file diff --git a/Games/Single_Player_Solitaire/styles.css b/Games/Single_Player_Solitaire/styles.css new file mode 100644 index 0000000000..c5daf70c2e --- /dev/null +++ b/Games/Single_Player_Solitaire/styles.css @@ -0,0 +1,163 @@ +body { + font-family: Arial, sans-serif; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + background-color: #2E7D32; +} + +#game-board { + display: grid; + grid-template-areas: + "stock waste . . foundations foundations foundations foundations" + "tableau tableau tableau tableau tableau tableau tableau tableau"; + gap: 10px; + padding: 10px; + background-color: #388E3C; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); + max-width: 90%; +} + +.card-pile { + width: 100px; + height: 140px; + background-color: #4CAF50; + border-radius: 10px; + box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); + position: relative; +} + +#stock { + grid-area: stock; +} + +#waste { + grid-area: waste; +} + +#foundations { + display: flex; + gap: 10px; + grid-area: foundations; +} + +.foundation { + width: 100px; + height: 140px; +} + +#tableau { + display: flex; + gap: 10px; + grid-area: tableau; +} + +.tableau-pile { + flex: 1; + display: flex; + flex-direction: column; + position: relative; +} + +.card { + width: 100px; + height: 140px; + border-radius: 10px; + background-color: white; + border: 2px solid #000; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + user-select: none; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + transition: transform 0.2s, box-shadow 0.2s; + font-family: 'Georgia', serif; + font-weight: bold; + color: #000; + position: absolute; +} + +.card.dragging { + opacity: 0.5; + z-index: 1000; +} + +.card.face-down { + background-color: #4CAF50; + border: 2px solid #388E3C; + box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.5); +} + +.card.face-up { + background-color: white; +} + +.card .rank { + position: absolute; + top: 5px; + left: 5px; + font-size: 18px; +} + +.card .suit { + position: absolute; + bottom: 5px; + right: 5px; + font-size: 24px; +} + +.card.hearts .rank, +.card.hearts .suit { + color: red; +} + +.card.diamonds .rank, +.card.diamonds .suit { + color: red; +} + +.card.clubs .rank, +.card.clubs .suit { + color: black; +} + +.card.spades .rank, +.card.spades .suit { + color: black; +} + +#controls { + margin-top: 20px; + text-align: center; +} + +#new-game-button, +#hint-button { + padding: 10px 20px; + font-size: 16px; + cursor: pointer; + background-color: #abc1ac; + color: white; + border: none; + border-radius: 5px; + transition: background-color 0.3s; +} + +#new-game-button:hover, +#hint-button:hover { + background-color: #bad2bb; +} + +#win-message { + margin-top: 20px; + font-size: 24px; + color: white; +} + +.hidden { + display: none; +} diff --git a/README.md b/README.md index 1d6c8d66eb..9644bfbcec 100644 --- a/README.md +++ b/README.md @@ -289,7 +289,7 @@ This repository also provides one such platforms where contributers come over an | [Physics_Quizz](https://github.com/kunjgit/GameZone/tree/main/Games/Physics_Quizz) | | [Tiny_Fishing](https://github.com/kunjgit/GameZone/tree/main/Games/Tiny_Fishing) | | [IKnowYou-Mind-Reading-Game](https://github.com/kunjgit/GameZone/tree/main/Games/IKnowYou-Mind-Reading-Game) | - +| [Single_Player_Solitaire](https://github.com/kunjgit/GameZone/tree/main/Games/Single_Player_Solitaire) | | [Hover_Board_Effect](https://github.com/kunjgit/GameZone/tree/main/Games/Hover_Board_Effect) | | [namefate](https://github.com/kunjgit/GameZone/tree/main/Games/namefate) | diff --git a/assets/images/Single_Player_Solitaire.png b/assets/images/Single_Player_Solitaire.png new file mode 100644 index 0000000000..7c58c83994 Binary files /dev/null and b/assets/images/Single_Player_Solitaire.png differ