/// <summary> /// Ensures moves from IGS are properly handled /// </summary> /// <param name="move">Move being processed</param> /// <param name="result">Result of move processing</param> protected override void AlterMoveProcessingResult(Move move, MoveProcessingResult result) { //enter will decide when to enter life and death phase if (result.Result == MoveResult.StartLifeAndDeath) { result.Result = MoveResult.Legal; } else { //permit all server-based moves var player = Controller.Players[move.WhoMoves]; if (player.Agent is KgsAgent) { result.Result = MoveResult.Legal; } } }
private void BoardViewModel_BoardTapped(object sender, Position e) { Move move = Move.PlaceStone(_playerToMove, e); GameTreeNode thatMove = CurrentNode.Branches.FirstOrDefault(gtn => gtn.Move.Coordinates == e); if (thatMove != null) { CurrentNode = thatMove; } else { // This is a new move. GameTreeNode newNode = new GameTreeNode(move); MoveProcessingResult mpr = TsumegoProblem.TsumegoRuleset.ProcessMove(CurrentNode, move); // TODO (future work) Petr: ko??? // Note that we're not handling ko. Most or all of our problems don't depend on ko, // and which positions are correct or wrong is written in the .sgf file anyway, so this is not a big deal. if (mpr.Result == MoveResult.Legal) { newNode.BoardState = mpr.NewBoard; newNode.GroupState = mpr.NewGroupState; CurrentNode.Branches.Insert(0, newNode); if (CurrentNode.Tsumego.Correct) { newNode.Tsumego.Correct = true; } else { newNode.Tsumego.Wrong = true; } CurrentNode = newNode; } } ReachNode(CurrentNode); if (CurrentNode.Tsumego.Expected && CurrentNode.Move.WhoMoves == _humansColor) { if (CurrentNode.Branches.Count(br => br.Tsumego.Expected) >= 1) { // The opponent responds... CurrentNode = CurrentNode.Branches.First(br => br.Tsumego.Expected); ReachNode(CurrentNode); } } }
/// <summary> /// Handles an illegal move /// </summary> /// <param name="move">Move</param> /// <param name="processingResult">Why was the move illegal</param> private void HandlePlayersIllegalMove(Move move, MoveProcessingResult processingResult) { var player = Controller.Players[move.WhoMoves]; switch (player.Agent.IllegalMoveHandling) { case IllegalMoveHandling.InformAgent: player.Agent.MoveIllegal(processingResult.Result); break; case IllegalMoveHandling.PassInstead: Controller.OnDebuggingMessage("Passing instead."); TryToMakeMove(Move.Pass(move.WhoMoves)); break; case IllegalMoveHandling.PermitItAnyway: Controller.OnDebuggingMessage("Permitting it anyway."); processingResult.Result = MoveResult.Legal; break; } }
public void Execute(IToolServices toolService) { StoneColor nextPlayer = toolService.Node.Move.WhoMoves.GetOpponentColor(toolService.Node, toolService.GameTree.GameTreeRoot); //process move MoveProcessingResult moveResult = toolService.Ruleset.ProcessMove( toolService.Node, Move.PlaceStone(nextPlayer, toolService.PointerOverPosition)); if (moveResult.Result == MoveResult.Legal) { GameTreeNode newNode = new GameTreeNode(Move.PlaceStone(nextPlayer, toolService.PointerOverPosition)); newNode.BoardState = moveResult.NewBoard; newNode.GroupState = moveResult.NewGroupState; newNode.Move.Captures.AddRange(moveResult.Captures); toolService.Node.Branches.AddNode(newNode); toolService.SetNode(newNode); toolService.PlayStonePlacementSound(newNode.Move.Captures.Count > 0); } }
/// <summary> /// Alters the processing result before it is handled by the move logic /// </summary> /// <param name="move">Move processed</param> /// <param name="result">Result of processing</param> protected virtual void AlterMoveProcessingResult(Move move, MoveProcessingResult result) { //keep the rules logic inact }
private void TryToMakeMove(Move move) { var player = Controller.Players[move.WhoMoves]; if (player != Controller.TurnPlayer) { throw new InvalidOperationException("It is not your turn."); } //ask the ruleset to validate the move MoveProcessingResult processingResult = Controller.Ruleset.ProcessMove(Controller.GameTree.LastNode, move); //let the specific game controller alter the processing result to match game type AlterMoveProcessingResult(move, processingResult); //are we about to enter life and death phase? if (processingResult.Result == MoveResult.StartLifeAndDeath) { if (player.Clock.IsViolating()) { if (HandleLocalClockOut(player)) { return; } } //applies the legal move Controller.OnDebuggingMessage(Controller.TurnPlayer + " moves: " + move); ApplyMove(move, processingResult.NewBoard, processingResult.NewGroupState); //switches players Controller.SwitchTurnPlayer(); // moves next GoToPhase(GamePhaseType.LifeDeathDetermination); return; } //is the move illegal? if (processingResult.Result != MoveResult.Legal) { Controller.OnDebuggingMessage("That move was illegal: " + processingResult.Result); //handle the illegal move, this may alter the HandlePlayersIllegalMove(move, processingResult); } // These MUST NOT be an "else" here because HandlePlayersIllegalMove may change processingResult. if (processingResult.Result == MoveResult.Legal) { //we have a legal move if (move.Kind == MoveKind.PlaceStone) { move.Captures.AddRange(processingResult.Captures); } if (player.Clock.IsViolating()) { if (HandleLocalClockOut(player)) { return; } } //applies the legal move Controller.OnDebuggingMessage(Controller.TurnPlayer + " moves: " + move); ApplyMove(move, processingResult.NewBoard, processingResult.NewGroupState); DetermineNextTurnPlayer(); Controller.OnDebuggingMessage("Asking " + Controller.TurnPlayer + " to make a move."); Controller.TurnPlayer.Agent.PleaseMakeAMove(); } }