Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mentor-tara authored Dec 31, 2024
0 parents commit a40f2f4
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: CI

on:
pull_request:
branches: [ main ]

jobs:
validate:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Validate Commands JSON structure
run: node ./internal/validate-commands-json.js

- name: Validate Commands
run: node ./internal/validate-commands.js
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# GitHub Minesweeper

Gain hands-on experience with a professional Git workflow used in many real-world teams with the help of a bot teammate. Find more information at [Profy.dev](https://profy.dev/project/github-minesweeper).
3 changes: 3 additions & 0 deletions commands.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"commands": []
}
1 change: 1 addition & 0 deletions internal/game
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
eyJncmlkIjpbW3sieHBvcyI6MCwieXBvcyI6MCwidmFsdWUiOjAsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjEsInlwb3MiOjAsInZhbHVlIjowLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjoyLCJ5cG9zIjowLCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6MywieXBvcyI6MCwidmFsdWUiOjEsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjQsInlwb3MiOjAsInZhbHVlIjoyLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo1LCJ5cG9zIjowLCJ2YWx1ZSI6Ijpib21iOiIsImlzTWluZSI6dHJ1ZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NiwieXBvcyI6MCwidmFsdWUiOiI6Ym9tYjoiLCJpc01pbmUiOnRydWUsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjcsInlwb3MiOjAsInZhbHVlIjoiOmJvbWI6IiwiaXNNaW5lIjp0cnVlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX1dLFt7Inhwb3MiOjAsInlwb3MiOjEsInZhbHVlIjoxLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjoxLCJ5cG9zIjoxLCJ2YWx1ZSI6MiwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6MiwieXBvcyI6MSwidmFsdWUiOjIsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjMsInlwb3MiOjEsInZhbHVlIjoiOmJvbWI6IiwiaXNNaW5lIjp0cnVlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo0LCJ5cG9zIjoxLCJ2YWx1ZSI6MiwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NSwieXBvcyI6MSwidmFsdWUiOjIsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjYsInlwb3MiOjEsInZhbHVlIjozLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo3LCJ5cG9zIjoxLCJ2YWx1ZSI6MiwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9XSxbeyJ4cG9zIjowLCJ5cG9zIjoyLCJ2YWx1ZSI6Ijpib21iOiIsImlzTWluZSI6dHJ1ZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6MSwieXBvcyI6MiwidmFsdWUiOjIsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjIsInlwb3MiOjIsInZhbHVlIjoiOmJvbWI6IiwiaXNNaW5lIjp0cnVlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjozLCJ5cG9zIjoyLCJ2YWx1ZSI6MiwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NCwieXBvcyI6MiwidmFsdWUiOjEsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjUsInlwb3MiOjIsInZhbHVlIjowLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo2LCJ5cG9zIjoyLCJ2YWx1ZSI6MCwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NywieXBvcyI6MiwidmFsdWUiOjAsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfV0sW3sieHBvcyI6MCwieXBvcyI6MywidmFsdWUiOjEsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjEsInlwb3MiOjMsInZhbHVlIjoyLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjoyLCJ5cG9zIjozLCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6MywieXBvcyI6MywidmFsdWUiOjEsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjQsInlwb3MiOjMsInZhbHVlIjowLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo1LCJ5cG9zIjozLCJ2YWx1ZSI6MCwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NiwieXBvcyI6MywidmFsdWUiOjAsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjcsInlwb3MiOjMsInZhbHVlIjowLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX1dLFt7Inhwb3MiOjAsInlwb3MiOjQsInZhbHVlIjowLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjoxLCJ5cG9zIjo0LCJ2YWx1ZSI6MCwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6MiwieXBvcyI6NCwidmFsdWUiOjAsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjMsInlwb3MiOjQsInZhbHVlIjowLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo0LCJ5cG9zIjo0LCJ2YWx1ZSI6MCwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NSwieXBvcyI6NCwidmFsdWUiOjAsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjYsInlwb3MiOjQsInZhbHVlIjoxLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo3LCJ5cG9zIjo0LCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9XSxbeyJ4cG9zIjowLCJ5cG9zIjo1LCJ2YWx1ZSI6MCwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6MSwieXBvcyI6NSwidmFsdWUiOjAsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjIsInlwb3MiOjUsInZhbHVlIjowLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjozLCJ5cG9zIjo1LCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NCwieXBvcyI6NSwidmFsdWUiOjEsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjUsInlwb3MiOjUsInZhbHVlIjoxLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo2LCJ5cG9zIjo1LCJ2YWx1ZSI6MiwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NywieXBvcyI6NSwidmFsdWUiOiI6Ym9tYjoiLCJpc01pbmUiOnRydWUsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfV0sW3sieHBvcyI6MCwieXBvcyI6NiwidmFsdWUiOjAsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjEsInlwb3MiOjYsInZhbHVlIjoxLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjoyLCJ5cG9zIjo2LCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6MywieXBvcyI6NiwidmFsdWUiOjIsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjQsInlwb3MiOjYsInZhbHVlIjoiOmJvbWI6IiwiaXNNaW5lIjp0cnVlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo1LCJ5cG9zIjo2LCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NiwieXBvcyI6NiwidmFsdWUiOjIsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjcsInlwb3MiOjYsInZhbHVlIjoiOmJvbWI6IiwiaXNNaW5lIjp0cnVlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX1dLFt7Inhwb3MiOjAsInlwb3MiOjcsInZhbHVlIjowLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjoxLCJ5cG9zIjo3LCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6MiwieXBvcyI6NywidmFsdWUiOiI6Ym9tYjoiLCJpc01pbmUiOnRydWUsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjMsInlwb3MiOjcsInZhbHVlIjoyLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo0LCJ5cG9zIjo3LCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9LHsieHBvcyI6NSwieXBvcyI6NywidmFsdWUiOjEsImlzTWluZSI6ZmFsc2UsImlzUmV2ZWFsZWQiOmZhbHNlLCJpc0ZsYWdnZWQiOmZhbHNlfSx7Inhwb3MiOjYsInlwb3MiOjcsInZhbHVlIjoxLCJpc01pbmUiOmZhbHNlLCJpc1JldmVhbGVkIjpmYWxzZSwiaXNGbGFnZ2VkIjpmYWxzZX0seyJ4cG9zIjo3LCJ5cG9zIjo3LCJ2YWx1ZSI6MSwiaXNNaW5lIjpmYWxzZSwiaXNSZXZlYWxlZCI6ZmFsc2UsImlzRmxhZ2dlZCI6ZmFsc2V9XV0sImdhbWVDb3VudCI6MSwibWluZXNGb3VuZCI6MCwiZmFsc2VNaW5lcyI6MCwic3RhdHVzIjoiT05HT0lORyIsIm1vdmVzTWFkZSI6MCwib3B0aW9ucyI6eyJyb3dzIjo4LCJjb2xzIjo4LCJtaW5lcyI6MTB9fQ==
6 changes: 6 additions & 0 deletions internal/handle-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function handleError(message) {
console.error(`\n\n${message}\n\n`);
process.exit(1);
};

module.exports = handleError;
26 changes: 26 additions & 0 deletions internal/validate-commands-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const fs = require('fs');
const handleError = require('./handle-error');

const commandsFile = fs.readFileSync('./commands.json');
let commandsJson;
try {
commandsJson = JSON.parse(commandsFile);
} catch (e) {
if (e instanceof SyntaxError) {
handleError(`The commands.json file contains a syntax error: ${e.message}`);
return;
}
throw e;
}

if (!commandsJson.commands || !Array.isArray(commandsJson.commands)) {
handleError('The structure of the commands object is broken.');
return;
}

commandsJson.commands.forEach(command => {
if (typeof command !== 'string') {
handleError('Each item in the commands array must be a string');
return;
}
})
44 changes: 44 additions & 0 deletions internal/validate-commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const fs = require('fs');
const handleError = require('./handle-error');

const VALID_COMMANDS = {
CLEAR: 'CLEAR',
FLAG: 'FLAG',
UNFLAG: 'UNFLAG',
END: 'END'
};
const NUM_ROWS = 8;
const NUM_COLS = 8;

const commandsFile = fs.readFileSync('./commands.json');
const { commands } = JSON.parse(commandsFile)

commands.forEach(command => {
const [action, cellId] = command.toUpperCase().split(/\s+/g);
if (!Object.values(VALID_COMMANDS).includes(action)) {
handleError(`Invalid command "${command}"`);
return;
}

if (action === VALID_COMMANDS.END) {
return;
}

const posX = Number(cellId.charCodeAt(0) - "A".charCodeAt(0));
const posY = Number.parseInt(cellId.charAt(1), 10) - 1;

if (isNaN(posY)) {
handleError(`${command}: The second character ${cellId.charAt(1)} in ${cellId} has to be a number`);
return;
}

if (
posX < 0 ||
posX >= NUM_COLS ||
posY < 0 ||
posY >= NUM_ROWS
) {
handleError(`${command}: Field ${cellId} does not exist.`);
return;
}
})

0 comments on commit a40f2f4

Please sign in to comment.