diff --git a/Domains/CompetitiveProgramming/Programs/Python/Tic Tac Toe/README.md b/Domains/CompetitiveProgramming/Programs/Python/Tic Tac Toe/README.md new file mode 100644 index 00000000..05e621d2 --- /dev/null +++ b/Domains/CompetitiveProgramming/Programs/Python/Tic Tac Toe/README.md @@ -0,0 +1,19 @@ +**Contributor:** GayatriVitkar + +# Tic Tac Toe Game ๐ŸŽฎ + +A simple Tic Tac Toe game built in Python allowing two players to play locally in the console. + +## Features +- Two-player gameplay +- Clear console interface +- Option to restart the game after finishing + +## How to Play +1. Run the Python script: `python tictactoe.py` +2. Player X starts and chooses a position (1-9). +3. Player O plays next. +4. The game continues until one player wins or the board is full. + +## Contributing +Feel free to improve the game or add new features! diff --git a/Domains/CompetitiveProgramming/Programs/Python/Tic Tac Toe/Tictactoe.py b/Domains/CompetitiveProgramming/Programs/Python/Tic Tac Toe/Tictactoe.py new file mode 100644 index 00000000..485817e1 --- /dev/null +++ b/Domains/CompetitiveProgramming/Programs/Python/Tic Tac Toe/Tictactoe.py @@ -0,0 +1,95 @@ +import tkinter as tk +from tkinter import messagebox + +class TicTacToe: + def __init__(self, root): + # Initialize the main application window + self.root = root + self.root.title("Tic Tac Toe") + + # Set the current player and initialize the board state + self.current_player = "X" + self.board = [""] * 9 + + # List to hold button references for the game board + self.buttons = [] + self.create_board() + + def create_board(self): + # Create a frame to hold the game board buttons + frame = tk.Frame(self.root, bg="lightblue") # Add background color for aesthetic + frame.pack(padx=10, pady=10) + + # Create 9 buttons (3x3 grid) for the board + for i in range(9): + button = tk.Button( + frame, text="", font=("Arial", 24, "bold"), width=5, height=2, + bg="white", fg="black", command=lambda i=i: self.on_click(i), relief="raised" # Pass button index to the click handler + ) + button.grid(row=i//3, column=i%3, padx=5, pady=5) # Position button in the grid + self.buttons.append(button) + + # Add a label to display the current player's turn + self.turn_label = tk.Label( + self.root, text=f"Player {self.current_player}'s Turn", font=("Arial", 16), bg="lightblue" + ) + self.turn_label.pack(pady=5) + + # Add a restart button below the game board + self.restart_button = tk.Button( + self.root, text="Restart Game", font=("Arial", 14, "bold"), bg="orange", fg="white", + command=self.restart_game + ) + self.restart_button.pack(pady=10) + + def on_click(self, index): + # Handle a button click event + if self.board[index] == "": # Ensure the button has not already been clicked + self.board[index] = self.current_player + self.buttons[index].config(text=self.current_player, fg="blue" if self.current_player == "X" else "red") # Update button text + + if self.check_winner(): # Check if the current player has won + messagebox.showinfo("Game Over", f"Player {self.current_player} wins!") + self.turn_label.config(text=f"Player {self.current_player} wins!") + self.disable_buttons() # Disable further interaction with the board + elif "" not in self.board: # Check for a draw condition + messagebox.showinfo("Game Over", "It's a draw!") + self.turn_label.config(text="It's a draw!") + else: + # Switch to the other player + self.current_player = "O" if self.current_player == "X" else "X" + self.turn_label.config(text=f"Player {self.current_player}'s Turn") + + def check_winner(self): + # Define winning patterns (rows, columns, diagonals) + win_patterns = [ + [0, 1, 2], [3, 4, 5], [6, 7, 8], # Rows + [0, 3, 6], [1, 4, 7], [2, 5, 8], # Columns + [0, 4, 8], [2, 4, 6] # Diagonals + ] + + # Check if any winning pattern is satisfied + for pattern in win_patterns: + if self.board[pattern[0]] == self.board[pattern[1]] == self.board[pattern[2]] != "": + return True + return False + + def disable_buttons(self): + # Disable all buttons to prevent further interaction + for button in self.buttons: + button.config(state="disabled") + + def restart_game(self): + # Reset the game to its initial state + self.current_player = "X" # Reset to player X + self.board = [""] * 9 # Clear the board state + self.turn_label.config(text=f"Player {self.current_player}'s Turn") # Update turn label + for button in self.buttons: + button.config(text="", state="normal", bg="white") # Clear button text and enable them + +if __name__ == "__main__": + # Create the main application window and run the game + root = tk.Tk() + root.configure(bg="lightblue") # Set a background color for the main window + game = TicTacToe(root) + root.mainloop() diff --git a/Domains/Frontend/MiniProjects/NewsFlash/README.md b/Domains/Frontend/MiniProjects/NewsFlash/README.md new file mode 100644 index 00000000..684a8570 --- /dev/null +++ b/Domains/Frontend/MiniProjects/NewsFlash/README.md @@ -0,0 +1,104 @@ +**Contributor:** GayatriVitkarcd + +๐Ÿ“ Description + +NewsFlash is a responsive and modern web application that delivers the latest news headlines from multiple categories in real-time using the NewsAPI. + +The project has a clean glassmorphism-inspired interface with smooth hover effects, animated loading transitions, and a seamless infinite scroll experience. +Users can explore top news, search for specific topics, and filter articles by categories like Technology, Sports, Business, Entertainment, and more. + +Each news card contains a thumbnail, headline, short description, source, and a โ€œRead Moreโ€ button that opens the full article in a new tab. + +๐ŸŽฏ Features + +๐ŸŒ Live News Fetching: Displays updated news headlines using NewsAPI. + +๐Ÿ”Ž Search Functionality: Find news instantly by typing keywords. + +๐Ÿท๏ธ Category Filters: Switch easily between trending topics. + +โ™พ๏ธ Infinite Scroll: Automatically loads more news as you scroll. + +๐Ÿ’Ž Responsive Glassmorphism UI: Works smoothly on all screen sizes. + +โšก Fast & Lightweight: Built using pure HTML, CSS, and vanilla JavaScript. + +๐Ÿ› ๏ธ Tech Stack + +HTML5: Structure and layout of the web pages. + +CSS3: Custom responsive design with glassmorphism and animations. + +JavaScript (Fetch API): Fetches and dynamically displays live news content. + +๐Ÿš€ How to Run +๐Ÿ–ฅ๏ธ Method 1: Open in Browser + +Download or clone this repository. + +Open index.html directly in your browser. + +โšก Method 2: Live Server (Recommended) + +Open project in VS Code. + +Right-click index.html โ†’ Open with Live Server. + +App runs locally at http://localhost:5500. + +๐Ÿ“ Project Structure +NewsFlash/ +โ”œโ”€โ”€ index.html # Main HTML file +โ”œโ”€โ”€ style.css # Styling and layout +โ”œโ”€โ”€ script.js # JavaScript logic and API integration +โ”œโ”€โ”€ README.md # Documentation +โ””โ”€โ”€ assets/ # Images or icons used + +๐Ÿ“š Learning Outcomes + +Working with public APIs (NewsAPI) + +Asynchronous JavaScript (Fetch, async/await) + +DOM Manipulation and Dynamic Rendering + +Responsive UI Design + +Event Handling and Search Filtering + +Implementing Infinite Scroll Mechanism + +๐Ÿ› Known Issues + +API requests may fail if the free API limit is reached. + +Slow networks can cause delayed image loading. + +Some articles might not contain images or descriptions from the API. + +๐Ÿš€ Future Enhancements + +Add dark/light mode toggle. + +Save favorite articles using local storage. + +Add โ€œTop Stories by Countryโ€ filter. + +Implement voice-based news search. + +Add a simple offline PWA version. + +๐Ÿ“„ License + +MIT License โ€“ Free for learning and personal use. + +๐Ÿค Contributing + +This project is part of ProjectHive Frontend Domain. +Feel free to: + +Fork and enhance the app + +Report bugs or suggest improvements + +Use it for your portfolio or learning practice \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/NewsFlash/index.html b/Domains/Frontend/MiniProjects/NewsFlash/index.html new file mode 100644 index 00000000..f620c55c --- /dev/null +++ b/Domains/Frontend/MiniProjects/NewsFlash/index.html @@ -0,0 +1,35 @@ + + + + + + NewsFlash - Live News Reader + + + +
+

