How to generate level for a laser game in Javascript? - javascript

I am trying to generate a random level for my silly game. The game consists of having laser/detector pairs around a square field of possible mirrors. Like this:
/*
LLLLLLLLLL
LmmmmmmmmL
LmmmmmmmmL
LmmmmmmmmL
LLLLLLLLLL
*/
Now, I have an algorithm which generates a level, quite poorly, by relying on random placement, and rejecting bad positions. This is not very fast, and does not really generate the kind of fields I'd like to have. Please feel free to try it out at http://cmouse.desteem.org/laser/
Any suggestions are welcome.
The current algorithm looks something like this:
function createLevel:
for i=0 to mirrors:
mirrorLocation = pickRandomPosition
mirrorType = pickRandomType
if (verifyPosition(mirrorLocation, mirrorType)):
i = i - 1
next
else:
storeMirror(mirrorLocation, mirrorType)
In verifyPosition, we test the mirror that it reaches a laser in all four directions, in hope of avoiding undetectedable mirrors. It is somewhat boring code, so I omit it here.

One way to make sure it's not trying multiple fields more than once is to iterate over the fields and put a mirror or not based on some probability. The probability to put a mirror should be #mirros / #fields, so that the expected number of mirrors is #mirrors at the end.

Related

Can I let shape with liquify effect like photoshop by p5.js

I want to create an irregular lines with liquify effect like photoshop. Also, want to implement it by p5.js.
Is it possible use some mathematical formula to create line like the referring image.
Or how can I do this effect? Any idea can guide me. thanks a lot!!
There is for sure an algorythm to liquify something. But there is way too much information missing on what you are trying to do, or what the photoshop-effect looks like.
I'd suggest you start small. Draw a vertical line in P5 center of your screen. (Loop to draw each dot individually). Now for every y of your line use a random value provided by "Open Simplex". Offset the dot x-position by the random value. Tip: Use a fixed seed.
When using the OpenSimplex. You will have to use any of those: noise2D, noise3D, noise4D
You can use any you want. The important thing is you modify only one value by your y and one by time (frameCount for example). The value you get back will be a little different from the previous one every time. Like this you will get a random value for every iteration, but a random value which is not too different from the previous value of y. Thats how the liquidity illusion is provided.
Read up on OpenSimplex.
This is the 2D(+1D [Time]) Version of it: https://editor.p5js.org/codingtrain/sketches/MPqnctIGg

Randomize numbers in a random order script

I have searched and although I see this addressed in Python and PHP, I don't see it using JS. This script randomizes order on refresh and I would like the numbers to be randomly generated as well as the order. The order part is already working, but I don't want it limited to numbers I input (150, 375 and 900 in this example). I'm going to have about 50 variables but I've just listed three to keep it short here.
I would also like to understand how to control the place values permitted, so I could have xx,xx,xx, etc./ xxx,xxx,xxx etc. and also how to state a range, so it could include xx,xxx,xxxx
Lastly I would be very keen to understand how to limit the generated numbers to meet certain profiles, like all tens (670,320,980,410,650), twenty-fives (375,925,400,850,175, etc.). This would be extremely helpful.
I'm sorry this is just beyond my ability, and I have tried and tried. I operate a school in India where I teach math, and we have had great success teaching number recognition and counting in English and Hindi using printed charts of numbers that fit different criteria like this, and I would like to adapt it to a mobile app, just to let you know why I'm asking. Many thanks.
var contents=new Array()
contents[0]='150'
contents[1]='375'
contents[2]='900'
*/
var spacing = "<br />"
var the_one
var z = 0
while (z<contents.length){
the_one=Math.floor(Math.random()*contents.length)
if (contents[the_one]!="_selected!"){
document.write(contents[the_one]+spacing)
contents[the_one]="_selected!"
z++
}
}

JavaScript: How do i use a string as a piece of code

I am making a simple-ish graph maker to visualise equations. I need to be able to have the user input a string in a textbox and then interpret that as a piece of code I can execute to produce the graph. The way I am displaying the graph is by going through x in small increments and using an equation to then calculate the y position and then drawing a line between the points. At the moment I am just manually making a function in the code for example:
function(val) { return (val * val) + 5; }
but I need to be able to create a similar function from a string so the user could just input something like "(x*x)+(2*x)". is there any way to do this?
Canonically, this is done with eval(), although it comes with many caveats and should probably be avoided.
There are several questions on SO that discuss eval alternatives, but in your case, I would suggest a very bare-bones parser -- especially if all you're handling are mathematical equations.

Simulate an infinite number of objects

On this example we can move inside a field of spheres but into certain limits. I want to be able to move infinitely among them. How can I do that ?
The trick is to reuse the spheres that are behind the camera and put them in front of it. Look at how it is done in this example. Here the programmer knows that the user will continue in the same direction so he removes the trees that come at a certain position.
If you use something like the example you quoted, you cannot know which direction the user will take. And so, you can use the same trick, but have to code it an other way. The most obvious is to check the distances with all the spheres regularly, if the user moves. If one sphere is too far behind the camera, you mirror it so it faces the camera, behind the fog.
'Regularly' can mean two things depending on your real number of spheres in your scene :
If you have a small scene and few spheres you can check those distances in your render loop. Neither cheap nor useful, 60 per seconds, but that can be the first coding step
Then the best way would be to use a web worker : you send the positions of the camera and those of the spheres, you let the worker compute all the stuff in its thread, and send instructions back : 'move those spheres to those positions'. Every seconds is more reasonable in the threejs example, but up to you to decide that depending on your scene.
NOTE : if you have a lot of spheres, or any meshes you use instead, like more than 20-30, having a mesh for each of them will slower performances. With few trees on the examples i linked it is ok, but with more objects and/or a heavier scene,
think about merging them all in a single geometry. You can check which sphere is where by deducing from the vertices indices, or adding an attribute that defines each sphere.
this will also impact the worker delay : it will have more to compute so it will need more time.
NOTE 2 : Note 1 would of course delete the level of details that the example aims to illustrate :) (Unless you also implement your own while checking the distances of the spheres....)
If you want to have an illusion of infinite world then you could:
Break your world space into regions (for example cubes).
Detect which region you are currently in.
Make sure you have objects (spheres) in neighbour regions. If some of regions are empty - fix it.
Clear regions which are not needed anymore.
For this you might want to have some class like this:
Class Region {
bool isEmpty = true;
Vector3 center;
float radius; // or 'range'
Array<Sphere> = null; // storage of your objects
// constructors / destructor
generateObjects(params); // perlin noise might be helpful there
removeObjects();
}
and do something like this periodically:
void updateRegions() {
computeClosestGridCoord(myPosition); // which is center of your current region
lookForNeighbourRegions(regionsArray); // and add new Region if needed
deleteOldRegionsStuff(regionsArray);
}

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