Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: init migration to vite #41

Merged
merged 6 commits into from
Apr 21, 2023
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

strategy:
matrix:
node-version: [16]
node-version: [18]

steps:
- uses: actions/checkout@v3
Expand All @@ -29,7 +29,7 @@ jobs:
- name: Build
run: yarn workspace @kenrick95/c4-browser run build-gh-pages
- name: Deploy
uses: JamesIves/github-pages-deploy-action@v4.2.5
uses: JamesIves/github-pages-deploy-action@v4.4.1
with:
branch: gh-pages
folder: browser/dist
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

strategy:
matrix:
node-version: [16]
node-version: [18]

steps:
- uses: actions/checkout@v3
Expand All @@ -27,4 +27,4 @@ jobs:
- name: Run Tests
run: yarn workspaces foreach --verbose run test
- name: Run Builds
run: yarn workspaces foreach --verbose run build
run: yarn workspaces foreach --verbose --topological run build
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:16-alpine
FROM node:18-alpine
WORKDIR /usr/src/app

COPY .yarn .yarn/
Expand Down
37 changes: 24 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,54 @@
c4
==
# c4

![Test](https://github.com/kenrick95/c4/workflows/Test/badge.svg)
![Test](https://github.com/kenrick95/c4/workflows/Test/badge.svg) ![Deploy](https://github.com/kenrick95/c4/workflows/Deploy/badge.svg)

**c4**, stands for **Connect Four**, is a browser game written in TypeScript and utilizes HTML's `canvas`. Player is playing against an AI that uses Minimax algorithm and alpha-beta pruning. The evaluation function is hard-coded, and hence the AI may not be moving using the most optimal move.

## Play
* [kenrick95.github.io/c4](https://kenrick95.github.io/c4/)

- [kenrick95.github.io/c4](https://kenrick95.github.io/c4/)

## Gameplay

### Objective
*Connect four* of your game pieces vertically, horizontally, or diagonally before the other player do so.

_Connect four_ of your game pieces vertically, horizontally, or diagonally before the other player do so.

### How to move?

At each turn, player will drop a game piece in one of the seven columns by clicking on the chosen column.

### More info

Read [Wikipedia page on Connect Four](https://en.wikipedia.org/wiki/Connect_Four)

## Browser compatibility
- Should be good in latest Firefox, Edge, Chrome, Opera, Safari, and IE.

Should be good in latest Firefox, Edge, Chrome, and Safari.

## Contributing

Contributions are welcome! I'm happy to accept any kind of contributions, pull requests, or bug reports.

### Developing

1. Fork and clone this repository
2. Install dependencies
```
yarn install
```

```
yarn install
```

3. Start local development server
```
yarn start
```

```
yarn start
```

4. Make your changes at either `browser/`, `core/`, or `server/`
5. Test it out at http://localhost:1234/
5. Test it out at http://localhost:5173/
6. After you are happy with your changes, please submit your Pull Request!

## License

This work is licensed under MIT License.
2 changes: 1 addition & 1 deletion browser/src/index.html → browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ <h2>Mode chooser</h2>
By <a href="http://kenrick95.org">Kenrick95</a>. Fork this project at
<a href="https://github.com/kenrick95/c4">GitHub</a>.
</footer>
<script src="./app.ts"></script>
<script type="module" src="./src/app.ts"></script>
</body>
</html>
20 changes: 9 additions & 11 deletions browser/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@kenrick95/c4-browser",
"private": true,
"version": "1.0.0",
"description": "Connect Four game in browser",
"repository": {
Expand Down Expand Up @@ -27,23 +28,20 @@
"dist/"
],
"scripts": {
"start": "parcel src/index.html",
"build": "yarn clean && parcel build src/index.html",
"build-gh-pages": "yarn clean && parcel build src/index.html --public-url \"https://kenrick95.github.io/c4/\"",
"dev": "vite",
"build": "vite build",
"build-gh-pages": "vite build --base=\"https://kenrick95.github.io/c4/\"",
"prettier": "prettier --write \"./**/*.?(ts|html|scss|css)\"",
"clean": "rimraf dist/",
"test": "echo 'OK'"
},
"dependencies": {
"@kenrick95/c4": "workspace:^",
"es6-promise": "^4.2.8",
"url-search-params-polyfill": "^8.1.1"
"@kenrick95/c4": "workspace:^"
},
"devDependencies": {
"@types/node": "^16.9.6",
"parcel-bundler": "^1.12.4",
"prettier": "^2.4.1",
"rimraf": "^3.0.2",
"typescript": "^4.4.3"
"prettier": "^2.8.7",
"rimraf": "^5.0.0",
"typescript": "~5.0.4",
"vite": "^4.2.1"
}
}
2 changes: 0 additions & 2 deletions browser/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'es6-promise/auto'
import 'url-search-params-polyfill'
import * as Game from './game'
import { Board } from './board'
import './style.css'
Expand Down
6 changes: 3 additions & 3 deletions browser/src/board/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BoardBase, BoardPiece } from '@kenrick95/c4'
import { Player } from '@kenrick95/c4'
import { onresize, animationFrame } from '@kenrick95/c4'
import { drawMask, drawCircle, clearCanvas } from './utils'
import { Player } from '@kenrick95/c4'
import { onresize, drawMask, drawCircle, clearCanvas } from './utils'
import { animationFrame } from '../utils/animate-frame'

export class Board extends BoardBase {
canvas: HTMLCanvasElement
Expand Down
42 changes: 42 additions & 0 deletions browser/src/board/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,46 @@
import { Board } from './index'
/**
* From Mozilla Developer Network
* https://developer.mozilla.org/en-US/docs/Web/Events/resize
*/
export function onresize(): { add: Function } {
const callbacks: Array<Function> = []
let running: boolean = false

// Fired on resize event.
function resize() {
if (!running) {
running = true

if (window.requestAnimationFrame)
window.requestAnimationFrame(runCallbacks)
else setTimeout(runCallbacks, 66)
}
}

// Run the actual callbacks.
function runCallbacks() {
callbacks.forEach((callback: Function): void => {
callback()
})

running = false
}

// Adds callback to loop.
function addCallback(callback: Function): void {
if (callback) callbacks.push(callback)
}

return {
// Public method to add additional callback.
add: (callback: Function) => {
if (!callbacks.length) window.addEventListener('resize', resize)

addCallback(callback)
},
}
}

export function drawCircle(
context: CanvasRenderingContext2D,
Expand Down
4 changes: 3 additions & 1 deletion browser/src/game/game-local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { Board } from '../board'
import { BoardBase, BoardPiece } from '@kenrick95/c4'
import { GameBase } from '@kenrick95/c4'
import { Player, PlayerHuman, PlayerAi } from '@kenrick95/c4'
import { showMessage, animationFrame, getColumnFromCoord } from '@kenrick95/c4'
import { getColumnFromCoord } from '@kenrick95/c4'
import { showMessage } from '../utils/message'
import { animationFrame } from '../utils/animate-frame'

const statusbox = document.querySelector('.statusbox')
const statusboxBodyGame = document.querySelector('.statusbox-body-game')
Expand Down
9 changes: 5 additions & 4 deletions browser/src/game/game-online-2p.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
GameOnlineMessage,
} from '@kenrick95/c4'
import { Player, PlayerHuman, PlayerShadow } from '@kenrick95/c4'
import { showMessage, getColumnFromCoord } from '@kenrick95/c4'
import { getColumnFromCoord } from '@kenrick95/c4'
import { showMessage } from '../utils/message'

enum GAME_MODE {
FIRST = BoardPiece.PLAYER_1,
Expand All @@ -23,9 +24,9 @@ const statusboxBodyConnection = document.querySelector(
const statusboxBodyPlayer = document.querySelector('.statusbox-body-player')

const C4_SERVER_ENDPOINT =
process.env.NODE_ENV === 'production'
? process.env.C4_SERVER_ENDPOINT
? process.env.C4_SERVER_ENDPOINT
import.meta.env.MODE === 'production'
? import.meta.env.C4_SERVER_ENDPOINT
? import.meta.env.C4_SERVER_ENDPOINT
: `wss://c4-server.fly.dev/`
: `ws://${location.hostname}:8080`

Expand Down
13 changes: 13 additions & 0 deletions browser/src/utils/animate-frame.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @see https://esdiscuss.org/topic/promises-async-functions-and-requestanimationframe-together
*/
export function animationFrame(): Promise<Function> {
let resolve: Function | null = null
const promise: Promise<Function> = new Promise(
(r: Function): Function => (resolve = r)
)

if (resolve) window.requestAnimationFrame(resolve)

return promise
}
35 changes: 35 additions & 0 deletions browser/src/utils/message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export function showMessage(message: string = ''): void {
const messageDOM: Element | null = document.querySelector('.message')

if (!messageDOM) return console.error('Message DOM is null!')

messageDOM.classList.remove('hidden')

const messageContentDOM: Element | null = document.querySelector(
'.message-body-content'
)

if (!messageContentDOM)
return console.error('Message body content DOM is null!')

messageContentDOM.innerHTML = message

const messageDismissDOM: Element | null = document.querySelector(
'.message-body-dismiss'
)

if (!messageDismissDOM)
return console.error('Message body dismiss DOM is null!')

const dismissHandler = (): void => {
messageDOM.classList.add('invisible')
messageDOM.addEventListener('transitionend', (): void => {
messageDOM.classList.add('hidden')
messageDOM.classList.remove('invisible')
})

messageDismissDOM.removeEventListener('click', dismissHandler)
}

messageDismissDOM.addEventListener('click', dismissHandler)
}
18 changes: 10 additions & 8 deletions browser/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{
"compilerOptions": {
"declaration": false,
"module": "esnext",
"strict": true,
"noImplicitAny": true,
"removeComments": true,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"sourceMap": true,
"target": "es5",
"lib": ["es2015", "dom", "dom.iterable"]
"isolatedModules": true,
"module": "ES2022",
"moduleResolution": "node",
"noEmit": true,
"strict": true,
"target": "ES2022",
"useDefineForClassFields": true,
"types": ["vite/client"],
"lib": ["ES2022", "DOM", "DOM.Iterable"]
},
"include": ["src/"],
"exclude": ["node_modules", "**/*.spec.ts"]
Expand Down
8 changes: 8 additions & 0 deletions browser/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from 'vite'

// https://vitejs.dev/config/
export default defineConfig({
resolve: {
conditions: ['__source', 'import', 'module', 'browser', 'default'],
},
})
4 changes: 0 additions & 4 deletions core/jest.config.js

This file was deleted.

33 changes: 22 additions & 11 deletions core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,37 @@
"connect-four",
"game"
],
"main": "./dist/lib.js",
"source": "src/lib.ts",
"main": "./dist/c4.js",
"module": "./dist/c4.mjs",
"umd:main": "./dist/c4.umd.js",
"unpkg": "./dist/c4.umd.js",
"exports": {
".": {
"import": {
"__source": "./src/lib.ts",
"default": "./dist/c4.mjs"
},
"require": "./dist/c4.js"
}
},
"types": "./src/lib.ts",
"source": "./src/lib.ts",
"files": [
"src/",
"dist/"
],
"scripts": {
"build": "yarn clean && parcel build ./src/lib.ts",
"dev": "vite",
"build": "vite build",
"clean": "rimraf dist/",
"prettier": "prettier --write \"./**/*.?(ts|html|scss|css)\"",
"test": "jest"
"test": "vitest --watch=false"
},
"devDependencies": {
"@types/jest": "^27.0.2",
"jest": "^27.2.1",
"parcel-bundler": "^1.12.4",
"prettier": "^2.4.1",
"rimraf": "^3.0.2",
"ts-jest": "^27.0.5",
"typescript": "^4.4.3"
"prettier": "^2.8.7",
"rimraf": "^5.0.0",
"typescript": "~5.0.4",
"vite": "^4.2.1",
"vitest": "^0.30.1"
}
}
Loading