๐Ÿ—ž๏ธ NewsFlash

+ +
+ + + +
+ + + + + + + + diff --git a/Domains/Frontend/MiniProjects/NewsFlash/script.js b/Domains/Frontend/MiniProjects/NewsFlash/script.js new file mode 100644 index 00000000..33eb2f45 --- /dev/null +++ b/Domains/Frontend/MiniProjects/NewsFlash/script.js @@ -0,0 +1,92 @@ +const apiKey = "84071566e88444519789a937d0240f6d"; // Replace this with your NewsAPI key +const newsContainer = document.getElementById("newsContainer"); +const searchInput = document.getElementById("searchInput"); +const loader = document.getElementById("loader"); + +let page = 1; +let category = "general"; +let query = ""; +let loading = false; + +async function fetchNews() { + if (loading) return; + loading = true; + loader.classList.remove("hidden"); + + let url = `https://newsapi.org/v2/top-headlines?country=us&pageSize=9&page=${page}&apiKey=${apiKey}`; + if (category !== "general") url += `&category=${category}`; + if (query) url = `https://newsapi.org/v2/everything?q=${query}&pageSize=9&page=${page}&apiKey=${apiKey}`; + + try { + const res = await fetch(url); + const data = await res.json(); + + if (data.status !== "ok" || !data.articles.length) { + if (page === 1) { + newsContainer.innerHTML = `

