Tic-tac-toe in Erlang — top-level loop

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 file and this tutorial are organized as follows:

Top-level loop

This is the top-level loop that plays the tic-tac-toe game. It is a common pattern, a read-eval-print loop that reads the user’s request, carries out the user command, displays the board, and repeats.

Interface

The top-level loop section implements play(), the exported function that plays the game of tic-tac-toe.

play( )
Plays tic-tac-toe with the user. Exported from tic module.

Source code

Here’s the Erlang source code for the top-level loop section of the tic.erl file.

% --------------------------------------------------------------
% Export Function - play()
% --------------------------------------------------------------
% play( )
%
%   Plays a game of tic-tac-toe, printing the board and reading
%   user instructions to/from standard IO.
%
%   This could print some final statistics.

play( ) ->

  % We use random:uniform(N) to break ties.
  % Take this out (or replace it with something that sets the
  % seed) if you want exact reproducability.
  randomize_random_seed( ),

  % The opening message.
  write_line( ),
  write_line( "Welcome to tic-tac-toe, the game that predicts"),
  write_line( "the outcomes of every move and lets you erase"),
  write_line( "X's and O's and skip turns."),

  % Play until the user quits.
  play_new_game( init_game( )),

  % The closing message.
  write_line( ),
  write_line( "Thanks for playing!"),
  write_line( ),
  ok.

% --------------------------------------------------------------
% play_new_game( Game )
%
%   Plays a new game created by the caller.

play_new_game( Game ) ->
  write_line( ),
  write_line( "Starting a new game."),
  case catch game_loop( Game) of
    quit -> ok;
    {new_game, Game_final} ->
      play_new_game( init_game( Game_final))
  end.

% --------------------------------------------------------------
% game_loop( Game )
%
%   Displays the board, gets user input, changes the board,
%   and calls itself tail-recursivly with the changed board.

game_loop( Game ) ->
  print_board( Game),
  game_loop(
    case get_next_move( Game) of
      quit     -> throw( quit);
      new_game -> throw( {new_game, Game});

      Option when
          Option == simple;
          Option == number;
          Option == predict ->
        set_game_print_option( Game, Option);

      skip ->
        skip_game_next_turn( Game);
      automatic ->
        automatic_game_next_turn( Game);
      {mark, Pos} ->
        mark_game_next_turn( Game, Pos);
      {erase, Pos} ->
        erase_game_next_turn( Game, Pos)
    end).

% --------------------------------------------------------------
% skip_game_next_turn( Game )
%
%   Called when the user asks to skip a turn.
%   Never called on a cat game or a game that is already won.
%
%   Returns a new #game{} object where the state is flipped
%   between "it is X's turn" and "it is O's turn".
%   May also calculate new predicted outcomes for the board.

skip_game_next_turn( Game ) ->
  set_game_state_board(
    Game,
    case get_game_state( Game) of
      x_next -> o_next;
      o_next -> x_next
    end,
    get_game_board( Game)).

% --------------------------------------------------------------
% automatic_game_next_turn( Game )
%
%   Called when the user asks the computer to choose the
%   next move.
%
%   Returns a #game{} with the new move recorded.

automatic_game_next_turn( Game ) ->
  mark_game_next_turn( Game,
    get_board_best_predicted_position(
      get_game_board( Game))).

% --------------------------------------------------------------
% mark_game_next_turn( Game, Position )
%
%   Called when the user selects a board position to mark
%   for the next move.
%
%   Returns a re-calculated #game{}.

mark_game_next_turn( Game, Pos ) ->
  State_old = get_game_state( Game),
  Board_old = clear_board_predicted_outcomes(
                get_game_board( Game)),
  ?m_assert( (State_old == x_next) or (State_old == o_next)),
  ?m_assert( get_board_mark( Board_old, Pos) == empty),

  { Xo, State_win, State_flip } =
    case State_old of
      x_next -> { x_mark, x_winner, o_next };
      o_next -> { o_mark, o_winner, x_next }
    end,

  Board_marked = mark_board( Board_old, Pos, Xo),
  set_game_state_board(
    Game,
    case is_board_won( Board_marked, Xo) of
      true  -> State_win;
      false ->
        case is_board_full( Board_marked) of
          true  -> cat_game;
          false -> State_flip
        end
    end,
    Board_marked).

