Tic-tac-toe in Erlang — utilities to introduce randomness

This is part of an Erlang tutorial built around a tic-tac-toe program. The program is stuffed into one file, called tic.erl and available here. The source code and this tutorial are organized into these sections:

Utilities to introduce randomness

The appearance of randomness is important for some games, where the computer sometimes has to choose between several equally good moves. By varying its choices, the computer’s play seems more natural, more human, and more interesting.

The game calls randomize_random_seed() once, when it starts up. If it didn’t then the computer would always play exactly the same moves if, for example, you had it play itself.

Of course when running some daily regression tests you might want the computer to play exactly the same moves every time. In that situation you shouldn’t call randomize_random_seed(). Instead you should set the seed explicitly or just use the fixed default seed.

Interface

This short section has only two functions, and both deal with psuedo-random integers.

random_list_element( List )
Returns one of the elements from List. List must not be empty. Chooses which element to return by calling random:uniform(N), which generates a psuedo-random integer from 1 to N (inclusive) with a uniform distribution over the interval.
randomize_random_seed( )
Plays dice with the (game) universe. Calling this at the start makes the computer’s arbitrary move choices different every time. Which makes the game more interesting.

Source code

Here’s the Erlang source code for the random utilities section of the tic.erl file.

% --------------------------------------------------------------
% Random Utilities
%
%   Utilities to introduce randomness into the game play.
% --------------------------------------------------------------

% --------------------------------------------------------------
% random_list_element( List )
%
%   Returns a single element from List.
%   List must have at least one element.

random_list_element( List ) ->
  if
    List      == [] -> erlang:error( badarg);
    tl( List) == [] -> hd( List);
    true ->
      Count = length( List),
      Index = random:uniform( Count),
      lists:nth( Index, List)
  end.

% --------------------------------------------------------------
% randomize_random_seed( )
%
%   Seed the random generator with unpredictable numbers.
%
%   Uses now( ), which returns the current time in this form:
%     {Mega_seconds, Seconds, Micro_seconds}
%
%   Maybe these integers aren't the best seeds since
%   Mega-seconds doesn't change much and Micro-seconds is
%   always a multiple of 1000 on my machine.
%
%   There are other sources of unpredictable numbers we could
%   use as seeds:
%
%     statistics( wall_clock) ->
%         {Total_milliseconds, Elapsed_milliseconds}
%     Total milliseconds seems a good candidate.
%
%     statistics( garbage_collection) ->
%         {Number_of_gcs, Words_reclaimed, 0}
%     Words_reclaimed is a good unpredictable integer.
%
%   random:seed(..) returns the previous seed value (3-tuple
%   of integers), so we could restore the seed value in case
%   some other system is counting on it.
%   Remember that random:seed(..) returns the atom 'undefined'
%   if the seed has never been set before.

randomize_random_seed( ) ->

  % Get a seed of 3 psuedo-random looking integers.
  {Meg_secs, Secs , Micro_secs} = now( ),

  % Set the seed.
  random:seed( Meg_secs, Secs, Micro_secs).

Comments

2 Responses to “Tic-tac-toe in Erlang — utilities to introduce randomness”

  1. Tic-tac-toe in Erlang — top-level loop : Code Obscurata on August 24th, 2012 6:23 pm

    […] Utilities to introduce randomness […]

  2. Tic-tac-toe in Erlang — user input : Code Obscurata on August 24th, 2012 6:25 pm

    […] Utilities to introduce randomness […]