Semi-random starting position

Hello folks,

This is probably more of a mathematical question than a Go question.

I want to experiment with playing a game from a semi-random starting position. To be more specific, each player gets a few (say 3) randomly-placed stones with the following tentative rules:

  • no 1st or 2nd lines (making the initial placement space 15 x 15)
  • no non-diagonal neighbors (if a stone is to be placed next to another one, we could “push” it away from the existing one? If it exactly coincides, i don’t know what to do.)

To play such a game in OGS requires an algorithm to generate a starting position from unique data, so each player can independently generate the same position and place the stones to start the game. Each game in OGS seems to have a unique 8-digit ID in URL. What are some ways to generate the starting position from the ID or with other data (such as GMT?)? Is such a thing even reasonable mathematically?


In short, I guess I need an algorithm that calculates a certain number (say 3 stones * 2 players = 6) of pairs (coordinates on Go board) of base-15 numbers from base-10 numbers (possibly also with alphabets, using some topical keyword?), with a method to resolve collision.


You can use (pseudo) random number generator. Using it you can get random numbers in pairs from 1 to 15 to get starting moves coordinates. If the placement is bad you can just reroll.

If you want reproduce-ability you can use game id as a seed for the generator so it’d give the same result.

But why do all of this? You both can promise to generate moves randomly and after the initial position is set up decide the colors by komi betting.

  1. Seeded
    I haven’t been able to find an online generator that takes a seed. (I will keep looking, but if someone finds one, let us know.). Also, I don’t know if this is relevant but, is there such a thing as having enough number of digits in a seed for certain number of stones? (15 * 2 = 10 * 3, so 3/2 * 2 coordinates * n stones * 2 players = 6n digits?)

I guess the above section is just for curiosity because the unseeded version is simpler.

  1. Unseeded
    Your game starts out (at move 0) with stones already placed. I guess you created and imported the starting position somehow. For komi betting, I guess it means each player bids and the highest bidder goes first? If so, without creating a starting position elsewhere and importing, is it possible to switch colors mid-game? Well, even if it’s not possible I guess who goes first doesn’t matter much due to the casualness of this endeaver (unless i’m missing something).

In summary, I will try the unseeded version if i can find someone in chat.

Thanks for your response.


I wrote a script that one of the players can run and then post the results to the chat:

function allowedCoord([newRow, newCol], placements) {
  return placements.every(([oldRow, oldCol]) => {
    if (oldRow === newRow) {
      return newCol < oldCol - 1 || oldCol + 1 < newCol;

    if (oldCol === newCol) {
      return newRow < oldRow - 1 || oldRow + 1 < newRow;

    return true;

function randomPos() {
  return 3 + Math.floor(Math.random() * 15);

function newCoord(placements) {
  const coord = [randomPos(), randomPos()];

  if (allowedCoord(coord, placements)) {
    return coord;

  return newCoord(placements);

function randomPlacements(n = 0, placements = []) {
  if (n <= 0) {
    return placements;


  return randomPlacements(n - 1, placements);

function transformRowCoord(pos) {
  const row = String.fromCodePoint(pos + 0x41);

  if (row === 'I') {
    // I is omitted from the board
    return 'R';

  return row;

function getStones(n) {
  const placements = randomPlacements(n * 2);

  placements.forEach(([row, col], i) => {
    const player = i % 2 === 0 ? 'B' : 'W';
    const turn = i + 1;

    console.log(`${turn}: ${player} ${transformRowCoord(row)}${col}`);

Simply open up your browser’s console, paste the above script in there, and type:


if you want each players to get 3 stones.

After the random stones have been posted to chat, each player simply places their stones in turn.

Note There is a slight change from the above requirements. If an adjacent stone is encountered we will redraw (as opposed to pushing). This is to prevent a slightly increased chance of seeing one point jumps or caps. As well as preventing the awkward situation of drawing a stone in the center of a ponnuki.


1st result:
1: B N8
2: W O10
3: B P5
4: W D13
5: B M4
6: W K11

It seems to work


I couldn’t confirm because i couldn’t seem to access console of safari from ipad but if this works it’s much simpler than using a online number generator. i guess i have to ask my opponent. Nice touch about the redrawing; i was unaware of the implication and the corner case there.

Thanks for helping.

1 Like

That’s runarberg’s script? Thanks for trying it out because i couldn’t on ipad.

I think the black stones are too clustered for only having 3 stones. Even though the shapes aren’t too bad if there are more stones.

One idea to mitigate it is to first choose a quadrant, exhausting it until all four are used, then choose where in that quadrant to put the stone on.

1 Like

Good Idea

Maybe it should be four extra stones?

1 Like

i saw a few articles written in 2012 and 2016, including that one. they didn’t seem to correspond to my settings menu somehow. but thanks anyway for trying to help out.

1 Like

One White and one Black in each quadrant? That sounds good.


I created a sandbox for you

1 Like

If anyone is interested I can publish my script on a website where you can download the placement stones as an sgf (which you can then upload to ogs, fork and challenge). Maybe even add a few features (such as handicaps and stuff).

Thanks a lot. I have actually resurrected my decade old laptop and tried the original code. it works as intended.

i was wondering if you could implement the quadrant idea as well? i couldn’t understand allowedCoord.

but before that,
if we think of drawing from a bag containing 4 elements corresponding to each quadrant, putting them back in when the bag is empty, it seems there are at least a few variations:

  1. whether to share the same bag between 2 colors, or to have a separate bag each
  2. whether to put a stone for each color after each draw (samraku)

i’m not sure which is more suitable.

as for the sandbox, it seems pushing “generate” button, nothing happens, both on ipad and laptop (js enabled). i will try again after updating.

thanks again.

after updating ipad, i noticed that in sandbox, if i put in a different number, 5 or 7, and push generate, the number goes back to 3 and no output is shown. without changing the number from 3, still no output is shown. console and problems windows are empty.

As for the quadrant idea, i’m starting to like the idea of shared bag and non-shared draw. To give a specific example, for quadrants A - D, black draws quadrant C and place a stone somewhere there, white draws quadrant A and place a stone, black draws B, white draws D, reset the bag, black draws A, white draws D, etc.

1 Like

It checks if the proposed new coordinate is already being used by a previous step. If so, a new coord is generated (by return newCoord(placements) in the newCoord function)

Barebone app is ready. Anyone is free to send me issues (bug reports or feature requests) or contribute (by sending pull requests). Or fork and host your own clone.

I might implement more features later today.

1 Like

wow it works great. could you look at the appended edit section in my previous reply? In particular about the quadrant idea to mitigate clustering when number of stones is low. sandbox didn’t work probably because something wrong on my end, but that’s fine this new one working great.

The only issue I see with the quadrant constraint is that it favors drawing tengen a little. Should we omit tengen when quadrant shuffle mode is active?

1 Like

didn’t think of that. i guess same for half lines as well though not as much?

are there other ways to mitigate clustering? i will look into it.

might have something to do with quasirandom numbers although i fail to understand even the simplest example in wikipedia page