Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "SgSystem.h"
00007 #include "SgBoardConst.h"
00008
00009 #include <algorithm>
00010 #include "SgInit.h"
00011 #include "SgStack.h"
00012
00013 using namespace std;
00014 using SgPointUtil::Pt;
00015
00016
00017
00018 SgBoardConst::BoardConstImpl::BoardConstImpl(SgGrid size)
00019 : m_size(size),
00020 m_firstBoardPoint(Pt(1, 1)),
00021 m_lastBoardPoint(Pt(size, size))
00022 {
00023 m_gridToLine.Fill(0);
00024 m_gridToPos.Fill(0);
00025 m_up.Fill(0);
00026 for (SgGrid line = 0; line <= SG_MAX_SIZE / 2; ++line)
00027 m_line[line].Clear();
00028
00029
00030 m_boardIterEnd = m_boardIter;
00031 SgGrid halfSize = (m_size + 1) / 2;
00032 for (SgGrid row = 1; row <= m_size; ++row)
00033 {
00034 for (SgGrid col = 1; col <= m_size; ++col)
00035 {
00036 SgPoint p = Pt(col, row);
00037 SgGrid lineRow = row > halfSize ? m_size + 1 - row : row;
00038 SgGrid lineCol = col > halfSize ? m_size + 1 - col : col;
00039 SgGrid line = min(lineRow, lineCol);
00040 SgGrid pos = max(lineRow, lineCol);
00041 m_gridToLine[p] = line;
00042 m_gridToPos[p] = pos;
00043 m_line[line - 1].Include(p);
00044 const int MAX_EDGE = m_size > 11 ? 4 : 3;
00045 if (line <= MAX_EDGE)
00046 {
00047 if (pos <= MAX_EDGE + 1)
00048 m_corners.Include(p);
00049 else
00050 m_edges.Include(p);
00051 }
00052 else
00053 m_centers.Include(p);
00054 int nuNb = 0;
00055 if (row > 1)
00056 m_neighbors[p][nuNb++] = Pt(col, row - 1);
00057 if (col > 1)
00058 m_neighbors[p][nuNb++] = Pt(col - 1, row);
00059 if (col < m_size)
00060 m_neighbors[p][nuNb++] = Pt(col + 1, row);
00061 if (row < m_size)
00062 m_neighbors[p][nuNb++] = Pt(col, row + 1);
00063 m_neighbors[p][nuNb] = SG_ENDPOINT;
00064 *(m_boardIterEnd++) = p;
00065 }
00066 }
00067
00068
00069 for (SgPoint p = 0; p < SG_MAXPOINT; ++p)
00070 {
00071 if (m_gridToLine[p] != 0)
00072 {
00073 SgGrid line = m_gridToLine[p];
00074 if (m_gridToLine[p - SG_NS] == line + 1)
00075 m_up[p] = -SG_NS;
00076 if (m_gridToLine[p - SG_WE] == line + 1)
00077 m_up[p] = -SG_WE;
00078 if (m_gridToLine[p + SG_WE] == line + 1)
00079 m_up[p] = SG_WE;
00080 if (m_gridToLine[p + SG_NS] == line + 1)
00081 m_up[p] = SG_NS;
00082
00083
00084 if (m_up[p] == 0)
00085 {
00086 if (m_gridToLine[p - SG_NS - SG_WE] == line + 1)
00087 m_up[p] = -SG_NS - SG_WE;
00088 if (m_gridToLine[p - SG_NS + SG_WE] == line + 1)
00089 m_up[p] = -SG_NS + SG_WE;
00090 if (m_gridToLine[p + SG_NS - SG_WE] == line + 1)
00091 m_up[p] = SG_NS - SG_WE;
00092 if (m_gridToLine[p + SG_NS + SG_WE] == line + 1)
00093 m_up[p] = SG_NS + SG_WE;
00094 }
00095 }
00096 }
00097
00098
00099
00100 {
00101 for (int i = 0; i <= 2 * (SG_NS + SG_WE); ++i)
00102 {
00103 m_side[0][i] = 0;
00104 m_side[1][i] = 0;
00105 }
00106
00107
00108 m_side[0][-SG_NS + (SG_NS + SG_WE)] = -SG_WE;
00109 m_side[1][-SG_NS + (SG_NS + SG_WE)] = +SG_WE;
00110 m_side[0][-SG_WE + (SG_NS + SG_WE)] = +SG_NS;
00111 m_side[1][-SG_WE + (SG_NS + SG_WE)] = -SG_NS;
00112 m_side[0][+SG_WE + (SG_NS + SG_WE)] = -SG_NS;
00113 m_side[1][+SG_WE + (SG_NS + SG_WE)] = +SG_NS;
00114 m_side[0][+SG_NS + (SG_NS + SG_WE)] = +SG_WE;
00115 m_side[1][+SG_NS + (SG_NS + SG_WE)] = -SG_WE;
00116
00117
00118 m_side[0][-SG_NS - SG_WE + (SG_NS + SG_WE)] = -SG_WE;
00119 m_side[1][-SG_NS - SG_WE + (SG_NS + SG_WE)] = -SG_NS;
00120 m_side[0][-SG_NS + SG_WE + (SG_NS + SG_WE)] = -SG_NS;
00121 m_side[1][-SG_NS + SG_WE + (SG_NS + SG_WE)] = +SG_WE;
00122 m_side[0][+SG_NS - SG_WE + (SG_NS + SG_WE)] = +SG_NS;
00123 m_side[1][+SG_NS - SG_WE + (SG_NS + SG_WE)] = -SG_WE;
00124 m_side[0][+SG_NS + SG_WE + (SG_NS + SG_WE)] = +SG_WE;
00125 m_side[1][+SG_NS + SG_WE + (SG_NS + SG_WE)] = +SG_NS;
00126 }
00127
00128
00129 *m_boardIterEnd = SG_ENDPOINT;
00130
00131
00132 {
00133 int lineIndex = 0;
00134 for (SgGrid line = 1; line <= (SG_MAX_SIZE / 2) + 1; ++line)
00135 {
00136 m_lineIterAddress[line-1] = &m_lineIter[lineIndex];
00137 for (SgPoint p = m_firstBoardPoint; p <= m_lastBoardPoint; ++p)
00138 {
00139 if (m_gridToLine[p] == line)
00140 m_lineIter[lineIndex++] = p;
00141 }
00142 m_lineIter[lineIndex++] = SG_ENDPOINT;
00143 SG_ASSERT(lineIndex
00144 <= SG_MAX_SIZE * SG_MAX_SIZE + (SG_MAX_SIZE / 2) + 1);
00145 }
00146 SG_ASSERT(lineIndex == m_size * m_size + (SG_MAX_SIZE / 2) + 1);
00147 }
00148
00149
00150 m_cornerIter[0] = Pt(1, 1);
00151 m_cornerIter[1] = Pt(m_size, 1);
00152 m_cornerIter[2] = Pt(1, m_size);
00153 m_cornerIter[3] = Pt(m_size, m_size);
00154 m_cornerIter[4] = SG_ENDPOINT;
00155
00156 m_sideExtensions = m_line[2 - 1] | m_line[3 - 1] | m_line[4 - 1];
00157
00158
00159
00160 m_sideExtensions.Exclude(Pt(2, 2));
00161 m_sideExtensions.Exclude(Pt(2, m_size + 1 - 2));
00162 m_sideExtensions.Exclude(Pt(m_size + 1 - 2, 2));
00163 m_sideExtensions.Exclude(Pt(m_size + 1 - 2, m_size + 1 - 2));
00164 if (m_size > 2)
00165 {
00166 m_sideExtensions.Exclude(Pt(3, 3));
00167 m_sideExtensions.Exclude(Pt(3, m_size + 1 - 3));
00168 m_sideExtensions.Exclude(Pt(m_size + 1 - 3, 3));
00169 m_sideExtensions.Exclude(Pt(m_size + 1 - 3, m_size + 1 - 3));
00170 if (m_size > 3)
00171 {
00172 m_sideExtensions.Exclude(Pt(4, 4));
00173 m_sideExtensions.Exclude(Pt(4, m_size + 1 - 4));
00174 m_sideExtensions.Exclude(Pt(m_size + 1 - 4, 4));
00175 m_sideExtensions.Exclude(Pt(m_size + 1 - 4, m_size + 1 - 4));
00176 }
00177 }
00178 }
00179
00180
00181
00182 SgBoardConst::BoardConstImplArray SgBoardConst::s_const;
00183
00184 void SgBoardConst::Create(SgGrid size)
00185 {
00186 SG_ASSERT_GRIDRANGE(size);
00187 if (! s_const[size])
00188 s_const[size] =
00189 boost::shared_ptr<BoardConstImpl>(new BoardConstImpl(size));
00190 m_const = s_const[size];
00191 SG_ASSERT(m_const);
00192 }
00193
00194 SgBoardConst::SgBoardConst(SgGrid size)
00195 {
00196 SG_ASSERT_GRIDRANGE(size);
00197 SgInitCheck();
00198 Create(size);
00199 }
00200
00201 void SgBoardConst::ChangeSize(SgGrid newSize)
00202 {
00203 SG_ASSERT_GRIDRANGE(newSize);
00204 SG_ASSERT(m_const);
00205
00206 SgGrid oldSize = m_const->m_size;
00207 if (newSize != oldSize)
00208 Create(newSize);
00209 }
00210
00211
00212