public static Move GetBestMove(Board b) { List<Tuple<Board, Move>> possibleNextBoards = new List<Tuple<Board, Move>>(); foreach (Move posMove in b.AllMoves) { possibleNextBoards.Add(new Tuple<Board, Move>(b.MakeMove(posMove.From, posMove.To), posMove)); } List<Tuple<Move, double>> moveScores = new List<Tuple<Move, double>>(); foreach (var posNextBoard in possibleNextBoards) { var bestPossibleBoard = allData.Where(x => x.Item1.WhosMove == posNextBoard.Item1.WhosMove) .OrderBy(x => Similarity.Calculate(x.Item1, posNextBoard.Item1)) .First(); double score = Similarity.Calculate(bestPossibleBoard.Item1, posNextBoard.Item1); moveScores.Add(new Tuple<Move, double>(posNextBoard.Item2, score)); } Move suggestedMove = moveScores.OrderBy(x => x.Item2).First().Item1; return suggestedMove; }
private double Negamax(Board b, int depth, double alpha, double beta, int colour) { Tuple<int, double> tuple = m_Zasher.GetDepthScoreTuple(b); // If the same or better calculation of this state has already been made, use it. if (tuple != null && tuple.Item1 >= depth && depth < MaxNegamaxDepth) { if (depth > 0) hashUsed++; if (depth >= 0) hashUsed++; return colour * tuple.Item2; } if (depth == 0) { double score = b.ScoreBoard(); m_Zasher.SetDepthScoreTuple(b, new Tuple<int, double>(0, score)); hashNotUsed++; return colour * score; } else { for (int i = 0; i < b.AllMovesCount; i++) { Move move = b.AllMoves[i]; Board boardAfterMove = new Board(b); bool moveOk = boardAfterMove.MakeMove(move.From, move.To); if (moveOk) { double score = -Negamax(boardAfterMove, depth - 1, -beta, -alpha, -colour); // Cache this score m_Zasher.AddIfBetter(boardAfterMove, new Tuple<int, double>(depth - 1, colour * score)); nodesVisited++; if (score >= beta) return score; if (score > alpha) { alpha = score; } if (depth == MaxNegamaxDepth) { m_RankedMoves.Add(new Tuple<Move, double>(move, colour * score)); m_Zasher.AddIfBetter(b, new Tuple<int, double>(depth, colour * score)); } } } return alpha; } }
public override Move ComputeBestMove() { for (int i = 0; i < 100; i++) { int r = rand.Next(0, b.AllMovesCount); Move randMove = new Move(b.AllMoves[r].From, b.AllMoves[r].To, -100); Board boardAfterMove = new Board(b); if (boardAfterMove.MakeMove(randMove.From, randMove.To)) return randMove; } throw new ApplicationException("Can't find possible move"); }
static void Main(string[] args) { string wholeFile = ""; List<Tuple<Board, Move>> allData = new List<Tuple<Board, Move>>(); using(StreamReader fs = new StreamReader(File.OpenRead(".\\Ivanchuk.pgn"))) wholeFile = fs.ReadToEnd(); string[] games = Regex.Split(wholeFile, "\\[Event.*\\]\r\n\r\n"); PgnParser.Parser parser = new PgnParser.Parser(); for (int i = 0; i < 100; i++) { Board board = new Board(); var enu = parser.Parse(games[i]).GetEnumerator(); board.SetupStandardBoard(); while (enu.MoveNext()) { board = board.MakeMove(enu.Current.From, enu.Current.To); allData.Add(new Tuple<Board, Move>(board, enu.Current)); } } Board b = allData[263].Item1; var mostSimilars = allData.Where(x => x.Item1.WhosMove == b.WhosMove). OrderBy(x => Similarity.Calculate(x.Item1, b)).ToList(); Move suggestedMove = new Move(-1, -1); for (int i = 0; i < mostSimilars.Count; i++) { Tuple<Board, Move> tup = mostSimilars[i]; suggestedMove = tup.Item2; if (b.AllMoves.Contains(suggestedMove)) break; } }
static Parser() { string wholeFile = ""; using (StreamReader fs = new StreamReader(File.OpenRead(".\\Ivanchuk.pgn"))) wholeFile = fs.ReadToEnd(); string[] games = Regex.Split(wholeFile, "\\[Event.*\\]\r\n\r\n"); PgnParser.Parser parser = new PgnParser.Parser(); for (int i = 0; i < 100; i++) { Board board = new Board(); var enu = parser.Parse(games[i]).GetEnumerator(); board.SetupStandardBoard(); while (enu.MoveNext()) { allData.Add(new Tuple<Board, Move>(board, enu.Current)); board = board.MakeMove(enu.Current.From, enu.Current.To); } } }
public IEnumerable<Move> Parse(string pgn) { string tmp = RemoveNonsense(pgn); string[] byMoves = SplitIntoMoves(tmp); bool whiteMove = true; Thursday.Board board = new Thursday.Board(); board.SetupStandardBoard(); int curMove = 0; foreach (string move in byMoves) { string[] ms = move.Split(whiteSpaces, StringSplitOptions.RemoveEmptyEntries); if (ms.Length == 0) { // Boring. Just continue } else if (ms.Length == 2) { if (IsEndStatement(ms[0])) goto ended; Move move1 = ParseMove(ms[0], board); board = board.MakeMove(move1.From, move1.To); curMove++; PrintDebug(curMove, board); yield return move1; if (IsEndStatement(ms[1])) goto ended; Move move2 = ParseMove(ms[1], board); board = board.MakeMove(move2.From, move2.To); curMove++; PrintDebug(curMove, board); yield return move2; } else if (ms.Length == 1) { if (IsEndStatement(ms[0])) goto ended; Move move1 = ParseMove(ms[0], board); board = board.MakeMove(move1.From, move1.To); curMove++; PrintDebug(curMove, board); yield return move1; } else if (ms.Length == 3 && IsEndStatement(ms[2])) { Move move1 = ParseMove(ms[0], board); board = board.MakeMove(move1.From, move1.To); curMove++; PrintDebug(curMove, board); yield return move1; Move move2 = ParseMove(ms[1], board); board = board.MakeMove(move2.From, move2.To); curMove++; PrintDebug(curMove, board); yield return move2; goto ended; } else { throw new ApplicationException("Not 0 1 or 2 moves found"); } } ended: ; }
private void HumanMoved() { int oldPos = (int)fromImage.Tag; int destPos = (int)toImage.Tag; try { board = board.MakeMove(oldPos, destPos); Move m = PgnParser.Parser.GetBestMove(board); board = board.MakeMove(m.From, m.To); RenderBoard(board); } catch (ApplicationException e) { MessageBox.Show(e.Message); } fromImage.Opacity = 1f; fromImage = null; toImage.Opacity = 1f; toImage = null; }
public void MakeMove(int fromPos, int toPos) { if (!Board.MoveIsLegal(fromPos, toPos)) throw new ApplicationException("Move is illegal. Try another"); Board newBoard = new Board(Board); bool isLegal = newBoard.MakeMove(fromPos, toPos); if (isLegal) { m_OldBoards.Push(Board); Board = newBoard; WhosMove = newBoard.WhosMove; } else { throw new ApplicationException("Move is illegal. Try another"); } }