Skip to content

Commit

Permalink
Add demo page
Browse files Browse the repository at this point in the history
Close #2
  • Loading branch information
yishn committed Feb 7, 2020
1 parent 60ef7a0 commit fcf52ef
Show file tree
Hide file tree
Showing 6 changed files with 4,101 additions and 140 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.nyc_output/
node_modules/
demo/bundle.js
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,27 @@ Returns an array of arrays of the same size as `data`. Each entry is an non-nega
Returns an array of arrays of the same size as `data`. Each entry is a non-negative number which encodes how many stones of the color corresponding to `sign` is in its vicinity. `-1` corresponds to white stones whereas `1` denotes black stones. Each chain of the color corresponding to `sign` emits *radiance* which diminishes over distance, adds up with the radiance of other chains, and reflects at the board edge.

`p1`, `p2`, and `p3` are parameters, controlling how strong the radiance is initially and how it diminishes.

## Build Demo

Make sure you have Node.js v12 and npm installed. First, clone this repository via Git, then install all dependencies with npm:

~~~
$ git clone https://github.com/SabakiHQ/influence
$ cd influence
$ npm install
~~~

Use the `build-demo` script to build the demo project:

~~~
$ npm run build-demo
~~~

You can use the `watch-demo` command for development:

~~~
$ npm run watch-demo
~~~

Open `demo/index.html` in your browser to run demo.
18 changes: 18 additions & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>Influence Demo</title>
<meta charset="utf-8"/>
<link rel="stylesheet" href="../node_modules/@sabaki/shudan/css/goban.css">
<style media="screen">
body {
font-family: 'Segoe UI', Ubuntu, Helvetica, Arial, sans-serif;
}
</style>
</head>
<body>
<div id="root"></div>

<script type="text/javascript" src="./bundle.js"></script>
</body>
</html>
176 changes: 176 additions & 0 deletions demo/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import {h, render, Component} from 'preact'
import {Goban} from '@sabaki/shudan'
import * as influence from '..'

const originalSignMap = [
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, -1, 0, 1, -1, 0, 0],
[0, 1, -1, 0, 0, 0, 0, -1, -1, 1, 0, 1, -1, 0, 1, -1, 1, 1, 0],
[0, 1, 1, -1, 0, 0, 0, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 0],
[0, 1, -1, -1, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1, -1, -1, 1, -1, 0],
[0, 0, 0, 0, -1, 0, 0, 1, 0, 1, -1, 1, 1, -1, -1, 1, 0, 1, 0],
[0, 1, 1, 1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 0],
[0, 1, -1, 1, -1, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, -1, 1, 0, 0],
[0, 1, -1, -1, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, -1, 0, 0, 0, 0],
[0, -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, -1, -1, 1, 0],
[0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, -1, -1, 1],
[0, 0, -1, 1, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, 1, -1, -1, 1, 0],
[0, 0, 1, -1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 1, 0, -1, 0],
[0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0],
[0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, -1, -1, -1, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, -1, -1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, -1, 0, 1, -1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
]

const createTwoWayRadioBox = component => (
({stateKey, text}) => h('label',
{
style: {
display: 'flex',
alignItems: 'center'
}
},

h('input', {
style: {marginRight: '.5em'},
type: 'radio',
checked: component.state[stateKey],

onClick: () => component.setState(s => {
let state = {}

for (let key in s) {
if (s[key] === true) {
state[key] = false
}
}

state[stateKey] = true
return state
})
}),

h('span', {style: {userSelect: 'none'}}, text)
)
)

class App extends Component {
constructor(props) {
super(props)

this.state = {
noMap: true,
showInfluenceMap: false,
showDiscreteInfluenceMap: false,
showAreaMap: false,
showBlackNearestNeighborMap: false,
showWhiteNearestNeighborMap: false,
showBlackRadianceMap: false,
showWhiteRadianceMap: false,
deadStones: []
}

this.RadioBox = createTwoWayRadioBox(this)
}

render() {
let {showInfluenceMap, showDiscreteInfluenceMap, showAreaMap,
showBlackNearestNeighborMap, showWhiteNearestNeighborMap,
showBlackRadianceMap, showWhiteRadianceMap} = this.state

let signMap = JSON.parse(JSON.stringify(originalSignMap))

for (let [x, y] of this.state.deadStones) {
signMap[y][x] = 0
}

let sign = showBlackNearestNeighborMap || showBlackRadianceMap ? 1 : -1
let influenceMap = showInfluenceMap || showDiscreteInfluenceMap
? influence.map(signMap, {discrete: showDiscreteInfluenceMap})
: null
let nearestNeighborMap = showBlackNearestNeighborMap || showWhiteNearestNeighborMap
? influence.nearestNeighborMap(signMap, sign)
: null
let radianceMap = showBlackRadianceMap || showWhiteRadianceMap
? influence.radianceMap(signMap, sign)
: null
let maxRadiance = radianceMap != null
? Math.max(...radianceMap.map(row => Math.max(...row)))
: null

return h('section',
{
style: {
display: 'grid',
gridTemplateColumns: '19em auto',
gridColumnGap: '1em'
}
},

h('form',
{
style: {
display: 'flex',
flexDirection: 'column'
}
},

h('p', {}, 'Click stones to mark them as dead.'),

h(this.RadioBox, {stateKey: 'noMap', text: 'No map'}),
h(this.RadioBox, {stateKey: 'showInfluenceMap', text: 'Show influence map'}),
h(this.RadioBox, {stateKey: 'showDiscreteInfluenceMap', text: 'Show discrete influence map'}),
h(this.RadioBox, {stateKey: 'showAreaMap', text: 'Show area map'}),
h(this.RadioBox, {
stateKey: 'showBlackNearestNeighborMap',
text: 'Show nearest neighbor map for black'
}),
h(this.RadioBox, {
stateKey: 'showWhiteNearestNeighborMap',
text: 'Show nearest neighbor map for white'
}),
h(this.RadioBox, {stateKey: 'showBlackRadianceMap', text: 'Show radiance map for black'}),
h(this.RadioBox, {stateKey: 'showWhiteRadianceMap', text: 'Show radiance map for white'})
),

h('div', {},
h(Goban, {
signMap: originalSignMap,
dimmedVertices: this.state.deadStones,
paintMap: influenceMap != null
? influenceMap.map(row => row.map(x => (Math.abs(x) * 2 + 1) / 4 * Math.sign(x)))
: showAreaMap
? influence.areaMap(signMap)
: nearestNeighborMap != null
? nearestNeighborMap.map(row => row.map(x => sign * Math.exp(-x / 2)))
: radianceMap != null
? radianceMap.map(row => row.map(x => sign * x / maxRadiance))
: null,
markerMap: nearestNeighborMap != null
? nearestNeighborMap.map(row => row.map(x => ({
type: 'label',
label: x.toString()
})))
: radianceMap != null
? radianceMap.map(row => row.map(x => ({
type: 'label',
label: x.toString().slice(0, 4)
})))
: null,

onVertexClick: (evt, vertex) => {
this.setState(s => ({
deadStones: s.deadStones.some(([x, y]) => vertex[0] === x && vertex[1] === y)
? s.deadStones.filter(([x, y]) => vertex[0] !== x || vertex[1] !== y)
: [...s.deadStones, vertex]
}))
}
})
)
)
}
}

render(h(App), document.getElementById('root'))
Loading

0 comments on commit fcf52ef

Please sign in to comment.