/// <summary> /// Verifies the legality of a move. Places the stone on the board. Finds prisoners and remove them. /// </summary> /// <param name="currentNode">Node of tree representing the previous move.</param> /// <param name="moveToMake">Move to check.</param> /// <returns>Object, which contains: the result of legality check, list of prisoners, the new state of game board, the new state of groups.</returns> public MoveProcessingResult ProcessMove(GameTreeNode currentNode, Move moveToMake) { lock (RulesetInfo) { StoneColor player = moveToMake.WhoMoves; Position position = moveToMake.Coordinates; GameBoard[] history = new GameBoard[0]; GroupState previousGroupState, currentGroupState; GameBoard previousBoard, currentBoard; if (currentNode == null) { previousGroupState = new GroupState(RulesetInfo); currentGroupState = new GroupState(RulesetInfo); previousBoard = new GameBoard(RulesetInfo.BoardSize); currentBoard = new GameBoard(RulesetInfo.BoardSize); } else { history = currentNode.GetGameBoardHistory().ToArray(); //set Ruleset state previousGroupState = new GroupState(currentNode.GroupState, RulesetInfo); currentGroupState = new GroupState(currentNode.GroupState, RulesetInfo); previousBoard = new GameBoard(currentNode.BoardState); currentBoard = new GameBoard(currentNode.BoardState); } SetRulesetInfo(currentBoard, currentGroupState); MoveProcessingResult processingResult = new MoveProcessingResult { Captures = new List <Position>(), NewBoard = previousBoard, NewGroupState = previousGroupState }; //1. step: check intersection if (moveToMake.Kind == MoveKind.Pass) { processingResult.Result = Pass(currentNode); return(processingResult); } else if (IsOutsideTheBoard(position) == MoveResult.OutsideTheBoard) { processingResult.Result = MoveResult.OutsideTheBoard; return(processingResult); } else if (IsPositionOccupied(position) == MoveResult.OccupiedPosition) { processingResult.Result = MoveResult.OccupiedPosition; return(processingResult); } else { //2. step: add stone RulesetInfo.GroupState.AddStoneToBoard(moveToMake.Coordinates, moveToMake.WhoMoves); //3. step: find captures and remove prisoners List <int> capturedGroups = CheckCapturedGroups(moveToMake); foreach (int groupID in capturedGroups) { processingResult.Captures.AddRange(RulesetInfo.GroupState.Groups[groupID].Members); RulesetInfo.GroupState.Groups[groupID].DeleteGroup(); } //4. step: check selfcapture, ko MoveResult r = CheckSelfCaptureKoSuperko(moveToMake, history); if (r == MoveResult.Legal) { RulesetInfo.GroupState.CountLiberties(); processingResult.NewBoard = currentBoard; processingResult.NewGroupState = currentGroupState; } else { SetRulesetInfo(previousBoard, previousGroupState); } processingResult.Result = r; return(processingResult); } } }
/// <summary> /// Determines whether a move is legal. Information about any captures and the new board state are discarded. /// </summary> /// <param name="currentNode">Node of tree representing the previous move.</param> /// <param name="moveToMake">The move of a player.</param> /// <returns>The result of legality check.</returns> public MoveResult IsLegalMove(GameTreeNode currentNode, Move moveToMake) { MoveProcessingResult result = ProcessMove(currentNode, moveToMake); return(result.Result); }