Last active
May 30, 2017 14:06
-
-
Save mritunjayupadhyay/35748ed2328edf434ae4aebb783f4ca5 to your computer and use it in GitHub Desktop.
This file contains 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
export const CREATEOPTIONS = 'CREATEOPTIONS'; | |
export const FILLPUZZLE = 'FILLPUZZLE'; | |
export const createOptions = (opts, wordList) => { | |
const options = {}; | |
options.width = opts.width || wordList[0].length; | |
options.height = opts.height || wordList[0].length; | |
options.preferOverlap = opts.preferOverlap === undefined ? true : opts.preferOverlap; | |
options.fillBlanks = opts.fillBlanks === undefined ? true : opts.fillBlanks; | |
options.maxattempts = opts.maxattempts || 3; | |
return { | |
type: CREATEOPTIONS, | |
payload: options | |
}; | |
}; | |
export const fillPuzzle = (puzzle) => { | |
return { | |
type: FILLPUZZLE, | |
payload: puzzle | |
}; | |
}; |
This file contains 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
import React, { Component } from 'react'; | |
import { connect } from 'react-redux'; | |
import { createOptions, fillPuzzle } from '../actions/index.js'; | |
class NewPuzzle extends Component { | |
constructor(props) { | |
super(props); | |
this.myobj = { | |
startSquare: null, | |
selectedSquares: [], | |
curWord: '', | |
curOrientation: null, | |
puzzleCons: '' | |
}; | |
this.fillPuzzle = this.fillPuzzle.bind(this); | |
this.findBestLocations = this.findBestLocations.bind(this); | |
this.pruneLocations = this.pruneLocations.bind(this); | |
this.placeWord = this.placeWord.bind(this); | |
this.placeWordInPuzzle = this.placeWordInPuzzle.bind(this); | |
this.fillBlanks = this.fillBlanks.bind(this); | |
} | |
componentWillMount() { | |
let puzzle; | |
let attempts = 0; | |
const wordList = this.props.words.slice(0).sort((a, b) => | |
((b.length - a.length > 0) ? 1 : -1) || b.localCompare(a)); | |
const opts = this.props.settings || {}; | |
this.props.createOptions(opts, wordList); | |
const options = {}; | |
options.width = opts.width || wordList[0].length; | |
options.height = opts.height || wordList[0].length; | |
options.orientations = opts.orientations || this.props.allMyOrientations.allOrientation; | |
options.preferOverlap = opts.preferOverlap === undefined ? true : opts.preferOverlap; | |
options.fillBlanks = opts.fillBlanks === undefined ? true : opts.fillBlanks; | |
options.maxattempts = opts.maxattempts || 3; | |
while (!puzzle) { | |
while (!puzzle && attempts++ < options.maxattempts) { | |
puzzle = this.fillPuzzle(wordList, options, this.props.allMyOrientations); | |
} | |
if (!puzzle) { | |
options.width++; | |
options.height++; | |
attempts = 0; | |
} | |
} | |
if (options.fillBlanks) { | |
this.fillBlanks(puzzle); | |
} | |
this.props.fillPuzzle(puzzle); | |
} | |
fillBlanks(puzzle) { | |
for (let i = 0; i < puzzle.length; i++) { | |
const row = puzzle[i]; | |
for (let j = 0; j < row.length; j++) { | |
if (puzzle[i][j] === '') { | |
puzzle[i][j] = this.props.letters[Math.floor(Math.random() * this.props.letters.length)]; | |
} | |
} | |
} | |
} | |
findBestLocations(puzzle, options, word, allMyOrientations) { | |
const locations = []; | |
const width = options.width; | |
const height = options.height; | |
const wordLength = word.length; | |
let maxOverlap = 0; | |
for (let k = 0; k < options.orientations.length; k++) { | |
const orientation = options.orientations[k]; | |
const check = allMyOrientations.checkOrientations[orientation]; | |
const next = allMyOrientations.orientations[orientation]; | |
const skipTo = allMyOrientations.skipOrientations[orientation]; | |
let x = 0; | |
let y = 0; | |
let overlap; | |
while (y < height) { | |
if (check(x, y, width, height, wordLength)) { | |
overlap = this.checkForOverLap(puzzle, word, x, y, next); | |
if (overlap >= maxOverlap || (!options.preferOverlap && overlap > -1)) { | |
maxOverlap = overlap; | |
locations.push({ | |
x, | |
y, | |
orientation, | |
overlap | |
}); | |
} | |
x++; | |
if (x >= width) { | |
x = 0; | |
y++; | |
} | |
} else { | |
const nextPossible = skipTo(x, y, wordLength); | |
x = nextPossible.x; | |
y = nextPossible.y; | |
} | |
} | |
} | |
return options.preferOverlap ? | |
this.pruneLocations(locations, maxOverlap) : | |
locations; | |
} | |
checkForOverLap(puzzle, word, x, y, fn) { | |
let overlap = 0; | |
for (let k = 0; k < word.length; k++) { | |
const next = fn(x, y, k); | |
const score = puzzle[next.x][next.y]; | |
if (score === word[k]) { | |
overlap++; | |
} else if (score !== '') { | |
return -1; | |
} | |
} | |
return overlap; | |
} | |
pruneLocations(locations, overlap) { | |
const pruned = []; | |
for (let i = 0, len = locations.length; i < len; i++) { | |
if (locations[i].overlap >= overlap) { | |
pruned.push(locations[i]); | |
} | |
} | |
return pruned; | |
} | |
placeWord(puzzle, word, x, y, fn) { | |
for (let i = 0; i < word.length; i++) { | |
const next = fn(x, y, i); | |
puzzle[next.x][next.y] = word[i]; | |
} | |
} | |
placeWordInPuzzle(puzzle, options, word, allMyOrientations) { | |
const locations = this.findBestLocations(puzzle, options, word, allMyOrientations); | |
if (locations.length === 0) { | |
return false; | |
} | |
const s = locations[Math.floor(Math.random() * locations.length)]; | |
this.placeWord(puzzle, word, s.x, s.y, allMyOrientations.orientations[s.orientation]); | |
return true; | |
} | |
fillPuzzle(words, options, allMyOrientations) { | |
let puzzle = []; | |
for (let i = 0; i < options.height; i++) { | |
puzzle.push([]); | |
for (let j = 0; j < options.width; j++) { | |
puzzle[i].push(''); | |
} | |
} | |
for (let k = 0; k < words.length; k++) { | |
if (!this.placeWordInPuzzle(puzzle, options, words[k], allMyOrientations)) { | |
return null; | |
} | |
} | |
return puzzle; | |
} | |
consolePuzzle() { | |
if (!this.props.puzzle) { | |
console.log('no Puzzle formed'); | |
} else { | |
for (let i = 0; i < this.props.puzzle.length; i++) { | |
const row = this.props.puzzle[i]; | |
for (let j = 0; j < row.length; j++) { | |
const p = row[j] + ' '; | |
this.myobj.puzzleCons += p; | |
} | |
this.myobj.puzzleCons += '\n'; | |
} | |
} | |
console.log(this.myobj.puzzleCons); | |
} | |
render() { | |
return ( | |
<div | |
className="word-box" onMouseUp={(e) => this.endTurn(e)} | |
> | |
<div className="game-box"> | |
{this.consolePuzzle()} | |
</div> | |
</div> | |
); | |
} | |
} | |
function mapStateToProps(state) { | |
return { | |
words: state.PuzzleData.words, | |
settings: state.PuzzleData.settings, | |
opts: state.PuzzleData.opts, | |
allMyOrientations: state.PuzzleData, | |
letters: state.PuzzleData.letters, | |
puzzle: state.PuzzleData.puzzle | |
}; | |
} | |
export default connect(mapStateToProps, { createOptions, fillPuzzle })(NewPuzzle); |
This file contains 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
import { combineReducers } from 'redux'; | |
import newPuzzleReducer from './newpuzzle_reducer.js'; | |
const rootReducer = combineReducers({ | |
PuzzleData: newPuzzleReducer | |
}); | |
export default rootReducer; |
This file contains 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
import { CREATEOPTIONS, FILLPUZZLE } from '../actions/index.js'; | |
const INITIAL_STATE = { | |
letters: 'abcdefghijklmnopqrstuvwxyz', | |
allOrientation: ['horizontal', 'horizontalBack', 'vertical', | |
'verticalUp', 'diagonal', 'diagonalUp', 'diagonalBack', 'diagonalUpBack'], | |
orientations: { | |
horizontal: (x, y, l) => { | |
return { | |
x: x + l, | |
y | |
}; | |
}, | |
horizontalBack: (x, y, l) => { | |
return { | |
x: x - l, | |
y | |
}; | |
}, | |
vertical: (x, y, l) => { | |
return { | |
x, | |
y: y + l | |
}; | |
}, | |
verticalUp: (x, y, l) => { | |
return { | |
x, | |
y: y - l | |
}; | |
}, | |
diagonal: (x, y, l) => { | |
return { | |
x: x + l, | |
y: y + l | |
}; | |
}, | |
diagonalUp: (x, y, l) => { | |
return { | |
x: x + l, | |
y: y - l | |
}; | |
}, | |
diagonalBack: (x, y, l) => { | |
return { | |
x: x - l, | |
y: y + l | |
}; | |
}, | |
diagonalUpBack: (x, y, l) => { | |
return { | |
x: x - l, | |
y: y - l | |
}; | |
} | |
}, | |
checkOrientations: { | |
horizontal: (x, y, w, h, l) => { | |
return w >= x + l; | |
}, | |
horizontalBack: (x, y, w, h, l) => { | |
return x + 1 >= l; | |
}, | |
vertical: (x, y, w, h, l) => { | |
return h >= y + l; | |
}, | |
verticalUp: (x, y, w, h, l) => { | |
return y + 1 >= l; | |
}, | |
diagonal: (x, y, w, h, l) => { | |
return (w >= x + l && h >= y + l); | |
}, | |
diagonalUp: (x, y, w, h, l) => { | |
return (w >= x + l && y + 1 >= l); | |
}, | |
diagonalBack: (x, y, w, h, l) => { | |
return (x + 1 >= l && h >= y + l); | |
}, | |
diagonalUpBack: (x, y, w, h, l) => { | |
return (x + 1 >= l && y + 1 >= l); | |
} | |
}, | |
skipOrientations: { | |
horizontal: (x, y, l) => { | |
return { | |
x: 0, | |
y: y + 1 | |
}; | |
}, | |
horizontalBack: (x, y, l) => { | |
return { | |
x: l - 1, | |
y | |
}; | |
}, | |
vertical: (x, y, l) => { | |
return { | |
x, | |
y: y + 100 | |
}; | |
}, | |
verticalUp: (x, y, l) => { | |
return { | |
x: 0, | |
y: l - 1 | |
}; | |
}, | |
diagonal: (x, y, l) => { | |
return { | |
x: 0, | |
y: y + 1 | |
}; | |
}, | |
diagonalUp: (x, y, l) => { | |
return { | |
x: 0, | |
y: y < l - 1 ? l - 1 : y + 1 | |
}; | |
}, | |
diagonalBack: (x, y, l) => { | |
return { | |
x: l - 1, | |
y: x < l - 1 ? y : y + 100 | |
}; | |
}, | |
diagonalUpBack: (x, y, l) => { | |
return { | |
x: l - 1, | |
y: x >= l - 1 ? l - 1 : y | |
}; | |
} | |
}, | |
words: ['sugar', 'alchemy', 'cows', 'tracks', 'arrived', 'located', 'sir', 'seat', | |
'sail', 'rolled', 'bear', 'wonder', 'smiled', 'angle', 'absent', | |
'decadent', 'excellent', 'frequent', 'impatient', 'cell', | |
'respiration' | |
], | |
settings: null, | |
puzzle: null, | |
opts: null, | |
fillBlanks: null | |
}; | |
export default function (state = INITIAL_STATE, action) { | |
switch (action.type) { | |
case CREATEOPTIONS: { | |
return { ...state, opts: action.payload }; | |
} | |
case FILLPUZZLE: { | |
return { ...state, puzzle: action.payload }; | |
} | |
default: | |
return state; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment