Change Value of specific Entry in JavaScript Array of Objects - javascript

I seem to be stuck at a probably idiotic problem but I can't figure it out...
There are classes for a Player, an Army, and a Unit.
The Player object contains several armies, which in turn contain several units.
I add a player like so: let player1 = new Player()
I add armies within the player object like: this.armies.push(new Army())
I add the units within the army object like: this.units.push(new Unit(data)) - data being an object, containing the unit's base stats.
This all works fine.
Now – when I try to change a stat of a single warrior unit (for example player1.armies[0].units[0].hp -= 2), it also changes the stats of each other warrior unit in all armies of player1.
How can I select a specific warrior unit by index within a specific army of player1?
Thanks in advance,
Simon

Related

How to track a running object in tensorflow.js?

I have forked a Tensorflow.js code which essentially detects a variety of objects using a webcam video. I would like to know, if there is a way to track the moved distance ( X and Y coordinates) of specific objects like humans within the webcam to calculate their speed.
The most important thing for me right now is, to give every detected human, a unique ID. So that i can use that ID to store the object's coordinates in an array, for example:
let speed = { ID: 1, xVal: [1,2,3,4], yVal: [2,3,4,5] } // this code works fine and gives the predicted image an ID
The problems here is, the code breaks down the video into image frames and predicts every object in every image frame independently. So if i give a predicted object an ID for example ID = 1,
The predicted element will have an ID which is equal to 1. But that id will be lost whenever a new image frame appears, the code will predict again and the new image frame will lose all the IDs.
if(prediction.class == 'person'){
prediction.id = 1;
}
// this code gives the predicted human object an id equal to 1. what i want is to give every human a unique ID.
// Let's say the camera detects 5 people, i want each of them to have a unique ID
// so that i can track their moved distance.
Here is a demo which shows the code in action: https://codesandbox.io/s/z364noozrm .
Here is the tutorial i got the code from: https://hackernoon.com/tensorflow-js-real-time-object-detection-in-10-lines-of-code-baf15dfb95b2 .

THREE.JS Multiple groups containing the same objects

I'm currently learning THREE.js and trying to make a playable rubik's cube.
I want to be able to rotate a face as a whole instead of moving every single cube one at a time, and I can do so by creating a THREE.Group and adding the cubes in it. The problem is that a single cube is contained in multiple faces, and I can't find a solution. If I create an object, add it to a first group, then add it to a second group, it is removed from the first group.
I'm pretty sure there is a workaround but can't find it as I'm really new to THREE.js and 3D programming (I only followed a basic course https://www.udemy.com/3d-programming-with-javascript-and-the-threejs-3d-library/).
There is my code but I don't think it will be very usefull anyway.
https://pastebin.com/Hq66UvBU
Thanks
Welcome to Stack Overflow. Please remember to edit your question to include your code, because when the pastebin link dies, your question loses important context.
The correct way to add an object to a THREE.Group is through the add function, like you do. But an object added to multiple groups will only ever be a child of the last group to which it was added. This is because add looks to see if the object already has a defined parent, and removes the object from that parent before setting the new parent (r97 code).
Example:
let obj = new THREE.Object3D()
let p1 = new THREE.Group()
let p2 = new THREE.Group()
p1.add(obj) // obj.parent == p1
p2.add(obj) // 1. three.js calls p1.remove(obj) 2. obj.parent == p2
Beyond this reason, and as #Mugen87 mentioned, your cubes need to not only be able to have multiple memberships, but also to be able to enter and leave face groups as their positions change. To me this says you will almost need to transform the cubes individually. You could use a THREE.Group to make it easier to conceptualize, but there would be extra overhead to actually implement it that way.
Maybe a late answer but try to work in another way and group the cubes that need to turn the moment the turn function is activated and then turn the group around, then empty the group.

3D Grid for multiple shapes

A few months ago I made a small terrain generator, like Minecraft, for a school project.
The way I did this was by using multiple chunks. Each chunk contained a 3-dimensional array that stored the blocks.
Every position in this array corresponded with the position of the block it contained.
blocks[x, y, z] = new Block();
Now I would like to add different sizes if blocks. However, I can't do that with the way I am storing the blocks right now, because bigger blocks would have to be spread over multiple positions in the 3-dimensional array.
An example of a game with different sizes of blocks (and different shapes) is LEGO Worlds. How does a game like this store all these little blocks?
I hope someone can help me with this.
The language I am using is Javascript in combination with WebGL.
Thanks in advance!
In my experience there are a few different ways of tackling an issue like this, but the one I'd recommend would depend on the amount of time you have to work on this and the scope (how big) you wanted to make this game.
Your Current Approach
At the moment I think your using what most people would consider the most straightforward approach by storing the voxels in a 3D grid
[Source].
But two problems you seem to be having is that there isn't an obvious way to create blocks that are bigger then 1x1 and that a 3D grid for a world space is fairly inefficient in terms of memory usage (As for an array you have to have memory allocated for every cell, including empty space. JavaScript is no different).
An Alternative Approach
An alternative to using a 3D array would be to instead use a different data structure, the full name being a sparse voxel octree.
This to put it simply is a tree data structure that works by subdividing an area of space until everything has been stored.
The 2D form of this where a square sub divides into four smaller quadrants is called a quad tree and likewise a 3D equivalent divides into eight quadrants, called an octree. This approach is generally preferable when possible as its much more efficient because the trees only occupy more memory when its absolutely essential and they can also be packed into a 1D array (Technically a 3D array can be too).
A common tactic used with quad/octrees in some block based games is to take a region of the same kind of voxel that fit into one larger quadrant of the tree is to simply stop sub division there, as there's no reason to go deeper if all the data is the same.
The other optimization they can make is called sparse where regions of empty space (air) are simply deleted since empty space doesn't do anything special and its location can be inferred.
[SVO Source]
[Z Order Curve Source]
Recommended Approach
Unless you have a few months to complete your game and you're at university I seriously wouldn't recommend an SVO (Though reading up about could impress any teachers you have). Instead I'd recommend taking the same approach that Minecraft appears to visibly has. E.G. A door is 1X2 but blocks can only be 1x1, then just make it two blocks.
In the example of a door you would have four unique blocks in total, two for the upper and lower half, and two variations of each being opened or closed.
E.G.
var cubeProgram; // shader program
var cubeVBO; // vertex buffer (I recommend combining vertex & UV coords)
var gl; // rendering context
// Preset list of block ID's
var BLOCK_TYPES = {
DOOR_LOWER_OPEN: 0,
DOOR_UPPER_OPEN: 1,
DOOR_LOWER_CLOSED: 2,
DOOR_UPPER_CLOSED: 3,
}
var BLOCK_MESHES = {
GENERIC_VBO: null,
DOOR_UPPER_VBO: null
DOOR_LOWER_VBO: null
}
// Declare a Door class using ES6 syntax
class Door {
// Assume X & Y are the lower half of the door
constructor(x,y,map) {
if (y - 1 > -1) {
console.error("Error: Top half of the door goes outside the map");
return;
}
this.x = x;
this.y = y;
map[x][y ] = BLOCK_TYPES.DOOR_LOWER_OPEN;
map[x][y-1] = BLOCK_TYPES.DOOR_UPPER_OPEN;
}
}

java script text based game and objects

I am writing a text based game where I want users to be able to manipulate any item.
I want the user to be able to say, for example, "I throw the bottle of oil at the monster."
Now when this happens [throw] will be an action, [bottle of oil] is an inventory item with the property [contains oil], and the monster will be the nearest monster in the room unless specified further.
Code needs to analyze the various properties of all these things and then pick actions that cause those things to interact.
When i write the Game story code it will be like follows
*room.darkroom.1 "wake up" [...] everything appears blurry, the voice sounds strange as if echoing down a long tunnel. From what you can see you can tell [you are in a dark room] your vision blurs from white to dark. [pc is inside very dark room. Inside this room everything is hidden in darkness. The northern wall has a locked thick wooden door. the southern wall has a barrel full of oil containing a bottle of oil. In the eastern side of the room are 2 medium sized crates one crate contains flint and rusty dagger. In the western side of the room a [small window] */room.darkroom.1
The script will take all those words and apply properties to them randomizing certain elements that are left unstated. So if you then say "chair" it will go to the chair properties and randomly assign unstated properties. One property of chair will be material. If its not stated that its an oak chair then the script should pick from any of the material properties and assign them. This new chair will pick up a few properties and be saved for future reference on the database with all properties.
Another property would be an action. A chair would not necessarily have an action .. but it might break. The script needs to know if the chair is breakable. But I am thinking that could be nested into another property like [toughness].
Many things will have many of the same properties: chair, night stand, table would all be similar in many ways. But they would also have different outcomes depending on the actions applied to them.
How do I specify for instance when "broken" contains chair legs and scrap material? The chair legs and the scrap material would both need to inherit the properties of the chair that was destroyed, such as oak / flammable / breakable. Obviously, as stated before, it might not have to inherit flammable or breakable if oak is the part that holds that value.
I want to make it easy to access the array that stores properties and that might include a script that effects behavior and descriptions of things.
I started to just create a keyed array which would be looped through... But now I am thinking that I should utilize the object based element of JavaScript.
Here is what i have started to do but I stopped right away:
var language = {
// key currentmodifyers possible modifyers action/condition description of item
item: ";medium,material;;its a thing thats not a person",
chair: "item,chair_Legs;;pile_of.#scraps.collection.chairlegx3/broken,#[chair ]scraps/destroyed; and someone could sit on it. ",
chair_leg:"item,blunt,light,"
}
I have so many definitions to write so it would be a shame to start writing it all and then have to do it over when I discover the best way.
I am looking at various ways to build objects in JavaScript, but would like the best way from someone experienced.
Understanding the complexity of my problem, what is the best way to store and apply properties?
There are actually two good thoughts in your question:
But now I am thinking that I should utilize the object based element of JavaScript.
You definitely need to use objects instead of arrays, the OOP ideas can be directly applied to your descriptions.
Some objects are composed of smaller parts (the "composition" in OOP) and some inherit properties of other objects (the "inheritance").
So you could have some base Item class which defines basic operations and properties for all objects (like they have different properties and can do some things).
Then you can add objects like StaticItem (will be base for chairs, night stands, etc) and LiveBeeing (monsters, etc).
And now you can actually create the Chair (pseudocode):
StaticItem extends Item
this.material = oak // oak is an object of OakMaterial
// is this static item flamable?
this.isFlamable = function() {
// we "redirect" flamability detection to the material
return this.material.flamable();
}
Chair extends Static
// break this chair!
this.break = function() {
// when it is broken we return a HeapOfCrap, it is a
// Static subclass which contains some sub-items
// In this case the heap contains 4 chair legs of the
// same material as the chair
return HeapOfCrap([
new ChairLeg(this.material), new ChairLeg(this.material),
new ChairLeg(this.material), new ChairLeg(this.material)
])
}
And so on, you need to plan you object structure carefully and there is a good field to apply some of the design patterns.
The example above is just what came in my mind immediately, while actual design should take much more time and thinking.
The second good thought in your question is about the huge amount of work:
I have so many definitions to write so it would be a shame to start writing it all and then have to do it over when I discover the best way.
You absolutely right here, would you select to use objects or arrays, or anything else - don't try to describe all your game right away.
Select few basic elements, like "Room", "Door", "Chair", "Monster", "Player" and try to code the minimal game with only these elements.
Play with the structure to find the good design and once you are sure it is good - go on and add more elements to the game.

Detect loops in computer player in a cardgame

A while ago I created a small cardgame web app for fun. The player plays against the computer and mostly it works fine. Sometimes though the computer player gets into a loop, the point of the game is to lose all your cards and if you don't have a card to play you take the pile. Sometimes the computer plays x,y,z, takes the pile, plays x,yz, takes the pile etc.
I keep track of the moves I've made, so at any point I have an array that looks something like : [C2,D5,H2,S4,C5,H2,S4,C5,H2,S4,C5]
In this case I can see that I've gotten into a loop of playing H2,S4,C5, then taking the pile and then repeating.
So, the generalized problem is, what's the best way to detect repeating patterns in a list? I could probably whip something up using a simple for loop, trying to find the card I'm about to play and if I find that in position x then I could check whether the pattern from x to n repeats at position x-(n-x) to x, but this seems like the kind of problem that could have a nice algorithm for it. How would you code this given the following function signature:
function findLoops(previousMoves, nextMove, maxPatternLength) {
//Return [loopLength, loopCount] or null if there are no loops
}
p.s. this is not a homework assignment, the game exists and is at http://www.idiot-cardgame.com if anyone is interested :)
First the general question: Your suggested method
trying to find the card I'm about to play and if I find that in position x then I could check whether the pattern from x to n repeats at position x-(n-x) to x,
looks really good. I would suggest basically the same. It is O(n) and needs a fixed amount of storage, and is simple: what else would you wish for?
Second: You can check for repetition in games generally if you keep a hash table of all previous game states (complete state, nothing left out). Everytime you reach a new state look up if it is in the hashtable, if its in it: you game state is looping.
In Javascript you have builtin hastables so this is very easy to do with something similar like this:
new_state = next_move(old_state);
new_encoded_state = encode(new_state); // make it into a string
if (allstates[new_encoded_state]) {
// we are looping!
} else {
allstates[new_encoded_state] = 1;
// no looping
}
The variable allstates is not an Array but of type Object. You can have array like access with strings and this uses the Object as hastable.

Categories

Resources