📄 knight.m
字号:
function varargout = Knight(method, varargin)
% Knight The knight objects.
% This m-function contains the variables and methods for all knights.
%
% Inputs:
% * method ... What the knight instance wants (i.e move, best_move,init,...).
% * varargin ... parameters required for the method(i.e from, to, ...)
% * global board ... chess board and related information
%
% Outputs:
% * varargout ... outputs generated by the method (i.e. best move, legal move,...)
% * global board ... updated chess board and related information
%
% Example
% Add a white knight on field c4 [5,3].
% |Knight('init',[5 3],1,'Bc4')|
%
% Move the knight from c4 [5,3] to d5 [4 4].
% |Knight('move',[5 3],[4 4])|
%
% Determine the knights best move from c4
% |Knight('best_move',[5 3])|
%
% See also: Chess, legal_move, show, remove_figure, Value_of_Figure
%
%% Signature
% Author: W.Garn
% E-Mail: wgarn@yahoo.com
% Date: 2006/03/23 12:00:00
%
% Copyright 2006 W.Garn
%
if nargin<1
Chess;
return;
end
persistent pos; % nx2 matrix of all knights
persistent instances; % cell array - names of all the knights
persistent color; % array of colors (0=black,1=white)
persistent handle; % array of handles to knights
% classic example that there is a big difference beween object orientated
% languages and procedural languages. I have to take care of all the
% instances, hence instance variables myself.
% the escape route is to copy all the variables, which by the way is
% Matlabs object approach, but it's a lot of copying, persistent variables
% offer the reference approach, that is why I stick to it.
global board;
switch method
case 'clear'
pos = []; instances = []; color = [];
for k = 1:length(handle)
try delete(handle);
catch end
end
handle = [];
case 'init'
% varargin: 1: pos, 2: color, 3: instance
n = length(instances)+1; % which instance number
instances{n} = varargin{3};
pos = [pos; varargin{1}]; %matrix position (i.e. [2 3]=c7)
color = [color; varargin{2}]; %color
if color(n), fig='N'; else fig='n'; end
if color(n), board.white(pos(n,1),pos(n,2))=3;
else board.black(pos(n,1),pos(n,2))=3; end
board.figures(pos(n,1),pos(n,2)) = fig;
handle = [handle, show('Knight',varargin{1},color(n))];
set(handle,'ButtonDownFcn','cursorListener(gcbo,[],guidata(gcbo))');
case 'legal_move'
varargout{1} = legal_move(varargin{1},varargin{2});
case 'move'
remove_figure( varargin{2} );
pos = move_figure(varargin{1}, varargin{2}, pos, handle);
case 'best_move'
from = varargin{1};
T = toFields(from); % all possible moves within board
cur_color = getColor(from);
if cur_color %white
P = possible(board.white, T); % only moves, where there is no own figure
[b,gain] = best(P,board.black);
else %black
P = possible(board.black, T); % only moves, where there is no own figure
[b,gain] = best(P,board.white);
end
varargout{1}=b;
varargout{2}=gain;
case 'remove'
k = findPos(pos,varargin{1});
if ~isempty(k)
pos(k,:)=[];
instances(k)=[];
color(k)=[];
delete(handle(k));
handle(k)=[];
end
otherwise
disp('Method is not defined.');
end
%--------------------------------------
function pos = move_figure(from, to, pos, handle)
% from, to ... matrix notation
% moves the figure from a field to a other field
% it is assumed that the legality of the move was checked
% if a opponent figure is on the field it will be first removed.
global board
p = findPos(pos, from);
pos(p,:) = to;
setFiguresPosition(handle(p),to);
% set board
color = getColor(from);
% to
board.figures(to(1),to(2)) = board.figures(from(1),from(2));
if color %white
board.white(to(1),to(2)) = board.white(from(1),from(2));
else
board.black(to(1),to(2)) = board.black(from(1),from(2));
end
% from
board.figures(from(1),from(2)) = ' ';
if color %white
board.white(from(1),from(2)) = 0;
else
board.black(from(1),from(2)) = 0;
end
%--------------------------------------
function T = toFields(position)
% determines all possibles fields witin the board
M = [[2 1 -1 -2 -2 -1 1 2]',[1 2 2 1 -1 -2 -2 -1]'];
e = ones(8,1);
D = e*position + M;
I = find ( sum((D > 0 & D < 9),2)==2 ); % only fields within the board
T = D(I,:);
function P = possible(board, T)
% checks whether there is no own figure on field
P =[];
for k = 1:size(T,1)
if board(T(k,1),T(k,2))==0
P = [P; T(k,:)];
end
end
%------------------------------------------------------------------
% Edis intelligence (ok. I admit, quite simple)
function [b,gain] = best(P, board)
% one move best
% Inputs:
% * board ... values of opponent
%
% Outputs:
% * b ... best field to go to
% * gain ... what the gain would be
b=[]; gain=-inf;
if ~isempty(P)
values = zeros(1, size(P,1));
for k = 1:size(P,1)
values(k) = board(P(k,1),P(k,2));
end
[M I] = max(values);
% take randomly one of the best
j = ceil(length(I)*rand); %(0,1]
b = P(I(j),:);
gain = values(I(j));
end
%------------------------------------------------------------------
function answer = legal_move(from, to)
global board;
answer = 0;
T = toFields(from); % all possible moves within board
color = getColor(from);
if color %white
P = possible(board.white, T); % only moves, where there is no own figure
else %black
P = possible(board.black, T); % only moves, where there is no own figure
end
if ~isempty(P)
I = find( sum((P == ones(size(P,1),1)*to),2) == 2 );
if isempty(I), answer=0; % not legal
else answer = 1; % legal move
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -