7

Overview

Looking to create random page background colours where the same background colour never appears more than once in succession (i.e., red, green, blue, green, blue, red, etc. -- never red, red, green, blue, blue).

Code

Example showing the issue:

% Randomize the seed without having to delete the tuc file.
\ctxlua{math.randomseed( os.time() )}

\setupcolors[state=start]

% Dark green
\definecolor[ThemeColourGreen][h=8DC366]
% Pale blue
\definecolor[ThemeColourBlue][h=79C9EF]
% Yellowy-orange
\definecolor[ThemeColourYellow][h=FFD631]

\startMPinclusions
  vardef ThemeBase( expr base_colour ) =
    fill Page withcolor transparent(1, .85, base_colour );
  enddef;

  vardef ThemeStyle( expr base_colour ) = 
    draw unitcircle withpen pencircle scaled 1cm withcolor
      .5[base_colour,white];
  enddef
\stopMPinclusions

\startuseMPgraphic{page:ThemeBackground}
  color colours[];
  color base_colour;

  colours[1] := \MPcolor{ThemeColourGreen};
  colours[2] := \MPcolor{ThemeColourBlue};
  colours[3] := \MPcolor{ThemeColourYellow};

  base_colour := colours[ round( uniformdeviate( 2 ) + 1 ) ];

  ThemeBase( base_colour );
\stopuseMPgraphic

\startuseMPgraphic{page:ThemeStyle}
  ThemeStyle( base_colour );
\stopuseMPgraphic

\defineoverlay[page:ThemeBackground][\uniqueMPgraphic{page:ThemeBackground}]
\defineoverlay[page:ThemeStyle][\uniqueMPgraphic{page:ThemeStyle}]

\starttext
  \setupbackgrounds[page][background={page:ThemeBackground,page:ThemeStyle}]
  \startchapter[title=One]
  \input knuth
  \stopchapter

  \startchapter[title=Two]
  \input zapf
  \stopchapter

  \startchapter[title=Three]
  \input knuth
  \stopchapter

  \startchapter[title=Four]
  \input zapf
  \stopchapter
\stoptext

Problem

Sometimes the random value selected is the same as the value generated for the previous page, which causes two pages in a row to have the same background colour.

Note that in the code above, the circle has a relationship to the current page's background colour.

Question

How would you randomly select a value such that on subsequent pages that same value is not used?

0
6

Loop-free solution:

% Randomize the seed without having to delete the tuc file.
%\ctxlua{math.randomseed( os.time() )}
\ctxlua{math.randomseed( 101)}

\setupcolors[state=start]

% Dark green
\definecolor[ThemeColourGreen][h=8DC366]
% Pale blue
\definecolor[ThemeColourBlue][h=79C9EF]
% Yellowy-orange
\definecolor[ThemeColourYellow][h=FFD631]

\startMPinclusions
  vardef ThemeBase( expr base_colour ) =
    fill Page withcolor transparent(1, .85, base_colour );
  enddef;

  vardef ThemeStyle( expr base_colour ) = 
    draw unitcircle withpen pencircle scaled 1cm withcolor
      .5[base_colour,white];
  enddef;

  color colours[];
  color base_colour;


  numeric id,idII;
  numeric indices[][];
  indices[1][1]=2;
  indices[1][2]=3;

  indices[2][1]=1;
  indices[2][2]=3;

  indices[3][1]=1;
  indices[3][2]=2;
  id := round( uniformdeviate( 2 ) + 1 );
\stopMPinclusions

\startuseMPgraphic{page:ThemeBackground}

  colours[1] := \MPcolor{ThemeColourGreen};
  colours[2] := \MPcolor{ThemeColourBlue};
  colours[3] := \MPcolor{ThemeColourYellow};

  idII:=indices[id][round( uniformdeviate( 1 ) + 1 )];
  base_colour := colours[ idII ];
  id:=idII;
  ThemeBase( base_colour );

\stopuseMPgraphic

\startuseMPgraphic{page:ThemeStyle}
  ThemeStyle( base_colour );
\stopuseMPgraphic

\defineoverlay[page:ThemeBackground][\uniqueMPgraphic{page:ThemeBackground}]
\defineoverlay[page:ThemeStyle][\uniqueMPgraphic{page:ThemeStyle}]

