%Řešení antagonistických her dvou hráčů - algebraické řešení jednomaticových her ve tvaru 2x2
close all, clear all, clc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Zadejte výplatní matici A, např. následovně:
%A=[7 -3; -1 6]

%Matice A musí nabývat rozměrů 2x2.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Příklady vstupních parametrů:

%0 sedlových bodů => smíšené strategie
%A=[-2,3;3,-4] 

%0 sedlových bodů => smíšené strategie
% A=[7 -3;-1 6] 

%1 sedlový bod
%A=[5,6;7,8]

%2 sedlové body
%A=[5,5;5,8] 

%4 sedlové body
% A=[5,5;5,5] 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Zadejte vstupní parametry:




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

if (size_check==1)
    %radkova minima
    for i=1:m
        Ai=A(i,:);
        mn=min(Ai);
        [~,p{i}]=find(Ai==mn); %[m,n]=find(min) <--zajima me jen index sloupce n
        k1(i)=numel(p{i}); %pocitani, kolikrat je minimum na radku
    end
    
    %sloupcova maxima
    for i=1:n
        Bi=A(:,i);
        mx=max(Bi);
        [q{i},~]=find(Bi==mx); %[m,n]=find(min) <--zajima me jen index radku m
        k2(i)=numel(q{i}); %pocitani, kolikrat je minimum ve sloupci     
    end
    
    %indexovani radkovych minim
    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
    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
    swap = [1 2];
    Y(:, swap) = Y(:, flip(swap));
    
    %nalezeni spolecnych strategii minmax=maxmin
    C = intersect(X,Y,'rows');
    
    disp('Nalezená řádková minima:')
    [length_Z,~] = size(X); %kolik ma matice radkovych minim radku(tzn, zaznamu)
    for i=1:length_Z
        fprintf('Strategie x%g: a(i=%g,j=%g)=%g\n',X(i,1),X(i,1),X(i,2),A(X(i,1),X(i,2)));
    end
    
    disp('............................')
    disp('Nalezená sloupcová maxima:')
    [length_U,~] = size(Y); %kolik ma matice sloupcovych maxim radku(tzn, zaznamu)
    for i=1:length_U
        fprintf('Strategie y%g: a(i=%g,j=%g)=%g\n',Y(i,2),Y(i,1),Y(i,2),A(Y(i,1),Y(i,2)));
    end
    
    [length_C,~] = size(C);
    saddle_check=0;
    %kontrola existence sedloveho prvku
    if (length_C>0)
        disp('............................')
        if(length_C>1)
            disp('Řešením hry jsou nedominované rovnovážné body:')
        else
            disp('Řešením hry je nedominovaný 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)));
        end
        fprintf('cena hry je: v=%g \n',A(C(1,1),C(1,2)));
    else
        disp('............................')
        % smisene strategie algebraicka metoda
        a=A(1,1);
        b=A(1,2);
        c=A(2,2);
        d=A(2,1);
        p_1=(c-d)/((a-b)+(c-d));
        p_2=1-p_1;
        q_1=(c-b)/((a-b)+(c-d));
        q_2=1-q_1;
        v=(a*c-b*d)/(a-b+c-d);
        disp('Matice hry nemá sedlový prvek, řešení existuje ve smíšených strategiích:')
        fprintf('Pravděpodobnost volby první strategie x1 hráče 1 je: %g\n',p_1);
        fprintf('Pravděpodobnost volby druhé strategie x2 hráče 1 je: %g\n',p_2);
        disp('............................')
        fprintf('Pravděpodobnost volby první strategie y1 hráče 2 je: %g\n',q_1);
        fprintf('Pravděpodobnost volby druhé strategie y2 hráče 2 je: %g\n',q_2);
        disp('............................')
        fprintf('Cena hry je: v=%g\n',v);
    end  
else
    disp('Chyba: matice nemá rozměry 2x2, a tudíž nelze provést algebraické řešení pro smíšené strategie.');
end