% --------------------------------------------------------------
% erase_game_next_turn( Game, Position )
%
%   Erases the X or O mark on the board at position.
%
%   Returns a re-calculated #game{}.

erase_game_next_turn( Game, Pos ) ->
  State_old = get_game_state( Game),
  Board_old = clear_board_predicted_outcomes(
                get_game_board( Game)),
  Xo_old    = get_board_mark( Board_old, Pos),
  ?m_assert( (Xo_old == x_mark) or (Xo_old == o_mark)),

  Board_erased = mark_board( Board_old, Pos, empty),
  set_game_state_board(
    Game,
    case {State_old, Xo_old} of
      {cat_game, x_mark} -> x_next;
      {cat_game, o_mark} -> o_next;
      {x_winner, o_mark} -> x_winner;
      {o_winner, x_mark} -> o_winner;
      {x_next  , x_mark} -> x_next;
      {o_next  , x_mark} -> x_next;
      {x_next  , o_mark} -> o_next;
      {o_next  , o_mark} -> o_next;
      {x_winner, x_mark} ->
        case is_board_won( Board_erased, x_mark) of
          true  -> x_winner;
          false -> x_next
        end;
      {o_winner, o_mark} ->
        case is_board_won( Board_erased, o_mark) of
          true  -> o_winner;
          false -> o_next
        end
    end,
    Board_erased).

Comments

