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