%Řešení neantagonistického konfliktu dvou hráčů - dvoumaticové hry ve tvaru m x n
close all, clear all, clc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Zadejte výplatní matice A,B hráčů jedna a dva, např. následovně:
% A=[-2 0; 3 -1]
% B=[-1 3; 0 -2]

%Matice A a B musí nabývat stejných rozměrů m x n.
%Pro výpočet smíšených strategií musí matice nabývat rozměrů 2x2.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Příklady vstupních parametrů:

% Čtyři rovnovážné body, jeden dominující:
% A=[9 3 4 2;1 2 3 10; 2 3 6 3; 2 4 3 1]
% B=[7 2 4 2;1 2 3 8; 2 3 5 3; 1 4 2 1]

% Čtyři rovnovážné body, dva dominující:
% A=[9 3 4 2;1 2 3 10; 2 3 10 3; 2 4 3 1]
% B=[7 2 4 2;1 2 3 8; 2 3 9 3; 1 4 2 1]

% Príklady rovnovážných bodů z diplomové práce:
% Jeden rovnovážný  bod:
% A=[4 6 2;9 7 3;7 5 6]
% B=[2 7 9;8 7 4;7 8 3]

% Dva rovnovážné body, jeden dominuje druhý:
% A=[5 7 2;9 6 7;7 10 6]
% B=[3 6 9;7 5 5;6 8 7]

% Čtyři zaměnitelné rovnovážné body:
% A=[4 8 5;8 6 8;8 5 8]
% B=[4 3 9;8 7 8;8 5 8]

% Dva rovnovážné body, nezaměnitelné:
% A=[4 7 5; 5 1 9; 6 7 1]
% B=[9 5 3; 2 1 5; 4 8 1]

% Pět rovnovážných bodů, nezaměnitelné:
% A=[4 8 5; 8 6 8; 8 5 8; 8 2 1]
% B=[4 3 9; 8 7 8; 8 5 8; 8 3 0]

% Nula rovnovážných bodů > smíšené strategie:
% A=[-2 0; 3 -1]
% B=[-1 3; 0 -2]

% Příklad z [4] > smíšené strategie:
% A=[1 -1; -1 1]
% B=[-1 1; 1 -1]

% Příklad z diplomové práce > smíšené strategie
% A=[2 1; 1 4]
% B=[-3 2; 1 -1]

% Příklad z diplomové práce:
% A=[75 85 105; 55 78 85; 30 65 73; 76 78 80]
% B=[75 55 30; 85 78 60; 105 80 73; 80 75 70]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Zadejte vstupní parametry:




%kód algoritmu:
mixed_strategy_check=0;
size_check=0;
[m,n]=size(A);
[m_2,n_2]=size(B);
if (m>=2 && n>=2) && (m==m_2 && n==n_2)
    size_check=1;
end

