Formula for procedurally generating the location of planets in a game - algorithm

I want to develop a game where the universe is a maximum 65536 x 65536 grid. I do not want the universe to be random, what I want is for it to be procedurally generated according to location. What it should generate is a number from 0 to 15.
0 means empty space. Most of the universe (probably 50-80%) is empty space.
1 - 9 a planet of that technology level
10-15 various anomalies (black hole, star, etc.)
Given an address from 0x8000-0xFFFF or 0 or 1-0x7fff for the X address, and the same range for the Y address, returns a number from 0 to 15. Presumably this would place planets nearer to 0,0 more plentiful than those at a distance of
The idea being, the function is called passing the two values and returns the planet number. I used to have a function to do this, but it has gotten lost over various moves.
While the board could be that big, considering how easy it would be to get lost, I'll probably cut the size to 1200 in both directions, -600 to +600. Even that would be huge.
I've tried a number of times, but I've come to the conclusion that I lack the sufficient math skills to do this. It's probably no more than 10 lines. As it is intended to be multiplayer, it'll probably be either a PHP application on the back end or a desktop application connecting to a server.
Any help would be appreciated. I can probably read any commonly used programming language you might use.
Paul Robinson

See How to draw sky chart? for the planetary position math. Especially pay attention to the image with equations you can use it to compute period of your planet based on its distance and mass to system central mass... for simple circular orbit just match the centripedal force with gravity like I did in here:
Is it possible to make realistic n-body solar system simulation in matter of size and mass?
So for example:
G = 6.67384e-11;
v = sqrt(G*M/a); // orbital speed
T = sqrt((4.0*M_PI*M_PI*a*a*a)/(G*(m+M))); // orbital period
pos = (a,0,0); // start position
vel = (0,sqrt(G*M/a),0); // start speed
The distribution of planets and their sizes complies specific (empirically obtained) rules (that is one of the reasons why we are still looking for 10th planet). I can't remember the name of the rule, however from quick look on Google Image from here can be used too:
Distribution of the planets in solar system according to their mass
and their distances from the Sun. The distances (X-axis) are in AU and
masses (Y-axis) in Yotta (10^24)
Jupiter mass is M=1,898e27 kg so mass units are in 10^24 kg.
So just match your PRNG generation to such curve and be done with it.

Related

Kalman Filter on a set of points belonging to the same object?

Let's say you're tracking a set of 20 segments with the same length belonging to the same 3D plane.
To visualize, imagine that you're drawing a set of segments of length 10 cm randomly on a sheet of paper. And make someone move this sheet in front of the camera.
Let's say those segments are represented by two points A and B.
Let's assume we manage to track A_t and B_t for all the segments. The tracked points aren't stable from frame to frame resulting in occasional jitter which might be solved by a Kalman filter.
My questions are concerning the state vector:
A Kalman filter for A and B for each segment (with 20 segments this results in 40 KF) is an obvious solution but it looks too heavy (knowing that this should run in real-time).
Since all the tracked points have the same properties (belonging to the same 3D plane, have the same length) isn't it possible to create one big KF with all those variables?
Thanks.
Runtime: keep in mind that the kalman equations involve matrix multiplications and one inversion. So having 40 states means having some 40x40 matrices. That will always take longer to calculate than running 40 one-state filters, where your matrices are 1x1 (scalar). Anyway, running the big filter only makes sense if you do know of a mathematical relationship between your states (=correlation), otherwise its output wise the same like running the 40 one-state filters.
With the information given thats really hard to tell. E.g. if your segments are always a polyline you could describe that differently in contrast to knowing nothing about the shape.

Estimate Feasibility of filling Main-Cube interior surfaces with some sub-cubes without Volume Interference

I have a stupid question but it's really hard I think to compute and it's part of my project to estimate the feasibility of layout these small boxes on the interior surfaces of the big empty box("Main-Cube") at the beginning of process ... So in my problem I have a big extruded cut cube (like empty box - that we called it "Main-Cube" as shown in the below fig ) and variable quantity small solid boxes (quantity of these small boxes is predefined by end user as input data and we called them "sub-cube" ) that stick to interior surfaces ( mate/projection/connected to surface) ... So I want to know when this problem Certainly has no answer (because of crowding small boxes on each 6 side of main cube interior surfaces ) and so won't let the end user to start computing at first time and tell the user that this problem Certainly can't have any feasible answer ( feasible answer means has no interference/violation in volume) so the user won't waste time for further computation .
for example the Main-Cube dimensions is 1000mm x 1000mm x 1000mm
I think the total Main-cube volume is (without considering 10mm for Mantle/thickness of cube) is Approx : 1 Cubic meters or 1,000,000,000 Cubic millimeters
I also find the total small box volume so the fraction of :
Total Sum of small boxes Volume / Main-cube total volume
is not really Useful !
I also try the sum of minimum area for each small boxes and then calculation this fraction :
Sum of Min All small boxes / 6 x (1000mm x 1000mm)
and because of common edges of Main cube it can't be useful too .
So any Idea or concept accepted :) that can Ensure that with this used area definitely no solution can find for this problem unless reducing some small box and repeat the process check ...
Crowding scenario
Low dispersion for simple scenario
P.S : As you seen in the below table (contain small and big box dimensions) the results said that roughly 44% interior surfaces area and 26% volume is filled (or used by 90 small boxes) how ever now the problem rarely has feasible solution and it's really hard to say if we increase amount from 90 boxes to 100 We can find one feasible solution but 26% or 44% don't represent this!
Specifications Table

distinguishing objects with opencv

I want to identify lego bricks for building a lego sorting machine (I use c++ with opencv).
That means I have to distinguish between objects which look very similar.
The bricks are coming to my camera individually on a flat conveyer. But they might lay in any possible way: upside down, on the side or "normal".
My approach is to teach the sorting machine the bricks by taping them with the camera in lots of different positions and rotations. Features of each and every view are calculated by surf-algorythm.
void calculateFeatures(const cv::Mat& image,
std::vector<cv::KeyPoint>& keypoints,
cv::Mat& descriptors)
{
// detector == cv::SurfFeatureDetector(10)
detector->detect(image,keypoints);
// extractor == cv::SurfDescriptorExtractor()
extractor->compute(image,keypoints,descriptors);
}
If there is an unknown brick (the brick that i want to sort) its features also get calculated and matched with known ones.
To find wrongly matched features I proceed as described in the book OpenCV 2 Cookbook:
with the matcher (=cv::BFMatcher(cv::NORM_L2)) the two nearest neighbours in both directions are searched
matcher.knnMatch(descriptorsImage1, descriptorsImage2,
matches1,
2);
matcher.knnMatch(descriptorsImage2, descriptorsImage1,
matches2,
2);
I check the ratio between the distances of the found nearest neighbours. If the two distances are very similar it's likely that a false value is used.
// loop for matches1 and matches2
for(iterator matchIterator over all matches)
if( ((*matchIterator)[0].distance / (*matchIterator)[1].distance) > 0.65 )
throw away
Finally only symmatrical match-pairs are accepted. These are matches in which not only n1 is the nearest neighbour to feature f1, but also f1 is the nearest neighbour to n1.
for(iterator matchIterator1 over all matches)
for(iterator matchIterator2 over all matches)
if ((*matchIterator1)[0].queryIdx == (*matchIterator2)[0].trainIdx &&
(*matchIterator2)[0].queryIdx == (*matchIterator1)[0].trainIdx)
// good Match
Now only pretty good matches remain. To filter out some more bad matches I check which matches fit the projection of img1 on img2 using the fundamental matrix.
std::vector<uchar> inliers(points1.size(),0);
cv::findFundamentalMat(
cv::Mat(points1),cv::Mat(points2), // matching points
inliers,
CV_FM_RANSAC,
3,
0.99);
std::vector<cv::DMatch> goodMatches
// extract the surviving (inliers) matches
std::vector<uchar>::const_iterator itIn= inliers.begin();
std::vector<cv::DMatch>::const_iterator itM= allMatches.begin();
// for all matches
for ( ;itIn!= inliers.end(); ++itIn, ++itM)
if (*itIn)
// it is a valid match
The result is pretty good. But in cases of extreme alikeness faults still occur.
In the picture above you can see that a similar brick is recognized well.
However in the second picture a wrong brick is recognized just as well.
Now the question is how I could improve the matching.
I had two different ideas:
The matches in the second picture trace back to the features really fitting, but only if the visual field is intensely changed. To recognize a brick I have to compare it in many different positions anyway (at least as shown in figure three). This means I know that I am only allowed to minimally change the visual field. The information how intensely the visual field is changed should be hidden in the fundamental matrix. How can I read out of this matrix how far the position in the room has changed? Especially the rotation and strong scaling should be of interest; if the brick once is taped farer on the left side this shouldn't matter.
Second idea:
I calculated the fundamental matrix out of 2 pictures and filtered out features that don't fit the projections - shouldn't there be a way to do the same using three or more pictures? (keyword Trifocal tensor). This way the matching should become more stable. But I neither know how to do this using OpenCV nor could I find any information on this on google.
I don't have a complete answer, but I have a few suggestions.
On the image analysis side:
It looks like your camera setup is pretty constant. Easy to just separate the brick from the background. I also see your system finding features in the background. This is unnecessary. Set all non-brick pixels to black to remove them from the analysis.
When you have located just the brick, your first step should be to just filter likely candidates based on the size (i.e. number of pixels) in the brick. That way the example faulty match you show is already less likely.
You can take other features into account such as the aspect ratio of the bounding box of the brick, the major and minor axes (eigevectors of the covariance matrix of the central moments) of the brick etc.
These simpler features will give you a reasonable first filter to limit your search space.
On the mechanical side:
If bricks are actually coming down a conveyor you should be able to "straighten" the bricks along a straight edge using something like a rod that lies at an angle to the direction of the conveyor across the belt so that the bricks arrive more uniformly at your camera like so.
Similar to the previous point, you could use something like a very loose brush suspended across the belt to topple bricks standing up as they pass.
Again both these points will limit your search space.

Finding the angle of stripeline/ Angle of rotation

So I’m trying to find the rotational angle for stripe lines in images like the attached photo.
The only assumption is that the lines are parallel, and their orientation is about 90 degrees approximately more or less [say 5 degrees tolerance].
I have to make sure the stripe lines in the result image will be %100 vertical. The quality of the images varies as well as their histogram/greyscale values. So methods based on non-adaptive thresholding already failed for my cases [I’m not interested in thresholding based methods if I cannot make it adaptive]. Also, there are some random black clusters on top of the stripe lines sometimes.
What I did so far:
1) Of course HoughLines is the first option, but I couldn’t make it work for all my images, I had some partial success though following this great article:
http://felix.abecassis.me/2011/09/opencv-detect-skew-angle/.
The main reason of failure to my understanding was that, I needed to fine tune the parameters for different images. Parameters such as Canny/BW/Morphological edge detection (If needed) | parameters for minLinelength/maxLineGap/etc. For sure there’s a way to hack into this and make it work, but, to me this is a fragile solution!
2) What I’m working on right now, is to divide the image to a top slice and a bottom slice, then find the peaks and valleys of each slice. Then basically find the angle using the width of the image and translation of peaks. I’m currently working on finding which peak of the top slice belongs to which of the bottom slice, since there will be some false positive peaks in my computation due to existence of black/white clusters on top of the strip lines.
Example: Location of peaks for slices:
Top Slice = { 1, 33,67,90,110}
BottomSlice = { 3, 14, 35,63,90,104}
I am actually getting similar vectors when extracting peaks. So as can be seen, the length of vector might vary, any idea how can I get a group like:
{{1,3},{33,35},{67,63},{90,90},{110,104}}
I’m open to any idea about improving any of these algorithms or a completely new approach. If needed, I can upload more images.
If you can get a list of points for a single line, a linear regression will give you a formula for the straight line that best fits the points. A simple trig operation will convert the line formula to an angle.
You can probably use some line thinning operation to turn the stripes into a list of points.
You can run an accumulator of spatial derivatives along different angles. If you want a half-degree precision and a sample of 5 lines, you have a maximum 10*5*1500 = 7.5m iterations. You can safely reduce the sampling rate along the line tenfold, which will give you a sample size of 150 points per sample, reducing the number of iterations to less than a million. Somewhere around that point the operation of straightening the image ought to become the bottleneck.

