Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
90 changes: 90 additions & 0 deletions INSTRUCTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Flask Sudoku App Instructions

## Project overview

This repository contains a Flask-based Sudoku game with puzzle generation, validation, hint support, and a web UI.

There are two related code paths in the `starter/` folder:
- `starter/app/` contains the current Flask application and Sudoku game logic used by the web app.
- `starter/sudoku/` contains the backend Sudoku generator, solver, and validation utilities imported by the Flask app.
- `starter/sudoku_logic.py` is a separate legacy Sudoku helper module and is not required by the current Flask app.

## Run the app


1. Activate the virtual environment:
```powershell
py -m venv .venv
.\.venv\Scripts\Activate.ps1
```
2. Install dependencies (if not already installed):
```powershell
pip install -r requirements.txt
```

3. Open a terminal in the workspace root:
```powershell
cd C:\Users\arti.rajendra.jaware\Documents\GitHub\github-copilot-python\starter
```

4. Start the Flask app:
```powershell
python app.py
```
5. Open a browser at `http://127.0.0.1:5000/`.

## Key files

- `starter/app.py`
- Application entrypoint.
- Imports `create_app()` from `starter/sudoku/__init__.py` and starts the Flask server.

- `starter/app/__init__.py`
- Creates the Flask app instance.
- Registers the main blueprint from `starter/app/routes.py`.

- `starter/app/routes.py`
- Defines frontend routes and JSON API endpoints:
- `/` returns the main HTML game page.
- `/api/new` starts a new game for the selected difficulty.
- `/api/validate` checks a user move against the stored solution.
- `/api/check` verifies the current board state.
- `/api/hint` returns the next hint and locks that cell.

- `starter/app/sudoku.py`
- Generates completed Sudoku grids and puzzles with unique solutions.
- Validates board completion.
- Finds incorrect cells.
- Provides a hint for the next empty or wrong cell.

- `starter/sudoku/generator.py`
- Creates a full Sudoku solution and removes cells to form a puzzle.
- Ensures puzzles have a unique valid solution.

- `starter/sudoku/solver.py`
- Implements backtracking-based solver utilities.
- Checks whether a move is safe and counts potential solutions.

- `starter/sudoku/validation.py`
- Validates an individual move within a board.

## Running tests

From `starter/`, run:
```powershell
pytest
```

Test files are located in `starter/tests/`.

## Notes

- The app stores current game state in Flask session variables: `puzzle`, `solution`, `fixed`, and `difficulty`.
- Difficulty levels are managed by the generator logic and control how many cells are left blank.
- The front-end logic and game UI live inside `starter/static/` and `starter/templates/index.html`.

## Good starting points for development

- `starter/app/routes.py` for API behavior.
- `starter/app/sudoku.py` for game logic and puzzle generation.
- `starter/tests/` to verify behavior and add new coverage.
80 changes: 20 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,20 @@
# Refactor a Sudoku Game written in Python Flask

Use this simple Sudoku game as a starting point to practice your skills with GitHub Copilot. The goal is to refactor the code to use modern technologies, while also adding new features and improving the overall user experience.

## Getting Started

Follow these instructions to get a copy of the project up and running on your local machine.

### Dependencies

```
- Modern web browser (Chrome, Firefox, Edge, etc.)
- Python 3
```

### Installation

1. Fork this repository to your GitHub account. (You can use the "Fork" button on the top right corner of the repository page.)

2. Clone your forked repository to your local machine.

3. Open a terminal window and navigate to the "github-copilot-python/starter" directory.

4. Create a Python virtual environment and activate it (optional but highly recommended).

```bash
python3 -m venv .venv
source .venv/bin/activate
```

5. Install required Python packages.

```bash
pip install -r requirements.txt
```

6. Run the Flask app.

```bash
python app.py
```

7. Open http://127.0.0.1:5000 in your browser.

## Project Instructions

Use GitHub Copilot to refactor the code for this game to add more advanced features. The goal is to create a more modern and maintainable codebase and add additional functionality to the final product. You can use any combination of code completion and chat features, like Ask, Edit, or Agent modes.

- Errors should be handled gracefully with appropriate messages to the user.
- Implement a Sudoku board generator that creates a valid Sudoku puzzle with a unique solution.
- Add a timer to track how long it takes to solve the puzzle.
- Implement a solution checker that verifies if the user's solution is correct using event delegation.
- Add a difficulty selector to allow users to choose between easy, medium, and hard puzzles.
- Add a hint feature that provides clues for the user that are noted with unique colors.
- Add a check puzzle button that checks the current state of the board against the solution.
- User should get immediate feedback on their input, such as highlighting invalid entries.
- Top 10 scores should be saved in local storage and displayed on the page with the user's name, time taken, hints used, and difficulty level.
- The game should be responsive and work well on both desktop and mobile devices.
- UI colors should be visually appealing and accessible.
- Completed and correct puzzles should display a congratulatory message with the time taken and hints used and ask for the user's name for Top 10 times.
# Flask Sudoku Game

