00001
00002
00003
00004
00005
00006
00007 #ifndef GOUCT_BOARD_H
00008 #define GOUCT_BOARD_H
00009
00010 #include <bitset>
00011 #include <cstring>
00012 #include <stdint.h>
00013 #include <boost/static_assert.hpp>
00014 #include "GoBoard.h"
00015 #include "GoBoardUtil.h"
00016 #include "GoPlayerMove.h"
00017 #include "SgArray.h"
00018 #include "SgBoardConst.h"
00019 #include "SgBoardColor.h"
00020 #include "SgMarker.h"
00021 #include "SgBWArray.h"
00022 #include "SgNbIterator.h"
00023 #include "SgPoint.h"
00024 #include "SgPointArray.h"
00025 #include "SgPointIterator.h"
00026 #include "SgSList.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 class GoUctBoard
00043 {
00044 public:
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 mutable SgMarker m_userMarker;
00055
00056 explicit GoUctBoard(const GoBoard& bd);
00057
00058 ~GoUctBoard();
00059
00060 const SgBoardConst& BoardConst() const;
00061
00062
00063 void Init(const GoBoard& bd);
00064
00065
00066 SgGrid Size() const;
00067
00068
00069
00070
00071 bool Occupied(SgPoint p) const;
00072
00073 bool IsEmpty(SgPoint p) const;
00074
00075 bool IsBorder(SgPoint p) const;
00076
00077 bool IsColor(SgPoint p, int c) const;
00078
00079 SgBoardColor GetColor(SgPoint p) const;
00080
00081 SgBlackWhite GetStone(SgPoint p) const;
00082
00083
00084 SgBlackWhite ToPlay() const;
00085
00086
00087 SgBlackWhite Opponent() const;
00088
00089
00090 SgGrid Line(SgPoint p) const;
00091
00092
00093 SgGrid Pos(SgPoint p) const;
00094
00095
00096
00097
00098
00099 int Up(SgPoint p) const;
00100
00101
00102
00103
00104
00105
00106 int Left(SgPoint p) const;
00107
00108
00109
00110
00111 int Right(SgPoint p) const;
00112
00113
00114 int Side(SgPoint p, int index) const;
00115
00116 bool IsSuicide(SgPoint p, SgBlackWhite toPlay) const;
00117
00118 bool IsValidPoint(SgPoint p) const;
00119
00120 bool HasEmptyNeighbors(SgPoint p) const;
00121
00122 int NumEmptyNeighbors(SgPoint p) const;
00123
00124
00125 int Num8EmptyNeighbors(SgPoint p) const;
00126
00127 bool HasNeighbors(SgPoint p, SgBlackWhite c) const;
00128
00129 int NumNeighbors(SgPoint p, SgBlackWhite c) const;
00130
00131
00132 int Num8Neighbors(SgPoint p, SgBlackWhite c) const;
00133
00134 bool HasDiagonals(SgPoint p, SgBoardColor c) const;
00135
00136 int NumDiagonals(SgPoint p, SgBoardColor c) const;
00137
00138 int NumEmptyDiagonals(SgPoint p) const;
00139
00140 bool HasNeighborsOrDiags(SgPoint p, SgBlackWhite c) const;
00141
00142 bool InCorner(SgPoint p) const;
00143
00144 bool OnEdge(SgPoint p) const;
00145
00146 bool InCenter(SgPoint p) const;
00147
00148
00149 int FirstBoardPoint() const;
00150
00151
00152 int LastBoardPoint() const;
00153
00154
00155
00156
00157 void Play(SgPoint p);
00158
00159
00160
00161
00162
00163
00164 bool IsLegal(int p, SgBlackWhite player) const;
00165
00166
00167
00168
00169 bool IsLegal(int p) const;
00170
00171 bool IsSuicide(SgPoint p) const;
00172
00173
00174 bool CapturingMove() const;
00175
00176
00177
00178
00179
00180 const GoPointList& CapturedStones() const;
00181
00182
00183
00184
00185 int NuCapturedStones() const;
00186
00187
00188
00189 int NumPrisoners(SgBlackWhite color) const;
00190
00191
00192
00193
00194
00195
00196 SgPoint GetLastMove() const;
00197
00198
00199
00200
00201 SgPoint Get2ndLastMove() const;
00202
00203
00204
00205
00206 int NumStones(SgPoint p) const;
00207
00208
00209 bool IsSingleStone(SgPoint p) const;
00210
00211
00212
00213
00214 bool AreInSameBlock(SgPoint stone1, SgPoint stone2) const;
00215
00216
00217
00218
00219
00220
00221
00222 SgPoint Anchor(SgPoint p) const;
00223
00224
00225 bool IsInBlock(SgPoint p, SgPoint anchor) const;
00226
00227
00228 bool IsLibertyOfBlock(SgPoint p, SgPoint anchor) const;
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 int AdjacentBlocks(SgPoint p, int maxLib, SgPoint anchors[],
00241 int maxAnchors) const;
00242
00243
00244
00245
00246
00247
00248 void NeighborBlocks(SgPoint p, SgBlackWhite c, SgPoint anchors[]) const;
00249
00250
00251
00252
00253
00254
00255 void NeighborBlocks(SgPoint p, SgBlackWhite c, int maxLib,
00256 SgPoint anchors[]) const;
00257
00258
00259
00260
00261 SgPoint TheLiberty(SgPoint blockInAtari) const;
00262
00263
00264
00265
00266 int NumLiberties(SgPoint p) const;
00267
00268
00269 bool AtMostNumLibs(SgPoint block, int n) const;
00270
00271
00272 bool AtLeastNumLibs(SgPoint block, int n) const;
00273
00274
00275
00276
00277 bool InAtari(SgPoint p) const;
00278
00279
00280
00281
00282
00283 bool OccupiedInAtari(SgPoint p) const;
00284
00285
00286
00287
00288 bool CanCapture(SgPoint p, SgBlackWhite c) const;
00289
00290
00291
00292
00293 void CheckConsistency() const;
00294
00295 private:
00296
00297 struct Block
00298 {
00299 public:
00300
00301
00302
00303 static const int MAX_LIBERTIES = (SG_MAX_SIZE / 3) * 2 * SG_MAX_SIZE;
00304
00305 typedef SgSList<SgPoint,MAX_LIBERTIES> LibertyList;
00306
00307 typedef LibertyList::Iterator LibertyIterator;
00308
00309 typedef GoPointList::Iterator StoneIterator;
00310
00311 SgPoint m_anchor;
00312
00313 SgBlackWhite m_color;
00314
00315 LibertyList m_liberties;
00316
00317 GoPointList m_stones;
00318
00319 void InitSingleStoneBlock(SgBlackWhite c, SgPoint anchor)
00320 {
00321 SG_ASSERT_BW(c);
00322 m_color = c;
00323 m_anchor = anchor;
00324 m_stones.SetTo(anchor);
00325 m_liberties.Clear();
00326 }
00327
00328 void InitNewBlock(SgBlackWhite c, SgPoint anchor)
00329 {
00330 SG_ASSERT_BW(c);
00331 m_color = c;
00332 m_anchor = anchor;
00333 m_stones.Clear();
00334 m_liberties.Clear();
00335 }
00336 };
00337
00338 SgPoint m_lastMove;
00339
00340 SgPoint m_secondLastMove;
00341
00342
00343 SgPoint m_koPoint;
00344
00345
00346 SgBlackWhite m_toPlay;
00347
00348 SgArray<Block*,SG_MAXPOINT> m_block;
00349
00350
00351 SgBWArray<int> m_prisoners;
00352
00353
00354 SgArray<int,SG_MAXPOINT> m_color;
00355
00356
00357 SgArray<int,SG_MAXPOINT> m_nuNeighborsEmpty;
00358
00359
00360 SgBWArray<SgArray<int,SG_MAXPOINT> > m_nuNeighbors;
00361
00362
00363 SgBoardConst m_const;
00364
00365
00366 SgGrid m_size;
00367
00368 SgPointArray<Block> m_blockArray;
00369
00370 mutable SgMarker m_marker;
00371
00372 SgMarker m_marker2;
00373
00374 GoPointList m_capturedStones;
00375
00376 SgArray<bool,SG_MAXPOINT> m_isBorder;
00377
00378
00379 GoUctBoard(const GoUctBoard&);
00380
00381
00382 GoUctBoard& operator=(const GoUctBoard&);
00383
00384 void AddLibToAdjBlocks(SgPoint p, SgBlackWhite c);
00385
00386 void AddStoneToBlock(SgPoint p, Block* block);
00387
00388 void CreateSingleStoneBlock(SgPoint p, SgBlackWhite c);
00389
00390 void InitSize(const GoBoard& bd);
00391
00392 bool IsAdjacentTo(SgPoint p, const Block* block) const;
00393
00394 void MergeBlocks(SgPoint p, const SgSList<Block*,4>& adjBlocks);
00395
00396 void RemoveLibAndKill(SgPoint p, SgBlackWhite opp,
00397 SgSList<Block*,4>& ownAdjBlocks);
00398
00399 void UpdateBlocksAfterAddStone(SgPoint p, SgBlackWhite c,
00400 const SgSList<Block*,4>& adjBlocks);
00401
00402 void CheckConsistencyBlock(SgPoint p) const;
00403
00404 bool FullBoardRepetition() const;
00405
00406 void AddStone(SgPoint p, SgBlackWhite c);
00407
00408 void KillBlock(const Block* block);
00409
00410 bool HasLiberties(SgPoint p) const;
00411
00412 public:
00413 friend class LibertyIterator;
00414 friend class StoneIterator;
00415
00416
00417 class Iterator
00418 : public SgPointRangeIterator
00419 {
00420 public:
00421 Iterator(const GoUctBoard& bd);
00422 };
00423
00424
00425
00426
00427
00428
00429 class LibertyIterator
00430 {
00431 public:
00432 LibertyIterator(const GoUctBoard& bd, SgPoint p);
00433
00434
00435 void operator++();
00436
00437
00438 SgPoint operator*() const;
00439
00440
00441 operator bool() const;
00442
00443 private:
00444 GoUctBoard::Block::LibertyList::Iterator m_it;
00445
00446 const GoUctBoard& m_board;
00447
00448
00449 LibertyIterator(const LibertyIterator&);
00450
00451
00452 LibertyIterator& operator=(const LibertyIterator&);
00453 };
00454
00455
00456
00457
00458
00459 class StoneIterator
00460 {
00461 public:
00462 StoneIterator(const GoUctBoard& bd, SgPoint p);
00463
00464
00465 void operator++();
00466
00467
00468 SgPoint operator*() const;
00469
00470
00471 operator bool() const;
00472
00473 private:
00474 GoUctBoard::Block::StoneIterator m_it;
00475
00476 const GoUctBoard& m_board;
00477
00478
00479 StoneIterator(const StoneIterator&);
00480
00481
00482 StoneIterator& operator=(const StoneIterator&);
00483 };
00484 };
00485
00486 inline std::ostream& operator<<(std::ostream& out, const GoUctBoard& bd)
00487 {
00488 return GoWriteBoard(out, bd);
00489 }
00490
00491 inline GoUctBoard::Iterator::Iterator(const GoUctBoard& bd)
00492 : SgPointRangeIterator(bd.BoardConst().BoardIterAddress(),
00493 bd.BoardConst().BoardIterEnd())
00494 {
00495 }
00496
00497 inline GoUctBoard::LibertyIterator::LibertyIterator(const GoUctBoard& bd,
00498 SgPoint p)
00499 : m_it(bd.m_block[p]->m_liberties),
00500 m_board(bd)
00501 {
00502 SG_ASSERT(m_board.Occupied(p));
00503 }
00504
00505 inline void GoUctBoard::LibertyIterator::operator++()
00506 {
00507 ++m_it;
00508 }
00509
00510 inline SgPoint GoUctBoard::LibertyIterator::operator*() const
00511 {
00512 return *m_it;
00513 }
00514
00515 inline GoUctBoard::LibertyIterator::operator bool() const
00516 {
00517 return m_it;
00518 }
00519
00520 inline GoUctBoard::StoneIterator::StoneIterator(const GoUctBoard& bd,
00521 SgPoint p)
00522 : m_it(bd.m_block[p]->m_stones),
00523 m_board(bd)
00524 {
00525 SG_ASSERT(m_board.Occupied(p));
00526 }
00527
00528 inline void GoUctBoard::StoneIterator::operator++()
00529 {
00530 ++m_it;
00531 }
00532
00533 inline SgPoint GoUctBoard::StoneIterator::operator*() const
00534 {
00535 return *m_it;
00536 }
00537
00538 inline GoUctBoard::StoneIterator::operator bool() const
00539 {
00540 return m_it;
00541 }
00542
00543 inline int GoUctBoard::AdjacentBlocks(SgPoint point, int maxLib,
00544 SgPoint anchors[], int maxAnchors) const
00545 {
00546 SG_DEBUG_ONLY(maxAnchors);
00547 SG_ASSERT(Occupied(point));
00548 const SgBlackWhite other = SgOppBW(GetStone(point));
00549 int n = 0;
00550 SgReserveMarker reserve(m_marker);
00551 SG_UNUSED(reserve);
00552 m_marker.Clear();
00553 for (StoneIterator it(*this, point); it; ++it)
00554 {
00555 if (NumNeighbors(*it, other) > 0)
00556 {
00557 SgPoint p = *it;
00558 if (IsColor(p - SG_NS, other)
00559 && m_marker.NewMark(Anchor(p - SG_NS))
00560 && AtMostNumLibs(p - SG_NS, maxLib))
00561 anchors[n++] = Anchor(p - SG_NS);
00562 if (IsColor(p - SG_WE, other)
00563 && m_marker.NewMark(Anchor(p - SG_WE))
00564 && AtMostNumLibs(p - SG_WE, maxLib))
00565 anchors[n++] = Anchor(p - SG_WE);
00566 if (IsColor(p + SG_WE, other)
00567 && m_marker.NewMark(Anchor(p + SG_WE))
00568 && AtMostNumLibs(p + SG_WE, maxLib))
00569 anchors[n++] = Anchor(p + SG_WE);
00570 if (IsColor(p + SG_NS, other)
00571 && m_marker.NewMark(Anchor(p + SG_NS))
00572 && AtMostNumLibs(p + SG_NS, maxLib))
00573 anchors[n++] = Anchor(p + SG_NS);
00574 }
00575 };
00576
00577 SG_ASSERT(n < maxAnchors);
00578 anchors[n] = SG_ENDPOINT;
00579 return n;
00580 }
00581
00582 inline SgPoint GoUctBoard::Anchor(SgPoint p) const
00583 {
00584 SG_ASSERT(Occupied(p));
00585 return m_block[p]->m_anchor;
00586 }
00587
00588 inline bool GoUctBoard::AreInSameBlock(SgPoint p1, SgPoint p2) const
00589 {
00590 return Occupied(p1) && Occupied(p2) && Anchor(p1) == Anchor(p2);
00591 }
00592
00593 inline bool GoUctBoard::AtLeastNumLibs(SgPoint block, int n) const
00594 {
00595 return NumLiberties(block) >= n;
00596 }
00597
00598 inline bool GoUctBoard::AtMostNumLibs(SgPoint block, int n) const
00599 {
00600 return NumLiberties(block) <= n;
00601 }
00602
00603 inline const GoPointList& GoUctBoard::CapturedStones() const
00604 {
00605 return m_capturedStones;
00606 }
00607
00608 inline bool GoUctBoard::CapturingMove() const
00609 {
00610 return ! m_capturedStones.IsEmpty();
00611 }
00612
00613 inline int GoUctBoard::FirstBoardPoint() const
00614 {
00615 return m_const.FirstBoardPoint();
00616 }
00617
00618 inline const SgBoardConst& GoUctBoard::BoardConst() const
00619 {
00620 return m_const;
00621 }
00622
00623 inline SgPoint GoUctBoard::Get2ndLastMove() const
00624 {
00625 return m_secondLastMove;
00626 }
00627
00628 inline SgBoardColor GoUctBoard::GetColor(SgPoint p) const
00629 {
00630 return m_color[p];
00631 }
00632
00633 inline SgPoint GoUctBoard::GetLastMove() const
00634 {
00635 return m_lastMove;
00636 }
00637
00638 inline SgBlackWhite GoUctBoard::GetStone(SgPoint p) const
00639 {
00640 SG_ASSERT(Occupied(p));
00641 return m_color[p];
00642 }
00643
00644 inline bool GoUctBoard::HasDiagonals(SgPoint p, SgBoardColor c) const
00645 {
00646 return (IsColor(p - SG_NS - SG_WE, c)
00647 || IsColor(p - SG_NS + SG_WE, c)
00648 || IsColor(p + SG_NS - SG_WE, c)
00649 || IsColor(p + SG_NS + SG_WE, c));
00650 }
00651
00652 inline bool GoUctBoard::HasEmptyNeighbors(SgPoint p) const
00653 {
00654 return m_nuNeighborsEmpty[p] != 0;
00655 }
00656
00657 inline bool GoUctBoard::HasLiberties(SgPoint p) const
00658 {
00659 return NumLiberties(p) > 0;
00660 }
00661
00662 inline bool GoUctBoard::HasNeighbors(SgPoint p, SgBlackWhite c) const
00663 {
00664 return (m_nuNeighbors[c][p] > 0);
00665 }
00666
00667 inline bool GoUctBoard::HasNeighborsOrDiags(SgPoint p, SgBlackWhite c) const
00668 {
00669 return HasNeighbors(p, c) || HasDiagonals(p, c);
00670 }
00671
00672 inline bool GoUctBoard::InAtari(SgPoint p) const
00673 {
00674 SG_ASSERT(Occupied(p));
00675 return AtMostNumLibs(p, 1);
00676 }
00677
00678 inline bool GoUctBoard::IsInBlock(SgPoint p, SgPoint anchor) const
00679 {
00680 SG_ASSERT(Occupied(anchor));
00681 const Block* b = m_block[p];
00682 return (b != 0 && b->m_anchor == anchor);
00683 }
00684
00685 inline bool GoUctBoard::IsLibertyOfBlock(SgPoint p, SgPoint anchor) const
00686 {
00687 SG_ASSERT(IsEmpty(p));
00688 SG_ASSERT(Occupied(anchor));
00689 SG_ASSERT(Anchor(anchor) == anchor);
00690 const Block* b = m_block[anchor];
00691 if (m_nuNeighbors[b->m_color][p] == 0)
00692 return false;
00693 return ( m_block[p - SG_NS] == b
00694 || m_block[p - SG_WE] == b
00695 || m_block[p + SG_WE] == b
00696 || m_block[p + SG_NS] == b);
00697 }
00698
00699 inline bool GoUctBoard::CanCapture(SgPoint p, SgBlackWhite c) const
00700 {
00701 SgBlackWhite opp = SgOppBW(c);
00702 for (SgNb4Iterator nb(p); nb; ++nb)
00703 if (IsColor(*nb, opp) && AtMostNumLibs(*nb, 1))
00704 return true;
00705 return false;
00706 }
00707
00708 inline bool GoUctBoard::IsSuicide(SgPoint p, SgBlackWhite toPlay) const
00709 {
00710 if (HasEmptyNeighbors(p))
00711 return false;
00712 SgBlackWhite opp = SgOppBW(toPlay);
00713 for (SgNb4Iterator it(p); it; ++it)
00714 {
00715 if (IsBorder(*it))
00716 continue;
00717 SgEmptyBlackWhite c = GetColor(*it);
00718 if (c == toPlay && NumLiberties(*it) > 1)
00719 return false;
00720 if (c == opp && NumLiberties(*it) == 1)
00721 return false;
00722 }
00723 return true;
00724 }
00725
00726 inline bool GoUctBoard::IsBorder(SgPoint p) const
00727 {
00728 SG_ASSERT(p != SG_PASS);
00729 return m_isBorder[p];
00730 }
00731
00732 inline bool GoUctBoard::IsColor(SgPoint p, int c) const
00733 {
00734 SG_ASSERT(p != SG_PASS);
00735 SG_ASSERT_EBW(c);
00736 return m_color[p] == c;
00737 }
00738
00739 inline bool GoUctBoard::IsEmpty(SgPoint p) const
00740 {
00741 SG_ASSERT(p != SG_PASS);
00742 return m_color[p] == SG_EMPTY;
00743 }
00744
00745 inline bool GoUctBoard::IsLegal(int p, SgBlackWhite player) const
00746 {
00747 SG_ASSERT_BW(player);
00748 if (p == SG_PASS)
00749 return true;
00750 SG_ASSERT(SgPointUtil::InBoardRange(p));
00751 if (! IsEmpty(p))
00752 return false;
00753
00754 if (IsSuicide(p, player))
00755 return false;
00756
00757 if (p == m_koPoint && m_toPlay == player)
00758 return false;
00759 return true;
00760 }
00761
00762 inline bool GoUctBoard::IsLegal(int p) const
00763 {
00764 return IsLegal(p, ToPlay());
00765 }
00766
00767 inline bool GoUctBoard::IsSingleStone(SgPoint p) const
00768 {
00769 return (Occupied(p) && NumNeighbors(p, GetColor(p)) == 0);
00770 }
00771
00772 inline bool GoUctBoard::IsSuicide(SgPoint p) const
00773 {
00774 return IsSuicide(p, ToPlay());
00775 }
00776
00777 inline bool GoUctBoard::IsValidPoint(SgPoint p) const
00778 {
00779 return SgPointUtil::InBoardRange(p) && ! IsBorder(p);
00780 }
00781
00782 inline int GoUctBoard::LastBoardPoint() const
00783 {
00784 return m_const.LastBoardPoint();
00785 }
00786
00787 inline int GoUctBoard::Left(SgPoint p) const
00788 {
00789 return m_const.Left(p);
00790 }
00791
00792 inline SgGrid GoUctBoard::Line(SgPoint p) const
00793 {
00794 return m_const.Line(p);
00795 }
00796
00797 inline void GoUctBoard::NeighborBlocks(SgPoint p, SgBlackWhite c, int maxLib,
00798 SgPoint anchors[]) const
00799 {
00800 SG_ASSERT(IsEmpty(p));
00801 SgReserveMarker reserve(m_marker);
00802 SG_UNUSED(reserve);
00803 m_marker.Clear();
00804 int i = 0;
00805 if (NumNeighbors(p, c) > 0)
00806 {
00807 if (IsColor(p - SG_NS, c) && m_marker.NewMark(Anchor(p - SG_NS))
00808 && AtMostNumLibs(p - SG_NS, maxLib))
00809 anchors[i++] = Anchor(p - SG_NS);
00810 if (IsColor(p - SG_WE, c) && m_marker.NewMark(Anchor(p - SG_WE))
00811 && AtMostNumLibs(p - SG_WE, maxLib))
00812 anchors[i++] = Anchor(p - SG_WE);
00813 if (IsColor(p + SG_WE, c) && m_marker.NewMark(Anchor(p + SG_WE))
00814 && AtMostNumLibs(p + SG_WE, maxLib))
00815 anchors[i++] = Anchor(p + SG_WE);
00816 if (IsColor(p + SG_NS, c) && m_marker.NewMark(Anchor(p + SG_NS))
00817 && AtMostNumLibs(p + SG_NS, maxLib))
00818 anchors[i++] = Anchor(p + SG_NS);
00819 }
00820 anchors[i] = SG_ENDPOINT;
00821 }
00822
00823 inline int GoUctBoard::Num8Neighbors(SgPoint p, SgBlackWhite c) const
00824 {
00825 return NumNeighbors(p, c) + NumDiagonals(p, c);
00826 }
00827
00828 inline int GoUctBoard::Num8EmptyNeighbors(SgPoint p) const
00829 {
00830 return NumEmptyNeighbors(p) + NumEmptyDiagonals(p);
00831 }
00832
00833 inline int GoUctBoard::NuCapturedStones() const
00834 {
00835 return m_capturedStones.Length();
00836 }
00837
00838 inline int GoUctBoard::NumDiagonals(SgPoint p, SgBoardColor c) const
00839 {
00840 int n = 0;
00841 if (IsColor(p - SG_NS - SG_WE, c))
00842 ++n;
00843 if (IsColor(p - SG_NS + SG_WE, c))
00844 ++n;
00845 if (IsColor(p + SG_NS - SG_WE, c))
00846 ++n;
00847 if (IsColor(p + SG_NS + SG_WE, c))
00848 ++n;
00849 return n;
00850 }
00851
00852 inline int GoUctBoard::NumEmptyDiagonals(SgPoint p) const
00853 {
00854 return NumDiagonals(p, SG_EMPTY);
00855 }
00856
00857 inline int GoUctBoard::NumEmptyNeighbors(SgPoint p) const
00858 {
00859 return m_nuNeighborsEmpty[p];
00860 }
00861
00862 inline int GoUctBoard::NumLiberties(SgPoint p) const
00863 {
00864 SG_ASSERT(IsValidPoint(p));
00865 SG_ASSERT(Occupied(p));
00866 return m_block[p]->m_liberties.Length();
00867 }
00868
00869 inline int GoUctBoard::NumNeighbors(SgPoint p, SgBlackWhite c) const
00870 {
00871 return m_nuNeighbors[c][p];
00872 }
00873
00874 inline int GoUctBoard::NumPrisoners(SgBlackWhite color) const
00875 {
00876 return m_prisoners[color];
00877 }
00878
00879 inline int GoUctBoard::NumStones(SgPoint block) const
00880 {
00881 SG_ASSERT(Occupied(block));
00882 return m_block[block]->m_stones.Length();
00883 }
00884
00885 inline bool GoUctBoard::Occupied(SgPoint p) const
00886 {
00887 return (m_block[p] != 0);
00888 }
00889
00890 inline bool GoUctBoard::OccupiedInAtari(SgPoint p) const
00891 {
00892 const Block* b = m_block[p];
00893 return (b != 0 && b->m_liberties.Length() <= 1);
00894 }
00895
00896 inline SgBlackWhite GoUctBoard::Opponent() const
00897 {
00898 return SgOppBW(m_toPlay);
00899 }
00900
00901 inline SgGrid GoUctBoard::Pos(SgPoint p) const
00902 {
00903 return m_const.Pos(p);
00904 }
00905
00906 inline int GoUctBoard::Right(SgPoint p) const
00907 {
00908 return m_const.Right(p);
00909 }
00910
00911 inline int GoUctBoard::Side(SgPoint p, int index) const
00912 {
00913 return m_const.Side(p, index);
00914 }
00915
00916 inline SgGrid GoUctBoard::Size() const
00917 {
00918 return m_size;
00919 }
00920
00921 inline SgPoint GoUctBoard::TheLiberty(SgPoint p) const
00922 {
00923 SG_ASSERT(Occupied(p));
00924 SG_ASSERT(NumLiberties(p) == 1);
00925 return m_block[p]->m_liberties[0];
00926 }
00927
00928 inline SgBlackWhite GoUctBoard::ToPlay() const
00929 {
00930 return m_toPlay;
00931 }
00932
00933 inline int GoUctBoard::Up(SgPoint p) const
00934 {
00935 return m_const.Up(p);
00936 }
00937
00938
00939
00940 #endif // GOUCT_BOARD_H
00941