Looking for a good world map generation algorithm [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'm working on a Civilization-like game and I'm looking for a good algorithm for generating Earth-like world maps. I've experimented with a few alternatives, but haven't hit on a real winner yet.
One option is to generate a heightmap using Perlin noise and add water at a level so that about 30% of the world is land. While Perlin noise (or similar fractal-based techniques) is frequently used for terrain and is reasonably realistic, it doesn't offer much in the way of control over the number, size and position of the resulting continents, which I'd like to have from a gameplay perspective.
A second option is to start with a randomly positioned one-tile seed (I'm working on a grid of tiles), determine the desired size for the continent and each turn add a tile that is horizontally or vertically adjacent to the existing continent until you've reached the desired size. Repeat for the other continents. This technique is part of the algorithm used in Civilization 4. The problem is that after placing the first few continents, it's possible to pick a starting location that's surrounded by other continents, and thus won't fit the new one. Also, it has a tendency to spawn continents too close together, resulting in something that looks more like a river than continents.
Does anyone happen to know a good algorithm for generating realistic continents on a grid-based map while keeping control over their number and relative sizes?
You could take a cue from nature and modify your second idea. Once you generate your continents (which are all about the same size), get them to randomly move and rotate and collide and deform each other and drift apart from each other. (Note: this may not be the easiest thing ever to implement.)
Edit: Here's another way of doing it, complete with an implementation — Polygonal Map Generation for Games.
I've created something similar to your first image in JavaScript. It's not super sophisticated but it works :
http://jsfiddle.net/AyexeM/zMZ9y/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<style type="text/css">
#stage{
font-family: Courier New, monospace;
}
span{
display: none;
}
.tile{
float:left;
height:10px;
width:10px;
}
.water{
background-color: #55F;
}
.earth{
background-color: #273;
}
</style>
</head>
<body>
<div id="stage">
</div>
<script type="text/javascript">
var tileArray = new Array();
var probabilityModifier = 0;
var mapWidth=135;
var mapheight=65;
var tileSize=10;
var landMassAmount=2; // scale of 1 to 5
var landMassSize=3; // scale of 1 to 5
$('#stage').css('width',(mapWidth*tileSize)+'px');
for (var i = 0; i < mapWidth*mapheight; i++) {
var probability = 0;
var probabilityModifier = 0;
if (i<(mapWidth*2)||i%mapWidth<2||i%mapWidth>(mapWidth-3)||i>(mapWidth*mapheight)-((mapWidth*2)+1)){
// make the edges of the map water
probability=0;
}
else {
probability = 15 + landMassAmount;
if (i>(mapWidth*2)+2){
// Conform the tile upwards and to the left to its surroundings
var conformity =
(tileArray[i-mapWidth-1]==(tileArray[i-(mapWidth*2)-1]))+
(tileArray[i-mapWidth-1]==(tileArray[i-mapWidth]))+
(tileArray[i-mapWidth-1]==(tileArray[i-1]))+
(tileArray[i-mapWidth-1]==(tileArray[i-mapWidth-2]));
if (conformity<2)
{
tileArray[i-mapWidth-1]=!tileArray[i-mapWidth-1];
}
}
// get the probability of what type of tile this would be based on its surroundings
probabilityModifier = (tileArray[i-1]+tileArray[i-mapWidth]+tileArray[i-mapWidth+1])*(19+(landMassSize*1.4));
}
rndm=(Math.random()*101);
tileArray[i]=(rndm<(probability+probabilityModifier));
}
for (var i = 0; i < tileArray.length; i++) {
if (tileArray[i]){
$('#stage').append('<div class="tile earth '+i+'"> </div>');
}
else{
$('#stage').append('<div class="tile water '+i+'"> </div>');
}
}
</script>
</body>
</html>
I'd suggest you back up and
Think about what makes "good" continents.
Write an algorithm that can tell a good continental layout from a bad one.
Refine the algorithm so that you can quantify how good a good layout is.
Once you have that in place, you can start to implement an algorithm which should be shaped like this:
Generate crappy continents and then improve them.
For improvement you can try all sorts of standard optimization tricks, whether it's simulated annealing, genetic programming, or something completely ad hoc, like moving a randomly chosen edge square from whereever it is on the continent to the edge opposite the continent's center of mass. But the key is to be able to write a program that can tell good continents from bad ones. Start out with hand-drawn continents as well as your test continents, until you get something you like.
I wrote something similar to what you're after for an automated screensaver-style clone of Civilization 1. For the record I wrote this in VB.net but since you don't mention anything about language or platform in your question I'll keep it abstract.
The "map" specifies the number of continents, continent size variance (eg 1.0 would keep all continents with the same approximate land area, down to 0.1 would allow continents to exist with 1/10th the mass of the largest continent), maximum land area (as a percentage) to generate, and the central land bias. A "seed" is distributed randomly around the map for each continent, weighted towards the centre of the map as per the central bias (eg a low bias produces distributed continents more similar to Earth, where as a high central bias will resemble more of a Pangaea). Then for each iteration of growth, the "seeds" assign land tiles according to a distribution algorithm (more on that later) until a maximum land area has been reached.
The land distribution algorithm can be as precise as you want but I found more interesting results applying various genetic algorithms and rolling the dice. Conway's "Game of Life" is a really easy one to start out with. You'll need to add SOME globally aware logic to avoid things like continents growing into each other but for the most part things take care of themselves. The problem I found with more fractal-based approaches (which was my first inclination) was the results either looked too patterned, or lead to too many scenarios requiring hacky-feeling workaround rules to get a result which still didn't feel dynamic enough. Depending on the algorithm you use, you may want to apply a "blurring" pass over the result to eliminate things like abundant single-square ocean tiles and checkered coastlines. In the event something like a continent being spawned surrounded by several others and having nowhere left to grow, relocate the seed to a new point on the map and continue the growth passes. Yes, it can mean you sometimes end up with more continents than planned, but if it's really something you firmly don't want then another way to help avoid it is bias the growth algorithms so they favour growth in the direction with least proximity to other seeds. At worst (in my opinion anyway), you can flag a series as invalid when a seed has nowhere left to grow and generate a new map. Just make sure you set a maximum number of attempts so if anything unrealistic is specified (like fitting 50 even-weighted continents on a 10x10 board) it doesn't spend forever trying to find a valid solution.
I can't vouch for how Civ etc do it, and of course doesn't cover things like climate, land age etc but by playing around with the seed growth algorithm you can get pretty interesting results that resemble continents, archipelagos etc. You can use the same approach to produce 'organic' looking rivers, mountain ranges etc too.
Just thinking off the cuff here:
Pick some starting points, and assign each a randomly drawn (hoped for) size. You can can maintain a separate size draw for planned continents and planned islands if you want.
Loop over the land elements, and where they are not yet at the planned size add one square. But the fun part is weighing the chance that each neighboring element will be the one. Some suggested thing that might factor in:
Distance to the nearest "other" land. Further is better generates wide oceanic spaces. Nearer is better makes narrow channels. You have to decide if you're going to let bits merge as well.
Distance from the seed. Nearer is better means compact land masses, farther is better means long strung out bits
Number of existing land squares adjacent. Weighting in favor of many adjacent squares gives you smooth coast, preferring few gives you lots of inlets and peninsulas.
Presence of "resources" squares nearby? Depends on the game rules, when you generate resource square, and if you want to make it easy.
Will you allow bits to approach or join with the poles?
??? don't know what else
Continue until all land masses have reached the planned size or can't grow anymore for some reason.
Notice that diddling the parameter to these weighting factors allows you to tune the kind of world generated , which is a feature I liked about some of the Civs.
This way you'll need to do terrain generation on each bit separately.
You could try a diamond square algorithm or perlin noise to generate something like a height map. Then, assign ranges values to what shows up on the map. If your "height" goes from 0 to 100, then make 0 - 20 water, 20 - 30 beach, 30 - 80 grass, 80 - 100 mountains. I think notch did something similar to this in minicraft, but I'm not an expert, I'm just in a diamond square mindset after finally getting it working.
I think you can use "dynamic programming" style approach here.
Solve small problems first and combine
solutions smartly to solve bigger
problem.
A1= [elliptical rectangular random ... ]// list of continents with area A1 approx.
A2= [elliptical rectangular random ... ]// list of continents with area A2 approx.
A3= [elliptical rectangular random ... ]// list of continents with area A3 approx.
...
An= [elliptical rectangular random ... ]// list of continents with area An approx.
// note that elliptical is approximately elliptical in shape and same for the other shapes.
Choose one/more randomly from each of the lists (An).
Now you have control over number and area of continents.
You can use genetic algorithm for positioning them
as you see "fit" ;)
It will be very good to take a look at some "Graph Layout Algorithms"
Force Based Algorithms
Genetic Algorithm for Graph Layout
You can modify these to suit your purpose.
I had an idea for map creation similar to the tectonic plates answer. It went something like this:
sweep through the grid squares giving each square a "land" square if rnd <= 0.292 (the actual percentage of dry land on planet earth).
Migrate each land chunk one square toward its nearest larger neighbour. If neighbours are equidistant, go toward the larger chunk. If chunks are equal size, choose one randomly.
if two land squares touch, group them into a chunk, moving all squares as one from now on.
repeat from step 2. Stop when all chunks are connected.
This is similar to how gravity works in a 3D space. It's pretty complicated. A simpler algorithm for your needs would work as follows:
Drop in n starter land squares at random x,y positions and acceptable distances from each other. These are seeds for your continents. (Use the Pythagorean theorem to ensure the seeds have a minimum distance between themselves and all others.)
spawn a land square from an existing land square in a random direction, if that direction is an ocean square.
repeat step 2. Stop when land squares fill 30% of total map size.
if continents are close enough to each other, drop in land bridges as desired to simulate a Panama type effect.
Drop in smaller, random islands as desired for a more natural look.
for each extra "island" square you add, cut out inland seas and lake squares from the continents using the same algorithm in reverse. This will maintain the land percentage at the desired amount.
Let me know how this works out. I've never tried it myself.
PS. I see this is similar to what you tried. Except it sets up all the seeds at once, before beginning, so the continents will be far enough apart and will stop when the map is sufficiently filled.
I haven't actually tried this but it was inspired by David Johnstone's answer regarding tectonic plates. I tried implementing it myself in my old Civ project and when it came to handling collisions I had another idea. Instead of generating tiles directly, each continent consists of nodes. Distribute mass to each node then generate a series of "blob" continents using a 2D metaball approach. Tectonics and continental drift would be ridiculously easy to "fake" simply by moving the nodes around. Depending on how complex you want to go, you could even apply things like currents to handle the node movement and generate mountain ranges that correspond to plate boundaries overlapping. Probably wouldn't add that much to the gameplay side of things, but it could make for an interesting map generation from a purely academic perspective :)
A good explanation of metaballs if you haven't worked with them before:
http://www.gamedev.net/page/resources/_//feature/fprogramming/exploring-metaballs-and-isosurfaces-in-2d-r2556
Here's what I'm thinking, since I'm about to implement something like this that I have for a game in development. :
The world divided into regions. depending on the size of the world, it will determine how many regions. For this example, we'll assume a medium sized world, with 6 regions. Each grid zone breaks into 9 grid zones. those grid zones break into 9 grids each. (this is not for character movement, but merely for map creation) The Grids are for biomes, grid zones are for over arching land features, (continent vs ocean) and the regions are for overall climate. The grids break down into tiles.
Randomly generated, the regions get assigned logical climate sets. Grid zones get randomly assigned to, for instance; ocean or land. Grids get assigned biomes randomly with modifiers based on their grid zones and climate, these being forest, desert, plains, glacial, swamp or volcanic. Once all those basics are assigned, it's time to blend them together, using a random percentage based function that fills in tile sets. For example; if you have a forest biome, next to a desert biome, you have an algorithm that decreases the likely hood that a tile will be "foresty" and increases that it will be "deserty." So, about half way between them, you'll see a sort of blended affect combining the two biomes to off a somewhat smooth transition between them. Transition from one grid zone to the next would probably take a little more work to insure logic landmass formations.Like, for example, a biome from one grid zone that touches the biome from another, instead of having a simple switching percentage based on proximity. For example, there are 50 tiles from the center of the biome to the edge of the biome, meaning, there are 50 from the edge it touches to the center of the next biome. That would logically leave a 100% change from one biome to the next. So as the tiles get nearer to the border of the two biomes, the percentage narrows out to around 60% or so. It'd, I think, be unwise to give too much probability of crossing biomes far from the border, but you'll want the border to be somewhat blended. For the grid zones, the percentage change will be much more pronounced. Instead of the % going down to around 60%, it'd only drop down to around 80%. And a secondary check would then have to be performed to ensure that there's not a random water tile in the middle of a land biome next to the ocean without some logic to it. So, either, connect that water tile to the ocean mass to make a channel to explain the water tile, or remove it altogether. Land in a water based biome is easier to explain using rock outcrops and such.
Oh, kinda dumb, sorry.
I'd place fractal terrain according to some layout that you know "works" (e.g. 2x2 grid, diamond, etc, with some jitter) but with a Gaussian distribution damping peaks down towards the edges of the continent centers. Place the water level lower so that is mostly land until you get near the edges.

Resources