othello_adt.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 537 行 · 第 1/2 页
ERL
537 行
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%-module(othello_adt).-compile(export_all).%%-------------------------------------------------------%% Use three main states for the strategy:%%%% BeginPlay: Stay in the inner square as long as possible.%% Use the possible_draws/3.%%%% MiddlePlay: Try to choose stable markers (?)%% Use stable/3%%%% EndPlay: Try to flip as many markers as possible%%%% The transition from Begin to Middle is obvious. From Middle%% to End however, is can be discussed.%%-------------------------------------------------------test(N,B) -> X=new(B), statistics(wall_clock), test0(N,X), {_,T} = statistics(wall_clock), {time_was,T/N}.test0(0,_) -> true;test0(N,X) -> possible_draws(black,X,begin_play), test0(N-1,X).%%-------------------------------------------------------%% new/1 - returns a new board%% %% Uses a tuple for storing the board%%-------------------------------------------------------new(B) -> Board = mk_board(B), {ordsets:from_list([18,19,20,21,26,29,34,37,42,43,44,45]),Board}.mk_board(t) -> Tup = list_to_tuple(gen_list(64,grey)), Tup1 = setelement(28+1, Tup, white), Tup2 = setelement(35+1, Tup1, white), Tup3 = setelement(27+1, Tup2, black), gen_score_board(), setelement(36+1, Tup3, black).gen_list(0,_) -> [];gen_list(I,Def) -> [Def|gen_list(I-1,Def)].gen_score_board() -> put(score,list_to_tuple(gen_list(64,0))).%%-------------------------------------------------------%% pos(Col,Row) - returns a position describing column%% and row.%% Col and Row have the range 1 - 8.%%-------------------------------------------------------pos(Col,Row) -> ((Row - 1) bsl 3) + (Col - 1).%%-------------------------------------------------------%% col(Pos) - returns the column of the Pos position%%-------------------------------------------------------col(Pos) -> (Pos band 7) + 1.%%-------------------------------------------------------%% row(Pos) - returns the row of the Pos position%%-------------------------------------------------------row(Pos) -> (Pos bsr 3) + 1.%%-------------------------------------------------------%% is_draw(Pos,Colour,Board) - returns true if Pos is a%% correct draw.%%-------------------------------------------------------is_draw(Pos,Colour,{Bset,Board}) -> case ordsets:is_element(Pos,Bset) of true -> case catch is_good(Colour,Pos,Board) of true -> true; _ -> false end; _ -> false end.%%-------------------------------------------------------%% set(Pos,Colour,Board) - returns an updated board%%-------------------------------------------------------set(Pos,Colour,{Bset,Board}) -> case ordsets:is_element(Pos,Bset) of true -> NewBoard = setelement(Pos+1,Board,Colour), Empty = empty_neighbour(Pos,NewBoard), NewBset = ordsets:union(Empty,ordsets:del_element(Pos,Bset)), turn(Colour,Pos,{NewBset,NewBoard}); _ -> {error,invalid_position} end. empty_neighbour(Pos,Board) -> ordsets:from_list(empty_neighbour(Pos,Board,deltas())).empty_neighbour(_,_,[]) -> [];empty_neighbour(Pos,Board,[H|T]) -> case is_empty(Pos+H,dir(Pos,H),Board) of true -> [Pos+H|empty_neighbour(Pos,Board,T)]; _ -> empty_neighbour(Pos,Board,T) end.is_empty(_,false,_) -> false;is_empty(X,_,_Board) when X<0 -> false;is_empty(X,_,_Board) when X>63 -> false;is_empty(X,_,Board) -> case element(X+1,Board) of grey -> true; % Empty _ -> false end.%%-------------------------------------------------------%% get(Pos,Board) - returns the contents in Pos%%-------------------------------------------------------get(Pos,{_Bset,Board}) -> element(Pos+1,Board).%%-------------------------------------------------------%% pieces(Colour,Board) - returns the number of Colour%% pieces.%%-------------------------------------------------------pieces(Colour,{_Bset,Board}) -> pieces(Colour,Board,0,0).pieces(Colour,Board,Pos,Count) when Pos < 64 -> case element(Pos+1,Board) of Colour -> pieces(Colour,Board,Pos+1,Count+1); _ -> pieces(Colour,Board,Pos+1,Count) end;pieces(_,_,_,Count) -> Count.%%-------------------------------------------------------%% possible_draws(Colour, Board, State) %% %% Returns a list of possible draws regarding the current%% strategy state.%%-------------------------------------------------------possible_draws(Colour,{Bset,Board},begin_play) -> Dset = ordsets:intersection(Bset,inner_square()), possible_draws_0(Colour,Dset,Board);possible_draws(Colour,{Bset,Board},_) -> possible_draws_0(Colour,Bset,Board).possible_draws(Colour,{Bset,Board}) -> possible_draws_0(Colour,Bset,Board).possible_draws_0(_,[],_) -> [];possible_draws_0(Colour,[H|T],Board) -> case catch is_good(Colour,H,Board) of true -> [H|possible_draws_0(Colour,T,Board)]; false -> possible_draws_0(Colour,T,Board) end.%%-------------------------------------------------------%% evaluate_board(Colour,Board) - returns the value of%% the board from Colours%% point of view.%%-------------------------------------------------------evaluate_board(Colour,{_Bset,Board}) -> Score = get(score), % Initialized (zeroed) score board !! Colour1 = swap(Colour), Score1 = eval_board(Colour,Colour1,Score,Board,0), Score2 = cnt_corner(0,Score1,Board,Colour,Colour1), Score3 = cnt_corner(7,Score2,Board,Colour,Colour1), Score4 = cnt_corner(56,Score3,Board,Colour,Colour1), Score5 = cnt_corner(63,Score4,Board,Colour,Colour1), count(Score5,0).% A = count(Score5,0),% io:format('Score = ~w~n',[A]),% A.eval_board(MyCol,OtCol,Score,Board,Pos) when Pos < 64 -> case element(Pos+1,Board) of MyCol -> Score1 = setelement(Pos+1,Score,score(Pos)), eval_board(MyCol,OtCol,Score1,Board,Pos+1); OtCol -> Score1 = setelement(Pos+1,Score,-score(Pos)), eval_board(MyCol,OtCol,Score1,Board,Pos+1); _ -> eval_board(MyCol,OtCol,Score,Board,Pos+1) end;eval_board(_,_,Score,_,_) -> Score.cnt_corner(Corner,Score,Board,MyCol,OtCol) -> case element(Corner+1,Board) of MyCol -> cnt_corn(Corner,setelement(Corner+1,Score,50), Board,50,MyCol); OtCol -> cnt_corn(Corner,setelement(Corner+1,Score,-50), Board,-50,OtCol); _ -> Score end.cnt_corn(0,Score,Board,Value,Colour) -> Score1 = cnt_corn(0,1,8,Score,Board,Value,Colour), cnt_corn(0,8,1,Score1,Board,Value,Colour);cnt_corn(7,Score,Board,Value,Colour) -> Score1 = cnt_corn(7,-1,8,Score,Board,Value,Colour), cnt_corn(7,8,-1,Score1,Board,Value,Colour);cnt_corn(56,Score,Board,Value,Colour) -> Score1 = cnt_corn(56,1,-8,Score,Board,Value,Colour), cnt_corn(56,-8,1,Score1,Board,Value,Colour);cnt_corn(63,Score,Board,Value,Colour) -> Score1 = cnt_corn(63,-1,-8,Score,Board,Value,Colour), cnt_corn(63,-8,-1,Score1,Board,Value,Colour).cnt_corn(Pos,Dir,LineDir,Score,Board,Value,Colour) -> case dir(Pos,Dir) of Dir -> NextEdge = Pos+Dir, case element(NextEdge+1,Board) of Colour -> Score1 = setelement(NextEdge+1,Score,Value), Score2 = cnt_line(NextEdge,LineDir,Score1,Board, Colour,Value), cnt_corn(NextEdge,Dir,LineDir,Score2,Board,Value,Colour); _ -> Score end; _ -> Score end.cnt_line(Pos,Dir,Score,Board,Colour,Value) -> case dir(Pos,Dir) of Dir -> OnLinePos = Pos+Dir,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?