Created
December 28, 2018 17:33
-
-
Save zerobias/9bf3a3cf7e56d9e3a982574eea51953e to your computer and use it in GitHub Desktop.
Snake: effector's stress-test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//@flow | |
import { | |
createStore, | |
createEvent, | |
combine, | |
createStoreObject, | |
type Store, | |
// } from '../../npm/effector/effector.bundle' | |
} from '../../npm/effector/effector.es' | |
global.__SNAKE__ = function snake() { | |
function cond<T>(fn: (_: T) => boolean): (_: T) => T | void { | |
return (_: T) => { | |
if (fn(_)) return _ | |
} | |
} | |
function propCond(prop, e, s) { | |
const result = e.filter(cond(data => data.prop === prop)) | |
s.on(result, (_, data) => data.value) | |
return result | |
} | |
const W = 60 | |
const H = 40 | |
const setProperty = createEvent<{ | |
x: number, | |
y: number, | |
prop: 'wall' | 'food' | 'snake' | 'cursor', | |
value: boolean, | |
}>('set property global') | |
function createPixel(x, y) { | |
const pixelEvent = setProperty.filter( | |
cond(data => data.x === x && data.y === y), | |
) | |
const hasWall = createStore(false) | |
const hasFood = createStore(false) | |
const hasSnake = createStore(false) | |
const hasCursor = createStore(false) | |
const setWall = propCond('wall', pixelEvent, hasWall) | |
const setFood = propCond('food', pixelEvent, hasFood) | |
const setSnake = propCond('snake', pixelEvent, hasSnake) | |
const setCursor = propCond('cursor', pixelEvent, hasCursor) | |
const baseInfo = createStoreObject({ | |
hasWall, | |
hasFood, | |
hasSnake, | |
hasCursor, | |
}) | |
const fill = baseInfo.map(opts => { | |
if (opts.hasCursor) return '↖' | |
if (opts.hasWall) return '#' | |
if (opts.hasSnake) return '*' | |
if (opts.hasFood) return '@' | |
return ' ' | |
}) | |
const fullInfo = createStoreObject({ | |
fill, | |
baseInfo, | |
}).map(({fill, baseInfo: {hasWall, hasFood, hasSnake, hasCursor}}) => ({ | |
fill, | |
hasWall, | |
hasFood, | |
hasSnake, | |
hasCursor, | |
})) | |
return fullInfo | |
} | |
const pixels = [] | |
const rowStores = [] | |
for (let y = 0; y < H; y++) { | |
const row = [] | |
for (let x = 0; x < W; x++) { | |
const pxl = createPixel(x, y) | |
row.push(pxl) | |
pixels.push(pxl) | |
} | |
const fillRow = row.map(p => p.map((o): string => o.fill)) | |
const fillRowStore = combine(...fillRow, (...args) => args.join('')) | |
rowStores.push(fillRowStore) | |
} | |
//$off | |
const fullTextStore: Store<string> = createStoreObject(rowStores).map(list => | |
list.join(`\n`), | |
) | |
fullTextStore.watch(e => { | |
// console.count('upd') | |
}) | |
const filler = textRaw => { | |
const text = textRaw.trim().split(`\n`) | |
const map = { | |
'#': 'wall', | |
'*': 'snake', | |
'@': 'food', | |
} | |
const lower = n => (n / 10) | 0 | |
console.log(text) | |
for (let y = 0, row, prop; y < H; y++) { | |
row = text[lower(y)] | |
for (let x = 0; x < W; x++) { | |
prop = map[row[lower(x)]] || 'cursor' | |
setProperty({x, y, prop, value: true}) | |
} | |
} | |
} | |
filler(` | |
###### | |
# @ # | |
# ***# | |
###### | |
`) | |
console.log(fullTextStore.getState()) | |
return fullTextStore | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment