I have following code and I was wondering, if that could be solved better?
The objective is to move an item within an object up / down.
moveTab = (action, tab) => event => {
event.stopPropagation();
let order = { ...this.state.settings.layout }
let sorted = false;
let sortedArray = Object.keys(order).sort((a, b) => {
if (!sorted && ((action === 'up' && b === tab) || (action === 'down' && a === tab))) {
sorted = true;
return 1;
}
return 0;
});
let sortedObject = {}
sortedArray.map(key => sortedObject[key] = order[key]);
console.log(order);
console.log(sortedObject);
// ... more code ...
}
Related
I've been trying to do some html and css but I'm really bad at this so far. I was using a function that would check if two selectors match. A friend of mine came up with this code but neither of us fully understands how the return of the "tag.class" case works. My question is, if it doesn't divide the newSelector, how can it succesfully check the tag and class?
var matchFunctionMaker = function(selector) {
var selectorType = selectorTypeMatcher(selector);
var matchFunction;
if (selectorType === "id") {
matchFunction = nuevoSelector => '#' + nuevoSelector.id === selector;
} else if (selectorType === "class") {
matchFunction = nuevoSelector => {
var lista = nuevoSelector.classList;
for (let x of lista) {
if (selector === '.' + x) return true;
}
return false;
}
} else if (selectorType === "tag.class") {
matchFunction = nuevoSelector => {
var [tag, clase] = selector.split('.');
return matchFunctionMaker(tag) (nuevoSelector) && matchFunctionMaker(`.${clase}`) (nuevoSelector);
};
} else if (selectorType === "tag") {
matchFunction = nuevoSelector => nuevoSelector.tagName.toLowerCase() === selector.toLowerCase();
}
return matchFunction;
};
Thanks in advance!
I'm working on an Othello game in React and I've already implemented the code to switch player turns. It does switch from one to another(between white and black). But if there's no move available for the upcoming player, the turn stays the same. I though I had it all done but now I came across to such a case when trying out the game, and although it does switch player turns regularly, my code does not consider keeping it the same when necessary. Do you know why? How can I solve it?
Here's my code:
Where I change it:
setWinnerAndTurn() {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[this.state.stepNumber];
const squares = current.squares.slice()
const blackSquares = []
const whiteSquares = []
// Check for a winner
for (var row=0;row<squares.length;row++) {
for (var col=0;col<squares[row].length;col++) {
if (squares[row][col] === 'black') {
blackSquares.push([row,col])
} else if (squares[row][col] === 'white') {
whiteSquares.push([row,col])
}
}
}
// Debug
//console.log(blackSquares)
//console.log(whiteSquares)
const total = [blackSquares,whiteSquares]
const movesAvailable = [[],[]]
for (var t=0;t<total.length;t++) {
const currentArray = total[t]
const returned = this.checkElementsAround(currentArray)
for (var r=0;r<returned.length;r++) {
movesAvailable[t].push(returned[r])
}
}
// Debug
console.log(movesAvailable)
if (blackSquares.length + whiteSquares.length === squares.length * squares[0].length || (movesAvailable[0] === [] && movesAvailable[1] === [])) {
// Declare a winner
if (blackSquares.length !== whiteSquares.length) {
this.setState({
winner: (blackSquares.length > whiteSquares.length) ? 'black' : 'white'
})
} else {
this.setState({
winner: 'tie'
})
}
} else {
// Change turn
if (movesAvailable[0] === []) {
this.setState({
blackIsNext: false
})
} else if (movesAvailable[1] === []){
this.setState({
blackIsNext: true
})
} else {
this.setState({
blackIsNext: !this.state.blackIsNext
})
}
}
}
And where I call the function:
render() {
<GameBoard squares={current.squares} onClick={(row,col) => {
const elems = this.checkElementsAround(this.checkMoveValidity())
//console.log(elems)
for (let el=0;el<elems.length;el++) {
const turning = this.checkTurningStones(elems[el].directions)
if (turning.length !== 0) {
if (row === elems[el].coordinates[0] && col === elems[el].coordinates[1]) {
this.handleMove(row,col);
//console.log(turning)
for (var t=0;t<turning.length;t++) {
this.handleMove(turning[t][0],turning[t][1])
}
this.setWinnerAndTurn()
break
}
}
}
}}/>
}
Solved the problem, but don't know how. That's strange...
Here's the Code:
setWinnerAndTurn() {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[this.state.stepNumber];
const squares = current.squares.slice()
const blackSquares = []
const whiteSquares = []
// Check for a winner
for (var row=0;row<squares.length;row++) {
for (var col=0;col<squares[row].length;col++) {
if (squares[row][col] === 'black') {
blackSquares.push([row,col])
} else if (squares[row][col] === 'white') {
whiteSquares.push([row,col])
}
}
}
const valids = this.checkElementsAround(this.checkEmptySpaces())
// checkEmptySpaces returns all the empty spaces in the game
// checkElementsAround returns all the objects in all directions if there's initially an element in that direction
const movesAvailable = [0,0]
for (var t=0;t<2;t++) {
const isBlack = (t === 0) ? true : false
for (var v=0;v<valids.length;v++) {
const valid = valids[v]
const turned = this.checkTurningStones(valid.directions,isBlack)
if (turned.length !== 0) {
movesAvailable[t]++;
}
}
}
if (blackSquares.length + whiteSquares.length === squares.length * squares[0].length || (movesAvailable === [0,0])) {
// Declare a winner
if (blackSquares.length !== whiteSquares.length) {
this.setState({
winner: (blackSquares.length > whiteSquares.length) ? 'black' : 'white'
})
} else {
this.setState({
winner: 'tie'
})
}
} else {
// Change turn
if (movesAvailable[0] === 0) {
this.setState({
blackIsNext: false
})
} else if (movesAvailable[1] === 0){
this.setState({
blackIsNext: true
})
} else {
this.setState({
blackIsNext: !this.state.blackIsNext
})
}
}
}
Where I used it:
<div className="master-container">
<GameBoard squares={current.squares} onClick={(row,col) => {
const elems = this.checkElementsAround(this.checkEmptySpaces())
for (let el=0;el<elems.length;el++) {
const turning = this.checkTurningStones(elems[el].directions, this.state.blackIsNext)
if (turning.length !== 0) {
turning.unshift([row,col])
if (row === elems[el].coordinates[0] && col === elems[el].coordinates[1]) {
this.handleMove(turning)
this.setWinnerAndTurn()
// Debug
console.log(history.length)
break
}
}
}
}}/>
// handleMove -> You give an array of coordinates and it does turn them
// setWinnerAndTurn -> Our function
// checkTurningStones -> I give it the output of checkElementsAround as a parameter, it does return the elements that are to be turned upside down
Actually I know how I fixed it; the thing is that since most of my conditional statements depend on the values returned from some of my functions, when used inappropriately, some conditional statements would never return true. That's what I solved.
I build a game and have an issue.
My game looks for a few keydown which move the character.
I added an A* algorithm to let the players the option to move their character with a mouse click (It gives the keys for destination point).
My issue is:
The code is looking for keydown which allowing continuous click and the algorithm return the keys for destination point which should be keypress as per-key.
How should I simulate the keypress for this? (The main question is in AStarWalk function)
Code:
class Event {
constructor(engine) {
this.engine = engine;
this.engine.event = this;
this.focus = false;
this.pressedKeys = {};
this.events = {};
// - - - - - - - - - -
// Events
this.onKey('keydown', 'gameWindow', ['KeyA', 'ArrowLeft'], () => {
this.engine.player.movePlayer(1);
}); // Left
this.onKey('keydown', 'gameWindow', ['KeyW', 'ArrowUp'], () => {
this.engine.player.movePlayer(3);
}); // Up
this.onKey('keydown', 'gameWindow', ['KeyD', 'ArrowRight'], () => {
this.engine.player.movePlayer(2);
}); // Right
this.onKey('keydown', 'gameWindow', ['KeyS', 'ArrowDown'], () => {
this.engine.player.movePlayer(0);
}); // Down
this.onKey('keydown', 'gameWindow', ['KeyR'], () => {
this.engine.player.running = true;
}); // Start running
this.onKey('keyup', 'gameWindow', ['KeyR'], () => {
this.engine.player.running = false;
}); // Stop running
this.onKey('keyup', 'gameWindow', ['PrintScreen'], () => {
console.log('save a picture');
});
this.onKey('focus', 'gameWindow', () => {
this.focus = true;
}); // On focus the game
this.onKey('focusout', 'gameWindow', () => {
this.focus = false;
this.pressedKeys = {};
}); // Focus has out from game
this.onKey('mousedown','gameWindow', [0], (e) => {
let x = Math.floor(e.layerX / this.engine.mapSettings.pxPerSquare);
let y = Math.floor(e.layerY / this.engine.mapSettings.pxPerSquare);
let node = [x, y];
let path = this.engine.astar.findPath(node);
this.AStarWalk(path);
});
// - - - - - - - - - -
// addEventListener
// code - for keyboard
// botton - for mouse
for (let id in this.events) {
for (let type in this.events[id]) {
if (!this.events[id].hasOwnProperty(type))
continue;
document.getElementById(id).addEventListener(type, (event) => {
let e = event;
if (this.inArray(type, ['keydown', 'keyup']))
event.preventDefault();
// Define variables
let key = e.code || e.button; // e.keyCode || e.which;
// Check if the key has event
if (!this.events[id][type].hasOwnProperty(key) && !this.events[id]['keyup'].hasOwnProperty(key))
return;
// Check if the key already pressed
if (this.pressedKeys.hasOwnProperty(key) && type === 'keydown')
return;
// Do
if (type === 'keydown')
this.pressedKeys[key] = e;
else if (type === 'keyup') {
this.runCallbacks(this.events[id][type][key]);
}
else if (this.inArray(type, ['focus', 'focusout'])) {
for (let callback in this.events[id][type]) {
if (!this.events[id][type].hasOwnProperty(callback))
continue;
this.events[id][type][callback](e);
}
}
else if (this.inArray(type, ['mousedown', 'mouseup'])) {
this.runCallbacks(this.events[id][type][key], e);
}
});
document.getElementById(id).addEventListener('contextmenu', (e) => {
e.preventDefault();
});
}
}
// - - - - - - - - - -
// Thread
this.engine.thread.thread(true, 0, (1000 / this.engine.graphic.lastfps), () => {
for (let id in this.events) {
for (let key in this.pressedKeys) {
this.runCallbacks(this.events[id].keydown[key], key);
}
}
});
}
runCallbacks(array, key) {
let e;
for (let callback in array) {
if (!array.hasOwnProperty(callback))
continue;
e = (this.pressedKeys[key] instanceof Event) ? this.pressedKeys[key] : key;
array[callback](e);
}
}
inArray(key, array) {
for (let i in array)
if (array.hasOwnProperty(i) && array[i] === key)
return true;
return false;
}
onKey() {
let event = arguments[0];
let id = arguments[1];
let keyCode = (this.inArray(event, ['keydown', 'keyup', 'mousedown', 'mouseup'])) ? arguments[2] : null;
let callback = (!this.inArray(event, ['keydown', 'keyup', 'mousedown', 'mouseup'])) ? arguments[2] : arguments[3];
// Convert keyCodeList to an array based on keyCode.
if (keyCode != null) {
if (!keyCode instanceof Array)
keyCode = [keyCode];
}
// Create event id if is not exist.
if (!this.events.hasOwnProperty(id)) {
this.events[id] = {
keydown: {},
keyup: {},
focus: [],
focusout: [],
mousedown: {},
mouseup: {}
};
}
// Add event to an array
if (keyCode !== null) {
let done = false;
for (let k in keyCode) {
if (!keyCode.hasOwnProperty(k))
continue;
k = keyCode[k].toString();
for (let key in this.events[id][event]) {
if (key === k) {
if (callback !== undefined)
this.events[id][event][k].push(callback);
if (event === 'keydown')
this.events[id]['keyup'][k].push(() => { delete this.pressedKeys[k]; });
done = true;
break;
}
}
if (!done) {
if (callback !== undefined)
this.events[id][event][k] = [callback];
if (event === 'keydown')
this.events[id]['keyup'][k] = [() => { delete this.pressedKeys[k]; }];
}
}
}
else {
this.events[id][event].push(callback);
}
}
AStarGetKey(state) {
if (state === 'LEFT') return 'ArrowLeft';
if (state === 'UP') return 'ArrowUp';
if (state === 'RIGHT') return 'ArrowRight';
if (state === 'DOWN') return 'ArrowDown';
if (state === 'LEFTUP') return ['ArrowLeft', 'ArrowUp'];
if (state === 'LEFTDOWN') return ['ArrowLeft', 'ArrowDown'];
if (state === 'RIGHTUP') return ['ArrowRight', 'ArrowUp'];
if (state === 'RIGHTDOWN') return ['ArrowRight', 'ArrowDown'];
return false;
}
AStarWalk(path) {
for (let i in path) {
let key = this.AStarGetKey(path[i]);
if (!key) break;
// How to simulate the keypress per key which works with keydown ?
document.getElementById('gameWindow').dispatchEvent(new KeyboardEvent('keypress',{'code': key}));
}
}
}
Sorry for my English guys, is not my native language. I hope you will find the power to understand me ;-)
Why does my code not work correctly in the Safari browser on Iphone 6 ios 10 and above. In the support table, all values used in the code are supported! The code works everywhere except this device. For my data i use Wilddog it same work as Firebase. Array look like {name: 'Some', like: 2, fav_count: 5 }, {name: 'Some2', like: 3, fav_count: 4 }, {name: 'Some3', like: 3, fav_count: 4 }. Something wrong going on sort() function;
var obj = $wilddogObject(ref); // get data from server
obj.$loaded()
.then(function(data) {
var _extends = Object.assign || function(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } }
return target; };
var moments = _.map(data, function(val, id) {
return _extends({}, val, {
id: id
});
});
$scope.ratePlaces = _.map(moments, function(place) {
// console.log(place);
if (place != null) {
if (place.like != undefined) {
function rating(like, favs) {
var parseFavs = parseInt(favs);
var parseLike = parseInt(like);
var newRate = parseLike * 0.5 + parseFavs;
return newRate;
}
place.rate = rating(place.like, place.fav_count);
}
}
return place
})
console.log($scope.ratePlaces);
list($scope.ratePlaces)
})
function list(r) {
r.shift();
r.shift();
r.shift();
r.sort((a, b) => {
if (a.rate != null || a.rate != undefined || a.rate != 'daylife' || !a.name) {
return a.rate - b.rate;
} else {}
})
r.sort((a, b) => {
if (a.rate != null || a.rate != undefined || a.rate != 'daylife' || !a.name) {
let rateA = a.rate;
let rateB = b.rate;
if (rateA < rateB) {
return -1;
}
if (rateA > rateB) {
return 1;
}
return 0;
}
});
$scope.posts = r.reverse();
I have a function like this:
Session.get = function(key) {
if (!window["_SESSION"] || typeof key == 'undefined') {
return window["_SESSION"] || {};
}
if (key.indexOf('.') === -1) {
return window["_SESSION"][key] || {};
}
var keyArr = key.split('.'), val = window["_SESSION"];
for ( var i = 0; i < keyArr.length; i++) {
if (typeof val[keyArr[i]] === 'undefined') {
return null;
}
val = val[keyArr[i]];
}
return val;
}
This function allows me to get nested values without temporary variable outside of the function. Example Session.get('var.nestedvar') is returns value of window[_SESSION']['var']['nestedvar'].
Bat how can I (un)set variables like so? Tried to delete val; but didn't work.. How do the javascript references work? Does anybody know any alternative to accomplish similiar functionality?
You can delete by parent like this:
[10:00:00.380] a = {'root': {'home':'~'}}
[10:00:00.385] ({root:{home:"~"}})
--
[10:00:09.625] b = a['root']
[10:00:09.631] ({home:"~"})
--
[10:00:20.569] delete b['home']
[10:00:20.573] true
[10:00:21.684] a
[10:00:21.688] ({root:{}})
You can use a slight modification of your existing code, like this:
Session.delete = function(key) {
if (!window["_SESSION"] || typeof key == 'undefined') {
return false;
}
if (key.indexOf('.') === -1) {
if (key) {
delete key;
return true;
}
}
var keyArr = key.split('.'), val = window["_SESSION"];
var keyDepth = keyArr.length;
for ( var i = 0; i < keyDepth-1; i++) {
if (typeof val[keyDepth] === 'undefined') {
return null;
}
val = val[keyDepth];
}
if (val[keyDepth-1]) {
delete val[keyDepth-1];
return true;
}
return false;
}