Game Over!
+The correct word was: rainbow
+ +diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..00352331 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,52 @@ +name: ๐ชฒ Bug Report +description: Report your bug by filling teh information given below +title: "[Bug]: " + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: textarea + id: bug-description + attributes: + label: Give a brief about the bug โ๏ธ + description: Enter a brief description about the bug report + placeholder: Please include a summary, also include relevant motivation and context. + value: "Description" + validations: + required: true + - type: textarea + id: behaviors + attributes: + label: What is the expected behavior? ๐ค + description: Enter the expected behavior of bug + placeholder: Please include a summary, also include relevant motivation and context. + value: "Description" + validations: + required: true + - type: textarea + id: instructions + attributes: + label: Provide step by step information reproduce the bug ๐ + description: Enter the description on how you plan to find the bug's solution + placeholder: Please include a summary, also include relevant motivation and context. + value: "Description" + validations: + required: true + - type: dropdown + id: contribution + attributes: + label: Select program in which you are contributing + multiple: true + options: + - GSSoC24 + - Other + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [CODE OF CONDUCT](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/CODE_OF_CONDUCT.md) + options: + - label: I follow [CONTRIBUTING GUIDELINE](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/Contributor.md) of this project. + required: true diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md deleted file mode 100644 index 80a27672..00000000 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Documentation Issue -about: Report an issue with the project documentation -title: "[Documentation] :" -labels: Easy, IWOC2024 -assignees: '' - ---- - -## About Documentation - -## Description - -## Affected Documentation Section - -## Expected Documentation - -## Severity -- [ ] Low -- [ ] Medium -- [ ] High -- [ ] Critical - - -## Connect Us On social media - -- [ ] Star the repositry -- [ ] GitHub -- [ ] LinkedIn -- [ ] YouTube -- [ ] Discord - -### Thank you for raising issue in GameSpher 3.0 diff --git a/.github/ISSUE_TEMPLATE/documentation_bug.yml b/.github/ISSUE_TEMPLATE/documentation_bug.yml new file mode 100644 index 00000000..68d7f99e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation_bug.yml @@ -0,0 +1,43 @@ +name: ๐ Documentation or README.md issue report +description: Report an issue in the project's documentation or README.md file. +title: "[Documentation Bug]: " + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this documentation bug report! + - type: textarea + id: documentation-bug-description + attributes: + label: Describe the bug โ๏ธ + description: Enter a brief description about the documentation bug report + placeholder: Please include a summary, also include relevant motivation and context. + value: "Describe your bug here" + validations: + required: true + - type: textarea + id: instructions + attributes: + label: Provide step by step information reproduce the bug ๐ + description: Enter the description on how you plan to find the bug's solution + placeholder: Please include a summary, also include relevant motivation and context. + value: "Description" + validations: + required: true + - type: dropdown + id: contribution + attributes: + label: Select program in which you are contributing + multiple: true + options: + - GSSoC24 + - Other + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [CODE OF CONDUCT](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/CODE_OF_CONDUCT.md) + options: + - label: I follow [CONTRIBUTING GUIDELINE](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/Contributor.md) of this project. + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 0f623f67..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Feature Request -about: Suggest a new feature or enhancement for the project -title: "[Feature Request] :" -labels: IWOC2024, Medium -assignees: '' - ---- - -## About Feature - -## Description - -## Technologies Used - -## Screenshot - -## Connect Us On Social Media - -- [ ] Star the repositry -- [ ] GitHub -- [ ] LinkedIn -- [ ] YouTube -- [ ] Discord - -### Thank you for raising issue in GameSpher 3.0 diff --git a/.github/ISSUE_TEMPLATE/game_enhancement.yml b/.github/ISSUE_TEMPLATE/game_enhancement.yml new file mode 100644 index 00000000..5fe60c61 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/game_enhancement.yml @@ -0,0 +1,43 @@ +name: ๐Game Enhancement Request +description: Suggest your enhancement for the existing game +title: "[Enhancement]: " + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this enhancement request form + - type: textarea + id: bug-description + attributes: + label: Do you want to have the enhancement of existing game ? ๐ Describe yourself.. + description: Enter a brief description about the enhancement you need + placeholder: Give all the context of your enhancement as well as the existing game + value: "Game enhancement" + validations: + required: true + - type: textarea + id: behaviour + attributes: + label: Describe the solution you'd like + description: Give steps in which you will solve it + placeholder: Please include a summary, also include relevant motivation and context. + value: "Solution steps" + validations: + required: true + - type: dropdown + id: contribution + attributes: + label: Select program in which you are contributing + multiple: true + options: + - GSSoC24 + - Other + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [CODE OF CONDUCT](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/CODE_OF_CONDUCT.md) + options: + - label: I follow [CONTRIBUTING GUIDELINE](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/Contributor.md) of this project. + required: true diff --git a/.github/ISSUE_TEMPLATE/new-game.md b/.github/ISSUE_TEMPLATE/new-game.md deleted file mode 100644 index 4d94e901..00000000 --- a/.github/ISSUE_TEMPLATE/new-game.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: New Game -about: Description of game -title: "[Game]: " -labels: IWOC2024, Medium -assignees: '' - ---- - -## Game Name - -## Description - - - -## Screenshot Section - - - -## Demo Video Section - - - -### Connect Us On Social Media - -- [ ] Star the repositry -- [ ] GitHub -- [ ] LinkedIn -- [ ] YouTube -- [ ] Discord - -### Thank you for raising issue in GameSpher 3.0 diff --git a/.github/ISSUE_TEMPLATE/new_game_request.yml b/.github/ISSUE_TEMPLATE/new_game_request.yml new file mode 100644 index 00000000..4007cedd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new_game_request.yml @@ -0,0 +1,43 @@ +name: ๐๐ฎ new game request +description: Suggest an idea and show your creativity to add new game +title: "[New game]: " + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out your new game issue + - type: textarea + id: new-game + attributes: + label: ๐ฎ Game Request + description: Describe the game logic and also give a brief about the features of the game + placeholder: add all necessary details required for your new game + value: "Game logic and basic description" + validations: + required: true + - type: textarea + id: features + attributes: + label: Point down the features + description: think about your the feature your game will have + placeholder: Please include a summary, also include relevant motivation and context. + value: "Game points" + validations: + required: true + - type: dropdown + id: contribution + attributes: + label: Select program in which you are contributing + multiple: true + options: + - GSSoC24 + - Other + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [CODE OF CONDUCT](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/CODE_OF_CONDUCT.md) + options: + - label: I follow [CONTRIBUTING GUIDELINE](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/Contributor.md) of this project. + required: true diff --git a/.github/ISSUE_TEMPLATE/question_and_support.yml b/.github/ISSUE_TEMPLATE/question_and_support.yml new file mode 100644 index 00000000..7fdbebd5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question_and_support.yml @@ -0,0 +1,34 @@ +name: โ Question or Support Request +description: Questions and requests for support. +title: "[Question]: " + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this and letting us know your question + - type: textarea + id: description + attributes: + label: Describe your question or ask for support.โ + description: Enter a brief description about your question or support needed + placeholder: Please include a summary, also include relevant motivation and context. + value: "Description" + validations: + required: true + - type: dropdown + id: contribution + attributes: + label: Select program in which you are contributing + multiple: true + options: + - GSSoC24 + - Other + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our [CODE OF CONDUCT](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/CODE_OF_CONDUCT.md) + options: + - label: I follow [CONTRIBUTING GUIDELINE](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/Contributor.md) of this project. + required: true diff --git a/.github/ISSUE_TEMPLATE/styles.yml b/.github/ISSUE_TEMPLATE/styles.yml deleted file mode 100644 index f857de7e..00000000 --- a/.github/ISSUE_TEMPLATE/styles.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Style Changing Request -description: Suggest a style designs -title: '[style]: ' -labels: ['enhancement'] -body: - - type: markdown - attributes: - value: | - Thanks for taking the time to fill out this template! - - type: textarea - id: style-idea - attributes: - label: What's the style idea? - placeholder: Add descriptions - value: 'We need to improve ' - validations: - required: true - - type: textarea - id: screenshots - attributes: - label: Add screenshots - required: true - - - label: I have read the [Contributing Guidelines](https://github.com/priyankarpal/ProjectsHut/blob/main/contributing.md) - required: true - - - label: I agree to follow this project's [Code of Conduct](https://github.com/priyankarpal/ProjectsHut/blob/main/CODE_OF_CONDUCT.md) - required: true - - - label: I'm a GSSoC'23 contributor - - - label: I want to work on this issue - description: Add screenshots to see the demo - placeholder: Add screenshots - value: 'Add screenshots' - - type: checkboxes - id: terms - attributes: - label: Code of Conduct - description: By submitting this issue, you agree to follow our Code of Conduct - options: - - label: I agree to follow this project's Code of Conduct - required: true - - - label: I have read the [Contributing Guidelines](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/Contributor.md) - required: true - - - label: I agree to follow this project's [Code of Conduct](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/CODE_OF_CONDUCT.md) - required: true - - - label: I'm a GSSoC'23 contributor - - - label: I want to work on this issue diff --git a/.github/workflows/AutoGreeting.yml b/.github/workflows/AutoGreeting.yml new file mode 100644 index 00000000..a06bdd22 --- /dev/null +++ b/.github/workflows/AutoGreeting.yml @@ -0,0 +1,25 @@ +name: Auto Greeting + +on: + issues: + types: [opened] + +permissions: + issues: write + +jobs: + greet: + runs-on: ubuntu-latest + steps: + - name: Add a greeting comment + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const issueComment = `Hey @${context.payload.issue.user.login}! ๐ \n\n ๐ Thanks for opening this issue. We appreciate your contribution and will look into it as soon as possible. \n ๐ Donโt forget to star our [GameSphere](https://github.com/GameSphere-MultiPlayer/GameSphere) and Follow Us on GitHub \n ๐ Make sure you join our [Discord](https://discord.gg/rZb46cCMmK), we have created separate channels for all projects`; + await github.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: issueComment + }); diff --git a/.github/workflows/assign.yml b/.github/workflows/assign.yml new file mode 100644 index 00000000..e5e3ad05 --- /dev/null +++ b/.github/workflows/assign.yml @@ -0,0 +1,72 @@ +name: Assign on Comment +on: + issue_comment: + types: + - created + +jobs: + assign: + runs-on: ubuntu-latest + + steps: + - name: Check if /assign command is present + id: check_command + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const commentBody = context.payload.comment.body; + const assignCommand = '/assign'; + const isCommandPresent = commentBody.includes(assignCommand); + console.log(`Command present: ${isCommandPresent}`); + console.log(`Comment: ${commentBody}`); + console.log(`Issue Number: ${context.payload.issue.number}`); + console.log(`Issue State: ${context.payload.issue.state}`); + console.log(`Assignees: ${context.payload.issue.assignees.map(assignee => assignee.login)}`); + console.log(`Issue URL: ${context.payload.issue.html_url}`); + console.log(`Comment URL: ${context.payload.comment.html_url}`); + console.log(`Comment Author: ${context.payload.comment.user.login}`); + console.log(`Repository: ${context.repo.owner}/${context.repo.repo}`); + console.log(`Repository URL: ${context.payload.repository.html_url}`); + console.log(`Repository Full Name: ${context.payload.repository.full_name}`); + console.log(`Repository Name: ${context.payload.repository.name}`); + console.log(`Repository Owner: ${context.payload.repository.owner.login}`); + console.log(`Repository Owner URL: ${context.payload.repository.owner.html_url}`); + console.log(`Event Name: ${context.eventName}`); + + const commentAuthor = context.payload.comment.user.login; + core.setOutput('comment_author', commentAuthor); + + const isGreetingFromOwner = commentAuthor === context.payload.repository.owner.login; + core.setOutput('is_greeting_from_owner', isGreetingFromOwner.toString()); + + const isAlreadyAssigned = context.payload.issue.assignees.length > 0; + core.setOutput('is_already_assigned', isAlreadyAssigned.toString()); + + if (isCommandPresent && isGreetingFromOwner) { + console.log('Skipping assigning issue: Greeting from repository owner.'); + console.log(`::set-output name=assign_issue::false`); + } else if (isCommandPresent && isAlreadyAssigned) { + const { owner, repo, number } = context.issue; + const assignees = context.payload.issue.assignees.map(assignee => assignee.login).join(', '); + const commentBody = `Hey @${commentAuthor} ! , This issue is already assigned to @${assignees}. ๐ \n You can work on other issues ๐ \n If there is anything wrong you can contact us on [Discord๐น๏ธ](https://discord.gg/fgwk4XZfxG)๐`; + await github.issues.createComment({ owner, repo, issue_number: number, body: commentBody }); + console.log(`Commented on the issue: ${commentBody}.`); + console.log(`::set-output name=assign_issue::false`); + } else if (isCommandPresent) { + console.log(`::set-output name=assign_issue::true`); + } else { + console.log(`::set-output name=assign_issue::false`); + } + + - name: Assign the issue + if: steps.check_command.outputs.assign_issue == 'true' + id: assign_issue + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + const assignee = context.payload.comment.user.login; + await github.issues.addAssignees({ owner, repo, issue_number: number, assignees: [assignee] }); + console.log(`Assigned the issue to ${assignee}.`); diff --git a/.github/workflows/auto-label-issues.yml b/.github/workflows/auto-label-issues.yml new file mode 100644 index 00000000..65dbc277 --- /dev/null +++ b/.github/workflows/auto-label-issues.yml @@ -0,0 +1,22 @@ +name: Auto-label on Any Issue + +on: + issues: + types: [opened] + +jobs: + auto-label: + runs-on: ubuntu-latest + steps: + - name: Add labels to any new issue + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const labelsToAdd = ["gssoc"]; + await github.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: labelsToAdd + }); diff --git a/.github/workflows/close_invalid_issue.yml b/.github/workflows/close_invalid_issue.yml new file mode 100644 index 00000000..7d94945c --- /dev/null +++ b/.github/workflows/close_invalid_issue.yml @@ -0,0 +1,59 @@ +name: Close Issues Without Keywords +on: + issues: + types: + - opened + +jobs: + close-issue: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Close issue without keywords + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const keywords = ['Documentation Bug', 'New game', 'Enhancement', 'Bug', 'Question']; + const issueTitle = context.payload.issue.title ? context.payload.issue.title.toLowerCase() : ''; + const openerUsername = context.payload.issue.user.login; + + let containsKeyword = false; + for (const keyword of keywords) { + if (issueTitle.includes(keyword.toLowerCase())) { + containsKeyword = true; + break; + } + } + + if (!containsKeyword) { + const commentBody = `Hey @${openerUsername}! ๐ \n It seems like you are not following proper guidelines !! ๐ \n Read documentation properly !!๐ \n If you have any queries reach out to us on [Discord](https://discord.gg/rZb46cCMmK) .`; + + // Close the issue + await github.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + state: 'closed' + }); + + // Add comment to the issue + await github.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: commentBody + }); + + console.log('Closed the issue and added a comment.'); + } else { + console.log('Issue contains one of the keywords. Skipping...'); + } diff --git a/.github/workflows/close_old_issues.yml b/.github/workflows/close_old_issues.yml new file mode 100644 index 00000000..a8ad6798 --- /dev/null +++ b/.github/workflows/close_old_issues.yml @@ -0,0 +1,80 @@ +name: Close Older Issues + +on: + workflow_dispatch: + +jobs: + close-older-issues: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Install dependencies + run: npm install @actions/github + + - name: Fetch opened issues + id: fetch_issues + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const oneWeekAgo = new Date(); + oneWeekAgo.setDate(oneWeekAgo.getDate() - 7); + + const { data: issues } = await github.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + sort: 'created', + direction: 'asc', + per_page: 100 + }); + + const olderIssues = issues.filter(issue => issue.pull_request === undefined && new Date(issue.created_at) < oneWeekAgo); + core.setOutput('older_issues', olderIssues.map(issue => issue.number).join(',')); + + - name: Close older issues and comment + if: steps.fetch_issues.outputs.older_issues != '' + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const olderIssueNumbers = '${{ steps.fetch_issues.outputs.older_issues }}'.split(','); + + for (const issueNumber of olderIssueNumbers) { + // Get the issue details + const { data: issue } = await github.issues.get({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber) + }); + + // Close the older issue + await github.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber), + state: 'closed' + }); + + // Comment on the closed issue + await github.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber), + body: `Hello @${issue.user.login}, Time's up!โฐ \n Sorry for closing your issue! \n But it's more than a week since we haven't received anything from your side ๐ข . \n Come up with new ideas, create a new issue and make sure you finish it within a week! ๐ฅ \n All the best! ๐ \n Happy Hacking! ๐` + }); + + console.log(`Closed and commented on issue #${issueNumber}.`); + } + + - name: Skip if no older issues + if: steps.fetch_issues.outputs.older_issues == '' + run: echo "No older issues found. Skipping..." diff --git a/.github/workflows/greet.yml b/.github/workflows/greet.yml new file mode 100644 index 00000000..4c70220f --- /dev/null +++ b/.github/workflows/greet.yml @@ -0,0 +1,125 @@ +name: Comment and Label on Issue Opened +on: + issues: + types: + - opened + +jobs: + comment_and_label: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Add comment + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const commentAuthor = context.payload.issue.user.login; + const commentBody = `Hey @${commentAuthor} ! \n Thank you for raising an issue ๐ \n You can self assign the issue by commenting /assign in comment ๐ \n Make sure you follow [CODE OF CONDUCT](https://github.com/GameSphere-MultiPlayer/GameSphere/blob/main/.github/CODE_OF_CONDUCT.md) `; + const { owner, repo, number } = context.issue; + + await github.issues.createComment({ + owner: owner, + repo: repo, + issue_number: number, + body: commentBody + }); + + - name: Add label if issue body contains "GSSoC24" + id: check_label_gs_soc24 + run: | + if grep -qE "GSSoC24" <<< "${{ github.event.issue.body }}"; then + echo "::set-output name=add_label_gs_soc24::true" + else + echo "::set-output name=add_label_gs_soc24::false" + fi + + - name: Add label "GSSoC24" + if: ${{ steps.check_label_gs_soc24.outputs.add_label_gs_soc24 == 'true' }} + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: number, + labels: ["gssoc"] + }); + + - name: Add label if issue body contains "GSSoC23" + id: check_label_gs_soc23 + run: | + if grep -qE "GSSoC23" <<< "${{ github.event.issue.body }}"; then + echo "::set-output name=add_label_gs_soc23::true" + else + echo "::set-output name=add_label_gs_soc23::false" + fi + + - name: Add label "GSSoC23" + if: ${{ steps.check_label_gs_soc23.outputs.add_label_gs_soc23 == 'true' }} + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: number, + labels: ["GSSoC23"] + }); + + - name: Add label if issue body contains "hacktoberfest" + id: check_label_hacktoberfest + run: | + if grep -qE "hacktoberfest" <<< "${{ github.event.issue.body }}"; then + echo "::set-output name=add_label_hacktoberfest::true" + else + echo "::set-output name=add_label_hacktoberfest::false" + fi + + - name: Add label "hacktoberfest" + if: ${{ steps.check_label_hacktoberfest.outputs.add_label_hacktoberfest == 'true' }} + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: number, + labels: ["hacktoberfest"] + }); + + - name: Add label if issue body contains "IWOC2024" + id: check_label_iwoc + run: | + if grep -qE "IWOC2024" <<< "${{ github.event.issue.body }}"; then + echo "::set-output name=add_label_iwoc::true" + else + echo "::set-output name=add_label_iwoc::false" + fi + + - name: Add label "IWOC2024" + if: ${{ steps.check_label_iwoc.outputs.add_label_iwoc == 'true' }} + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: number, + labels: ["IWOC2024"] + }); diff --git a/.github/workflows/issue_close_greet.yml b/.github/workflows/issue_close_greet.yml new file mode 100644 index 00000000..9489218e --- /dev/null +++ b/.github/workflows/issue_close_greet.yml @@ -0,0 +1,22 @@ +name: Comment on Issue Closure +on: + issues: + types: + - closed + +jobs: + comment: + runs-on: ubuntu-latest + + steps: + - name: Comment on Issue Closure + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + const author = context.payload.issue.user.login; + const commentBody = `Hey @${author} ! Thank you so much for your raising the issue๐ \n Itโs all yours, you can come anytime again and make some contributions! ๐ \n Alone, we can do little, but together we can do so much! ๐ + `; + await github.issues.createComment({ owner, repo, issue_number: number, body: commentBody }); + console.log(`Commented on the issue: ${commentBody}.`); diff --git a/.github/workflows/level_tags.yml b/.github/workflows/level_tags.yml new file mode 100644 index 00000000..95ed1971 --- /dev/null +++ b/.github/workflows/level_tags.yml @@ -0,0 +1,55 @@ +name: Add Tags to Issues +on: + issues: + types: + - opened + +jobs: + add-tags: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Add tags to issues + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { issue } = context.payload; + const { owner, repo } = context.repo; + const { title, body } = issue; + + let tagsToAdd = []; + + // Check if issue text contains "Documentation Bug" + if (title && title.toLowerCase().includes('documentation bug')) { + tagsToAdd.push('Documentation Bug ๐'); + tagsToAdd.push('level1'); + } + + // Check if issue title contains "Enhancement" + if (title && title.toLowerCase().includes('enhancement')) { + tagsToAdd.push('Enhancement โก๏ธ'); + tagsToAdd.push('level2'); + } + + if (tagsToAdd.length > 0) { + // Add tags to the issue + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: issue.number, + labels: tagsToAdd + }); + + console.log(`Added tags ${tagsToAdd.join(', ')} to issue #${issue.number}.`); + } else { + console.log('No tags to add.'); + } diff --git a/.github/workflows/new_game.yml b/.github/workflows/new_game.yml new file mode 100644 index 00000000..8a95d1b4 --- /dev/null +++ b/.github/workflows/new_game.yml @@ -0,0 +1,45 @@ +name: Add New Game Label +on: + issues: + types: + - opened + +jobs: + label: + runs-on: ubuntu-latest + + steps: + - name: Check if issue title contains "New Game" + id: check_title + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const issueTitle = context.payload.issue.title; + const isNewGame = issueTitle.includes('New game'); + console.log(`Issue title: ${issueTitle}`); + console.log(`Is New Game: ${isNewGame}`); + console.log(`Issue Number: ${context.payload.issue.number}`); + console.log(`Issue State: ${context.payload.issue.state}`); + console.log(`Issue URL: ${context.payload.issue.html_url}`); + console.log(`Repository: ${context.repo.owner}/${context.repo.repo}`); + console.log(`Repository URL: ${context.payload.repository.html_url}`); + console.log(`Repository Full Name: ${context.payload.repository.full_name}`); + console.log(`Repository Name: ${context.payload.repository.name}`); + console.log(`Repository Owner: ${context.payload.repository.owner.login}`); + console.log(`Repository Owner URL: ${context.payload.repository.owner.html_url}`); + console.log(`Event Name: ${context.eventName}`); + + core.setOutput('is_new_game', isNewGame.toString()); + + - name: Add "New Game" label + if: steps.check_title.outputs.is_new_game == 'true' + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + const label = 'New Game ๐ฎ'; + const level_label='level3'; + await github.issues.addLabels({ owner, repo, issue_number: number, labels: [label,level_label] }); + console.log(`Added label "${label}" to the issue.`); diff --git a/.github/workflows/pr_check.yml b/.github/workflows/pr_check.yml new file mode 100644 index 00000000..132ef733 --- /dev/null +++ b/.github/workflows/pr_check.yml @@ -0,0 +1,216 @@ +name: Pull Request Validation + +on: + pull_request_target: + types: + - opened + - synchronize + +jobs: + pr-validation: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Install dependencies + run: npm install --prefix .github octokit + + - name: Validate pull request + id: validate_pr + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const prNumber = context.payload.pull_request.number; + const repoOwner = context.payload.repository.owner.login; + const repoName = context.payload.repository.name; + + const { data: pr } = await github.pulls.get({ + owner: repoOwner, + repo: repoName, + pull_number: prNumber + }); + + // Check if the PR content contains an issue reference + const hasIssueReference = /#[0-9]+/.test(pr.body); + if (!hasIssueReference) { + // Close the PR + await github.pulls.update({ + owner: repoOwner, + repo: repoName, + pull_number: prNumber, + state: 'closed' + }); + + // Comment on the closed PR + await github.issues.createComment({ + owner: repoOwner, + repo: repoName, + issue_number: prNumber, + body: `Hey @${pr.user.login},\nPlease make sure to link the relevant issue using the appropriate syntax, such as "#issueNumber" ๐. \n Follow the proper guideline and make a new PR again ๐. \n Happy Hacking ๐` + }); + + console.log(`Closed and commented on pull request #${prNumber} due to missing issue reference.`); + return; // Stop further processing + } + + // Get the issue number from the PR content + const issueNumber = pr.body.match(/#([0-9]+)/)[1]; + + // Get the issue details + const { data: issue } = await github.issues.get({ + owner: repoOwner, + repo: repoName, + issue_number: issueNumber + }); + + // Check if the issue is open + if (issue.state !== 'open') { + // Close the PR + await github.pulls.update({ + owner: repoOwner, + repo: repoName, + pull_number: prNumber, + state: 'closed' + }); + + // Comment on the closed PR + await github.issues.createComment({ + owner: repoOwner, + repo: repoName, + issue_number: prNumber, + body: `Hey @${pr.user.login},\n You can't work on a closed issue ๐! \n Follow the proper guideline and make a new PR again ๐. \n Happy Hacking ๐` + }); + + console.log(`Closed and commented on pull request #${prNumber} due to closed issue reference.`); + return; // Stop further processing + } + + // Check if the issue has the "level3" label + const hasLevel3Label = issue.labels.some(label => label.name.toLowerCase() === 'level3'); + if (hasLevel3Label) { + // Get the PR files + const { data: files } = await github.pulls.listFiles({ + owner: repoOwner, + repo: repoName, + pull_number: prNumber + }); + + // Check for required changes in the PR + const changes = []; + + // Check if a new folder is created inside the "Games" folder and contains a new file + const gamesFolderPath = 'Games/'; + const newFolderRegex = new RegExp(`${gamesFolderPath}([^/]+)/.*$`); + const newFolderCreated = files.some(file => newFolderRegex.test(file.filename)); + + // Check if a README.md file is added in the newly created folder + const readmeRegex = new RegExp(`${gamesFolderPath}([^/]+)/README.md$`); + const readmeAdded = files.some(file => readmeRegex.test(file.filename)); + + // Comment with the required changes, if any + if (!newFolderCreated) { + changes.push('- Please create a new folder inside the "Games" folder.'); + } + if (!readmeAdded) { + changes.push('- Please add a README.md file inside the newly created folder.'); + } + + // Check if the main README.md file is modified + const mainReadmeModified = files.some(file => file.filename === 'README.md'); + + if (!mainReadmeModified) { + changes.push('- Please modify the main README.md file.'); + } + + // Check if an image is added to the assets/images directory + const imageAdded = files.some(file => file.filename.startsWith('assets/images/')); + + if (!imageAdded) { + changes.push('- Please add an image to the assets/images directory.'); + } + + if (changes.length > 0) { + const comment = [ + `Hello @${pr.user.login},`, + `You need to make the following changes:`, + ...changes.map(change => ` ${change}`), + '', + 'Hoping that you will make those changes soon ๐' + ].join('\n'); + + // Comment on the pull request + await github.pulls.createReview({ + owner: repoOwner, + repo: repoName, + pull_number: prNumber, + event: 'REQUEST_CHANGES', + body: comment + }); + + // Add labels to the pull request + await github.issues.addLabels({ + owner: repoOwner, + repo: repoName, + issue_number: prNumber, + labels: ['Changes Requested โ๏ธ', 'Pending โฑ๏ธ'] + }); + + console.log(`Commented on pull request #${prNumber} with required changes.`); + } else { + const existingLabels = pr.labels.map(label => label.name.toLowerCase()); + + if (existingLabels.includes('changes requested') || existingLabels.includes('pending')) { + // Remove the "changes requested" and "pending" labels + await github.issues.removeLabel({ + owner: repoOwner, + repo: repoName, + issue_number: prNumber, + name: 'Changes Requested โ๏ธ' + }); + await github.issues.removeLabel({ + owner: repoOwner, + repo: repoName, + issue_number: prNumber, + name: 'Pending โฑ๏ธ' + }); + + // Approve the changes + await github.pulls.createReview({ + owner: repoOwner, + repo: repoName, + pull_number: prNumber, + event: 'APPROVE' + }); + + // Add the "under review" label + await github.issues.addLabels({ + owner: repoOwner, + repo: repoName, + issue_number: prNumber, + labels: ['Pending โฑ๏ธ'] + }); + + console.log(`Updated pull request #${prNumber} with approved changes.`); + } else { + // Add label to the pull request + await github.issues.addLabels({ + owner: repoOwner, + repo: repoName, + issue_number: prNumber, + labels: ['Pending โฑ๏ธ'] + }); + + console.log(`Pull request #${prNumber} is valid and meets the requirements.`); + } + } + } else { + console.log(`Pull request #${prNumber} does not have the "level3" label. No further validation is performed.`); + } diff --git a/.github/workflows/pr_close_greet.yml b/.github/workflows/pr_close_greet.yml new file mode 100644 index 00000000..814e727c --- /dev/null +++ b/.github/workflows/pr_close_greet.yml @@ -0,0 +1,22 @@ +name: Comment on PR Closure +on: + pull_request_target: + types: + - closed + +jobs: + comment: + runs-on: ubuntu-latest + + steps: + - name: Comment on PR Closure + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + const commentAuthor = context.payload.pull_request.user.login; + const commentBody = `Thank you @${commentAuthor} , for your valuable time and contribution in our GameZone ๐. \n Itโs our GameZone, so Letโs build this GameZone altogether !!๐ค\n Hoping to see you soon with another PR again ๐ \n Wishing you all the best for your journey into Open Source๐ + `; + await github.issues.createComment({ owner, repo, issue_number: number, body: commentBody }); + console.log(`Commented on the closed PR: ${commentBody}.`); diff --git a/.github/workflows/pr_greet.yml b/.github/workflows/pr_greet.yml new file mode 100644 index 00000000..eda9dc1a --- /dev/null +++ b/.github/workflows/pr_greet.yml @@ -0,0 +1,22 @@ +name: Comment on PR Creation +on: + pull_request_target: + types: + - opened + +jobs: + comment: + runs-on: ubuntu-latest + + steps: + - name: Comment on PR + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const { owner, repo, number } = context.issue; + const commentAuthor = context.payload.sender.login; + const commentBody = `Thank you @${commentAuthor} ,for creating the PR and contributing to our GameZone ๐ \n Review team will review the PR and will reach out to you soon! ๐ \n Make sure that you have marked all the tasks that you are done with โ . \n Thank you for your patience! ๐ + `; + await github.issues.createComment({ owner, repo, issue_number: number, body: commentBody }); + console.log(`Commented on the PR: ${commentBody}.`); diff --git a/.github/workflows/prevent_multiple_issues.yml b/.github/workflows/prevent_multiple_issues.yml new file mode 100644 index 00000000..1d3ca634 --- /dev/null +++ b/.github/workflows/prevent_multiple_issues.yml @@ -0,0 +1,77 @@ +name: Close Issue if Opener has Opened Issues + +on: + issues: + types: + - opened + +jobs: + close_issue: + runs-on: ubuntu-latest + + steps: + - name: Check if opener has multiple open issues + id: check_open_issues + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const issueNumber = context.issue.number; + const issueOpener = context.payload.issue.user.login; + + const previousIssuesResponse = await github.request('GET /repos/{owner}/{repo}/issues', { + owner, + repo, + state: 'open', + creator: issueOpener + }); + + const previousOpenIssues = previousIssuesResponse.data.filter(issue => issue.number !== issueNumber && !issue.pull_request); + const previousOpenIssueNumbers = previousOpenIssues.map(issue => `#${issue.number}`); + const openerName = context.payload.issue.user.login; + + const closeIssue = previousOpenIssues.length > 0; + console.log(`Close issue: ${closeIssue}`); + + if (closeIssue) { + const comment = `Hey @${openerName} , You can't have another issue before completing the previous one ๐ \n you already have the following ${previousOpenIssues.length} open issues ๐ ! :\n\n${previousOpenIssueNumbers.join('\n')}`; + core.exportVariable('comment_body', comment); // Export the variable + core.setOutput('close_issue', true); + } else { + core.exportVariable('comment_body', ''); + core.setOutput('close_issue', false); + } + + - name: Close the issue and add a comment + if: always() && ${{ needs.check_open_issues.outputs.close_issue }} + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const issueNumber = context.issue.number; + const comment = process.env.comment_body; // Retrieve the exported variable + + if (comment.trim() === '') { + console.log('Comment body is empty. Skipping comment creation.'); + return; + } + + const closeComment = `${comment}`; + + await github.issues.createComment({ + owner, + repo, + issue_number: issueNumber, + body: closeComment + }); + + await github.issues.update({ + owner, + repo, + issue_number: issueNumber, + state: 'closed' + }); diff --git a/.github/workflows/prevent_multiple_pr.yml b/.github/workflows/prevent_multiple_pr.yml new file mode 100644 index 00000000..65e542a4 --- /dev/null +++ b/.github/workflows/prevent_multiple_pr.yml @@ -0,0 +1,77 @@ +name: Close Issue if Opener has Opened Pull Requests + +on: + pull_request_target: + types: + - opened + +jobs: + close_pull_request: + runs-on: ubuntu-latest + + steps: + - name: Check if opener has multiple open pull requests + id: check_open_pull_requests + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const pullRequestNumber = context.payload.pull_request.number; + const pullRequestOpener = context.payload.pull_request.user.login; + + const previousPullRequestsResponse = await github.pulls.list({ + owner, + repo, + state: 'open' + }); + + const previousOpenPullRequests = previousPullRequestsResponse.data.filter(pr => pr.user.login === pullRequestOpener && pr.number !== pullRequestNumber); + const previousOpenPullRequestNumbers = previousOpenPullRequests.map(pr => `#${pr.number}`); + const openerName = context.payload.pull_request.user.login; + + const closePullRequest = previousOpenPullRequests.length > 0; + console.log(`Close pull request: ${closePullRequest}`); + + if (closePullRequest) { + const comment = `Hey @${openerName}, you can't open another pull request before completing the previous one ๐\nYou already have the following ${previousOpenPullRequests.length} open pull request(s):\n${previousOpenPullRequestNumbers.join('\n')}`; + core.exportVariable('comment_body', comment); + core.setOutput('close_pull_request', true); + } else { + core.exportVariable('comment_body', ''); + core.setOutput('close_pull_request', false); + return; // Return and skip further steps + } + + - name: Close the pull request and add a comment + if: always() && ${{ needs.check_open_pull_requests.outputs.close_pull_request }} + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const pullRequestNumber = context.payload.pull_request.number; + const comment = process.env.comment_body; + + if (comment.trim() === '') { + console.log('Comment body is empty. Skipping comment creation.'); + return; + } + + const closeComment = `${comment}`; + + await github.issues.createComment({ + owner, + repo, + issue_number: pullRequestNumber, + body: closeComment + }); + + await github.pulls.update({ + owner, + repo, + pull_number: pullRequestNumber, + state: 'closed' + }); diff --git a/.github/workflows/remove_duplicate.yml b/.github/workflows/remove_duplicate.yml new file mode 100644 index 00000000..a0947dfb --- /dev/null +++ b/.github/workflows/remove_duplicate.yml @@ -0,0 +1,117 @@ +name: Prevent Duplicate Issues +on: + issues: + types: + - opened + +jobs: + prevent-duplicate-issues: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Install dependencies + run: npm install --prefix .github string-similarity + + - name: Check for duplicate issue + id: check_duplicate + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const newIssueTitle = context.payload.issue.title ? context.payload.issue.title.toLowerCase() : ''; + const newIssueWords = newIssueTitle.split(' '); + + const { data: issues } = await github.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + per_page: 100 // Adjust the per_page value as per your requirements + }); + + const stringSimilarity = require('.github/node_modules/string-similarity'); + let isDuplicate = false; + let duplicateIssueNumber = null; + let similarIssueNumber = null; + + for (const issue of issues) { + if (issue.number === context.issue.number) { + continue; // Skip the current issue being checked + } + + const existingIssueTitle = issue.title ? issue.title.toLowerCase() : ''; + const existingIssueWords = existingIssueTitle.split(' '); + + let matchedWordCount = 0; + for (const word of newIssueWords) { + let maxSimilarity = 0; + for (const existingWord of existingIssueWords) { + const similarity = stringSimilarity.compareTwoStrings(word, existingWord); + if (similarity >= 0.75 && similarity > maxSimilarity) { + maxSimilarity = similarity; + } + } + if (maxSimilarity >= 0.75) { + matchedWordCount++; + } + } + + const similarityPercentage = (matchedWordCount / newIssueWords.length) * 100; + if (similarityPercentage >= 80) { + // Check if both current and similar issues have '[New Game]:' in the title + const hasNewGameTitle = newIssueTitle.includes('[new game]:'); + const hasSimilarNewGameTitle = existingIssueTitle.includes('[new game]:'); + + if (hasNewGameTitle && hasSimilarNewGameTitle) { + isDuplicate = true; + duplicateIssueNumber = issue.number; + similarIssueNumber = issue.number; + break; + } + } + } + + core.setOutput('is_duplicate', isDuplicate.toString()); + core.setOutput('duplicate_issue_number', duplicateIssueNumber ? duplicateIssueNumber.toString() : ''); + core.setOutput('similar_issue_number', similarIssueNumber ? similarIssueNumber.toString() : ''); + + - name: Close duplicate issue and comment + if: steps.check_duplicate.outputs.is_duplicate == 'true' + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + script: | + const duplicateIssueNumber = parseInt('${{ steps.check_duplicate.outputs.duplicate_issue_number }}'); + const { owner, repo } = context.repo; + + // Close the newly created duplicate issue + await github.issues.update({ + owner: owner, + repo: repo, + issue_number: context.issue.number, + state: 'closed' + }); + + // Get the issue opener's username + const openerUsername = context.payload.issue.user.login; + + // Comment on the newly created duplicate issue + await github.issues.createComment({ + owner: owner, + repo: repo, + issue_number: context.issue.number, + body: `Hey @${openerUsername}! \nWe are already having a similar game request in #${duplicateIssueNumber} ๐ \nMake sure you come up with a cool unique idea ๐ \n Waiting for your new game idea ๐.` + }); + + console.log(`Closed the duplicate issue #${duplicateIssueNumber}.`); + + - name: Skip if not a duplicate issue + if: steps.check_duplicate.outputs.is_duplicate != 'true' + run: echo "Not a duplicate issue. Skipping..." diff --git a/MultiPlayer - Games/Flames_Game/Banner-image/bg.webp b/MultiPlayer - Games/Flames_Game/Banner-image/bg.webp new file mode 100644 index 00000000..68b2a186 Binary files /dev/null and b/MultiPlayer - Games/Flames_Game/Banner-image/bg.webp differ diff --git a/MultiPlayer - Games/Flames_Game/index.html b/MultiPlayer - Games/Flames_Game/index.html new file mode 100644 index 00000000..88b70fdd --- /dev/null +++ b/MultiPlayer - Games/Flames_Game/index.html @@ -0,0 +1,24 @@ + +
+Pick a level
+ + +Use a mike!
+ + + + ++ Welcome to The Blows, the game where you DON'T want to guess the lucky number! + We have two different levels for you, and Easy Level and a Harder Level. In both levels, + a random number will be chosen, and you and your friends try to not guess the number. The range of numbers + you can guess gets smaller every turn (the lowest and highest numbers you can guess are at the top of the screen), + and when that poor, unfortunate soul guesses the number the balloon pops! +
++ In the Easy Level, all the players can guess any number, as long as they are between the lowest and highest number. + The starting range of numbers is 1 to 100. +
++ In the Harder Level, you can only guess numbers that are between the lowest number and 12 plus the lowest number, or numbers + that are between the highest number and the highest number minus 12. The starting range of numbers is 1 to 84. +
+ + +0%
+ + +Use arrow keys to move the ship !
+Press spacebar to shoot !
+Hold shift key to use booster!
+100%
+100%
+OVERHEAT:
+ +Thank you for your service.
+ + +Total kills:
+Time played multiplier:
+Final score:
+Current Highscore:
+${message}
`; + + // Remove the notification active class after 4 seconds + setTimeout(() => { + this.notificationText.classList.remove("activeNotification"); + }, 3000); + } + + // Game's timer + timer(secondsLeft){ + clearInterval(this.countdown); + + const now = Date.now(); + const then = now + this.time * 1000; + this.displayTimeLeft(this.time); + + this.countdown = setInterval(() =>{ + this.secondsLeft = Math.round((then - Date.now()) / 1000); + + // Show a warning for few seconds left + if(this.secondsLeft === 10) { + this.timerDisplay.classList.add("timeLow"); + this.displayNotification("You don't have much time left!"); + } else if (this.secondsLeft < 0) { + // If the timer ran out, end the game + clearInterval(this.countdown); + clearInterval(game); + this.endgame(this.secondsLeft); + return; + } + this.currentTime = this.secondsLeft; + this.time = this.currentTime; + + this.displayTimeLeft(this.secondsLeft); + }, 1000) + }; + + // Display time left + displayTimeLeft(seconds) { + const minutes = Math.floor(seconds / 60); + const remainder = seconds % 60; + this.timerDisplay.textContent = `${minutes}:${remainder < 10 ? 0 : ""}${remainder}`; + }; + + // Add playtime when user picks up timer + addPlaytime() { + // First remove the class before re-adding it + document.querySelector(".time").classList.remove("timeShake"); + + // Random time awarded for picking up the time renewal + let minTime = 8; + let maxTime = 12; + minTime = Math.ceil(minTime); + maxTime = Math.floor(maxTime); + let spawnTime = Math.floor(Math.random() * (maxTime - minTime + 1)) + minTime; + + this.time = this.secondsLeft + spawnTime; + this.timer(this.time); + + // Display message and add shaking to the time + document.querySelector(".time").classList.add("timeShake"); + this.timerDisplay.classList.remove("timeLow"); + this.displayNotification("Added play time!"); + }; + + // New score + newScore(finalScore) { + const inputMenu = document.querySelector(".newHighscore-input"); + const scoreText = document.querySelector("#scoreText"); + const inputField = document.querySelector("#playerName-input"); + const saveBtn = document.querySelector("#savePlayer"); + inputMenu.style.display = "flex"; + + // Display different message according to the score + if(finalScore > this.highscore) { + scoreText.innerHTML = `'+ userScore +'
out of'+ questions.length +'
'; + scoreText.innerHTML = scoreTag; + } + else if (userScore > 1){ + let scoreTag = 'and nice, You got'+ userScore +'
out of'+ questions.length +'
'; + scoreText.innerHTML = scoreTag; + } + else{ + let scoreTag = 'and sorry, You got only'+ userScore +'
out of'+ questions.length +'
'; + scoreText.innerHTML = scoreTag; + } +} + +function startTimer(time){ + counter = setInterval(timer, 1000); + function timer(){ + timeCount.textContent = time; + time--; + if(time < 9){ + let addZero =timeCount.textContent; + timeCount.textContent = "0" + addZero; + } + if(time < 0){ + clearInterval(counter); + timeCount.textContent = "00"; + timeOff.textContent = "Time Off"; + + let correctAns = questions[que_count].answer; + let allOptions = option_list.children.length; + + for (let i = 0; i < allOptions; i++) { + if (option_list.children[i].textContent == correctAns){ + option_list.children[i].setAttribute("class", "option correct"); + option_list.children[i].insertAdjacentHTML("beforeend", tickIcon); + + } + } + for (let i = 0; i < allOptions; i++){ + option_list.children[i].classList.add("disabled"); + } + next_btn.style.display = "block"; + } + } +} + +function startTimerLine(time){ + counterLine = setInterval(timer, 29); + function timer(){ + time += 1; + timeLine.style.width = time +"px"; + if(time > 549){ + clearInterval(counterLine); + } + } +} + + + + +function queCounter(index) { + const bottom_ques_counter = quiz_box.querySelector(".total_que"); + let totalQuesCountTag = ''+ index +'
of'+ questions.length +'
Questions'; + bottom_ques_counter.innerHTML = totalQuesCountTag; +} diff --git a/SinglePlayer - Games/General Knowledge Quiz/style.css b/SinglePlayer - Games/General Knowledge Quiz/style.css new file mode 100644 index 00000000..e1e7c6e8 --- /dev/null +++ b/SinglePlayer - Games/General Knowledge Quiz/style.css @@ -0,0 +1,305 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap'); +*{ + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Poppins',sans-serif; +} + +body{ + background-image: url(./bg.jpg); +} + +.start_btn, .quiz_box, .result_box{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + box-shadow: 0px 4px 8px 0 rgba(0, 0, 0, 0.2), + 0px 6px 20px 0 rgba(0, 0, 0, 0.19); + transition: all 0.3s ease; +} + +.quiz_box.activeQuiz, +.result_box.activeResult{ + + z-index: 5; + opacity: 1; + pointer-events: auto; + transform: translate(-50%, -50%) scale(1); +} + +.start_btn button{ + font-size: 25px; + font-weight: 500; + color: #d6bf6a; + padding: 15px 30px; + outline: none; + border: none; + border-radius: 10px; + background: #fff; + cursor: pointer; +} + +.quiz_box{ + width: 550px; + background: #fff; + border-radius: 5px; + opacity: 0; + pointer-events: none; + transform: translate(-50%, -50%) scale(0.9); +} + +.quiz_box header{ + position: relative; + z-index: 99; + height: 70px; + padding: 0 30px; + background: #fff; + display: flex; + align-items: center; + justify-content: space-between; + border-radius: 5px 5px 0 0; + box-shadow: 0px 3px 5px 1px rgba(0, 0, 0, 0.1); +} + +.quiz_box header .title{ + font-size: 20px; + font-weight: 600; +} + +.quiz_box header .timer{ + display: flex; + align-items: center; + justify-content: space-between; + width: 145px; + height: 45px; + background: #decc8c; + border: 1px solid #ffe893; + border-radius: 5px; + padding: 0 8px; +} + +.quiz_box header .timer .time_text{ + font-weight: 400; + font-size: 17px; + user-select: none; +} + +.quiz_box header .timer .time_sec{ + font-size: 18px; + font-weight: 500; + background: #343a40; + height: 30px; + width: 45px; + color: #fff; + text-align: center; + line-height: 30px; + border-radius: 5px; + border: 1px solid #343a40; + user-select: none; +} + +.quiz_box header .time_line{ + position: absolute; + bottom: 0px; + height: 3px; + left: 0px; + background: #d6bf6a; +} + +.quiz_box section{ + padding: 25px 30px 20px 30px; + background: #fff; +} + +.quiz_box section .que_text{ + font-size: 25px; + font-weight: 600; +} + +.quiz_box section .option_list{ + padding: 20px 0; + display: block; +} + +section .option_list .option{ + background: #f8f6f0; + border: 1px solid #c2ad5f; + border-radius: 5px; + padding: 8px 15px; + margin-bottom: 15px; + font-size: 17px; + display: flex; + align-items: center; + justify-content: space-between; + cursor: pointer; + transition: all 0.3s ease; +} + +section .option_list .option:hover{ + color: #fff; + background: #dccd97; + border-color: #cbb97a; +} + +.option_list .option:last-child{ + margin-bottom: 0px; +} + +.option_list .option .icon{ + height: 26px; + width: 26px; + border: 2px solid transparent; + border-radius: 50%; + text-align: center; + font-size: 13px; + line-height: 24px; + pointer-events: none; +} + +.option_list .option .icon.tick{ + color: #23903c; + border-color: #23903c; + background: #d4edda; +} + +.option_list .option .icon.cross{ + color: #a42834; + border-color: #a42834; + background: #f8d7da; +} + +.option_list .option.correct{ + color: #155724; + border-color: #c3e6cb; + background: #d4edda; +} + +.option_list .option.incorrect{ + color: #721c24; + border-color: #f5c6cb; + background: #f8d7da; +} + +.option_list .option.disabled{ + pointer-events: none; +} + +.quiz_box footer{ + height: 60px; + width: 100%; + padding: 0 30px; + display: flex; + align-items: center; + justify-content: space-between; +} + +.quiz_box footer .total_que span{ + display: flex; + user-select: none; +} + +footer .total_que span p{ + font-weight: 500; + padding: 0 5px; +} + +.total_que span p:first-child{ + padding-left: 0px; +} + +footer .next_btn{ + display: none; + height: 40px; + padding: 0 13px; + font-size: 18px; + font-weight: 400; + border: none; + outline: none; + color: #fff; + background: #d6bf6a; + border-radius: 5px; + border: 1px solid #d6bf6a; + cursor: pointer; + transition: all 0.3s ease; +} + +footer .next_btn:hover{ + background: #bfa64c; +} + +.result_box{ + background: #fff; + width: 450px; + padding: 25px 30px; + border-radius: 5px; + display: flex; + text-align: center; + align-items: center; + flex-direction: column; + justify-content: space-between; + opacity: 0; + pointer-events: none; + transform: translate(-50%, -50%) scale(0.9); +} + +.result_box .icon{ + font-size: 100px; + color: #d6bf6a; + margin-bottom: 10px; +} + +.result_box .complete_text{ + font-size: 20px; + font-weight: 500; +} + +.result_box .score_text span{ + display: flex; + margin: 10px 0; + font-size: 18px; + font-weight: 500; +} + +.score_text span p{ + font-weight: 600; + padding: 0 4px; +} + +.result_box .buttons{ + display: flex; + margin: 20px 0; +} + +.result_box .buttons button{ + margin: 0 10px; + height: 40px; + padding: 0 20px; + border: none; + outline: none; + font-size: 18px; + font-weight: 500; + border-radius: 5px; + border: 1px solid #d6bf6a; + cursor: pointer; + transition: all 0.3s ease; +} + +.buttons button.restart{ + color: #fff; + background: #d6bf6a; +} + +.buttons button.restart:hover{ + background: #bfa64c; +} + +.buttons button.quit{ + color: #d6bf6a; +} + +.buttons button.quit:hover{ + color: #fff; + background: #d6bf6a; +} \ No newline at end of file diff --git a/SinglePlayer - Games/Guess The Sequence/index.html b/SinglePlayer - Games/Guess The Sequence/index.html new file mode 100644 index 00000000..19364e2e --- /dev/null +++ b/SinglePlayer - Games/Guess The Sequence/index.html @@ -0,0 +1,52 @@ + + + + + +Congratulations, you won!
+ ++ Welcome to Hand Cricket Champ, where every flick counts towards your victory! Play against the computer and test your skills in this thrilling game of strategy and precision. Aim for the highest scores with each flick of your finger. Experience the excitement of cricket at your fingertips in Finger Flick Cricket. +
+The correct word was: rainbow
+ +
+ Game Rules!
+ * Eat the food to gain score
+ * Do not touch the fire
+ * The fire multiplies once with even scores
+ * If you stay idle, the fire won't do anything
+ * Do not touch the moving fire
+ * Please play using arrow keys
+
0
+You
+0
+Computer
+Play your move
+Enter a letter:
+ + + + + +Contact us at ...
Doraemon Run is an adventurous maze-navigation game where players guide Doraemon through obstacles, collect cakes, and avoid traps while managing score and health to prevent game over. + +
+Release Date:
+28.05.2023
+Updated:
+Action | Desktop
+Snakebites is an exciting, fast-paced arcade game where players navigate a growing snake to consume food while avoiding obstacles. Test your reflexes and strategy as you aim for high scores and unlock new levels.
+Release Date:
+28.05.2023
+Updated:
+Action | Desktop
+Attempt to logically guess the a random secret sequence of colours
+Release Date:
+27.05.2024
+Updated:
+Puzzle | Desktop
+Experience the timeless puzzle sensation of "rock papaer scissors"
+Release Date:
+07.12.2015
+Updated:
+Action | Desktop
+Ball_Shooting_Game
+Release Date:
+20.06.2023
+Updated:
+Action | Desktop
+Cricket at your Fingertips!
+Release Date:
+21.05.2024
+Updated:
+Casual | Desktop/Mobile
+Flappy Bird is an endless game that involves a bird that the player can control. The player has to save the bird from colliding with the hurdles like pipes. Each time the bird passes through the pipes, the score gets incremented by one...
+Release Date:
+21.05.2024
+Updated:
+Action | Desktop
+Are you ready to put your programming knowledge to the test? Whether you're a seasoned developer or just starting your coding journey, a General Knowledge Quiz for programmers can be both fun and educational.
+Release Date:
+22.05.2024
+Updated:
+Action | Desktop
+-Earth Guardian is a remake of the classic Space shooter type of games, with 8-bit (pixel art) assets. This project used free assets (music and graphics) provided by [Jonathan So](https://jonathan-so.itch.io/),[KennyNL](https://kenney.nl/) and other sources, like Google images and [OpenGameArt](https://opengameart.org). This was a learning project. There will be some updates in the near future. Hope you like it, have fun! +
+Release Date:
+14.05.2024
+Updated:
+Action | Desktop
+Pop My Balloon is a game in which you have to guess a number avoiding the lucky number otherwise the balloon will pop.
+Release Date:
+18.05.2024
+Updated:
+Action | Desktop
+FLAMES is a fun game to predict relationships by using the initials of two people's names to determine if they will be Friends, Lovers, Affectionate, Married, Enemies, or Siblings
+Release Date:
+25.05.2024
+Updated:
+Action | Desktop
+