本文整理汇总了C#中State.GetMoves方法的典型用法代码示例。如果您正苦于以下问题:C# State.GetMoves方法的具体用法?C# State.GetMoves怎么用?C# State.GetMoves使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类State
的用法示例。
在下文中一共展示了State.GetMoves方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: ExpectimaxAlgorithm
// Classic Expectimax search
public Move ExpectimaxAlgorithm(State state, int depth, WeightVector weights)
{
Move bestMove;
if (depth == 0 || state.IsGameOver())
{
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return bestMove;
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return bestMove;
}
else throw new Exception();
}
if (state.Player == GameEngine.PLAYER) // AI's turn
{
bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = ExpectimaxAlgorithm(resultingState, depth - 1, weights).Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
}
bestMove.Score = highestScore;
return bestMove;
}
else if (state.Player == GameEngine.COMPUTER) // computer's turn (the random event node)
{
bestMove = new ComputerMove();
// return the weighted average of all the child nodes's scores
double average = 0;
List<Cell> availableCells = state.GetAvailableCells();
List<Move> moves = state.GetAllComputerMoves(availableCells);
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
average += StateProbability(((ComputerMove)move).Tile) * ExpectimaxAlgorithm(resultingState, depth - 1, weights).Score;
}
bestMove.Score = average / moves.Count;
return bestMove;
}
else throw new Exception();
}
示例2: ParallelIterativeDeepening
// Runs a parallel version of iterative deepening
// A search is started in a separate thread for each child of root node
private Move ParallelIterativeDeepening(State state, double timeLimit)
{
Move bestMove = new PlayerMove();
List<Move> moves = state.GetMoves();
ConcurrentBag<Tuple<double, Move>> scores = new ConcurrentBag<Tuple<double, Move>>();
if (moves.Count == 0)
{
// game over
return bestMove;
}
// create the resulting states before starting the threads
List<State> resultingStates = new List<State>();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
resultingStates.Add(resultingState);
}
Parallel.ForEach(resultingStates, resultingState =>
{
double score = IterativeDeepening(resultingState, timeLimit).Score;
scores.Add(new Tuple<double, Move>(score, resultingState.GeneratingMove));
});
// find the best score
double highestScore = Double.MinValue;
foreach (Tuple<double, Move> score in scores)
{
PlayerMove move = (PlayerMove)score.Item2;
if (score.Item1 > highestScore)
{
highestScore = score.Item1;
bestMove = score.Item2;
}
}
return bestMove;
}
示例3: MinimaxAlgorithm
// Standard Minimax search with no pruning
Move MinimaxAlgorithm(State state, int depth)
{
Move bestMove;
if (depth == 0 || state.IsGameOver())
{
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove();
bestMove.Score = AI.Evaluate(state);
return bestMove;
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove();
bestMove.Score = AI.Evaluate(state);
return bestMove;
}
else throw new Exception();
}
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = MinimaxAlgorithm(resultingState, depth - 1).Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
}
bestMove.Score = highestScore;
return bestMove;
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove();
double lowestScore = Double.MaxValue, currentScore = Double.MaxValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = MinimaxAlgorithm(resultingState, depth - 1).Score;
if (currentScore < lowestScore)
{
lowestScore = currentScore;
bestMove = move;
}
}
bestMove.Score = lowestScore;
return bestMove;
}
else throw new Exception();
}
示例4: Min
// MIN part of Minimax (with alpha-beta pruning)
Move Min(State state, int depth, double alpha, double beta)
{
Move bestMove = new ComputerMove();
double lowestScore = Double.MaxValue, currentScore = Double.MaxValue;
List<Move> moves = state.GetMoves();
if (debug)
logger.writeParent(state, chosenDepth - depth);
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = AlphaBeta(resultingState, depth - 1, alpha, beta).Score;
if (debug)
logger.writeChild(resultingState, chosenDepth - depth, currentScore);
if (currentScore < lowestScore)
{
lowestScore = currentScore;
bestMove = move;
}
beta = Math.Min(beta, lowestScore);
if (beta <= alpha)
break;
}
bestMove.Score = lowestScore;
return bestMove;
}
示例5: Max
// MAX part of Minimax (with alpha-beta pruning)
Move Max(State state, int depth, double alpha, double beta)
{
Move bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
List<Move> moves = state.GetMoves();
if (depth == chosenDepth)
{
int numMax = moves.Count;
}
if (debug)
logger.writeParent(state, chosenDepth - depth);
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = AlphaBeta(resultingState, depth - 1, alpha, beta).Score;
if (debug)
logger.writeChild(resultingState, chosenDepth - depth, currentScore);
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
alpha = Math.Max(alpha, highestScore);
if (beta <= alpha)
{ // beta cut-off
break;
}
}
bestMove.Score = highestScore;
return bestMove;
}
示例6: IterativeDeepeningAlphaBeta
// recursive part of the minimax algorithm when used in iterative deepening search
// checks at each recursion if timeLimit has been reached
// if is has, it cuts of the search and returns the best move found so far, along with a boolean indicating that the search was not fully completed
private Tuple<Move, Boolean> IterativeDeepeningAlphaBeta(State state, int depth, double alpha, double beta, double timeLimit, Stopwatch timer)
{
Move bestMove;
if (depth == 0 || state.IsGameOver())
{
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.Evaluate(state);
return new Tuple<Move, Boolean>(bestMove, true);
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.Evaluate(state);
return new Tuple<Move, Boolean>(bestMove, true);
}
else throw new Exception();
}
if (state.Player == GameEngine.PLAYER) // AI's turn
{
bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = IterativeDeepeningAlphaBeta(resultingState, depth - 1, alpha, beta, timeLimit, timer).Item1.Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
alpha = Math.Max(alpha, highestScore);
if (beta <= alpha)
{ // beta cut-off
break;
}
if (timer.ElapsedMilliseconds > timeLimit)
{
bestMove.Score = highestScore;
return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
}
}
bestMove.Score = highestScore;
return new Tuple<Move, Boolean>(bestMove, true);
}
else if (state.Player == GameEngine.COMPUTER) // computer's turn (the random event node)
{
bestMove = new ComputerMove();
double lowestScore = Double.MaxValue, currentScore = Double.MaxValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = IterativeDeepeningAlphaBeta(resultingState, depth - 1, alpha, beta, timeLimit, timer).Item1.Score;
if (currentScore < lowestScore)
{
lowestScore = currentScore;
bestMove = move;
}
beta = Math.Min(beta, lowestScore);
if (beta <= alpha)
break;
if (timer.ElapsedMilliseconds > timeLimit)
{
bestMove.Score = lowestScore;
return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
}
}
bestMove.Score = lowestScore;
return new Tuple<Move, Boolean>(bestMove, true);
}
else throw new Exception();
}
示例7: SimulateGame
// Simulates a game to the end (game over) based on the default policy
// Returns the game over state
private State SimulateGame(State state, int POLICY)
{
if (POLICY == RANDOM_POLICY)
{
while (state.GetMoves().Count != 0)
{
state = state.ApplyMove(state.GetRandomMove());
}
return state;
}
else if (POLICY == BEST_EVAL_POLICY)
{
List<Move> moves = state.GetMoves();
while (moves.Count != 0)
{
// random move for computer
if (state.Player == GameEngine.COMPUTER)
{
state = state.ApplyMove(state.GetRandomMove());
}
else
{
// find the move that results in the best child state, based on the evaluation function
State bestState = null;
double bestScore = Double.MinValue;
foreach (Move move in moves)
{
State result = state.ApplyMove(move);
double score = AI.Evaluate(result);
if (score > bestScore)
{
bestScore = score;
bestState = result;
}
}
state = bestState;
}
moves = state.GetMoves();
}
return state;
}
else if (POLICY == EXPECTIMAX_POLICY)
{
Expectimax expectimax = new Expectimax(gameEngine, 2);
while (state.GetMoves().Count != 0) {
if (state.Player == GameEngine.COMPUTER)
{
state = state.ApplyMove(state.GetRandomMove());
}
else
{
Move move = expectimax.ExpectimaxAlgorithm(state, 2, weights);
state = state.ApplyMove(move);
}
}
return state;
}
else throw new Exception();
}
示例8: RootParallelizationMCTSTimeLimited
// Runs a root-parallelized Monte Carlo Tree Search in the same way as the RootParallelizationMCTS,
// but limited by a time limit instead of number of iterations
public DIRECTION RootParallelizationMCTSTimeLimited(State rootState, int timeLimit, int numOfThreads)
{
ConcurrentBag<Node> allChildren = new ConcurrentBag<Node>();
int numOfChildren = rootState.GetMoves().Count;
Stopwatch timer = new Stopwatch();
timer.Start();
Parallel.For(0, numOfThreads, i =>
{
Node resultRoot = TimeLimited(rootState, timeLimit, timer);
foreach (Node child in resultRoot.Children)
{
allChildren.Add(child);
}
});
timer.Stop();
List<int> totalVisits = new List<int>(4) { 0, 0, 0, 0 };
List<double> totalResults = new List<double>(4) { 0, 0, 0, 0 };
foreach (Node child in allChildren)
{
int direction = (int)((PlayerMove)child.GeneratingMove).Direction;
totalVisits[direction] += child.Visits;
totalResults[direction] += child.Results;
}
double best = Double.MinValue;
int bestDirection = -1;
for (int k = 0; k < 4; k++)
{
double avg = totalResults[k] / totalVisits[k];
if (avg > best)
{
best = avg;
bestDirection = k;
}
}
if (bestDirection == -1) return (DIRECTION)(-1);
return (DIRECTION)bestDirection;
}
示例9: RecursiveIterativeDeepeningExpectimaxWithStar1
// Recursive part of iterative deepening Expectimax with star 1 pruning
private Tuple<Move, Boolean> RecursiveIterativeDeepeningExpectimaxWithStar1(State state, double alpha, double beta, int depth,
int timeLimit, Stopwatch timer, WeightVector weights)
{
Move bestMove;
if (depth == 0 || state.IsGameOver())
{
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return new Tuple<Move, Boolean>(bestMove, true);
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return new Tuple<Move, Boolean>(bestMove, true); ;
}
else throw new Exception();
}
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = RecursiveIterativeDeepeningExpectimaxWithStar1(resultingState, alpha, beta, depth - 1, timeLimit, timer, weights).Item1.Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
alpha = Math.Max(alpha, highestScore);
if (beta <= alpha)
{ // beta cut-off
break;
}
if (timer.ElapsedMilliseconds > timeLimit)
{
bestMove.Score = highestScore;
return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
}
}
bestMove.Score = highestScore;
return new Tuple<Move, Boolean>(bestMove, true);
}
else if (state.Player == GameEngine.COMPUTER) // computer's turn (the random event node)
{
bestMove = new ComputerMove();
List<Cell> availableCells = state.GetAvailableCells();
List<Move> moves = state.GetAllComputerMoves(availableCells);
int numSuccessors = moves.Count;
double upperBound = AI.GetUpperBound(weights);
double lowerBound = AI.GetLowerBound(weights);
double curAlpha = numSuccessors * (alpha - upperBound) + upperBound;
double curBeta = numSuccessors * (beta - lowerBound) + lowerBound;
double scoreSum = 0;
int i = 1;
foreach (Move move in moves)
{
double sucAlpha = Math.Max(curAlpha, lowerBound);
double sucBeta = Math.Min(curBeta, upperBound);
State resultingState = state.ApplyMove(move);
double score = StateProbability(((ComputerMove)move).Tile) *
RecursiveIterativeDeepeningExpectimaxWithStar1(resultingState, sucAlpha, sucBeta, depth - 1, timeLimit, timer, weights).Item1.Score;
scoreSum += score;
if (score <= curAlpha)
{
scoreSum += upperBound * (numSuccessors - i);
bestMove.Score = scoreSum / numSuccessors;
return new Tuple<Move, Boolean>(bestMove, true); // pruning
}
if (score >= curBeta)
{
scoreSum += lowerBound * (numSuccessors - i);
bestMove.Score = scoreSum / numSuccessors;
return new Tuple<Move, Boolean>(bestMove, true); // pruning
}
if (timer.ElapsedMilliseconds > timeLimit)
{
bestMove.Score = scoreSum / i;
return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
}
curAlpha += upperBound - score;
curBeta += lowerBound - score;
i++;
//.........这里部分代码省略.........
示例10: PickSuccessor
// Used by Star2 in probing phase
private State PickSuccessor(State state)
{
List<Move> moves = state.GetMoves();
int numSuccessors = moves.Count;
if (numSuccessors < 2) return state.ApplyMove(moves[0]);
else
{
State choice = state.ApplyMove(moves[0]);
double best = AI.Evaluate(choice);
for (int i = 1; i < numSuccessors; i++)
{
State resultingState = state.ApplyMove(moves[i]);
double score = AI.Evaluate(resultingState);
if (score > best)
{
best = score;
choice = resultingState;
}
}
return choice;
}
}
示例11: ParallelExpectimax
// Runs a parallel expectimax search to speed up search
// A search is started in a separate thread for each child of the given root node
// This method should only be called for the the root, where depth will always
// be > 0 and player will always be GameEngine.PLAYER - the recursion is started
// for the children of the root using standard Expectimax algorithm
private Move ParallelExpectimax(State state, int depth, WeightVector weights)
{
Move bestMove = new PlayerMove();
List<Move> moves = state.GetMoves();
ConcurrentBag<Tuple<double, Move>> scores = new ConcurrentBag<Tuple<double, Move>>();
if (moves.Count == 0)
{
// game over
return bestMove;
}
// create the resulting states before starting the threads
List<State> resultingStates = new List<State>();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
resultingStates.Add(resultingState);
}
// start a thread for each child
Parallel.ForEach(resultingStates, resultingState =>
{
double score = ExpectimaxAlgorithm(resultingState, depth - 1, weights).Score;
scores.Add(new Tuple<double, Move>(score, resultingState.GeneratingMove));
});
// find the best score
double highestScore = Double.MinValue;
foreach (Tuple<double, Move> score in scores)
{
PlayerMove move = (PlayerMove)score.Item2;
if (score.Item1 > highestScore)
{
highestScore = score.Item1;
bestMove = score.Item2;
}
}
return bestMove;
}
示例12: IterativeDeepeningExpectimax
// Recursive part of iterative deepening Expectimax
private Tuple<Move, Boolean> IterativeDeepeningExpectimax(State state, int depth, double timeLimit, Stopwatch timer, WeightVector weights)
{
Move bestMove;
if (depth == 0 || state.IsGameOver())
{
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return new Tuple<Move, Boolean>(bestMove, true);
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return new Tuple<Move, Boolean>(bestMove, true);
}
else throw new Exception();
}
if (state.Player == GameEngine.PLAYER) // AI's turn
{
bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = IterativeDeepeningExpectimax(resultingState, depth - 1, timeLimit, timer, weights).Item1.Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
if (timer.ElapsedMilliseconds > timeLimit)
{
bestMove.Score = highestScore;
return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
}
}
bestMove.Score = highestScore;
return new Tuple<Move, Boolean>(bestMove, true);
}
else if (state.Player == GameEngine.COMPUTER) // computer's turn (the random event node)
{
bestMove = new ComputerMove();
// return the weighted average of all the child nodes's scores
double average = 0;
List<Cell> availableCells = state.GetAvailableCells();
List<Move> moves = state.GetAllComputerMoves(availableCells);
int moveCheckedSoFar = 0;
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
average += StateProbability(((ComputerMove)move).Tile) * IterativeDeepeningExpectimax(resultingState, depth - 1, timeLimit, timer, weights).Item1.Score;
moveCheckedSoFar++;
if (timer.ElapsedMilliseconds > timeLimit)
{
bestMove.Score = average / moveCheckedSoFar;
return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
}
}
bestMove.Score = average / moves.Count;
return new Tuple<Move, Boolean>(bestMove, true);
}
else throw new Exception();
}
示例13: Star2Expectimax
// Expectimax with Star2 pruning
// NB: DO NOT USE - way too slow
private Move Star2Expectimax(State state, double alpha, double beta, int depth, WeightVector weights)
{
Move bestMove;
if (depth == 0 || state.IsGameOver())
{
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.Evaluate(state);
return bestMove;
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.Evaluate(state);
return bestMove;
}
else throw new Exception();
}
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = Star2Expectimax(resultingState, alpha, beta, depth - 1, weights).Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
alpha = Math.Max(alpha, highestScore);
if (beta <= alpha)
{ // beta cut-off
break;
}
}
bestMove.Score = highestScore;
return bestMove;
}
else if (state.Player == GameEngine.COMPUTER) // computer's turn (the random event node)
{
bestMove = new ComputerMove();
List<Cell> availableCells = state.GetAvailableCells();
List<Move> moves = state.GetAllComputerMoves(availableCells);
int numSuccessors = moves.Count;
double upperBound = AI.GetUpperBound(weights);
double lowerBound = AI.GetLowerBound(weights);
double curAlpha = numSuccessors * (alpha - upperBound);
double curBeta = numSuccessors * (beta - lowerBound);
double sucAlpha = Math.Max(curAlpha, lowerBound);
double[] probeValues = new double[numSuccessors];
// probing phase
double vsum = 0;
int i = 1;
foreach (Move move in moves)
{
curBeta += lowerBound;
double sucBeta = Math.Min(curBeta, upperBound);
State resultingState = state.ApplyMove(move);
probeValues[i - 1] = Probe(resultingState, sucAlpha, sucBeta, depth - 1, weights);
vsum += probeValues[i - 1];
if (probeValues[i - 1] >= curBeta)
{
vsum += lowerBound * (numSuccessors - i);
bestMove.Score = vsum / numSuccessors;
return bestMove; // pruning
}
curBeta -= probeValues[i - 1];
i++;
}
// search phase
vsum = 0;
i = 1;
foreach (Move move in moves)
{
curAlpha += upperBound;
curBeta += probeValues[i - 1];
sucAlpha = Math.Max(curAlpha, lowerBound);
double sucBeta = Math.Min(curBeta, upperBound);
State resultingState = state.ApplyMove(move);
double score = StateProbability(((ComputerMove)move).Tile) * Star2Expectimax(resultingState, sucAlpha, sucBeta, depth - 1, weights).Score;
vsum += score;
if (score <= curAlpha)
//.........这里部分代码省略.........
示例14: Star1WithUnlikelyPruning
// Expectimax search with Star1 pruning and forward pruning
private Move Star1WithUnlikelyPruning(State state, double alpha, double beta, int depth, int lastSpawn, WeightVector weights)
{
Move bestMove;
if (depth == 0 || state.IsGameOver())
{
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return bestMove;
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return bestMove;
}
else throw new Exception();
}
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
State resultingState = state.ApplyMove(move);
currentScore = Star1WithUnlikelyPruning(resultingState, alpha, beta, depth - 1, lastSpawn, weights).Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
alpha = Math.Max(alpha, highestScore);
if (beta <= alpha)
{ // beta cut-off
break;
}
}
bestMove.Score = highestScore;
return bestMove;
}
else if (state.Player == GameEngine.COMPUTER) // computer's turn (the random event node)
{
bestMove = new ComputerMove();
List<Cell> availableCells = state.GetAvailableCells();
List<Move> moves = state.GetAllComputerMoves(availableCells);
int numSuccessors = moves.Count;
double upperBound = AI.GetUpperBound(weights);
double lowerBound = AI.GetLowerBound(weights);
double curAlpha = numSuccessors * (alpha - upperBound) + upperBound;
double curBeta = numSuccessors * (beta - lowerBound) + lowerBound;
double scoreSum = 0;
int i = 1;
foreach (Move move in moves)
{
int value = ((ComputerMove)move).Tile;
if (value == 4 && lastSpawn == 4) continue; // unlikely event pruning (2 4-spawns in sequence only has 1% chance)
double sucAlpha = Math.Max(curAlpha, lowerBound);
double sucBeta = Math.Min(curBeta, upperBound);
State resultingState = state.ApplyMove(move);
double score = StateProbability(((ComputerMove)move).Tile) * Star1WithUnlikelyPruning(resultingState, sucAlpha, sucBeta, depth - 1, value, weights).Score;
scoreSum += score;
if (score <= curAlpha)
{
scoreSum += upperBound * (numSuccessors - i);
bestMove.Score = scoreSum / numSuccessors;
return bestMove; // pruning
}
if (score >= curBeta)
{
scoreSum += lowerBound * (numSuccessors - i);
bestMove.Score = scoreSum / numSuccessors;
return bestMove; // pruning
}
curAlpha += upperBound - score;
curBeta += lowerBound - score;
i++;
}
bestMove.Score = scoreSum / numSuccessors;
return bestMove;
}
else throw new Exception();
}
示例15: RecursiveTTStar1
// Recursive part of ^^ iterative deepening Expectimax with Star1, move ordering and transposition table
private Tuple<Move, Boolean> RecursiveTTStar1(State state, double alpha, double beta, int depth, double timeLimit, Stopwatch timer, WeightVector weights)
{
Move bestMove;
if (depth == 0 || state.IsGameOver())
{
if (state.Player == GameEngine.PLAYER)
{
bestMove = new PlayerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return new Tuple<Move, Boolean>(bestMove, true);
}
else if (state.Player == GameEngine.COMPUTER)
{
bestMove = new ComputerMove(); // dummy action, as there will be no valid move
bestMove.Score = AI.EvaluateWithWeights(state, weights);
return new Tuple<Move, Boolean>(bestMove, true);
}
else throw new Exception();
}
if (state.Player == GameEngine.PLAYER) // AI's turn
{
DIRECTION bestDirection = (DIRECTION)(-1);
bestMove = new PlayerMove();
double highestScore = Double.MinValue, currentScore = Double.MinValue;
// transposition table look-up
long zob_hash = GetHash(state);
if (transposition_table.ContainsKey(zob_hash) && transposition_table[zob_hash].depth > depth)
{
Move move = new PlayerMove(transposition_table[zob_hash].direction);
move.Score = transposition_table[zob_hash].value;
return new Tuple<Move, Boolean>(move, true);
}
// move ordering - make sure we first check the move we believe to be best based on earlier searches
else if (transposition_table.ContainsKey(zob_hash))
{
bestDirection = transposition_table[zob_hash].direction;
State resultingState = state.ApplyMove(new PlayerMove(bestDirection));
currentScore = RecursiveTTStar1(resultingState, alpha, beta, depth - 1, timeLimit, timer, weights).Item1.Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = new PlayerMove(bestDirection);
}
if (timer.ElapsedMilliseconds > timeLimit)
{
bestMove.Score = highestScore;
return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
}
}
// now check the rest of moves
List<Move> moves = state.GetMoves();
foreach (Move move in moves)
{
if (((PlayerMove)move).Direction != bestDirection)
{
State resultingState = state.ApplyMove(move);
currentScore = RecursiveTTStar1(resultingState, alpha, beta, depth - 1, timeLimit, timer, weights).Item1.Score;
if (currentScore > highestScore)
{
highestScore = currentScore;
bestMove = move;
}
alpha = Math.Max(alpha, highestScore);
if (beta <= alpha)
{ // beta cut-off
break;
}
if (timer.ElapsedMilliseconds > timeLimit)
{
bestMove.Score = highestScore;
return new Tuple<Move, Boolean>(bestMove, false); // recursion not completed, return false
}
}
}
bestMove.Score = highestScore;
// add result to transposition table
TableRow row = new TableRow((short)depth, ((PlayerMove)bestMove).Direction, bestMove.Score);
transposition_table.AddOrUpdate(zob_hash, row, (key, oldValue) => row);
return new Tuple<Move, Boolean>(bestMove, true);
}
else if (state.Player == GameEngine.COMPUTER) // computer's turn (the random event node)
{
bestMove = new ComputerMove();
int moveCheckedSoFar = 0;
List<Cell> availableCells = state.GetAvailableCells();
List<Move> moves = state.GetAllComputerMoves(availableCells);
int numSuccessors = moves.Count;
double upperBound = AI.GetUpperBound(weights);
double lowerBound = AI.GetLowerBound(weights);
double curAlpha = numSuccessors * (alpha - upperBound) + upperBound;
//.........这里部分代码省略.........