diff --git a/Recursion/StonePaperScissor/Readme.md b/Recursion/StonePaperScissor/Readme.md new file mode 100644 index 00000000..cd8c1581 --- /dev/null +++ b/Recursion/StonePaperScissor/Readme.md @@ -0,0 +1,122 @@ +# Stone Paper Scissor Problem + +## Description of Stone Paper Scissor Problem + +The Stone-Paper-Scissors problem is a classic hand game where two players simultaneously form one of three shapes with their hands: rock, paper, or scissors. Each shape has a specific interaction with the others: + +1. **Rock (r)** : Wins against Scissors but loses to Paper. +2. **Paper (p)** : Wins against Rock but loses to Scissors. +3. **Scissors (s)** : Wins against Paper but loses to Rock. + +The objective of the game is to select a shape that defeats the opponent's shape based on these rules. In a typical setup, the game is played in multiple rounds, and the player who wins the most rounds is the overall winner. + +In programming, the Stone-Paper-Scissors game is often implemented as an interactive game where: + +* A player competes against a computer. +* The user inputs their choice each round. +* The computer randomly selects a choice. +* The winner of each round is determined based on the above rules. + +The game can be further extended by: + +* Tracking the score across multiple rounds. +* Declaring the overall winner based on the maximum number of wins. + +This problem is an excellent exercise in programming logic, condition handling, and randomness, and it can be implemented using various programming techniques, such as recursion, loops, and conditional statements. + +### Use Cases of Stone Paper Scissor Problem + +* **Game Development** : The Stone-Paper-Scissors game serves as a foundational project in game development. It’s often a beginner-friendly introduction to concepts such as input handling, random choice generation, and scorekeeping. It is also used to demonstrate logic-based decision-making, game loops, and user interaction. +* **Decision-Making Tool** : Stone-Paper-Scissors can be a simple, fair method for decision-making in situations where parties need a quick, random outcome, similar to a coin flip or drawing lots. It's commonly used informally to resolve minor disputes or determine turns. +* **Programming Education** : This problem is widely used in programming courses to introduce core concepts like conditionals, loops, and functions. It can also extend to recursion, object-oriented programming (OOP) principles, and data structures. By implementing the game, students learn about random number generation, logical operators, and program flow. +* **Artificial Intelligence and Machine Learning** : In AI and ML studies, the Stone-Paper-Scissors game is used to test and develop algorithms for decision-making, pattern recognition, and learning models. It serves as a basic exercise in reinforcement learning, where an AI attempts to predict and counter the player’s moves over time. +* **Statistical Analysis and Probability** : The game provides a straightforward context for studying probability and randomness. Researchers and students can analyze win/loss ratios, the likelihood of specific outcomes, and strategies in repeated games, often using statistical models or simulations. +* **Psychology and Behavioral Studies** : Stone-Paper-Scissors is used to study human behavior, strategy, and decision-making patterns. Researchers analyze how players might attempt to "out-think" each other, revealing cognitive biases and tendencies in competitive decision-making. +* **Gamification and User Engagement** : Companies and apps use Stone-Paper-Scissors as a gamified activity to engage users, enhance user experience, or add interactive elements to apps and websites. For example, it might be used in loyalty programs or onboarding flows to make interactions more enjoyable and rewarding. +* **Simulation and Testing Environments** : Developers use this simple game as a testing environment for various frameworks and languages to prototype logic and simulate user input, often as a preliminary step before developing more complex programs. + +## Problem Definition + +### **Limitations:** + +### Problem Definition for Stone-Paper-Scissors Game + +The **Stone-Paper-Scissors** game problem involves creating a program where a player competes against the computer by selecting one of three possible moves: **Stone (Rock)** , **Paper** , or **Scissors** . Each move interacts with the others in a predetermined way: + +1. **Stone (Rock)** beats **Scissors** (crushes it). +2. **Paper** beats **Stone (Rock)** (covers it). +3. **Scissors** beat **Paper** (cuts it). + +The game proceeds over multiple rounds, and in each round: + +* The user inputs their move. +* The computer randomly selects its move. +* The program compares the moves to determine the round's winner based on the game rules. + +At the end of all rounds, the player with the most round wins is declared the overall winner. + +#### Requirements: + +1. **User Input** : The program should allow the user to select their move. +2. **Random Choice for Computer** : The computer's move should be generated randomly. +3. **Comparison Logic** : The program should compare the user's and computer's choices to determine the winner for each round. +4. **Score Tracking** : Track the number of wins for both the user and the computer. +5. **Final Outcome** : After all rounds, declare the player with the most wins as the overall winner, or declare a tie if both players have the same score. + +#### Constraints: + +* The input must be validated to ensure that the user selects a valid move. +* The number of rounds should be positive and pre-determined by the user. + +#### Objective: + +The primary goal is to create a fair and engaging game where the winner is decided based on the classic Stone-Paper-Scissors rules, implemented efficiently in code, potentially using recursive or iterative methods to manage the game flow. + +This problem provides a simple yet effective way to explore fundamental programming concepts such as user input handling, conditional statements, randomization, and logic. + +* **Recursive Depth Limitation** : +* **Stack Overflow** : In languages or environments with limited stack sizes, deeply nested trees (e.g., skewed trees) can lead to a stack overflow error due to excessive recursion depth. +* **Recursion Depth Limits** : Many programming languages impose a limit on recursion depth, which can hinder the traversal of large or unbalanced trees. +* **Performance on Unbalanced Trees** : +* While Postorder Traversal has a time complexity of O(n)O(n)**O**(**n**), unbalanced trees can lead to inefficient memory usage due to high recursion depths. This can impact performance in terms of space. +* **No Immediate Node Processing** : +* Unlike other traversal methods (like Preorder), Postorder Traversal processes the root node after its children. This might not be suitable for applications that require immediate processing of the root node. +* **Limited Use Cases** : +* Postorder Traversal is specifically useful for scenarios where child nodes must be processed before their parent nodes (e.g., deleting trees, evaluating expressions). It may not be suitable for other applications, such as those requiring breadth-first or the level-order traversal. +* **Iterative Implementation Complexity** : +* While the recursive approach is straightforward, implementing Postorder Traversal iteratively (using stacks) can be more complex and less intuitive. This could lead to increased development time and potential for errors. +* **Memory Consumption** : +* For large trees, especially in cases where the tree is significantly deep, the recursive implementation can consume considerable memory, which might be a concern in memory-constrained environments. + +### Complexity Analysis + +**Time Complexity** : + +* **Single Round** : In each round, the game performs a few operations: + + * Capturing user input (constant time, O(1), + * Generating a random move for the computer (constant time, O(1) + * Determining the round winner by comparing moves (constant time, O(1). + + Since all operations in a single round take constant time, each round runs in O(1) time complexity. +* **Multiple Rounds** : If there are nn**n** rounds, the game will have a time complexity of O(n) because it iterates once per round, and each round consists of O(1) operations. + + Therefore, the overall time complexity is: + O(n) where n is the number of rounds. + +**Space Complexity** : + +* **Single Round** : The space complexity per round is minimal since it only requires variables to store the users choice, the computers choice, and the result of the round. Each of these variables uses constant space, resulting in O(1) space per round. +* **Multiple Rounds** : Since we only track the total scores for the user and computer without storing the results of each round individually, the space complexity remains constant regardless of the number of rounds. + + Therefore, the overall space complexity is: + O(1) + +**Recursive Solution Complexity** : +If implemented recursively, each recursive call represents a single game round. With n rounds, there would be n recursive calls, resulting in a **space complexity of O(n)** due to the call stack. The time complexity remains the same at O(n) as each recursive call operates in O(1) time. + +### Summary + +* **Time Complexity** : O(n) +* **Space Complexity (Iterative)** : O(1) +* **Space Complexity (Recursive)** : O(n) diff --git a/Recursion/StonePaperScissor/StonePaperScissor.c b/Recursion/StonePaperScissor/StonePaperScissor.c new file mode 100644 index 00000000..e0bff189 --- /dev/null +++ b/Recursion/StonePaperScissor/StonePaperScissor.c @@ -0,0 +1,84 @@ +#include +#include +#include + +char determineWinner(char userChoice, char computerChoice) +{ + if (userChoice == computerChoice) + { + return 'D'; // Draw + } + else if ((userChoice == 's' && computerChoice == 'p') || + (userChoice == 'p' && computerChoice == 'r') || + (userChoice == 'r' && computerChoice == 's')) + { + return 'C'; // Computer wins + } + else + { + return 'U'; // User wins + } +} + +void playGame(int rounds, int *userWins, int *computerWins) +{ + if (rounds == 0) + { + if (*userWins > *computerWins) + { + printf("User wins the game with %d wins!\n", *userWins); + } + else if (*computerWins > *userWins) + { + printf("Computer wins the game with %d wins!\n", *computerWins); + } + else + { + printf("It's a tie game!\n"); + } + return; + } + + char userChoice; + printf("Enter your choice (r for rock, p for paper, s for scissors): "); + scanf(" %c", &userChoice); + + srand(time(0)); + int randomChoice = rand() % 3; + char computerChoice = (randomChoice == 0) ? 'r' : (randomChoice == 1) ? 'p' + : 's'; + + printf("Computer chose: %c\n", computerChoice); + + char roundResult = determineWinner(userChoice, computerChoice); + if (roundResult == 'U') + { + printf("User wins this round.\n"); + (*userWins)++; + } + else if (roundResult == 'C') + { + printf("Computer wins this round.\n"); + (*computerWins)++; + } + else + { + printf("It's a draw this round.\n"); + } + + playGame(rounds - 1, userWins, computerWins); +} + +int main() +{ + int rounds; + printf("Welcome to Stone Paper Scissors Game!\n"); + printf("Enter the number of rounds: "); + scanf("%d", &rounds); + + int userWins = 0, computerWins = 0; + + playGame(rounds, &userWins, &computerWins); + + return 0; +}