Пример #1
0
 public GoTurn(GoMove move, int number)
 {
     Move = move;
     TurnNumber = number;
     PreviousTurn = null;
     NextTurns = new List<GoTurn>();
 }
Пример #2
0
        public List <GoPoint> WillCapture(GoMove move)
        {
            List <GoPoint> captured      = new List <GoPoint>();
            GoColor        capturedColor = Helper.GetOppositeColor(move.Color);

            // check adjacents
            foreach (GoPoint potentialCaptured in getAdjacents(move.Point))
            {
                if (Stones.ContainsKey(potentialCaptured))
                {
                    if (Stones[potentialCaptured] == capturedColor &&
                        !captured.Contains(potentialCaptured))
                    {
                        // check liberties
                        // note: this checking is done before the move is executed
                        // means that actually if this adjacent group has only one liberty
                        // we will play on it, so yes it will be captured
                        List <GoPoint> group, liberties;
                        CheckGroupLiberties(potentialCaptured, capturedColor, out group, out liberties);
                        if (liberties.Count < 2)
                        {
                            // it is captured
                            captured.AddRange(group);
                        }
                    }
                }
            }

            return(captured);
        }
Пример #3
0
 public GoTurn(GoMove move, int number)
 {
     Move         = move;
     TurnNumber   = number;
     PreviousTurn = null;
     NextTurns    = new List <GoTurn>();
 }
Пример #4
0
        public bool IsSuicide(GoMove move)
        {
            List <GoPoint> group, liberties;

            CheckGroupLiberties(move.Point, move.Color, out group, out liberties);

            return(liberties.Count == 0);
        }
Пример #5
0
        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();
        }
Пример #6
0
        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();
        }
Пример #7
0
        // 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
Пример #8
0
        public List<GoPoint> WillCapture(GoMove move)
        {
            List<GoPoint> captured = new List<GoPoint>();
            GoColor capturedColor = Helper.GetOppositeColor(move.Color);

            // check adjacents
            foreach (GoPoint potentialCaptured in getAdjacents(move.Point))
            {
                if (Stones.ContainsKey(potentialCaptured))
                {
                    if (Stones[potentialCaptured] == capturedColor
                        && !captured.Contains(potentialCaptured))
                    {
                        // check liberties
                        // note: this checking is done before the move is executed
                        // means that actually if this adjacent group has only one liberty
                        // we will play on it, so yes it will be captured
                        List<GoPoint> group, liberties;
                        CheckGroupLiberties(potentialCaptured, capturedColor, out group, out liberties);
                        if (liberties.Count < 2)
                        {
                            // it is captured
                            captured.AddRange(group);
                        }
                    }
                }
            }

            return captured;
        }
Пример #9
0
        public bool IsSuicide(GoMove move)
        {
            List<GoPoint> group, liberties;
            CheckGroupLiberties(move.Point, move.Color, out group, out liberties);

            return liberties.Count == 0;
        }
Пример #10
0
        // 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;
        }