\starttext
  \setupbackgrounds[page][background={page:ThemeBackground,page:ThemeStyle}]
  \startchapter[title=One]
  \input knuth
  \stopchapter

  \startchapter[title=Two]
  \input zapf
  \stopchapter

  \startchapter[title=Three]
  \input knuth
  \stopchapter

  \startchapter[title=Four]
  \input zapf
  \stopchapter

  \startchapter[title=Five]
  \input knuth
  \stopchapter

  \startchapter[title=Six]
  \input zapf
  \stopchapter
\stoptext

EDIT: This is more general loop-free solution, and no extra arrays are used: EDIT-2: Added automatic counter of the number of colors.

% Randomize the seed without having to delete the tuc file.
%\ctxlua{math.randomseed( os.time() )}
\ctxlua{math.randomseed( 101)}

\setupcolors[state=start]

% Dark green
\definecolor[ThemeColourGreen][h=8DC366]
% Pale blue
\definecolor[ThemeColourBlue][h=79C9EF]
% Yellowy-orange
\definecolor[ThemeColourYellow][h=FFD631]
% Pink
\definecolor[ThemeColourPink][h=FF2764]
% Gray
\definecolor[ThemeColourGray][h=C3C3C3]

\startMPinclusions
  vardef ThemeBase( expr base_colour ) =
    fill Page withcolor transparent(1, .85, base_colour );
  enddef;

  vardef ThemeStyle( expr base_colour ) = 
    draw unitcircle withpen pencircle scaled 1cm withcolor
      .5[base_colour,white];
  enddef;

  color colours[];
  color base_colour;
  numeric n, id;

  colours[0] := \MPcolor{ThemeColourGreen};
  colours[1] := \MPcolor{ThemeColourBlue};
  colours[2] := \MPcolor{ThemeColourYellow};
  colours[3] := \MPcolor{ThemeColourPink};
  colours[4] := \MPcolor{ThemeColourGray};
  n:=0; forever : exitunless known(colours[n+1]); n:=n+1; endfor;   
  id:=0;
\stopMPinclusions

\startuseMPgraphic{page:ThemeBackground}

  id:=(id+1+(round( uniformdeviate(n-1) ))) mod (n+1);
  base_colour := colours[ id ];

  ThemeBase( base_colour );

\stopuseMPgraphic

\startuseMPgraphic{page:ThemeStyle}
  ThemeStyle( base_colour );
\stopuseMPgraphic

\defineoverlay[page:ThemeBackground][\uniqueMPgraphic{page:ThemeBackground}]
\defineoverlay[page:ThemeStyle][\uniqueMPgraphic{page:ThemeStyle}]

\starttext
  \setupbackgrounds[page][background={page:ThemeBackground,page:ThemeStyle}]
  \startchapter[title=One]
  \input knuth
  \stopchapter

  \startchapter[title=Two]
  \input zapf
  \stopchapter

  \startchapter[title=Three]
  \input knuth
  \stopchapter

  \startchapter[title=Four]
  \input zapf
  \stopchapter

  \startchapter[title=Five]
  \input knuth
  \stopchapter

  \startchapter[title=Six]
  \input zapf
  \stopchapter

  \startchapter[title=Seven]
  \input knuth
  \stopchapter

  \startchapter[title=Eight]
  \input zapf
  \stopchapter
\stoptext
4
  • @Dave Jarvis: Yes, of course, a general solution for many colors can be automated, and an optimal realization most probably depends on the number of the basic colors and how often that number is expected to change. One simplest way would be to generate a list of indices excluding the previous one and then select one of them.
    – g.kov
    Oct 8 '13 at 16:31
  • @Dave Jarvis: See more general solution added. It uses random shift to the next color index from the current index.
    – g.kov
    Oct 8 '13 at 18:02
  • Thank you, that's almost ideal. Now if only MetaPost had a unary operator so that we could write colours[n++] := ... and not have to use n := 4 manually. Would n := length( colours ) work? Your solution is very slick, by the way. Oct 8 '13 at 18:16
  • @Dave Jarvis: See a new correction. This kind of works like a length: n:=0; forever : exitunless known(colours[n+1]); n:=n+1; endfor;
    – g.kov
    Oct 8 '13 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.