if (size_check==1)
    %radkova maxima v B
    for i=1:m
        Bi=B(i,:);
        mx_B=max(Bi);
        [~,p{i}]=find(Bi==mx_B); %[m,n]=find(max) <--zajima me jen index sloupce n
        k1(i)=numel(p{i}); %pocitani, kolikrat je maximum na radku
    end
    
    %sloupcova maxima v A
    for i=1:n
        Ai=A(:,i);
        mx_A=max(Ai);
        [q{i},~]=find(Ai==mx_A); %[m,n]=find(max) <--zajima me jen index radku m
        k2(i)=numel(q{i}); %pocitani, kolikrat je maximum ve sloupci
        
    end
    
    %indexovani radkovych maxim v B
    X= [0,0];
    for i=1:numel(k1)
        for j=1:k1(i)
            C1(j,:)=[i,p{i}(j)]; %v ramci i-teho p-cka najdi j-tou hodnotu C1(1,1)=[]
        end
        X=[X;C1];
        C1=[];
    end
    
    %indexovani sloupcovych maxim v A
    Y=[0,0];
    for i=1:numel(k2)
        for j=1:k2(i)
            C2(j,:)=[i,q{i}(j)]; %v ramci iteho q-cka najdi jtou hodnotu
        end
        Y=[Y;C2];
        C2=[];
    end
    
    %odstraneni prvnich nul
    X=X(2:end,:);
    Y=Y(2:end,:);
    
    %prohozeni indexu ve sloupcovych maximech v A
    swap = [1 2];
    Y(:, swap) = Y(:, flip(swap));
    
    %nalezeni spolecnych oznacenych strategii
    C = intersect(X,Y,'rows');
    
    disp('Nalezená sloupcová maxima v matici A:')
    [length_U,~] = size(Y); %kolik ma matice sloupcovych maxim radku(tzn, zaznamu)
    for i=1:length_U
        fprintf('a(i=%g,j=%g)=%g\n',Y(i,1),Y(i,2),A(Y(i,1),Y(i,2)));
    end
    disp('............................')
    
    disp('Nalezená řádková maxima v matici B:')
    [length_Z,~] = size(X); %kolik ma matice radkovych maxim radku(tzn, zaznamu)
    for i=1:length_Z
        fprintf('b(i=%g,j=%g)=%g\n',X(i,1),X(i,2),B(X(i,1),X(i,2)));
    end
    
    [length_C,~] = size(C);
    if (length_C>0)
        disp('............................');
        
        if(length_C>1)
            disp('Nalezené rovnovážné body:')
        else
            disp('Nalezený rovnovážný bod:')
        end
        for i=1:length_C
            fprintf('a(i=%g,j=%g)=%g \n',C(i,1),C(i,2),A(C(i,1),C(i,2)));
            fprintf('b(i=%g,j=%g)=%g \n',C(i,1),C(i,2),B(C(i,1),C(i,2)));
            disp('...');
        end
        disp('............................');
        disp('Hledání a odstranění dominovaných rovnovážných bodů:');
        [length_C,~] = size(C);
        D=[0 0];
        for j=1:length_C
            for i=1:length_C
                if (A(C(j,1),C(j,2)) > A(C(i,1),C(i,2))) && (B(C(j,1),C(j,2)) > B(C(i,1),C(i,2)))
                    fprintf('a(i=%g,j=%g)=%g > a(i=%g,j=%g)=%g , b(i=%g,j=%g)=%g > b(i=%g,j=%g)=%g \n',C(j,1),C(j,2),A(C(j,1),C(j,2)),C(i,1),C(i,2),A(C(i,1),C(i,2)),C(j,1),C(j,2),B(C(j,1),C(j,2)),C(i,1),C(i,2),B(C(i,1),C(i,2)));
                    disp('...');
                    D(i,:)=[C(i,1),C(i,2)]; %radkove indexy dominovanych strategii
                end
                
            end
        end
        C=setdiff(C,D,'rows');
        %odstraneni nulovych radku
        C(C(:,1)==0,:) = [] ;
        disp('............................');
        [length_C,~] = size(C);
        %jediny rovnovazny bod
        if length_C==1
            disp('Nalezen jediný nedominovaný rovnovážný bod:');
            fprintf('a(i=%g,j=%g)=%g \n',C(1,1),C(1,2),A(C(1,1),C(1,2)));
            fprintf('b(i=%g,j=%g)=%g \n',C(1,1),C(1,2),B(C(1,1),C(1,2)));
        else
            %eq_check overuje rovnost funkcnich hodnot rovnovaznych bodu
            eq_check=1;
            disp('Kontrola rovnosti funkčních hodnot nedominovaných rovnovážných bodů:');
            for j=1:length_C
                for i=1:length_C
                    if (A(C(j,1),C(j,2)) ~= A(C(i,1),C(i,2))) || (B(C(j,1),C(j,2)) ~= B(C(i,1),C(i,2)))
                        fprintf('a(i=%g,j=%g)=%g ~= a(i=%g,j=%g)=%g nebo b(i=%g,j=%g)=%g ~= b(i=%g,j=%g)=%g \n',C(j,1),C(j,2),A(C(j,1),C(j,2)),C(i,1),C(i,2),A(C(i,1),C(i,2)),C(j,1),C(j,2),B(C(j,1),C(j,2)),C(i,1),C(i,2),B(C(i,1),C(i,2)));
                        disp('...');
                        eq_check=0;
                    end
                end
            end
            %exchangable_check_count>0 znamena, ze nektery z rovnovaznych bodu je nezamenitelny
            exchangable_check_count=0;
            disp('............................');
            %rovnovazne body jsou si rovny, kontrola zamenitelnosti - resitelny pripad
            if eq_check==1
                disp('Kontrola zaměnitelnosti nedominovaných rovnovážných bodů:');
                member_check=inf;
                for j=1:length_C
                    for i=1:length_C
                        exchangable=intersect(C,[C(j,1) C(i,2)],'rows');
                        [member_check,~]=size(exchangable);
                        if (member_check==0)
                            exchangable_check_count=exchangable_check_count+1;
                        end
                    end
                end
            end
            %rovnovazne body jsou stejne (a zamenitelne) - resitelny pripad
            if (exchangable_check_count==0 && eq_check==1)
                disp('Nalezené nedominované rovnovážné body mají stejnou funkční hodnotu a jsou zaměnitelné, hráči mohou libovolně volit ze svých strategií, které tvoří tyto rovnovážné body.');
            else
                %rovnovazne body nejsou stejne nebo nejsou zamenitelne - smisene strategie
                disp('Nalezené nedominované rovnovážné body nemají stejnou funkční hodnotu, nebo nejsou zaměnitelné, a tudíž existuje řešení pouze ve strategiích smíšených.');
                mixed_strategy_check=1;
            end
        end
    else
        mixed_strategy_check=1;
    end
    
    if mixed_strategy_check==1
        
        disp('............................')
        disp('Řešení hry existuje ve smíšených strategiích:');
        
        if (m==2 && n==2)
            
            %rovnice pro pravděpodobnosti voleb strategií druhého hráče:
            syms q
            disp('Rovnice pro výpočet hodnoty q:');
            eq1=[(A(1,1)*q)+(A(1,2)*(1-q)) == (A(2,1)*q)+(A(2,2)*(1-q))]
            Q=solve(eq1,q);
            fprintf('q=%g \n \n',Q);
            y_1=Q;
            y_2=1-Q;
            
            %rovnice pro pravděpodobnosti voleb strategií prvního hráče:
            syms p
            disp('Rovnice pro výpočet hodnoty p:');
            eq2=[(B(1,1)*p)+(B(2,1)*(1-p)) == (B(1,2)*p)+(B(2,2)*(1-p))]
            P=solve(eq2,p);
            fprintf('p=%g \n \n',P);
            x_1=P;
            x_2=1-P;
            
            %vypocet ocekevanych vyher obou hráčů
            v1=subs(eq1,Q);
            v2=subs(eq2,P);
            
            fprintf('Pravděpodobnost volby první strategie x1 hráče 1 je: %g\n',x_1);
            fprintf('Pravděpodobnost volby druhé strategie x2 hráče 1 je: %g\n',x_2);
            disp('Pro očekávané výhry prvního hráče při volbě první a druhé startegie s těmito pravděpodobnostmi platí:');
            v1
            disp('............................')
            fprintf('Pravděpodobnost volby první strategie y1 hráče 2 je: %g\n',y_1);
            fprintf('Pravděpodobnost volby druhé strategie y2 hráče 2 je: %g\n',y_2);
            disp('Pro očekávané výhry druhého hráče při volbě první a druhé startegie s těmito pravděpodobnostmi platí:');
            v2
        else
            disp('Pro výpočet smíšených strategií musí Matice A, B nabývat rozměrů 2x2.')
        end
    end
else
    disp('Chyba: Obě matice A, B musí mít tototžné rozměry o rozměrech alespoň 2x2.');
end



