/// <summary> /// Determines the group state based on the given board state. /// </summary> /// <param name="board">Board state</param> public void SetState(GameBoard currentBoard) { BoardState = new GameBoard(currentBoard); GroupState = new GroupState(this); GroupState.FillGroupMap(currentBoard); GroupState.CountLiberties(); }
/// <summary> /// Initializes a new <see cref="GroupState"/> as a copy of the given group state. /// </summary> /// <param name="groupState">The group state to copy.</param> /// <param name="info">Ruleset state.</param> public GroupState(GroupState groupState, IRulesetInfo info) : this(info) { for (int x = 0; x < info.BoardSize.Width; x++) { for (int y = 0; y < info.BoardSize.Height; y++) { GroupMap[x, y] = groupState.GroupMap[x, y]; } } for (int i = 0; i < groupState.Groups.Length; i++) { if (groupState.Groups[i] != null) { Groups[i] = new Group(groupState.Groups[i], info); } } }
/// <summary> /// Sets the group state and board state. /// </summary> /// <param name="board">Board state</param> /// <param name="groupState">Group state</param> public void SetState(GameBoard board, GroupState groupState) { BoardState = board; GroupState = groupState; }
/// <summary> /// Initializes the state of ruleset. /// </summary> /// <param name="gbSize">Size of game board.</param> internal RulesetInfo(GameBoardSize gbSize) { BoardSize = gbSize; BoardState = new GameBoard(gbSize); GroupState = new GroupState(this); }
/// <summary> /// Gets the results of moves. /// </summary> /// <param name="currentNode">Node of tree representing the previous move.</param> /// <returns>Map of move results.</returns> public MoveResult[,] GetMoveResult(GameTreeNode currentNode) { if (currentNode == null) { MoveResult[,] moveResults = new MoveResult[RulesetInfo.BoardSize.Width, RulesetInfo.BoardSize.Height]; for (int x = 0; x < RulesetInfo.BoardSize.Width; x++) { for (int y = 0; y < RulesetInfo.BoardSize.Height; y++) { moveResults[x, y] = MoveResult.Legal; } } return(moveResults); } lock (RulesetInfo) { MoveResult[,] moveResults = new MoveResult[RulesetInfo.BoardSize.Width, RulesetInfo.BoardSize.Height]; GameBoard[] history = currentNode.GetGameBoardHistory().ToArray(); GameBoard boardState = new GameBoard(currentNode.BoardState); GroupState groupState = new GroupState(currentNode.GroupState, RulesetInfo); StoneColor player; if (currentNode.Move.WhoMoves == StoneColor.None) { player = StoneColor.White; // TODO (future work) Petr: ensure this is actually appropriate in all such situations (probably isn't) } else { player = currentNode.Move.WhoMoves.GetOpponentColor(); } for (int x = 0; x < RulesetInfo.BoardSize.Width; x++) { for (int y = 0; y < RulesetInfo.BoardSize.Height; y++) { //set Ruleset state SetRulesetInfo(boardState, groupState); Position position = new Position(x, y); Move move = Move.PlaceStone(player, position); if (IsPositionOccupied(position) == MoveResult.OccupiedPosition) { moveResults[x, y] = MoveResult.OccupiedPosition; } else { //Find captures and remove prisoners List <int> capturedGroups = CheckPossiblyCapturedGroups(move); if (capturedGroups.Count != 0) { SetRulesetInfo(new GameBoard(currentNode.BoardState), new GroupState(currentNode.GroupState, RulesetInfo)); } //remove prisoners foreach (int groupID in capturedGroups) { RulesetInfo.GroupState.Groups[groupID].DeleteGroup(); } // add temporarily a stone to board RulesetInfo.GroupState.AddTempStoneToBoard(position, player); //check selfcapture, ko moveResults[x, y] = CheckSelfCaptureKo(move, history); // remove added stone RulesetInfo.GroupState.RemoveTempStoneFromPosition(position); } } } return(moveResults); } }
/// <summary> /// Initializes the ruleset. For each game, a new ruleset must be created. /// </summary> /// <param name="gbSize">Size of the game board.</param> protected Ruleset(GameBoardSize gbSize) { RulesetInfo = new RulesetInfo(gbSize); GameBoard newBoard = new GameBoard(gbSize); GroupState groupState = new GroupState(RulesetInfo); }
/// <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> /// Sets the state of ruleset. /// </summary> /// <param name="boardState">State of board to use.</param> /// <param name="groupState">State of groups to use.</param> public void SetRulesetInfo(GameBoard boardState, GroupState groupState) { RulesetInfo.SetState(boardState, groupState); }