Skip to content

SagarBiswas-MultiHAT/SnakeWaterGun-Game

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Snake — Water — Gun

CI   Python   pytest   License   Last Commit

A simple, robust, and well-documented terminal game (like Rock–Paper–Scissors) implemented in Python.

This README explains everything: what the game is, how to run it, how the logic works, examples, automated tests, CI, and next steps — so anyone can understand and contribute by reading this file alone.

Table of contents

Overview

Snake — Water — Gun is a small, beginner-friendly terminal game. Players choose among Snake, Water, or Gun. The computer picks randomly.

Outcome rules:

  • Snake drinks Water → Snake beats Water
  • Water drowns Gun → Water beats Gun
  • Gun shoots Snake → Gun beats Snake

This repository contains a polished, testable Python implementation with clear separation of logic, user input handling, and a small test suite.

Features

  • Clean, modular Python code (functions for parsing, game logic, and main loop).
  • Robust input handling (accepts s, w, g or full words snake, water, gun, case-insensitive).
  • Two play modes: interactive (until Ctrl+C) and fixed rounds (-n N).
  • Unit-testable logic (determine_outcome) so you can add automated tests.
  • Ready for CI (workflow included).
  • Designed to be extended (AI opponent strategies, best-of-N, GUI).

Quick start

  1. Clone the repository (or download and extract the ZIP).

  2. Make sure you have Python 3.9+ installed.

  3. (Optional) Create a virtual environment:

    python -m venv .venv
    source .venv/bin/activate   # macOS / Linux
    .\.venv\Scripts\activate    # Windows PowerShell
  4. Run the game:

    python Snake-Water-Gun_Game.py

If you rename the script, update the command accordingly. The current filename is Snake-Water-Gun_Game.py.

Usage & options

Option A — Interactive mode (default)

Run without options. The game keeps asking for choices until you press Ctrl+C:

python Snake-Water-Gun_Game.py

Valid inputs (case-insensitive):

  • s or snake → Snake
  • w or water → Water
  • g or gun → Gun

Invalid inputs are ignored (not counted as rounds) and the program prompts again.

Option B — Fixed rounds (-n)

Play a fixed number of valid rounds (invalid input does not count):

python Snake-Water-Gun_Game.py -n 5

This runs until 5 valid rounds are played and then prints final stats.

Best-of mode example (suggested extension)

Not included by default, but recommended: provide --best-of 5 to end when a player reaches majority wins (first to 3 wins in best-of-5).

Pseudo-logic:

  • target_wins = best_of // 2 + 1
  • keep playing rounds until either player reaches target_wins
  • invalid inputs still do not count

This is intentionally straightforward to add in main().

Examples (commands & sample output)

Interactive

$ python Snake-Water-Gun_Game.py
Welcome to Snake - Water - Gun!
Play until you press Ctrl-C (invalid inputs will be ignored).
Choose: S (Snake), W (Water), G (Gun). You can also type full words.

1. Enter your choice (S/W/G): s
---> You chose: Snake | Computer chose: Water
..:: You Win!

2. Enter your choice (S/W/G): g
---> You chose: Gun | Computer chose: Snake
..:: You Win!

^C
Game interrupted by user.
==> Score so far (after 2 rounds): Wins: 2, Losses: 0, Draws: 0

Fixed rounds

$ python Snake-Water-Gun_Game.py -n 3
We'll play 3 valid rounds. Invalid inputs are not counted.

1. Enter your choice (S/W/G): w
---> You chose: Water | Computer chose: Gun
..:: You Win!

2. Enter your choice (S/W/G): s
---> You chose: Snake | Computer chose: Gun
..:: You Lose!

3. Enter your choice (S/W/G): g
---> You chose: Gun | Computer chose: Gun
..:: Match Draw.

==> Final result after 3 rounds: Wins: 1, Losses: 1, Draws: 1

How the game logic works (concise explanation)

There are three choices. A compact and reliable way to check wins uses modular arithmetic.

Mapping used (in the provided code):

  • 0 → Snake
  • 1 → Water
  • 2 → Gun

Win rule (single condition):

  • If player == computer → draw
  • Else, player wins if (player - computer) % 3 == 2
  • Otherwise player loses

Why this works:

  • (0 - 1) % 3 = 2 → Snake (0) beats Water (1)
  • (1 - 2) % 3 = 2 → Water (1) beats Gun (2)
  • (2 - 0) % 3 = 2 → Gun (2) beats Snake (0)

Using modular arithmetic keeps the logic compact and avoids long chains of if statements.

Design & code structure — what to look for in the source

Open the main script at Snake-Water-Gun_Game.py. Key parts:

  • parse_args() — parses -n/--rounds.
  • determine_outcome(player, computer) — pure function, returns "win" | "lose" | "draw". Easy to test.
  • play_round(raw_input) — normalizes input, validates, chooses computer move, returns outcome and choices. Raises ValueError for invalid inputs.
  • main() — orchestration loop, score tracking, friendly messages and graceful handling of KeyboardInterrupt.

This separation makes each part simple to reason about and unit-testable.

Testing (pytest)

A small test file exists at tests/test_logic.py. It validates all win/lose/draw combinations for determine_outcome.

Run tests locally:

python -m pip install -r requirements.txt
pytest -q

If you add new logic, please add tests for it.

Continuous Integration (GitHub Actions)

The workflow is defined in .github/workflows/python-ci.yml. It runs on push and pull requests for main/master and includes:

  • A Python version matrix (3.9–3.12)
  • Dependency install (if requirements.txt exists)
  • Pytest test run
  • A non-blocking smoke run of the game using -n 1 and a single input

This setup keeps CI green and ensures the project stays healthy.

Troubleshooting & FAQ

Q: The CI job hangs — why?

If a script waits for interactive input, CI can hang. The workflow avoids this by running the game with -n 1 and providing input via stdin. Tests only exercise pure logic.

Q: My input isn't recognized.

Valid inputs are s/snake, w/water, g/gun (case-insensitive). Leading/trailing whitespace is ignored. Anything else is rejected and you are prompted again.

Q: Can I change the mapping back to 1, 0, -1?

You can, but the modular arithmetic rule uses the index mapping 0, 1, 2. The current approach is recommended for clarity and extensibility.

Contributing

Fork the repo.

Create a feature branch:

git checkout -b feature/my-new-feature

Add tests for new behavior.

Open a pull request describing your changes.

Please follow these guidelines:

  • Keep functions small and single-responsibility.
  • Add or update tests for any logic changes.
  • Keep the CLI friendly and avoid blocking behavior for automated runs.

Future improvements

  • Add --best-of N mode (first to majority wins).
  • Add an adaptive AI opponent that learns player tendencies.
  • Add a small web UI with Streamlit or Flask.
  • Track historical stats (save to JSON) and show leaderboards.
  • Add code coverage reporting to CI and a coverage badge in README.

License

This project is released under the MIT License. See LICENSE for details.

About

A compact, beginner-friendly terminal game (Snake — Water — Gun) with interactive and fixed-round modes. Robust input parsing (s/w/g or full words), a pure determine_outcome function for easy unit testing, a small pytest suite, and CI-ready workflow—ideal for learning Python, TDD, and building small CLI games.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages