Я реализую шахматную игру (китайские шахматы, а точнее, Xiangqi) в Erlang.
Часть представлена кортежем {Color, Type}
, а точка (т. Е. Местоположение) представлена кортежем {File, Rank}
. Доска представлена схемой "точка-часть" (т.е. #{point() => piece()}
).
Есть функция для запроса, занята ли конкретная точка на доске фигурой или нет:
is_point_occupied_simple(Board, Point) ->
ensure_is_point(Point),
case maps:find(Point, Board) of
{ok, _} ->
true;
error ->
false
end.
Однако я хотел бы добавить необязательный параметр для проверки цвета детали - если точка занята куском указанного цвета, функция возвращает true; в противном случае возвращается false. Если меня не волнует цвет детали, я могу просто указать '_'
в параметре TargetColor
(или, что то же самое, вызвать is_point_occupied/2
):
is_point_occupied(Board, Point) ->
is_point_occupied(Board, Point, '_').
is_point_occupied(Board, Point, '_') ->
ensure_is_point(Point),
case maps:find(Point, Board) of
{ok, _} ->
true;
error ->
false
end;
is_point_occupied(Board, Point, TargetColor) ->
ensure_is_point(Point),
ensure_is_color(TargetColor),
case maps:find(Point, Board) of
{ok, {TargetColor, _}} ->
true;
{ok, _} ->
false;
error ->
false
end.
Мне не нравится приведенная выше реализация из-за большой доли копирования и вставки, поэтому я упростил указанную выше функцию следующим образом:
is_point_occupied_2(Board, Point) ->
is_point_occupied_2(Board, Point, '_').
is_point_occupied_2(Board, Point, TargetColor) ->
ensure_is_point(Point),
ensure_is_color_or_wildcard(TargetColor),
case maps:find(Point, Board) of
{ok, {TargetColor, _}} ->
true;
{ok, _} ->
is_wildcard(TargetColor);
error ->
false
end.
Функция is_wildcard/1
- это просто однострочник:
is_wildcard(Wildcard) -> Wildcard =:= '_'.
Теперь я хотел бы пойти дальше и заменить TargetColor
на TargetPiece
, который является {TargetColor, TargetType}
кортежем. Нет, один или оба элемента кортежа могут быть подстановочным знаком ('_'
). Мне было трудно написать case
пункты. Я также заметил, что для соответствия n-кортежу, разрешающему «безразлично» таким образом, необходимы 2 предложения n. Очевидно, что это неправильный способ реализовать это.
Есть ли у кого-нибудь идеи получше?
PS: Я не включил исходный код всех функций, поскольку те, которые я не включил, на мой взгляд, тривиально реализовать. Пожалуйста, оставьте комментарий ниже, если вам интересно. Спасибо!