
//
// To jest przykładowy kod z podrozdziału 24.5.3 „Macierze dwuwymiarowe” książki
// "Programowanie. Teoria i praktyka z wykorzystaniem C++" Bjarne'a Stroustrupa.
//

#include "Matrix.h"

using namespace Numeric_lib;

//------------------------------------------------------------------------------

int f(int a) { return a*a; }

//------------------------------------------------------------------------------

int g(int a, int b) { return a*b; }

//------------------------------------------------------------------------------

enum Piece { none, pawn, knight, queen, king, bishop, rook};

//------------------------------------------------------------------------------

void board()
{
    //enum Piece { none, pawn, knight, queen, king, bishop, rook };
    Matrix<Piece,2> board(8,8);        // szachownica

    const int white_start_row = 0;
    const int black_start_row = 7;

    //Matrix<Piece>& white_start = board[0]; // Działa w MS C++, ale nie działa w ISO C++; wiąże się z r-wartością
    //Matrix<Piece>& red_start = board[7];

    Piece a[] = { rook, knight, bishop, queen, king, bishop, knight, rook};
    Matrix<Piece> start_row(a); // = { castle, knight, bishop, queen, king, bishop, knight, castle};
    Matrix<Piece> clear_row(8);

    board[white_start_row] = start_row;    // resetuje białe figury
    for (int i = 1; i<7; ++i) board[i] = clear_row;    // czyści środek planszy
    board[black_start_row] = start_row;    // resetuje czarne figury
}

//------------------------------------------------------------------------------

int main()
{
    Matrix<int,2> a(3,4);

    int s  = a.size();    // liczba elementów
    int d1 = a.dim1();     // liczba elementów w wierszu
    int d2 = a.dim2();    // liczba elementów w kolumnie
    int* p = a.data();    // Wyodrębnia dane jako wskaźnik do tablicy w stylu języka C.

    int  i = 1;
    int  j = 2;
    int  n = 2;
    a(i,j);               // (i,j)-ty element (styl języka Fortran), ale ze sprawdzaniem zakresu
    a[i];                 // i-ty wiersz (styl języka C), ze sprawdzaniem zakresu
    a[i][j];              // (i,j)-ty element (styl języka C)

    a.slice(i);           // wiersze od elementu a[i] do ostatniego
    a.slice(i,n);         // wiersze od elementu a[i] do a[i+n–1].

    Matrix<int,2> a2 = a; // inicjowanie kopiujące
    a = a2;               // przypisanie kopiujące
    a *= 7;               // skalowanie (także +=, –=, /=, itp.)
    a.apply(f);           // a(i,j)=f(a(i,j)) dla każdego elementu a(i,j)
    a.apply(g,7);         // a(i,j)=f(a(i,j),7) dla każdego elementu a(i,j)
    Matrix<int,2> b(3,4);
    b=apply(f,a);         // Tworzy nową macierz, w której b(i,j)==f(a(i,j))
    b=apply(g,a,7);       // Tworzy nową macierz, w której b(i,j)==f(a(i,j),7)

    a.swap_rows(1,2);     // Zamienia wiersze — a[1] <–> a[2].

    board();
}

//------------------------------------------------------------------------------
