%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   HAUPTFUNKTION DES SPIELS   %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [] = tictactoe()
% initialisiere graphisches Spielfeld
figure('Name','TicTacToe');
pbaspect([1 1 1])
set(gca,'xTick',0:3)
set(gca,'yTick',0:3)
set(gca,'xTickLabel','')
set(gca,'yTickLabel','')
axis([0 3 0 3])
grid on
shg
% initialisiere Spielstatus: 0 = leeres Feld
state = [[0 0 0];[0 0 0];[0 0 0]]; 
% waehle Startspieler zufaellig
current_player = 2*randi(2)-3;
% intialisiere Gewinner
winner = 0;
% starte Hauptschleife des Spiels
while winner == 0
    % bestimme naechsten Spieler
    if current_player == 1
        current_player = -1;
        xlabel('Computerzug');
    else
        current_player = 1;
        xlabel('Dein Zug!');
    end
    % fuehre einen Spielzug aus
    next_state = play(current_player, state);
    % pruefe ob Zug ungueltig
    while next_state == 0
        title('Ungueltiger Zug');
        next_state = play(current_player, state);
    end
    % aktualisiere Spielstatus
    state = next_state;
    title('');
    % pruefe ob das Spiel gewonnen wurde
    winner = won(state);
 end
if winner == -1
    title('O hat gewonnen');
    xlabel('');
elseif winner == 1
    title('X hat gewonnen');
    xlabel('');
else
    title('Unentschieden!');
    xlabel('');
end
end

% SPIELZUG-FUNKITON: erhaelt den aktuellen Spieler und Spielzustand und
% fuehrt genau einen Spielzug durch
function state = play(current_player, state)
% pruefe ob menschlicher Spieler an der Reihe ist
if current_player == 1
    % bestimme Position des Mausklicks
    [x y] = ginput(1);
    % wandle Mausklickposition in Zeile und Spalte um
    [row col] = rowcol(x, y);
else
    % führe Computerzug aus
    [row, col] = computer_move(state, current_player);
end
% pruefe ob das Feld schon belegt ist
if state(row,col) ~= 0
    state = 0;
else
    % aktualisiere Spielstatus und zeichne X oder O
    state(row,col) = current_player;
    if current_player == -1
        drawO(row,col);
    else
        drawX(row,col);
    end
end
end

% NAIVE KI-FUNKTION
% TODO: Besseren Spielalgorithmus implementieren
function [row col] = computer_move(state, player)
% finde leere Felder
[r c] = find(state==0);
% waehle zufaellig ein leeres Feld
i = randi(length(r));
row = r(i);
col = c(i);
end

% PRUEFUNG OB DAS SPIEL IM AKTUELLEN ZUSTAND GEWONNEN ODER UNTENTSCHIEDEN IST
function won = won(state)
won = 0;
% pruefe Zeilen
for j=1:3
    if abs(state(1,j)+state(2,j)+state(3,j)) == 3
        won=state(1,j);
        break;
    end
end
if won == 0
    % pruefe Spalten
    for i=1:3
        if abs(state(i,1)+state(i,2)+state(i,3)) == 3
            won=state(i,1);
            break;
        end
    end
end
if won == 0
    % pruefe Diagonalen
    if (abs(state(1,1)+state(2,2)+state(3,3)) == 3 || abs(state(1,3)+state(2,2)+state(3,1)) == 3)
        won = state(2,2);
    end
end
% wenn alle Felder ausgefuellt sind ohne Gewinner: unentschieden(=2)
if won == 0   
    if (~ismember(state, 0))
        won = 2;
    end
end
end

% UMRECHNUNG VON MAUSKLICKPOSITION IN ZEILE/SPALTE
function [row col] = rowcol(x, y)
% runde x- und y-Koordinate ab
col = floor(x)+1;
row = floor(y)+1;
% bilde Klicks ausserhalb des Spielfelds auf naechste Zeile/Spalte ab
if col > 3
    col = 3;
end
if col < 1
    col = 1;
end
if row > 3
    row = 3;
end
if row < 1
    row = 1;
end
% passe Zeilennummer an gewoehnliche Matrixnummerierung an
row = 4 - row;
end

% X AUF SPIELFELD ZEICHNEN
function drawX(row, col)
hold on
row = 3-row;
col = col-1;
x = 0:1;
pos = 0:1;
neg = 1-x;
plot(x+col, pos+row,'Color','b')
plot(x+col, neg+row,'Color','b')
hold off
end

% O AUF SPIELFELD ZEICHNEN
function drawO(row, col)
hold on
row = 3-row;
col = col-1;
t = 0:0.1:2*pi;
x = cos(t)/2+0.5;
y = sin(t)/2+0.5;
plot(x+col, y+row,'Color','g')
hold off
end