Reputation: 95
So I'm trying to write tic-tac-toe for erlang using touples (a learning exercise). I always want a Board variable to be a tuple of nine elements. I've got the win matching down, but the matching to a cat's game is proving difficult. I want to do {_,_,_,_,_,_,_,_,_}
-> "Cat's Game!"; , but that would match other elements like []
, or ""
, when I only want it to match x OR y, but nothing else. Example:
{(x||y),(x||y),(x||y),(x||y),(x||y),(x||y),(x||y),(x||y),(x||y)} -> "Cat's game!"
is essentially what I want to do, but I don't know how to do this with Erlang tuples, and it's proving difficult to google.
-module(d2bonus).
-export([status/1]).
status(Board) ->
case Board of
{x,x,x,_,_,_,_,_,_} -> "X Wins!";
{o,o,o,_,_,_,_,_,_} -> "O Wins!";
{_,_,_,x,x,x,_,_,_} -> "X Wins!";
{_,_,_,o,o,o,_,_,_} -> "O Wins!";
{_,_,_,_,_,_,x,x,x} -> "X Wins!";
{_,_,_,_,_,_,o,o,o} -> "O Wins!";
{x,_,_,x,_,_,x,_,_} -> "X Wins!";
{o,_,_,o,_,_,o,_,_} -> "O Wins!";
{_,x,_,_,x,_,_,x,_} -> "X Wins!";
{_,o,_,_,o,_,_,o,_} -> "O Wins!";
{_,_,x,_,_,x,_,_,x} -> "X Wins!";
{_,_,o,_,_,o,_,_,o} -> "O Wins!";
{x,_,_,_,x,_,_,_,x} -> "X Wins!";
{o,_,_,_,o,_,_,_,o} -> "O Wins!";
{_,_,x,_,x,_,x,_,_} -> "X Wins!";
{_,_,o,_,o,_,o,_,_} -> "O Wins!";
({P1,P2,P3,P4,P5,P6,P7,P8,P9}) when (P1 =:= x orelse P1 =:= y), (P2 =:= x orelse P2 =:= y), (P3 =:= x orelse P3 =:= y), (P4 =:= x orelse P4 =:= y), (P5 =:= x orelse P5 =:= y), (P6 =:= x orelse P6 =:= y), (P7 =:= x orelse P7 =:= y), (P8 =:= x orelse P8 =:= y), (P9 =:= x orelse P9 =:= y) -> "Cat's Game!";
_ -> "No winner yet"
end
.
Upvotes: 2
Views: 530
Reputation: 95
-module(d2bonus). -export([status/1]).
status(Board)-> case Board of {x,x,x,,,_,,,_} -> "X Wins!"; {o,o,o,,,_,,,_} -> "O Wins!"; {,,_,x,x,x,,,_} -> "X Wins!"; {,,_,o,o,o,,,_} -> "O Wins!"; {,,_,,,_,x,x,x} -> "X Wins!"; {,,_,,,_,o,o,o} -> "O Wins!"; {x,,,x,,,x,,} -> "X Wins!"; {o,,,o,,,o,,} -> "O Wins!"; {,x,,_,x,,,x,} -> "X Wins!"; {,o,,,o,,,o,} -> "O Wins!"; {,_,x,,,x,,,x} -> "X Wins!"; {,,o,,,o,,,o} -> "O Wins!"; {x,,,_,x,,,_,x} -> "X Wins!"; {o,,,_,o,,,_,o} -> "O Wins!"; {,,x,,x,,x,,} -> "X Wins!"; {,,o,,o,,o,,} -> "O Wins!"; {P1,P2,P3,P4,P5,P6,P7,P8,P9} when (P1 =:= x orelse P1 =:= o), (P2 =:= x orelse P2 =:= o), (P3 =:= x orelse P3 =:= o), (P4 =:= x orelse P4 =:= o), (P5 =:= x orelse P5 =:= o), (P6 =:= x orelse P6 =:= o), (P7 =:= x orelse P7 =:= o), (P8 =:= x orelse P8 =:= o), (P9 =:= x orelse P9 =:= o) -> "Cat's game!"; _ -> "No winner yet" end .
Upvotes: 0
Reputation: 725
Couple more
is_cats_game1(Board) when is_tuple(Board), size(Board) =:= 9 ->
[] =:= [Z || Z <- tuple_to_list(Board), Z =/= x andalso Z =/= y].
-define(is_yx(E), (E =:= x orelse E =:= y)).
is_cats_game2({Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9} = __Board)
when ?is_yx(Z1)
andalso ?is_yx(Z2)
andalso ?is_yx(Z3)
andalso ?is_yx(Z4)
andalso ?is_yx(Z5)
andalso ?is_yx(Z6)
andalso ?is_yx(Z7)
andalso ?is_yx(Z8)
andalso ?is_yx(Z9) ->
true;
is_cats_game2(_) -> false.
Upvotes: 1
Reputation: 1306
You could validate your input values before they get into your tuple, like:
make_move(Pos, Z, StateTuple) when Pos >= 1, Pos =< 9, (Z =:= x orelse Z =:= y) ->
erlang:setelement(Pos, StateTuple, Z).
Upvotes: 1
Reputation: 2984
If you want to be strict, you can do:
f({P1,P2,...}) when (X1 =:= x orelse X1 =:= y), (P2 =:= x orelse P2 =:= y), ... ->
"Cat's game!".
I would do something like:
f(Board) when is_tuple(Board), size(Board) =:= 9 ->
true = lists:all(fun(x) -> true;
(y) -> true;
(_) -> false
end,
tuple_to_list(Board)),
"Cat's Game".
But that's mostly because I have a low tolerance for long winded checks.
Upvotes: 3