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
6 changes: 6 additions & 0 deletions .csharpierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 100,
"useTabs": false,
"tabWidth": 4,
"endOfLine": "lf"
}
63 changes: 63 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: CI

on:
push:
branches: [master]
pull_request:
branches: [master]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- run: dotnet restore hoteltime.sln
- run: dotnet build hoteltime.sln --no-restore

format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- run: dotnet tool install --global csharpier
- run: csharpier check .

test:
runs-on: ubuntu-latest
needs: [build, format]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- run: dotnet restore hoteltime.sln
- run: dotnet test hoteltime.sln --no-restore --collect:"XPlat Code Coverage" --results-directory ./coverage
- name: Install ReportGenerator
run: dotnet tool install -g dotnet-reportgenerator-globaltool
- name: Generate coverage summary
run: |
reportgenerator \
-reports:"./coverage/**/coverage.cobertura.xml" \
-targetdir:"./coverage/summary" \
-reporttypes:TextSummary
cat ./coverage/summary/Summary.txt
- name: Check coverage threshold
run: |
threshold=$(grep -oP '^COVERAGE_THRESHOLD\s*=\s*\K[0-9]+' Makefile)
line_coverage=$(grep -oP 'Line coverage: \K[0-9.]+' ./coverage/summary/Summary.txt | head -1)
pass=$(echo "$line_coverage >= $threshold" | bc -l)
if [ "$pass" = "1" ]; then
echo "PASS: Line coverage ${line_coverage}% >= ${threshold}%"
else
echo "FAIL: Line coverage ${line_coverage}% < ${threshold}%"
exit 1
fi
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bin/
obj/
.vscode/
coverage/
53 changes: 53 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.PHONY: build run-maze run-refactoring format test coverage coverage-html coverage-check clean-coverage

COVERAGE_DIR = ./coverage
COVERAGE_THRESHOLD = 75

build:
$(MAKE) -C refactoring build
$(MAKE) -C maze build

run-refactoring:
$(MAKE) -C refactoring run

run-maze:
$(MAKE) -C maze run MAZE=$(MAZE)

format:
$(MAKE) -C refactoring format
$(MAKE) -C maze format
csharpier format tests/

test:
dotnet test hoteltime.sln

coverage: clean-coverage
dotnet test hoteltime.sln --collect:"XPlat Code Coverage" --results-directory $(COVERAGE_DIR)
@echo "Cobertura XML reports written to $(COVERAGE_DIR)/"

coverage-html: coverage
reportgenerator \
-reports:"$(COVERAGE_DIR)/**/coverage.cobertura.xml" \
-targetdir:"$(COVERAGE_DIR)/html" \
-reporttypes:Html
@echo "HTML report: $(COVERAGE_DIR)/html/index.html"

coverage-check: coverage
reportgenerator \
-reports:"$(COVERAGE_DIR)/**/coverage.cobertura.xml" \
-targetdir:"$(COVERAGE_DIR)/summary" \
-reporttypes:TextSummary
@cat $(COVERAGE_DIR)/summary/Summary.txt
@echo ""
@echo "--- Threshold check ($(COVERAGE_THRESHOLD)%) ---"
@line_coverage=$$(grep -oP 'Line coverage: \K[0-9.]+' $(COVERAGE_DIR)/summary/Summary.txt | head -1); \
threshold=$(COVERAGE_THRESHOLD); \
pass=$$(echo "$$line_coverage >= $$threshold" | bc -l); \
if [ "$$pass" = "1" ]; then \
echo "PASS: Line coverage $${line_coverage}% >= $${threshold}%"; \
else \
echo "FAIL: Line coverage $${line_coverage}% < $${threshold}%"; exit 1; \
fi

clean-coverage:
rm -rf $(COVERAGE_DIR)
173 changes: 173 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,174 @@
Home assignment for https://www.hoteltime.com/

## Prerequisites

