/* The next best thing to a picture in the source code. IsLegal() || || IsKill n/ \y IsSuicide IsKo n/ \y n/ \y PLAY NO PLAY NO */ public IsLegalResponse IsLegal(Loc proposedLoc) { IsLegalResponse response = new IsLegalResponse(); if (isConflict(proposedLoc)) { response.Reason = ReasonEnum.Conflict; return response; } response.Killed = determineKills(proposedLoc); if (response.Killed.Any()) { // IsKill if (isKo(proposedLoc, response.Killed)) { response.Reason = ReasonEnum.Ko; return response; } else { // Determine MergeResultant and AbsorbedByMerge for future use. // Does proposedLoc have any friendly neighbors? List<Chain> friendlyNeighborChains = findFriendlyNeighborChains(proposedLoc); if (friendlyNeighborChains.Any()) { // If so, merge friendlyNeighborChains.Add(new Chain(new Stone(proposedLoc, IsWhiteMove), this.findLiberties(proposedLoc))); response.MergeResultant = this.merge(friendlyNeighborChains); response.AbsorbedInMerge = friendlyNeighborChains; } else { response.MergeResultant = new Chain(new Stone(proposedLoc, IsWhiteMove), this.findLiberties(proposedLoc)); response.AbsorbedInMerge = new List<Chain>(); } return response; } } else { // !IsKill this.determineSuicide(proposedLoc, response); return response; } }
private void determineSuicide(Loc proposedLoc, IsLegalResponse response) { // Does proposedLoc have any friendly neighbors? List<Chain> friendlyNeighborChains = findFriendlyNeighborChains(proposedLoc); if (friendlyNeighborChains.Any()) { // If so, merge friendlyNeighborChains.Add(new Chain(new Stone(proposedLoc, IsWhiteMove), this.findLiberties(proposedLoc))); Chain mergeResultant = this.merge(friendlyNeighborChains); if (!mergeResultant.Liberties.Any()) { response.Reason = ReasonEnum.Suicide; return; } else { response.MergeResultant = mergeResultant; response.AbsorbedInMerge = friendlyNeighborChains; return; } } else { // If not, if there are any liberties, it's playable if (this.findLiberties(proposedLoc).Any()) { response.MergeResultant = new Chain(new Stone(proposedLoc, IsWhiteMove), this.findLiberties(proposedLoc)); response.AbsorbedInMerge = new List<Chain>(); return; } } // else, it's suicide response.Reason = ReasonEnum.Suicide; }
// Updates lists accordingly with correct location and color. public RequestResponse PlaceStone(Loc loc, IsLegalResponse isLegalResponse) { // By this point, we have MergeResult and KilledChains this.Game.PossibleKoLoc = new Loc(-1, -1); // Update logical groups of Chains by adding the mergeResult and removing what went into the merge this.enactMerge(isLegalResponse.MergeResultant, isLegalResponse.AbsorbedInMerge); // Update logical groups of Chains by removing the killed ones. this.deadifyKilledChains(isLegalResponse.Killed); if (IsWhiteMove) { this.Game.PrisonersTakenByWhite += isLegalResponse.Killed.Sum(chain => chain.Stones.Count); foreach (Chain chain in this.Game.whiteChains) this.reCalcLiberties(chain); } else { this.Game.PrisonersTakenByBlack += isLegalResponse.Killed.Sum(chain => chain.Stones.Count); foreach (Chain chain in this.Game.blackChains) this.reCalcLiberties(chain); } // Update logical groups of Opponent's Chains by removing breath for current Loc this.takeMyBreathAwaaaaay(loc); // Set possibleKoLoc. if (isLegalResponse.Killed.Count == 1 && isLegalResponse.Killed[0].Stones.Count == 1) { this.Game.PossibleKoLoc = isLegalResponse.Killed[0].Stones[0].Loc; } RequestResponse response = new RequestResponse(new Move(new Stone(loc, IsWhiteMove), isLegalResponse.Killed)); this.ChangeTurn(); return response; }