我正在Erlang中實施一個國際象棋比賽(準確的說是中國象棋)。適當的方式來實現(Mnesia式/通配符/不關心)元組匹配(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:我沒有包括所有功能的來源,因爲我沒有包括這些功能在我看來是微不足道的。如果您有興趣,請在下面留言。謝謝!
謝謝你你的答案!那麼,這是否意味着您的棋盤需要8 x 8 = 64個棋子(而中國象棋需要9 x 10 = 90個棋子)?由於內存消耗在這裏很重要,我認爲這可能不是一個好方法。此外,爲了匹配一個n元組{E1,E2,...,En},必須寫入2^n個匹配/ 2個子句。正如我所提到的,我懷疑這是否是正確的做法。順便說一句,國際象棋僅僅作爲一個例子,我主要關注的是「不關心」式的匹配。是否必須改變電路板定義?有沒有比我更優雅的解決方案來實現這一目標?謝謝! – 2014-11-22 12:46:11