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 + -
显示快捷键?