Tic-tac-toe in Erlang — board display
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 for download. The source code and this tutorial are organized into these sections:
- Introduction
- Top-level loop
- User input
- Board display (this page)
- Board abstraction
- Game abstraction
- Next move calculations and predictions
- Predicted outcome abstraction
- Utilities to introduce randomness
- Macros for testing and debugging
Board display
This section provides a function to display the tic-tac-toe board as the game progresses. Although only one function is used outside this section, about 30 functions are defined and used internally.
This draws the board using fixed-width text on standard-IO. It is very primitive. It would not be too hard to replace it with code to draw the board to a window (using GS, the Erlang graphics module), or code to create an XML or HTML description of the board and send it to a waiting Erlang process.
Interface
The board display section of the code provides a single function that is used elsewhere.
Source code
Here’s the Erlang source code for the board display section of the tic.erl file.
% --------------------------------------------------------------
% Board Display - print_board(..)
% --------------------------------------------------------------
%
% This section "exports" the function print_board( Game ).
%
% Prints the tic-tac-toe board to standard IO.
% The printed board looks like this (with predictions):
%
% [] OOOOO [] XXX XXX
% 1 WINNING [] OOO OOO [] XX XX
% MOVE! [] OOO OOO [] XXX
% [] OOO OOO [] XX XX
% [] OOOOO [] XXX XXX
% ===============##===============##===============
% [] XXX XXX [] XXX XXX
% 2 Loses in [] XX XX [] XX XX
% three moves [] XXX [] XXX
% after this [] XX XX [] XX XX
% [] XXX XXX [] XXX XXX
% ===============##===============##===============
% OOOOO [] OOOOO []
% OOO OOO [] OOO OOO [] 9 Leads to
% OOO OOO [] OOO OOO [] CAT game
% OOO OOO [] OOO OOO []
% OOOOO [] OOOOO []
% --------------------------------------------------------------
% print_board( Game )
% print_board( Board, Option )
%
% Writes a big-display board to standard IO.
%
% Option controls what we show in empty cells.
% It is one of the following:
% simple - leave empty cells blank
% number - show position number in empty cell
% predict - show position and predicted outcome
print_board( Game ) ->
print_board(
get_game_board( Game), get_game_print_option( Game)).
print_board( Board, Option ) ->
?m_assert(
(Option == simple) or
(Option == number) or
(Option == predict)),
Option_adjusted =
case (Option == predict) andalso is_board_empty( Board) of
true -> number;
false -> Option
end,
write_line( ),
print_row( Board, Option_adjusted, 1),
print_hori_divider( ),
print_row( Board, Option_adjusted, 4),
print_hori_divider( ),
print_row( Board, Option_adjusted, 7),
write_line( ).
% --------------------------------------------------------------
% print_hori_divider( )
% print_vert_divider( )
print_hori_divider( ) ->
write_string( "===============##"),
write_string( "===============##"),
write_line( "===============").
print_vert_divider( ) ->
write_string( "[]").
% --------------------------------------------------------------
% print_row( Board, Option, Position )
% print_row( Option, Pos, Mark1, Mark2, Mark3, Index )
% print_row( Option, Pos, Mark, Index )
print_row( Board, Option, Pos ) ->
M1 = get_board_mark( Board, Pos + 0),
M2 = get_board_mark( Board, Pos + 1),
M3 = get_board_mark( Board, Pos + 2),
lists:foreach(
fun ( Index ) ->
print_row( Option, Pos, M1, M2, M3, Index)
end,
lists:seq( 1, 5)).
print_row( Option, Pos, M1, M2, M3, Index ) ->
print_row( Option, Pos + 0, M1, Index),
print_vert_divider( ),
print_row( Option, Pos + 1, M2, Index),
print_vert_divider( ),
print_row( Option, Pos + 2, M3, Index),
write_line( ).
print_row( Option, Pos, M, Index ) ->
case M of
x_mark -> print_cell_x( Index);
o_mark -> print_cell_o( Index);
_ ->
case Option of
simple ->
print_cell_empty( );
number ->
print_cell_number( Pos, Index);
predict ->
case M of
empty ->
print_cell_number( Pos, Index);
_ ->
% M must be an Outcome.
?m_assert( is_outcome_valid( M)),
print_cell_predict_outcome( M, Pos, Index)
end
end
end.
% --------------------------------------------------------------
% print_cell_x( Index )
% print_cell_o( Index )
% print_cell_empty( )
% print_cell_number( Position, Index )
%
% Index goes from 1 thru 5.
print_cell_x( Index ) ->
write_string(
if
Index == 1; Index == 5 -> " XXX XXX ";
Index == 2; Index == 4 -> " XX XX ";
Index == 3 -> " XXX "
end).
print_cell_o( Index ) ->
write_string(
if
Index == 1; Index == 5 -> " OOOOO ";
Index == 2; Index == 4 -> " OOO OOO ";
Index == 3 -> " OOO OOO "
end).
print_cell_empty( ) ->
write_space( 15).
print_cell_number( Pos, Index ) ->
if
Index == 3 ->
write_space( 7),
write_arg( Pos),
write_space( 7);
true ->
write_space( 15)
end.
% --------------------------------------------------------------
% print_cell_predict_outcome( Outcome, Position, Index )
print_cell_predict_outcome( Outcome, Pos, Index ) ->
if
Index == 1;
Index == 5 ->
write_space( 15);
true ->
write_space( 2),
case Index of
2 -> print_cell_predict_outcome_1( Outcome, Pos);
3 -> print_cell_predict_outcome_2( Outcome);
4 -> print_cell_predict_outcome_3( Outcome)
end,
write_space( 2)
end.
% --------------------------------------------------------------
% print_cell_predict_outcome_1( Outcome, Position )
% print_cell_predict_outcome_2( Outcome )
% print_cell_predict_outcome_3( Outcome )
print_cell_predict_outcome_1( Outcome, Pos ) ->
write_arg( Pos),
write_space( ),
write_string(
case is_outcome_undecided( Outcome) of
true -> get_print_string_leads_to( );
false ->
case is_outcome_a_win( Outcome) of
true ->
case outcome_turn_count( Outcome) of
1 -> get_print_string_winning( );
_ -> get_print_string_wins_in( )
end;
false ->
case is_outcome_a_loss( Outcome) of
true ->
case outcome_turn_count( Outcome) of
1 -> get_print_string_loses( );
_ -> get_print_string_loses_in( )
end
end end end).
print_cell_predict_outcome_2( Outcome ) ->
write_string(
case is_outcome_undecided( Outcome) of
true -> get_print_string_cat_game( );
false ->
case is_outcome_a_win( Outcome) of
true ->
case outcome_turn_count( Outcome) of
1 -> get_print_string_move( );
2 -> get_print_string_next_turn( );
3 -> get_print_string_three_turns( );
4 -> get_print_string_four_turns( );
5 -> get_print_string_five_turns( )
end;
false ->
case is_outcome_a_loss( Outcome) of
true ->
case outcome_turn_count( Outcome) of
1 -> get_print_string_after_this( );
2 -> get_print_string_two_turns( );
3 -> get_print_string_three_turns( );
4 -> get_print_string_four_turns( )
end
end end end).
print_cell_predict_outcome_3( Outcome ) ->
write_string(
case
is_outcome_undecided( Outcome) orelse
(outcome_turn_count( Outcome) == 1)
of
true -> get_print_string_blank( );
false -> get_print_string_after_this( )
end).
% --------------------------------------------------------------
% Strings used to construct messages
get_print_string_leads_to( ) -> " Leads to".
get_print_string_winning( ) -> " WINNING".
get_print_string_loses( ) -> " Loses".
get_print_string_wins_in( ) -> " Wins in".
get_print_string_loses_in( ) -> " Loses in".
get_print_string_cat_game( ) -> " CAT game".
get_print_string_move( ) -> " MOVE!".
get_print_string_next_turn( ) -> " next turn".
get_print_string_two_turns( ) -> " two turns".
get_print_string_three_turns( ) -> "three turns".
get_print_string_four_turns( ) -> " four turns".
get_print_string_five_turns( ) -> " five turns".
get_print_string_after_this( ) -> " after this".
get_print_string_blank( ) -> " ".
Comments
3 Responses to “Tic-tac-toe in Erlang — board display”
Leave a Reply
plz send me this TIC TAC TOE OpenGL program
plz send me tic tac toe opengl program soon reply
This program doesn’t use OpenGL.