public override void onMyTurn() { base.onMyTurn(); if (Model.PrepareCheckedChessType == MyChessType) { if (ConnectStrategy.IsWin(MyChessType)) { View.ShowMsg($"{Name.Split('_')[0]} ({Name.Split('_')[3]}) WIN !!!"); System.Console.WriteLine($"{Name.Split('_')[0]} ({Name.Split('_')[3]}) WIN !!!"); } else if (ConnectStrategy.IsTie()) { System.Console.WriteLine($"It's tie !!!"); View.ShowMsg($"It's tie !!!"); } else { RoleMgr.ChangeNextRole(); } } else { System.Console.WriteLine($"{Name} judge error type"); } }
private BoradStatus GetBoardStatus(Model model, ChessType chessType) { BoradStatus status = BoradStatus.Nothing; ConnectStrategy connectStrategy = new ConnectStrategy(model); if (connectStrategy.IsWin(chessType)) { status = BoradStatus.Winlose; } else if (connectStrategy.IsTie()) { status = BoradStatus.Tie; } return(status); }
private MinMaxSearchInfo MinMaxSearch(Model pModel, ChessType chessType, bool isMaxLayer, int depth, int alpha, int beta) { MinMaxSearchCount++; int bestScore = isMaxLayer ? int.MinValue : int.MaxValue; MinMaxSearchInfo bestPosInfo = new MinMaxSearchInfo(-1, -1, bestScore); //Console.WriteLine($"depth: {depth} isMaxLayer: {isMaxLayer} MinMaxSearchCount: {MinMaxSearchCount.ToString()} alpha: {alpha.ToString()} beta: {beta}"); // y, x, score List <Tuple <int, int, int> > OrderPosScoreList = GetPossibleBestPosOrderList(pModel, chessType); foreach (Tuple <int, int, int> PosScoreTuple in OrderPosScoreList) { int y = PosScoreTuple.Item1; int x = PosScoreTuple.Item2; Model cloneModel = pModel.Clone() as Model; cloneModel.PutChessToBoard(x, y, chessType); bool isWin = false; bool isTie = false; int tmpScore = 0; Model tmpModel; //when anyone win or tie, stop search ConnectStrategy connectStrategy = new ConnectStrategy(cloneModel); isWin = connectStrategy.IsWin(chessType); isTie = connectStrategy.IsTie(); if (isWin) { Console.WriteLine($"win happen"); SearchHasResultCount++; MinMaxSearchInfo Info = new MinMaxSearchInfo(x, y, isMaxLayer ? int.MaxValue - 1 : int.MinValue + 1); Info.Model = cloneModel; return(Info); } if (depth == MinMaxSearchDepth || isTie) { SearchHasResultCount++; tmpScore = MyEvaluation.GetScore(cloneModel, MyChessType); tmpModel = cloneModel; //cloneModel.PrintBoard(); //Console.WriteLine($"y: {y} x: {x} score: {score}"); } else { ChessType nextChessType = Utility.GetOppositeChessType(chessType); MinMaxSearchInfo info = MinMaxSearch(cloneModel, nextChessType, !isMaxLayer, depth + 1, alpha, beta); //===== alpha beta pruning ===== if (isMaxLayer) { alpha = Math.Max(alpha, info.Score); } else { beta = Math.Min(beta, info.Score); } if (alpha >= beta) { return(info); } //=============================== tmpScore = info.Score; tmpModel = info.Model; } if (isMaxLayer) { if (tmpScore > bestPosInfo.Score) { bestPosInfo.Score = tmpScore; bestPosInfo.X = x; bestPosInfo.Y = y; bestPosInfo.Model = tmpModel; } } else { if (tmpScore < bestPosInfo.Score) { bestPosInfo.Score = tmpScore; bestPosInfo.X = x; bestPosInfo.Y = y; bestPosInfo.Model = tmpModel; } } if (depth == 0) { Console.WriteLine($"y: {y} x: {x} score: {tmpScore} depth: {depth} MinMaxSearchCount = {MinMaxSearchCount.ToString()}"); //bestModel.PrintBoard(); } } #region Not use find order list /* * for (int y = 0; y < GameDef.board_cell_length; y++) * { * for (int x = 0; x < GameDef.board_cell_length; x++) * { * List<List<ChessType>> board = pModel.GetBoardByCopy(); * if (board[y][x] == ChessType.None && IsPosNeedSearch(board, x, y)) * { * Model cloneModel = pModel.Clone() as Model; * cloneModel.PutChessToBoard(x, y, chessType); * * bool isWin = false; * * int score = 0; * * if (depth == MinMaxSearchDepth) * { * SearchHasResultCount++; * score = MyEvaluation.GetScore(cloneModel, MyChessType); * * //cloneModel.PrintBoard(); * //Console.WriteLine($"y: {y} x: {x} score: {score}"); * } * else * { * ConnectStrategy connectStrategy = new ConnectStrategy(cloneModel); * isWin = connectStrategy.IsWin(chessType) || connectStrategy.IsTie(); * * //when anyone win, stop search * //isWin = MyEvaluation.IsEndSearch(cloneModel, chessType); * * if (isWin) * { * score = MyEvaluation.GetScore(cloneModel, MyChessType); * } * else * { * ChessType nextChessType = Utility.GetOppositeChessType(chessType); * MinMaxSearchInfo info = MinMaxSearch(cloneModel, nextChessType, !isMaxLayer, depth + 1, alpha, beta); * * if (isMaxLayer) * alpha = Math.Max(alpha, info.Score); * else * beta = Math.Min(beta, info.Score); * * if (alpha >= beta) * return info; * * score = info.Score; * } * * } * * if (depth == 0) * { * Console.WriteLine($"y: {y} x: {x} score: {score} depth: {depth}"); * } * * if (isWin) * { * Console.WriteLine($"Win happen y: {y} x: {x} score: {score} depth: {depth}"); * } * * if (isMaxLayer) * { * if (score > bestPosInfo.Score) * { * bestPosInfo.Score = score; * bestPosInfo.X = x; * bestPosInfo.Y = y; * } * } * else * { * if (score < bestPosInfo.Score) * { * bestPosInfo.Score = score; * bestPosInfo.X = x; * bestPosInfo.Y = y; * } * } * } * } * } */ #endregion return(bestPosInfo); }