- [.NET SDK 10.0+](https://dotnet.microsoft.com/download)
- CSharpier (code formatter):
```bash
dotnet tool install --global csharpier
```
- ReportGenerator (HTML coverage reports - optional):
```bash
dotnet tool install --global dotnet-reportgenerator-globaltool
```
- Add tools to PATH if needed:
```bash
export PATH="$PATH:$HOME/.dotnet/tools" # add to ~/.bashrc or ~/.zshrc
```

## Quick start

```bash
make build # build the solution
make test # run all unit tests
make run-refactoring # run the calculator
make run-maze # run the maze (default maze)
make format # format all C# files with CSharpier
```

---

# HotelTime Calculator

Interactive console calculator supporting addition, subtraction, multiplication, and division of decimal numbers.

## Getting started

```bash
cd refactoring
dotnet run
```

Or using `make` from the project root:

```bash
make run-refactoring # run the app
make build # build the solution
```

## CLI options

| Option | Description | Default |
|---|---|---|
| `--decimalPlaces <n>` | Number of decimal places in the result | `2` |

### Examples

```bash
dotnet run # result rounded to 2 decimal places
dotnet run -- --decimalPlaces 0 # result as a whole number
dotnet run -- --decimalPlaces 10 # result with 10 decimal places
```

## Usage

1. Enter number A (decimal number, use `.` as separator)
2. Enter number B
3. Select an operation by typing `1`–`4`
4. When asked whether to run a new calculation:
- `a`, `A`, `y`, `Y`, `ano`, `yes` or **Enter** (default: yes) to continue
- `n`, `N`, `ne`, `no` to exit

---

# MazeRunner

Console animation of four dwarves navigating a maze using different strategies.

## Getting started

```bash
make run-maze # default maze (mazes/Maze.dat)
make run-maze MAZE=mazes/Maze2.dat # custom maze file
```

Or directly:

```bash
cd maze
dotnet run --project MazeRunner.csproj -- mazes/Maze.dat
```

## Dwarves

| Symbol | Name | Strategy |
|---|---|---|
| `L` | Zeman | Left-hand rule — always follows the left wall |
| `R` | Klaus | Right-hand rule — always follows the right wall |
| `T` | Babiš | Teleporter — walks randomly, teleports to finish at a random time |
| `P` | Masaryk | Pathfinder — computes shortest path via BFS at start, then follows it |

Each dwarf is spawned with a 5 s delay after the previous one.

## Maze format

Maze files are plain text in `maze/mazes/`:

| Character | Meaning |
|---|---|
| `#` | Wall |
| ` ` | Path |
| `S` | Start |
| `F` | Finish |

## Adding a new maze

Create a `.dat` file in `maze/mazes/` following the format above and run:

```bash
make run-maze MAZE=mazes/YourMaze.dat
```

A 30×19 example is included as `mazes/Maze2.dat`. New mazes can be generated with the included script:

```bash
cd maze/mazes
python3 generate_maze.py # 20×20, prints to stdout
python3 generate_maze.py 30 20 # 30 wide × 20 tall
python3 generate_maze.py 30 20 42 MyMaze.dat # with fixed seed, written to file
```

---

# Testing & Coverage

## Running tests

```bash
make test # run all unit tests (xUnit)
```

## Coverage

Coverage is collected via [coverlet](https://github.com/coverlet-coverage/coverlet) (Cobertura XML) and rendered via [ReportGenerator](https://github.com/danielpalme/ReportGenerator).

```bash
make coverage # generate Cobertura XML reports into ./coverage/
make coverage-html # XML + HTML report in ./coverage/html/index.html
make coverage-check # XML + per-class summary + threshold check (default 70%)
```

### Threshold

The `coverage-check` target enforces a minimum line coverage percentage. Adjust it in the root `Makefile`:

```makefile
COVERAGE_THRESHOLD ?= 77
```

Override at runtime:

```bash
make coverage-check COVERAGE_THRESHOLD=80
```

If coverage is below the threshold, the build fails with a non-zero exit code - suitable for CI.

### Coverage output

| Path | Content |
|---|---|
| `coverage/**/coverage.cobertura.xml` | Raw Cobertura XML (one per test project) |
| `coverage/html/index.html` | Interactive HTML report (browse in browser) |

The `coverage/` directory is gitignored.
Loading
Loading