public List <GoPoint> getAdjacents(GoPoint point) { if (!isOnBoard(point)) { throw new Exception("There is no point checking a move which is not on board!"); } List <GoPoint> adjacents = new List <GoPoint>(); if (isOnBoard(point.GetUp())) { adjacents.Add(point.GetUp()); } if (isOnBoard(point.GetRight())) { adjacents.Add(point.GetRight()); } if (isOnBoard(point.GetDown())) { adjacents.Add(point.GetDown()); } if (isOnBoard(point.GetLeft())) { adjacents.Add(point.GetLeft()); } return(adjacents); }
public void CheckGroupLiberties(GoPoint point, GoColor color, out List <GoPoint> group, out List <GoPoint> liberties) { group = new List <GoPoint>(); liberties = new List <GoPoint>(); if (color != GoColor.EMPTY) { CheckGroupLiberties_rec(point, color, ref group, ref liberties); } }
public override bool Equals(object obj) { if (obj == null) { return(false); } GoPoint right = (GoPoint)obj; return(this.X == right.X && this.Y == right.Y); }
// Coordinates should be in [1, size] // Origin is bottom left like for pachi public bool isOnBoard(GoPoint point) { if (point.X < 1 || point.Y < 1 || point.X > m_size || point.Y > m_size) { return(false); } return(true); }
public GoGame(GoGameInfo info) { GameInfo = info; Clock = new GoClock(GameInfo.TimeSettings); Tree = new GoGameTree(); Board = new GoBoard(GameInfo.Size, GameInfo.Handicap); Turns = new List <GoTurn>(); KoPoint = null; IsGameOver = false; GameRule = RulesType.normal; NumberOfStonesToCapture = 5; m_currentTurn = 0; m_colorToMove = GameInfo.Handicap < 2 ? GoColor.BLACK : GoColor.WHITE; }
public GoGame(GoGameInfo info) { GameInfo = info; Clock = new GoClock(GameInfo.TimeSettings); Tree = new GoGameTree(); Board = new GoBoard(GameInfo.Size, GameInfo.Handicap); Turns = new List<GoTurn>(); KoPoint = null; IsGameOver = false; GameRule = RulesType.normal; NumberOfStonesToCapture = 5; m_currentTurn = 0; m_colorToMove = GameInfo.Handicap < 2 ? GoColor.BLACK : GoColor.WHITE; }
private void CheckGroupLiberties_rec(GoPoint point, GoColor color, ref List <GoPoint> alreadyParsed, ref List <GoPoint> liberties) { alreadyParsed.Add(point); foreach (GoPoint adjacent in getAdjacents(point)) { if (!alreadyParsed.Contains(adjacent)) { if (Stones.ContainsKey(adjacent)) { if (Stones[adjacent] == color) { CheckGroupLiberties_rec(adjacent, color, ref alreadyParsed, ref liberties); } } else if (!liberties.Contains(adjacent)) { liberties.Add(adjacent); } } } }
public bool isPointFree(GoPoint point) { return !Stones.ContainsKey(point); }
public GoPoint GetLeft() { GoPoint point = new GoPoint(this.X - 1, this.Y); return(point); }
public bool isPointFree(GoPoint point) { return(!Stones.ContainsKey(point)); }
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) { Console.WriteLine(outLine.Data); // Collect the sort command output. if (!String.IsNullOrEmpty(outLine.Data)) { // Send event to notify response if (ResponsePushed != null) { ResponsePushed(this, new ResponseEventArgs(outLine.Data)); } if (!string.IsNullOrEmpty(m_expectedAnswer)) { if (m_expectedAnswer != outLine.Data) { throw new Exception("The program Pachi is not behaving as expected! The program needs to shutdown!"); } else { // we can clear that expected answer then m_expectedAnswer = null; } } // TODO proper parsing with regex to avoid errors // Analyse the response if (outLine.Data.StartsWith("=")) { m_waitingForAnswer = false; if (m_invalidateAnyMoves) { return; } if (outLine.Data == "= pass") { GoMove move = new GoMove(m_lastColorAsked, null, true); // Send the play if (HasPlayed != null && move != null) { HasPlayed(this, move); } } else { // parse the answer String coord = outLine.Data.Substring(2); if (coord.Length >= 2) { int x = (int)(coord[0] - 'A') + 1; // because I column doesn't exist if (coord[0] > 'I') { x = x - 1; } int y = int.Parse(coord.Substring(1)); GoPoint point = new GoPoint(x, y); GoMove move = new GoMove(m_lastColorAsked, point, false); // Send the play if (HasPlayed != null && move != null) { HasPlayed(this, move); } } } } } ExecuteNextCommand(); }
public GoMove(GoColor color, GoPoint point, bool isPass) { Color = color; Point = point; IsPass = isPass; }
public GoPoint GetDown() { GoPoint point = new GoPoint(this.X, this.Y - 1); return(point); }
public GoPoint GetUp() { GoPoint point = new GoPoint(this.X, this.Y + 1); return point; }
public GoPoint GetLeft() { GoPoint point = new GoPoint(this.X - 1, this.Y); return point; }
public GoPoint GetRight() { GoPoint point = new GoPoint(this.X + 1, this.Y); return(point); }
// Coordinates should be in [1, size] // Origin is bottom left like for pachi public bool isOnBoard(GoPoint point) { if (point.X < 1 || point.Y < 1 || point.X > m_size || point.Y > m_size) { return false; } return true; }
public List<GoPoint> getAdjacents(GoPoint point) { if (!isOnBoard(point)) { throw new Exception("There is no point checking a move which is not on board!"); } List<GoPoint> adjacents = new List<GoPoint>(); if (isOnBoard(point.GetUp())) { adjacents.Add(point.GetUp()); } if (isOnBoard(point.GetRight())) { adjacents.Add(point.GetRight()); } if (isOnBoard(point.GetDown())) { adjacents.Add(point.GetDown()); } if (isOnBoard(point.GetLeft())) { adjacents.Add(point.GetLeft()); } return adjacents; }
public void CheckGroupLiberties(GoPoint point, GoColor color, out List<GoPoint> group, out List<GoPoint> liberties) { group = new List<GoPoint>(); liberties = new List<GoPoint>(); if (color != GoColor.EMPTY) { CheckGroupLiberties_rec(point, color, ref group, ref liberties); } }
// return true if the move is accepted, otherwise false // and message indicate why public bool PlayMove(GoMove move, ref GoMessageId message) { bool isValid = false; if (m_currentTurn != Turns.Count) { throw new Exception("You can't play if the state of the game is not the most recent, you might want to create a variation though but it is not implemented yet!"); } if(move.IsPass) { // this is a pass // is it the second one? if (Turns.Last().Move.Point == null) { // compute score float score = 0.0f; GoColor winner = GoColor.EMPTY; float whiteScore = 0.0f; float blackScore = 0.0f; StrasCouting(out whiteScore, out blackScore); if (whiteScore > blackScore) { winner = GoColor.WHITE; score = whiteScore - blackScore; } else { winner = GoColor.BLACK; score = blackScore - whiteScore; } // two pass the game is over switch (GameRule) { case RulesType.normal: OnGameIsOver(new GameResultEventArgs(winner, score, blackScore, whiteScore, false)); break; case RulesType.capture_N: int numberOfCapturesForWhite = GetNumberOfCapturedStonesFor(GoColor.WHITE); int numberOfCapturesForBlack = GetNumberOfCapturedStonesFor(GoColor.BLACK); GoColor moreCaptures = numberOfCapturesForWhite == numberOfCapturesForBlack ? GoColor.EMPTY : numberOfCapturesForWhite > numberOfCapturesForBlack ? GoColor.WHITE : GoColor.BLACK; OnGameIsOver(new GameResultEventArgs(moreCaptures , 0 , numberOfCapturesForBlack , numberOfCapturesForWhite , false)); break; default: throw new Exception("Error: unsupported rules type!"); } } GoTurn thisTurn = new GoTurn(move, m_currentTurn); thisTurn.OldKoPoint = KoPoint; // link the turns if (GetLastTurn() != null) { GetLastTurn().NextTurns.Add(thisTurn); thisTurn.PreviousTurn = GetLastTurn(); } // add to the list of turns Turns.Add(thisTurn); m_currentTurn++; isValid = true; } else if(move.Color == m_colorToMove) { // is it the ko point? if (KoPoint != null && move.Point == KoPoint) { message = GoMessageId.KO_THREAT_FIRST; isValid = false; } else { // is it on an empty space? if (Board.isPointFree(move.Point)) { // is it capturing something? List<GoPoint> captured = Board.WillCapture(move); if (captured.Count > 0) { GoTurn thisTurn = new GoTurn(move, m_currentTurn); thisTurn.Killed = captured; thisTurn.OldKoPoint = KoPoint; // link the turns if (GetLastTurn() != null) { GetLastTurn().NextTurns.Add(thisTurn); thisTurn.PreviousTurn = GetLastTurn(); } // add to the list of turns Turns.Add(thisTurn); m_currentTurn++; isValid = true; } else { // otherwise is it a suicide? if (Board.IsSuicide(move)) { message = GoMessageId.SUICIDE_MOVE; isValid = false; } else { // play the move increment turn counting GoTurn thisTurn = new GoTurn(move, m_currentTurn); thisTurn.OldKoPoint = KoPoint; // link the turns if (GetLastTurn() != null ) { GetLastTurn().NextTurns.Add(thisTurn); thisTurn.PreviousTurn = GetLastTurn(); } // add to the list of turns Turns.Add(thisTurn); m_currentTurn++; isValid = true; } } } else { message = GoMessageId.ALREADY_A_STONE; isValid = false; } } } else { // WARNING your move will be ignored message = GoMessageId.NOT_COLOR_TURN; isValid = false; } if (isValid) { Board.Execute(Turns.Last()); KoPoint = null; // did it created a ko? if (GetLastTurn().Killed != null && GetLastTurn().Killed.Count == 1) { // test if the captured position would be a suicide for the other color GoMove suicideTest = new GoMove( Helper.GetOppositeColor(move.Color), GetLastTurn().Killed[0], false); if( Board.IsSuicide(suicideTest)) { // but if it capture exactly one stone back it is a ko List<GoPoint> koTest = Board.WillCapture(suicideTest); if (koTest.Count == 1) { KoPoint = suicideTest.Point; } } } else { // otherwise reinitialise the ko to null KoPoint = null; } // if it capture and we are playing the capture 5 stones rules // we need to check if the game is over if (GameRule == RulesType.capture_N && GetLastTurn().Killed != null && GetLastTurn().Killed.Count > 0) { if (GetNumberOfCapturedStonesFor(m_colorToMove) >= NumberOfStonesToCapture) { OnGameIsOver(new GameResultEventArgs(m_colorToMove , 0 , GetNumberOfCapturedStonesFor(GoColor.BLACK) , GetNumberOfCapturedStonesFor(GoColor.WHITE) , false)); } } Clock.NotifyMovePlayed(m_colorToMove); m_colorToMove = Helper.GetOppositeColor(m_colorToMove); } return isValid; }
public GoPoint GetDown() { GoPoint point = new GoPoint(this.X, this.Y - 1); return point; }
private void CheckGroupLiberties_rec(GoPoint point, GoColor color, ref List<GoPoint> alreadyParsed, ref List<GoPoint> liberties) { alreadyParsed.Add(point); foreach (GoPoint adjacent in getAdjacents(point)) { if( !alreadyParsed.Contains(adjacent)) { if (Stones.ContainsKey(adjacent)) { if (Stones[adjacent] == color) { CheckGroupLiberties_rec(adjacent, color, ref alreadyParsed, ref liberties); } } else if( !liberties.Contains(adjacent)) { liberties.Add(adjacent); } } } }
public GoPoint GetRight() { GoPoint point = new GoPoint(this.X + 1, this.Y); return point; }
// return true if the move is accepted, otherwise false // and message indicate why public bool PlayMove(GoMove move, ref GoMessageId message) { bool isValid = false; if (m_currentTurn != Turns.Count) { throw new Exception("You can't play if the state of the game is not the most recent, you might want to create a variation though but it is not implemented yet!"); } if (move.IsPass) { // this is a pass // is it the second one? if (Turns.Last().Move.Point == null) { // compute score float score = 0.0f; GoColor winner = GoColor.EMPTY; float whiteScore = 0.0f; float blackScore = 0.0f; StrasCouting(out whiteScore, out blackScore); if (whiteScore > blackScore) { winner = GoColor.WHITE; score = whiteScore - blackScore; } else { winner = GoColor.BLACK; score = blackScore - whiteScore; } // two pass the game is over switch (GameRule) { case RulesType.normal: OnGameIsOver(new GameResultEventArgs(winner, score, blackScore, whiteScore, false)); break; case RulesType.capture_N: int numberOfCapturesForWhite = GetNumberOfCapturedStonesFor(GoColor.WHITE); int numberOfCapturesForBlack = GetNumberOfCapturedStonesFor(GoColor.BLACK); GoColor moreCaptures = numberOfCapturesForWhite == numberOfCapturesForBlack ? GoColor.EMPTY : numberOfCapturesForWhite > numberOfCapturesForBlack ? GoColor.WHITE : GoColor.BLACK; OnGameIsOver(new GameResultEventArgs(moreCaptures , 0 , numberOfCapturesForBlack , numberOfCapturesForWhite , false)); break; default: throw new Exception("Error: unsupported rules type!"); } } GoTurn thisTurn = new GoTurn(move, m_currentTurn); thisTurn.OldKoPoint = KoPoint; // link the turns if (GetLastTurn() != null) { GetLastTurn().NextTurns.Add(thisTurn); thisTurn.PreviousTurn = GetLastTurn(); } // add to the list of turns Turns.Add(thisTurn); m_currentTurn++; isValid = true; } else if (move.Color == m_colorToMove) { // is it the ko point? if (KoPoint != null && move.Point == KoPoint) { message = GoMessageId.KO_THREAT_FIRST; isValid = false; } else { // is it on an empty space? if (Board.isPointFree(move.Point)) { // is it capturing something? List <GoPoint> captured = Board.WillCapture(move); if (captured.Count > 0) { GoTurn thisTurn = new GoTurn(move, m_currentTurn); thisTurn.Killed = captured; thisTurn.OldKoPoint = KoPoint; // link the turns if (GetLastTurn() != null) { GetLastTurn().NextTurns.Add(thisTurn); thisTurn.PreviousTurn = GetLastTurn(); } // add to the list of turns Turns.Add(thisTurn); m_currentTurn++; isValid = true; } else { // otherwise is it a suicide? if (Board.IsSuicide(move)) { message = GoMessageId.SUICIDE_MOVE; isValid = false; } else { // play the move increment turn counting GoTurn thisTurn = new GoTurn(move, m_currentTurn); thisTurn.OldKoPoint = KoPoint; // link the turns if (GetLastTurn() != null) { GetLastTurn().NextTurns.Add(thisTurn); thisTurn.PreviousTurn = GetLastTurn(); } // add to the list of turns Turns.Add(thisTurn); m_currentTurn++; isValid = true; } } } else { message = GoMessageId.ALREADY_A_STONE; isValid = false; } } } else { // WARNING your move will be ignored message = GoMessageId.NOT_COLOR_TURN; isValid = false; } if (isValid) { Board.Execute(Turns.Last()); KoPoint = null; // did it created a ko? if (GetLastTurn().Killed != null && GetLastTurn().Killed.Count == 1) { // test if the captured position would be a suicide for the other color GoMove suicideTest = new GoMove( Helper.GetOppositeColor(move.Color), GetLastTurn().Killed[0], false); if (Board.IsSuicide(suicideTest)) { // but if it capture exactly one stone back it is a ko List <GoPoint> koTest = Board.WillCapture(suicideTest); if (koTest.Count == 1) { KoPoint = suicideTest.Point; } } } else { // otherwise reinitialise the ko to null KoPoint = null; } // if it capture and we are playing the capture 5 stones rules // we need to check if the game is over if (GameRule == RulesType.capture_N && GetLastTurn().Killed != null && GetLastTurn().Killed.Count > 0) { if (GetNumberOfCapturedStonesFor(m_colorToMove) >= NumberOfStonesToCapture) { OnGameIsOver(new GameResultEventArgs(m_colorToMove , 0 , GetNumberOfCapturedStonesFor(GoColor.BLACK) , GetNumberOfCapturedStonesFor(GoColor.WHITE) , false)); } } Clock.NotifyMovePlayed(m_colorToMove); m_colorToMove = Helper.GetOppositeColor(m_colorToMove); } return(isValid); } // end of PlayMove
public bool IsPass; // if point is null public GoMove(GoColor color, GoPoint point, bool isPass) { Color = color; Point = point; IsPass = isPass; }
public GoPoint GetUp() { GoPoint point = new GoPoint(this.X, this.Y + 1); return(point); }