How to resolve the algorithm Tic-tac-toe step by step in the Erlang programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Tic-tac-toe step by step in the Erlang programming language
Table of Contents
Problem Statement
Play a game of tic-tac-toe. Ensure that legal moves are played and that a winning position is notified.
Tic-tac-toe is also known as:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Tic-tac-toe step by step in the Erlang programming language
Source code in the erlang programming language
-module(tic_tac_toe).
-export( [task/0] ).
task() -> io:fwrite( "Result: ~p.~n", [turn(player(random:uniform()), board())] ).
board() -> [{X, erlang:integer_to_list(X)} || X <- lists:seq(1, 9)].
board_tuples( Selections, Board ) -> [lists:keyfind(X, 1, Board) || X <- Selections].
computer_move( Player, Board ) ->
[N | _T] = lists:flatten( [X(Player, Board) || X <- [fun computer_move_win/2, fun computer_move_block/2, fun computer_move_middle/2, fun computer_move_random/2]] ),
N.
computer_move_block( Player, Board ) -> computer_move_two_same_player( player(false, Player), Board ).
computer_move_middle( _Player, Board ) ->
{5, Y} = lists:keyfind( 5, 1, Board ),
computer_move_middle( is_empty(Y) ).
computer_move_middle( true ) -> [5];
computer_move_middle( false ) -> [].
computer_move_random( _Player, Board ) ->
Ns = [X || {X, Y} <- Board, is_empty(Y)],
[lists:nth( random:uniform(erlang:length(Ns)), Ns )].
computer_move_two_same_player( Player, Board ) ->
Selections = [X || X <- three_in_row_all(), is_two_same_player(Player, X, Board)],
computer_move_two_same_player( Player, Board, Selections ).
computer_move_two_same_player( _Player, _Board, [] ) -> [];
computer_move_two_same_player( _Player, Board, [Selection | _T] ) -> [X || {X, Y} <- board_tuples(Selection, Board), is_empty(Y)].
computer_move_win( Player, Board ) -> computer_move_two_same_player( Player, Board ).
is_empty( Square ) -> Square =< "9". % Do not use < "10".
is_finished( Board ) -> is_full( Board ) orelse is_three_in_row( Board ).
is_full( Board ) -> [] =:= [X || {X, Y} <- Board, is_empty(Y)].
is_three_in_row( Board ) ->
Fun = fun(Selections) -> is_three_in_row_same_player( board_tuples(Selections, Board) ) end,
lists:any( Fun, three_in_row_all() ).
is_three_in_row_same_player( Selected ) -> three_in_row_player( Selected ) =/= no_player.
is_two_same_player( Player, Selections, Board ) -> is_two_same_player( Player, [{X, Y} || {X, Y} <- board_tuples(Selections, Board), not is_empty(Y)] ).
is_two_same_player( Player, [{_X, Player}, {_Y, Player}] ) -> true;
is_two_same_player( _Player, _Selected ) -> false.
player( Random ) when Random > 0.5 -> "O";
player( _Random ) -> "X".
player( true, _Player ) -> finished;
player( false, "X" ) -> "O";
player( false, "O" ) -> "X".
result( Board ) -> result( is_full(Board), Board ).
result( true, _Board ) -> draw;
result( false, Board ) ->
[Winners] = [Selections || Selections <- three_in_row_all(), three_in_row_player(board_tuples(Selections, Board)) =/= no_player],
"Winner is " ++ three_in_row_player( board_tuples(Winners, Board) ).
three_in_row_all() -> three_in_row_horisontal() ++ three_in_row_vertical() ++ three_in_row_diagonal().
three_in_row_diagonal() -> [[1,5,9], [3,5,7]].
three_in_row_horisontal() -> [[1,2,3], [4,5,6], [7,8,9]].
three_in_row_vertical() -> [[1,4,7], [2,5,8], [3,6,9]].
three_in_row_player( [{_X, Player}, {_Y, Player}, {_Z, Player}] ) -> three_in_row_player( not is_empty(Player), Player );
three_in_row_player( _Selected ) -> no_player.
three_in_row_player( true, Player ) -> Player;
three_in_row_player( false, _Player ) -> no_player.
turn( finished, Board ) -> result( Board );
turn( "X"=Player, Board ) ->
N = computer_move( Player, Board ),
io:fwrite( "Computer, ~p, selected ~p~n", [Player, N] ),
New_board = [{N, Player} | lists:keydelete(N, 1, Board)],
turn( player(is_finished(New_board), Player), New_board );
turn( "O"=Player, Board ) ->
[turn_board_write_horisontal(X, Board) || X <- three_in_row_horisontal()],
Ns = [X || {X, Y} <- Board, is_empty(Y)],
Prompt = lists:flatten( io_lib:format("Player, ~p, select one of ~p: ", [Player, Ns]) ),
N = turn_next_move( Prompt, Ns ),
New_board = [{N, Player} | lists:keydelete(N, 1, Board)],
turn( player(is_finished(New_board), Player), New_board ).
turn_board_write_horisontal( Selections, Board ) ->
Tuples = [lists:keyfind(X, 1, Board) || X <- Selections],
[io:fwrite( "~p ", [Y]) || {_X, Y} <- Tuples],
io:fwrite( "~n" ).
turn_next_move( Prompt, Ns ) ->
{ok,[N]} = io:fread( Prompt, "~d" ),
turn_next_move_ok( lists:member(N, Ns), Prompt, Ns, N ).
turn_next_move_ok( true, _Prompt, _Ns, N ) -> N;
turn_next_move_ok( false, Prompt, Ns, _N ) -> turn_next_move( Prompt, Ns ).
You may also check:How to resolve the algorithm Hofstadter Q sequence step by step in the VBA programming language
You may also check:How to resolve the algorithm Semiprime step by step in the 11l programming language
You may also check:How to resolve the algorithm Sierpinski triangle/Graphical step by step in the FutureBasic programming language
You may also check:How to resolve the algorithm Mad Libs step by step in the AWK programming language
You may also check:How to resolve the algorithm Execute a system command step by step in the Haskell programming language