Added ChessGameState, related classes and tests.
[tagua/yd.git] / tests / hlvariants / prototype / board.h
blobb07013b8364bd7e71809e4fef645a7b1a2bbf5e6
1 #ifndef HLVARIANT__BOARD_H
2 #define HLVARIANT__BOARD_H
4 #include <vector>
6 #include "point.h"
7 #include "pathinfo.h"
9 namespace HLVariant {
11 template <typename _Piece>
12 class Board {
13 public:
14 typedef _Piece Piece;
15 private:
16 Point m_size;
17 std::vector<Piece> m_data;
18 public:
19 /**
20 * Create a new Board with the given size.
22 Board(const Point& size);
24 /**
25 * Create a Board copying a given one.
27 Board(const Board<Piece>& other);
29 /**
30 * Compare two boards for equality.
32 bool operator==(const Board& other) const;
33 bool operator!=(const Board& other) const;
35 /**
36 * \return Board size.
38 Point size() const;
40 /**
41 * Retrieve a piece from the board.
42 * \param p Coordinates of the piece.
43 * \return The piece at that square, or an invalid piece, if the square is out of the board.
45 Piece get(const Point& p) const;
47 /**
48 * Add a piece to the board.
49 * \param p Coordinates of the piece.
50 * \param piece The piece to add.
51 * \note This function does nothing if @a p is out of the board.
53 void set(const Point& p, const Piece& piece);
55 /**
56 * \return Whether @a p is a valid board square.
58 bool valid(const Point& p) const;
60 /**
61 * \return Information on the path joining @a from and @a to.
63 PathInfo path(const Point& from, const Point& to) const;
66 // IMPLEMENTATION
68 template <typename Piece>
69 Board<Piece>::Board(const Point& size)
70 : m_size(size) {
71 m_data.resize(m_size.x * m_size.y);
74 template <typename Piece>
75 Board<Piece>::Board(const Board<Piece>& other)
76 : m_size(other.m_size)
77 , m_data(other.m_data) { }
79 template <typename Piece>
80 bool Board<Piece>::operator==(const Board<Piece>& other) const {
81 if (m_size != other.m_size)
82 return false;
84 const unsigned int total = m_data.size();
85 for (unsigned int i = 0; i < total; i++) {
86 if (m_data[i] != other.m_data[i])
87 return false;
90 return true;
93 template <typename Piece>
94 bool Board<Piece>::operator!=(const Board<Piece>& other) const {
95 return !((*this) == other);
98 template <typename Piece>
99 Point Board<Piece>::size() const { return m_size; }
101 template <typename Piece>
102 Piece Board<Piece>::get(const Point& p) const {
103 if (valid(p)) {
104 return m_data[p.x + p.y * m_size.x];
106 else {
107 return Piece();
111 template <typename Piece>
112 void Board<Piece>::set(const Point& p, const Piece& piece) {
113 if (valid(p)) {
114 m_data[p.x + p.y * m_size.x] = piece;
118 template <typename Piece>
119 bool Board<Piece>::valid(const Point& p) const {
120 return p.x < m_size.x &&
121 p.x >= 0 &&
122 p.y < m_size.y &&
123 p.y >= 0;
126 template <typename Piece>
127 PathInfo Board<Piece>::path(const Point& from, const Point& to) const {
128 if (!valid(from) || !valid(to))
129 return PathInfo(PathInfo::Undefined, 0);
131 Point delta = to - from;
132 PathInfo::Direction direction;
134 if (delta.x == 0)
135 direction = PathInfo::Vertical;
136 else if (delta.y == 0)
137 direction = PathInfo::Horizontal;
138 else if (delta.x == delta.y)
139 direction = PathInfo::Diagonal1;
140 else if (delta.x == -delta.y)
141 direction = PathInfo::Diagonal2;
142 else
143 direction = PathInfo::Undefined;
145 int num_obs = 0;
146 if (direction != PathInfo::Undefined) {
147 Point step = delta.normalizeInfinity();
148 Point position = from;
149 while ((position += step) != to) {
150 if (get(position) == Piece())
151 continue;
152 num_obs++;
156 return PathInfo(direction, num_obs);
161 #endif // HLVARIANT__BOARD_H