Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "SgSystem.h"
00007 #include "SpDumbTacticalPlayer.h"
00008
00009 #include "GoBensonSolver.h"
00010 #include "GoBoardUtil.h"
00011 #include "GoLadder.h"
00012 #include "GoModBoard.h"
00013 #include "SgEvaluatedMoves.h"
00014 #include "SgNbIterator.h"
00015
00016 using GoLadderUtil::LadderStatus;
00017
00018
00019
00020 SpDumbTacticalMoveGenerator::SpDumbTacticalMoveGenerator(const GoBoard& board)
00021 : SpStaticMoveGenerator(board), m_useLadders(false)
00022 { }
00023
00024 int SpDumbTacticalMoveGenerator::Score(SgPoint p)
00025 {
00026 SG_UNUSED(p);
00027
00028
00029 SG_ASSERT(false);
00030 return INT_MIN;
00031 }
00032
00033 void SpDumbTacticalMoveGenerator::GenerateMoves(SgEvaluatedMoves& eval,
00034 SgBlackWhite toPlay)
00035 {
00036 GoModBoard modBoard(m_board);
00037 GoBoard& bd = modBoard.Board();
00038 GoRestoreToPlay restoreToPlay(bd);
00039 bd.SetToPlay(toPlay);
00040
00041 GoRestoreSuicide restoreSuicide(bd, false);
00042 GenerateDefendMoves(eval);
00043 GenerateAttackMoves(eval);
00044
00045
00046
00047 }
00048
00049 void SpDumbTacticalMoveGenerator::GenerateDefendMoves(SgEvaluatedMoves& eval)
00050 {
00051 const int stoneweight = 1000;
00052
00053 for (GoBlockIterator anchorit(m_board); anchorit; ++anchorit)
00054 {
00055
00056 if (m_board.IsColor(*anchorit, m_board.Opponent()))
00057 continue;
00058
00059
00060 if (! m_board.InAtari(*anchorit))
00061 continue;
00062
00063
00064 if (m_useLadders)
00065 {
00066 GoLadderStatus status = LadderStatus(m_board, *anchorit, false);
00067 if (status == GO_LADDER_CAPTURED)
00068 continue;
00069 }
00070
00071 int score = stoneweight * m_board.NumStones(*anchorit);
00072
00073
00074 eval.AddMove(m_board.TheLiberty(*anchorit), score);
00075
00076
00077 for (GoAdjBlockIterator<GoBoard> adjbit(m_board, *anchorit, 1);
00078 adjbit; ++adjbit)
00079 {
00080 int bonus = stoneweight * m_board.NumStones(*adjbit);
00081 if (m_board.InAtari(*adjbit))
00082
00083 {
00084 eval.AddMove(m_board.TheLiberty(*adjbit), score + bonus);
00085 }
00086 }
00087 }
00088 }
00089
00090 void SpDumbTacticalMoveGenerator::GenerateAttackMoves(SgEvaluatedMoves& eval)
00091 {
00092 const int capturestoneweight = 100;
00093 const int firstlibweight = 100;
00094 const int secondlibweight = 20;
00095 const int stoneweight = 1;
00096
00097
00098 SgBWSet safepoints;
00099 GoModBoard modBoard(m_board);
00100 GoBoard& bd = modBoard.Board();
00101 GoBensonSolver benson(bd);
00102 benson.FindSafePoints(&safepoints);
00103
00104
00105 for (GoBlockIterator anchorit(bd); anchorit; ++anchorit)
00106 {
00107
00108 if (bd.IsColor(*anchorit, bd.ToPlay()))
00109 continue;
00110
00111
00112 if (safepoints[bd.Opponent()].Contains(*anchorit))
00113 continue;
00114
00115
00116 if (m_useLadders)
00117 {
00118 SgPoint tocapture, toescape;
00119 GoLadderStatus status = LadderStatus(bd, *anchorit, false,
00120 &tocapture, &toescape);
00121 if (status == GO_LADDER_CAPTURED)
00122 {
00123 int score = bd.NumStones(*anchorit) * capturestoneweight;
00124 eval.AddMove(tocapture, score);
00125 }
00126 }
00127
00128
00129
00130
00131
00132
00133 int firstlibs = bd.NumLiberties(*anchorit);
00134 int size = bd.NumStones(*anchorit);
00135 for (GoBoard::LibertyIterator libit(bd, *anchorit); libit;
00136 ++libit)
00137 {
00138 int secondlibs = 0;
00139 for (SgNb4Iterator nbit(*libit); nbit; ++nbit)
00140 {
00141 if (bd.IsValidPoint(*nbit) && bd.IsEmpty(*nbit))
00142 {
00143 secondlibs++;
00144 }
00145 }
00146 int score = size * stoneweight
00147 + secondlibs * secondlibweight
00148 - firstlibs * firstlibweight;
00149 eval.AddMove(*libit, score);
00150 }
00151 }
00152 }
00153
00154