我正在编写一个类似于扫雷的权力游戏游戏程序。用户被问到王国的大小,并根据大小有一定数量的骑士。我创建一个零(矩阵大小)的矩阵来预先分配和分配相同数量的国王,因为有骑士到矩阵中的随机位置。我现在已经创建了一个新函数,我在主脚本中调用,我希望遍历矩阵,并根据相邻位置中有多少个国王为每个元素分配新值,例如:
_ 1 2 3 4 5 6 7 8
1 * 1 1 1 1 0 0 0
2 1 2 2 * 2 2 1 1
3 1 2 * 3 * 2 * 1
4 * 3 1 2 1 2 1 1
5 * 2 0 0 0 0 0 0
6 1 0 0 1 1 2 1 1
7 1 1 1 1 * 2 * 1
8 1 * 1 1 1 2 1 1
问题是我真的不知道如何实际计算邻近的国王并改变我的矩阵中的值。我已经开始为侧面的一些for循环,但我不知道如何继续。主流程序和功能如下:谢谢!
主脚本:
clear all;close all;clc;
%display menu of options to play gam or exit
choice = menu('Choose an option', 'Exit Program', 'Start New Game');
%choise 1 is to exit the program
while choice ~= 1
switch choice
case 0
disp('Error - please choose one of the options.')
choice = menu('Choose an option', 'Exit Program', 'Start New Game');
%choice two is to start a new game
case 2
disp('Welcome to the GAME of THRONES!');
name = input('State your name, Your Grace: ','s');
size = input(['How vast is your Kindom ', name , ' your Grace?: ']);
Kings = floor((size^2)/6);
A = [name, ' Your Grace, you have ' num2str(Kings), ' Knights left to defeat ' num2str(Kings), ' Kings'];
disp(A);
game_choices = menu('Choose an option','Show the Kingdoms','Enter a new Coordinat');
switch game_choices
case 1 %Show the board
mymat = zeros(size);%matrix of users size
Kr=randsample(size^2,Kings);%vector of random positions for the kings
for i= 1:Kings
mymat([Kr(i)])=999;%put kings into mat of zeros in there random assignments
end
makeBoard(size);
%cell array game board
case 2 %enter a new coordinate
end
end
choice = menu('Choose an option', 'Exit Program', 'Start New Game');
end
功能我不知道怎么写:
function [ mymatG ] = countTheKings( mymat )
%this function counts the kings and puts the numbers where they should be
%should have 2 for loops
for i = 1:size
for j = 1:size
%top
mymat(1,j)=
%bottom
mymat(size,j)=
%left side
mymat(i,1)=
%right side
mymat(i,size)=
end
答案 0 :(得分:2)
计算邻居数量的经典方法是使用convolution。在离散世界中,2D卷积将矩阵("内核")移动到更大的矩阵上,并且对于每个移位,计算重叠。重叠被定义为内核的元素乘法与其下面的数据的总和。然后,结果值将用于替换内核所在的值。
我们可以将内核设计为"检测"邻居。我们希望它有一些你认为是邻居的地方和你认为不是认为是邻居的地方的零。如果你不希望你的国王认为自己是邻居,那么这可能看起来像这样。
1 1 1
1 0 1
1 1 1
此矩阵将以电路板上的每个点为中心,并且将执行与电路板的元素倍增,并且将对所有元素进行求和。
例如,如果这是以下列数据为中心
1 2 3
4 5 6
7 8 9
它将被处理为:
(1 * 1) + (2 * 1) + (3 * 1) + (4 * 1) + (5 * 0) + (6 * 1) + (7 * 1) + (8 * 1) + (9 * 1)
1 + 2 + 3 + 4 + 0 + 6 + 7 + 8 + 9
40
所以我们也可以使用这个"内核的卷积" 计算二进制矩阵中的1的数量。
所以对于这个数据
1 0 1
0 0 0
1 0 0
当我们将内核应用于此时,我们得到
(1 * 1) + (0 * 1) + (1 * 1) + (0 * 1) + (0 * 0) + (0 * 1) + (1 * 1) + (0 * 1) + (0 * 1)
1 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0
3
如果你想象我们应用这个内核的二进制数据是1,那里有一个王,0就是没有,这就是围绕给定元素的国王数。
所以我们能做的就是从问题的开头拿出内核,然后创建一个二进制矩阵,其中有一个有王的二进制矩阵,否则就是0。结果将是您的电路板的大小,值将是相邻国王的数量。
kernel = [1 1 1;
1 0 1;
1 1 1];
mymat = [9 0 0 0 0 0 0 0
0 0 0 9 0 0 0 0
0 0 9 0 9 0 9 0
9 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 9 0 9 0
0 9 0 0 0 0 0 0];
isKing = mymat == 9;
nKingNeighbors = conv2(double(isKing), kernel, 'same');
%// 0 1 1 1 1 0 0 0
%// 1 2 2 2 2 2 1 1
%// 1 2 1 3 1 2 0 1
%// 1 3 1 2 1 2 1 1
%// 1 2 0 0 0 0 0 0
%// 1 1 0 1 1 2 1 1
%// 1 1 1 1 0 2 0 1
%// 1 0 1 1 1 2 1 1
如果您不想将对角线条目视为邻居,则只需将内核更改为。
0 1 0
1 0 1
0 1 0
因此,如果我们回到您的示例,我们可以将您的countTheKings
函数写为
function mymatG = countTheKings(mymat)
kernel = [1 1 1
1 0 1
1 1 1];
mymatG = conv2(double(mymat == 999), kernel, 'same');
end
这是一个动画,显示2D卷积实际上在做什么。内核以红色显示,当内核移动到图像上时,您可以看到nKingNeighbors
的值被填充。