Fix Shogi::Piece::OppositeColor.
[tagua/yd.git] / src / hlvariant / board.h
blob10baadb12024cf54abe660a211a8f83987e65ba7
1 /*
2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2007 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #ifndef HLVARIANT__BOARD_H
12 #define HLVARIANT__BOARD_H
14 #include <QStringList>
15 #include <vector>
17 #include "point.h"
18 #include "pathinfo.h"
20 namespace HLVariant {
22 template <typename _Piece>
23 class Board {
24 public:
25 typedef _Piece Piece;
26 private:
27 Point m_size;
28 std::vector<Piece> m_data;
29 public:
30 /**
31 * Create a new Board with the given size.
33 Board(const Point& size);
35 /**
36 * Create a Board copying a given one.
38 Board(const Board<Piece>& other);
40 /**
41 * Compare two boards for equality.
43 bool operator==(const Board& other) const;
44 bool operator!=(const Board& other) const;
46 /**
47 * \return Board size.
49 Point size() const;
51 /**
52 * Retrieve a piece from the board.
53 * \param p Coordinates of the piece.
54 * \return The piece at that square, or an invalid piece, if the square is out of the board.
56 Piece get(const Point& p) const;
58 /**
59 * Add a piece to the board.
60 * \param p Coordinates of the piece.
61 * \param piece The piece to add.
62 * \note This function does nothing if @a p is out of the board.
64 void set(const Point& p, const Piece& piece);
66 /**
67 * \return Whether @a p is a valid board square.
69 bool valid(const Point& p) const;
71 /**
72 * \return Information on the path joining @a from and @a to.
74 PathInfo path(const Point& from, const Point& to) const;
76 /**
77 * Searches the board for a given piece.
78 * \return The first square where the piece is found, or an
79 * invalid point, if no such piece exists on the board.
81 Point find(const Piece& piece) const;
83 /**
84 * Coordinates displayed at the board border.
86 QStringList borderCoords() const;
89 // IMPLEMENTATION
91 template <typename Piece>
92 Board<Piece>::Board(const Point& size)
93 : m_size(size) {
94 m_data.resize(m_size.x * m_size.y);
97 template <typename Piece>
98 Board<Piece>::Board(const Board<Piece>& other)
99 : m_size(other.m_size)
100 , m_data(other.m_data) { }
102 template <typename Piece>
103 bool Board<Piece>::operator==(const Board<Piece>& other) const {
104 if (m_size != other.m_size)
105 return false;
107 const unsigned int total = m_data.size();
108 for (unsigned int i = 0; i < total; i++) {
109 if (m_data[i] != other.m_data[i])
110 return false;
113 return true;
116 template <typename Piece>
117 bool Board<Piece>::operator!=(const Board<Piece>& other) const {
118 return !((*this) == other);
121 template <typename Piece>
122 Point Board<Piece>::size() const { return m_size; }
124 template <typename Piece>
125 Piece Board<Piece>::get(const Point& p) const {
126 if (valid(p)) {
127 return m_data[p.x + p.y * m_size.x];
129 else {
130 return Piece();
134 template <typename Piece>
135 void Board<Piece>::set(const Point& p, const Piece& piece) {
136 if (valid(p)) {
137 m_data[p.x + p.y * m_size.x] = piece;
141 template <typename Piece>
142 bool Board<Piece>::valid(const Point& p) const {
143 return p.x < m_size.x &&
144 p.x >= 0 &&
145 p.y < m_size.y &&
146 p.y >= 0;
149 template <typename Piece>
150 PathInfo Board<Piece>::path(const Point& from, const Point& to) const {
151 if (!valid(from) || !valid(to))
152 return PathInfo(PathInfo::Undefined, 0);
154 Point delta = to - from;
155 PathInfo::Direction direction;
157 if (delta.x == 0)
158 direction = PathInfo::Vertical;
159 else if (delta.y == 0)
160 direction = PathInfo::Horizontal;
161 else if (delta.x == delta.y)
162 direction = PathInfo::Diagonal1;
163 else if (delta.x == -delta.y)
164 direction = PathInfo::Diagonal2;
165 else
166 direction = PathInfo::Undefined;
168 int num_obs = 0;
169 if (direction != PathInfo::Undefined) {
170 Point step = delta.normalizeInfinity();
171 Point position = from;
172 while ((position += step) != to) {
173 if (get(position) == Piece())
174 continue;
175 num_obs++;
179 return PathInfo(direction, num_obs);
182 template <typename Piece>
183 Point Board<Piece>::find(const Piece& piece) const {
184 for (int i = 0; i < m_size.x; i++) {
185 for (int j = 0; j < m_size.y; j++) {
186 Point p(i, j);
187 if (get(p) == piece)
188 return p;
192 return Point::invalid();
195 template <typename Piece>
196 QStringList Board<Piece>::borderCoords() const {
197 QStringList retv;
198 Point p = size();
199 for (int i = 0; i < p.x; i++)
200 retv << Point(i, 0).col();
201 for (int i = 1; i <= p.y; i++)
202 retv << QString::number(i);
203 return retv + retv;
208 #endif // HLVARIANT__BOARD_H