Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adding a new game Single_Player_Solitaire #4767

Merged
merged 2 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
98 changes: 98 additions & 0 deletions Games/Single_Player_Solitaire/README.md
Original file line number Diff line number Diff line change
@@ -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----------------------------
36 changes: 36 additions & 0 deletions Games/Single_Player_Solitaire/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Solitaire</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="game-board">
<div id="stock" class="card-pile"></div>
<div id="waste" class="card-pile"></div>
<div id="foundations">
<div class="foundation card-pile"></div>
<div class="foundation card-pile"></div>
<div class="foundation card-pile"></div>
<div class="foundation card-pile"></div>
</div>
<div id="tableau">
<div class="tableau-pile card-pile"></div>
<div class="tableau-pile card-pile"></div>
<div class="tableau-pile card-pile"></div>
<div class="tableau-pile card-pile"></div>
<div class="tableau-pile card-pile"></div>
<div class="tableau-pile card-pile"></div>
<div class="tableau-pile card-pile"></div>
</div>
</div>
<div id="controls">
<button id="new-game-button">New Game</button>
<button id="hint-button">Hint</button>
<div id="win-message" class="hidden">Congratulations, you won!</div>
</div>
<script src="script.js"></script>
</body>
</html>
212 changes: 212 additions & 0 deletions Games/Single_Player_Solitaire/script.js
Original file line number Diff line number Diff line change
@@ -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);
Loading
Loading