#include <iostream>
#include "board.h"
using namespace std;

Board::Board()
{
   for (auto& col : mFields)
   {
      for (auto& field : col)
      {
         field = FieldState::empty;
      }
   }
}

void Board::print() const
{
   for (const auto& col : mFields)
   {
      for (const auto field : col)
      {
         switch (field)
         {
            using enum FieldState;
         case empty:
            cout << "_ ";
            break;
         case white:
            cout << "O ";
            break;
         case black:
            cout << "X ";
            break;
         }
      }
      cout << '\n';
   }
   cout << '\n';
}

bool Board::isFree(int col, int row) const
{
   return mFields[row][col] == FieldState::empty;
}

void Board::set(const Move& move)
{
   mFields[move.getRow()][move.getCol()] = asFieldState(move.getColor());
}

Board::FieldState Board::asFieldState(Color color)
{
   static_assert(static_cast<int>(Color::white) == static_cast<int>(FieldState::white), "Die Enum-Konstanten müssen die gleichen Werte haben");
   static_assert(static_cast<int>(Color::black) == static_cast<int>(FieldState::black), "Die Enum-Konstanten müssen die gleichen Werte haben");
   return static_cast<FieldState>(static_cast<int>(color));
}

bool Board::hasWin(Color color) const
{
   FieldState s = asFieldState(color);
   if (mFields[0][0] == s && mFields[1][0] == s && mFields[2][0] == s) return true;
   if (mFields[0][1] == s && mFields[1][1] == s && mFields[2][1] == s) return true;
   if (mFields[0][2] == s && mFields[1][2] == s && mFields[2][2] == s) return true;
   if (mFields[0][0] == s && mFields[0][1] == s && mFields[0][2] == s) return true;
   if (mFields[1][0] == s && mFields[1][1] == s && mFields[1][2] == s) return true;
   if (mFields[2][0] == s && mFields[2][1] == s && mFields[2][2] == s) return true;
   if (mFields[0][0] == s && mFields[1][1] == s && mFields[2][2] == s) return true;
   if (mFields[0][2] == s && mFields[1][1] == s && mFields[2][0] == s) return true;
   return false;
}

bool Board::isRemis() const
{
   for (const auto& col : mFields)
   {
      for (const auto field : col)
      {
         if (field == FieldState::empty)
         {
            return false;
         }
      }
   }
   return true;
}