No news found ๐Ÿ“ฐ

`; + } + loader.classList.add("hidden"); + loading = false; + return; + } + + displayNews(data.articles); + } catch (err) { + console.error("Error fetching news:", err); + newsContainer.innerHTML = `

Error loading news. Check API key or network.

`; + } + + loader.classList.add("hidden"); + loading = false; +} + +function displayNews(articles) { + articles.forEach(article => { + const card = document.createElement("div"); + card.classList.add("news-card"); + card.innerHTML = ` + news image +
+

${article.title || "Untitled"}

+

${article.description || "No description available."}

+ Read More โ†’ +
+ `; + newsContainer.appendChild(card); + }); +} + +// Category buttons +document.querySelectorAll(".category").forEach(btn => { + btn.addEventListener("click", () => { + document.querySelectorAll(".category").forEach(b => b.classList.remove("active")); + btn.classList.add("active"); + category = btn.dataset.category; + query = ""; + page = 1; + newsContainer.innerHTML = ""; + fetchNews(); + }); +}); + +// Search +searchInput.addEventListener("keypress", e => { + if (e.key === "Enter") { + query = searchInput.value.trim(); + category = "general"; + page = 1; + newsContainer.innerHTML = ""; + fetchNews(); + } +}); + +// Infinite Scroll +window.addEventListener("scroll", () => { + if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 200) { + page++; + fetchNews(); + } +}); + +// First Load +fetchNews(); diff --git a/Domains/Frontend/MiniProjects/NewsFlash/style.css b/Domains/Frontend/MiniProjects/NewsFlash/style.css new file mode 100644 index 00000000..4134ff00 --- /dev/null +++ b/Domains/Frontend/MiniProjects/NewsFlash/style.css @@ -0,0 +1,181 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap'); + +* { + box-sizing: border-box; + margin: 0; + padding: 0; + font-family: 'Poppins', sans-serif; +} + +body { + background: linear-gradient(135deg, #0f2027, #203a43, #2c5364); + color: #fff; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + overflow-x: hidden; +} + +/* Header */ +header { + width: 100%; + padding: 20px; + text-align: center; + background: rgba(255, 255, 255, 0.05); + backdrop-filter: blur(10px); + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +header h1 { + font-size: 2rem; + font-weight: 700; + color: #fff; + letter-spacing: 1px; +} + +header input { + margin-top: 15px; + padding: 10px 20px; + width: 90%; + max-width: 400px; + border: none; + border-radius: 30px; + background: rgba(255, 255, 255, 0.15); + color: white; + font-size: 1rem; + outline: none; +} + +header input::placeholder { + color: #ddd; +} + +/* Nav */ +nav { + margin: 15px 0; + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 10px; +} + +.category { + background: rgba(255, 255, 255, 0.1); + color: #fff; + border: none; + padding: 10px 20px; + border-radius: 25px; + cursor: pointer; + transition: all 0.3s ease; + font-weight: 500; +} + +.category.active, +.category:hover { + background: linear-gradient(90deg, #ff6a00, #ee0979); + transform: scale(1.05); +} + +/* News Container */ +#newsContainer { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 25px; + width: 90%; + max-width: 1200px; + margin: 20px auto; +} + +.news-card { + background: rgba(255, 255, 255, 0.1); + border-radius: 20px; + overflow: hidden; + backdrop-filter: blur(12px); + transition: transform 0.3s, box-shadow 0.3s; +} + +.news-card:hover { + transform: translateY(-8px); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); +} + +.news-card img { + width: 100%; + height: 180px; + object-fit: cover; +} + +.news-card-content { + padding: 15px; +} + +.news-card-content h3 { + font-size: 1.1rem; + font-weight: 600; + color: #fff; + margin-bottom: 8px; +} + +.news-card-content p { + font-size: 0.9rem; + color: #ddd; + margin-bottom: 10px; +} + +.news-card-content a { + text-decoration: none; + color: #ff7eb3; + font-weight: 500; +} + +/* Loader */ +#loader { + display: flex; + justify-content: center; + align-items: center; + margin: 30px; +} + +.hidden { + display: none; +} + +.spinner { + width: 40px; + height: 40px; + border: 5px solid rgba(255, 255, 255, 0.2); + border-top-color: #ff7eb3; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +/* Footer */ +footer { + text-align: center; + padding: 20px; + color: #ccc; + font-size: 0.9rem; +} + +footer span { + color: #ff4b2b; +} + +/* Responsive */ +@media (max-width: 600px) { + header h1 { + font-size: 1.5rem; + } + + .category { + font-size: 0.9rem; + padding: 8px 16px; + } +}