This project is a refactored Flask Sudoku application with difficulty settings, unique solution validation, timer, hints, live feedback, dark mode, and a top 10 scoreboard.

## Features

- Flask-based Sudoku board
- Easy, Medium, and Hard difficulty levels
- Puzzle generation with unique solution validation
- Immediate feedback for invalid moves
- Hint button
- Check button
- Timer
- Completion message
- Dark mode toggle
- Top 10 scoreboard using local storage
- Responsive layout for desktop and mobile
- Alternating colors for 3x3 Sudoku squares

## Project Structure
Binary file added Screenshots/API_Crashing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/Final_Output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/copilot_grid_styling.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/copilot_refactor_architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/copilot_testing_framework.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/copilot_top10_storage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/copilot_unique_solution.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/final_test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/initial_tests.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/pytest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added starter/__pycache__/sudoku_logic.cpython-314.pyc
Binary file not shown.
43 changes: 5 additions & 38 deletions starter/app.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,6 @@
from flask import Flask, render_template, jsonify, request
import sudoku_logic

app = Flask(__name__)

# Keep a simple in-memory store for current puzzle and solution
CURRENT = {
'puzzle': None,
'solution': None
}

@app.route('/')
def index():
return render_template('index.html')

@app.route('/new')
def new_game():
clues = int(request.args.get('clues', 35))
puzzle, solution = sudoku_logic.generate_puzzle(clues)
CURRENT['puzzle'] = puzzle
CURRENT['solution'] = solution
return jsonify({'puzzle': puzzle})

@app.route('/check', methods=['POST'])
def check_solution():
data = request.json
board = data.get('board')
solution = CURRENT.get('solution')
if solution is None:
return jsonify({'error': 'No game in progress'}), 400
incorrect = []
for i in range(sudoku_logic.SIZE):
for j in range(sudoku_logic.SIZE):
if board[i][j] != solution[i][j]:
incorrect.append([i, j])
return jsonify({'incorrect': incorrect})

if __name__ == '__main__':
from sudoku import create_app

app = create_app()

if __name__ == "__main__":
app.run(debug=True)
11 changes: 11 additions & 0 deletions starter/app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from flask import Flask


def create_app():
app = Flask(__name__)
app.config["SECRET_KEY"] = "dev-secret-key-change-for-production"

from app.routes import main_bp
app.register_blueprint(main_bp)

return app
110 changes: 110 additions & 0 deletions starter/app/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
from flask import Blueprint, jsonify, render_template, request, session

from app.sudoku import (
board_is_complete_and_correct,
find_incorrect_cells,
generate_puzzle,
get_next_hint,
)

main_bp = Blueprint("main", __name__)


@main_bp.route("/")
def index():
return render_template("index.html")


@main_bp.route("/api/new", methods=["POST"])
def new_game():
data = request.get_json() or {}
difficulty = data.get("difficulty", "easy").lower()

puzzle, solution = generate_puzzle(difficulty)

fixed = [
[puzzle[row][col] != 0 for col in range(9)]
for row in range(9)
]

session["puzzle"] = puzzle
session["solution"] = solution
session["fixed"] = fixed
session["difficulty"] = difficulty

return jsonify({
"puzzle": puzzle,
"fixed": fixed,
"difficulty": difficulty,
})


@main_bp.route("/api/validate", methods=["POST"])
def validate_move():
data = request.get_json() or {}

row = int(data.get("row"))
col = int(data.get("col"))
value = int(data.get("value") or 0)

solution = session.get("solution")
fixed = session.get("fixed")

if solution is None or fixed is None:
return jsonify({"valid": False, "message": "No active game"}), 400

if fixed[row]return jsonify({"valid": False, "message": "This cell is locked"})

if value == 0:
return jsonify({"valid": True})

return jsonify({
"valid": value == solution[row][col]
})


@main_bp.route("/api/check", methods=["POST"])
def check_board():
data = request.get_json() or {}
board = data.get("board")

solution = session.get("solution")

if solution is None:
return jsonify({"message": "No active game"}), 400

errors = find_incorrect_cells(board, solution)
solved = board_is_complete_and_correct(board, solution)

return jsonify({
"errors": errors,
"solved": solved,
})


@main_bp.route("/api/hint", methods=["POST"])
def hint():
data = request.get_json() or {}
board = data.get("board")

solution = session.get("solution")
fixed = session.get("fixed")

if solution is None or fixed is None:
return jsonify({"message": "No active game"}), 400

next_hint = get_next_hint(board, solution)

if next_hint is None:
return jsonify({"hint": None, "message": "No hints available"})

row = next_hint["row"]
col = next_hint["col"]

fixed[row][col] = True
session["fixed"] = fixed

return jsonify({
"hint": next_hint,
"fixed": fixed,
})
Loading