33 Responses to “Tic-tac-toe in Erlang — top-level loop”

  1. http://criminalbackgroundchecked.com/ on July 4th, 2012 12:17 pm

    Youre so cool! I dont suppose Ive read something such because this before.
    So nice to get somebody by incorporating authentic ideas on this subject.
    realy i appreciate you for starting this up. this first-class website are some things thats needed on that the internet, somebody after a small bit originality.
    helpful work for bringing something new to that the web!

  2. website link on July 7th, 2012 8:55 am

    kitchen aids have a number of different appliances that can help you cook
    your food easier

  3. scholarships for single mothers on July 8th, 2012 3:39 am

    The script, cowritten by McKay & Chris Henchy, sends up
    buddy cop movies with more verve than most films of this type.

  4. scholarships for college students|scholarships for college students in texas|2011 scholarships for college students|scholarships for college students in california|scholarships for college students 2011|easy scholarships for college students|grants and ss on July 8th, 2012 2:18 pm

    I for example what you guys have been up also. Such intelligent work and reporting!

    Carry on that the first-class works guys I have incorporated you guys to my
    blogroll. I think itll improve the value of my web site

  5. education grants for single mothers on July 8th, 2012 3:33 pm

    I discovered your blog web site on google and examine just
    a few of your early posts. Continue to maintain up that the
    superb operate. I only extra up your RSS feed to my MSN News
    Reader. Looking for forward to reading more from
    you later on!

  6. assistance single mothers on July 8th, 2012 4:23 pm

    soem websites that give download games have viruses
    and spywares on it. so make sure to have some antivirus on your PC,,

  7. cell phone lookup on July 8th, 2012 4:45 pm

    tomatoes are actually great for gardening. they have been that
    the best garden vegetables out there

  8. reverse phone lookup on July 9th, 2012 4:37 pm

    wooden kitchen cabinets are perfect your your home, that they look good and
    can be cleaned without problems,.

  9. cell phone lookup on July 10th, 2012 4:20 am

    Thank you for an additional wonderful article. Wherever else could anyone figure out that kind
    of information in this type of the ideal tactic of writing Ive got a presentation next week, and Im round that the search for these
    information.

  10. reverse phone on July 16th, 2012 12:48 pm

    The best and observable News and why it approach a lot.

  11. reverse number lookup on July 16th, 2012 1:03 pm

    Excellent post. I used to be checking continuously
    this weblog and I am impressed! Very helpful information specifically the ultimate section :) I take care of such information much.
    I used to be looking for this certain information for a very lengthy time.
    Thank you and best of luck.

  12. cell phone number lookup on July 16th, 2012 2:11 pm

    Thanks a ton for this kind of facts I had been exploring all
    Yahoo to locate it!

  13. reverse phone lookup on July 16th, 2012 2:27 pm

    There is noticeably a bundle to learn about this.

    I assume you made sure first-rate factors in features also.

  14. criminal background check on July 16th, 2012 3:26 pm

    This is a great blog and i want to visit this every day of the week

  15. http://www.prlog.org/11674605-reverse-phone-lookup-finders.html on July 16th, 2012 3:31 pm

    It’s in point of fact a great and useful piece of information. I am satisfied that you simply shared this useful info with us. Please stay us informed like this. Thanks for sharing.

  16. reverse phone lookup on July 16th, 2012 4:57 pm

    Thanks a ton for sharing this with all of us you actually recognize what you have been
    talking about! Bookmarked. Kindly also visit my
    site =. We could have a link exchange contract between
    us!

  17. phone number lookup on July 16th, 2012 6:07 pm

    We stumbled over here by an alternative page and thought I might check things out.

    I along the lines of what I see so now im following you.
    Look forward to finding out about your web page for a second
    time.

  18. http://www.prlog.org/11734625-reverse-cell-phone-directory-finds-anyone-with-telephone-number.html on July 16th, 2012 8:22 pm

    I hardly write comments, however I glanced through a few comments here Tic-tac-toe in Erlang – top-level loop : Code Obscurata. I actually do have a few questions for you if you do not mind. Is it only me or does it look like some of the remarks appear like they are written by brain dead folks? :-P And, if you are writing at additional online sites, I would like to keep up with you. Could you make a list of every one of all your social community sites like your linkedin profile, Facebook page or twitter feed?

  19. phone number on July 16th, 2012 8:23 pm

    With the exception of Willis, the cast is made up of actors who have no company
    waving guns around.

  20. reverse address lookup on July 16th, 2012 8:54 pm

    First-class work done by the blogger, Keep up the work going.

  21. reverse phone lookup on July 16th, 2012 9:01 pm

    Tremendous issues here. I am very glad to look your article.
    Thanks a lot and I’m looking forward to contact you. Will you please drop me a mail?

  22. http://www.prlog.org/11684341-reverse-cell-phone-lookup-number.html on July 16th, 2012 10:27 pm

    Very nice post. I just stumbled upon your blog and wished
    to say that I have really enjoyed surfing around your blog posts.
    In any case I’ll be subscribing to your rss feed and I hope you write again soon!

  23. http://ezinearticles.com/?Reverse-Phone-Lookup---Easy-Way-to-Know-the-Truth&id=5909597 on July 17th, 2012 2:08 am

    Hello, you used to write excellent, in spite of this that the last few posts have been kinda boring
    I miss your super writings. Past a couple of posts are just
    a minor out of track! come on!

  24. http://www.prlog.org/11734633-free-people-search-finder-directory.html on July 17th, 2012 2:37 am

    This website doesnt show up properly on my i cell you might wanna try and repair
    that

  25. http://ezinearticles.com/?Phone-Number-Search---Stopping-a-Cheater-the-Easy-Way&id=5909547 on July 17th, 2012 2:38 am

    cooking is my passion and a hobby for me, besides, i love to eat lots
    of foods,.

  26. http://www.prlog.org/11261550-phone-number-lookup-catch-cheater-quickly.html on July 25th, 2012 2:02 am

    I learn here out of google, in spite of this unfortunatelly Im not found what I want.

    But this is a great article! THX!Kate Ruhn

  27. how to make money online on July 27th, 2012 6:38 am

    some jewelry stores give away a excellent deal of bargain for
    their new jewelry styles

  28. http://101watchmoviesonline.com/ on July 31st, 2012 7:36 am

    Thank you for your time and effort to have had these things together on this website.
    Mary and I very much loved your suggestions through your own
    articles over certain things. I recognize someone to have a
    number of demands on your own schedule so the fact that you actually took because much
    time for instance you did to help people just like us through this article is definitely highly liked.

  29. official website on August 7th, 2012 12:44 am

    I am not sure where youre getting your info, in spite of this excellent
    topic. I needs to spend some time learning more or understanding more.
    Thanks for great information I was hunting for this info for my mission.

  30. cell phone lookup on August 20th, 2012 8:02 am

    that the prettiest girl on Gossip Girl is none other than blake lively, oh
    i just love her

  31. Tic-tac-toe in Erlang — full game space : Code Obscurata on August 24th, 2012 6:21 pm

    […] Top-level loop […]

  32. Tic-tac-toe in Erlang — utilities to introduce randomness : Code Obscurata on August 24th, 2012 6:24 pm

    […] Top-level loop […]

  33. Tic-tac-toe in Erlang — board display : Code Obscurata on August 24th, 2012 6:25 pm

    […] Top-level loop […]