예제 #1
0
 public GoTurn(GoMove move, int number)
 {
     Move         = move;
     TurnNumber   = number;
     PreviousTurn = null;
     NextTurns    = new List <GoTurn>();
 }
예제 #2
0
파일: GoTurn.cs 프로젝트: nyoshi/strasgo
 public GoTurn(GoMove move, int number)
 {
     Move = move;
     TurnNumber = number;
     PreviousTurn = null;
     NextTurns = new List<GoTurn>();
 }
예제 #3
0
파일: GoBoard.cs 프로젝트: nyoshi/strasgo
 public void Execute(GoTurn turn)
 {
     if (!turn.Move.IsPass)
     {
         // add played stone
         Stones.Add(turn.Move.Point, turn.Move.Color);
         // remove captured
         if (turn.Killed != null)
         {
             foreach (GoPoint point in turn.Killed)
             {
                 Stones.Remove(point);
             }
         }
     }
 }
예제 #4
0
        // step can be negative
        public void GetBoardModifications(ref List <GoPoint> pointsToRemove, ref List <GoMove> moveToAdd, int step)
        {
            pointsToRemove.Clear();
            moveToAdd.Clear();

            // special case when m_currentNode is null but a move has been played
            if (m_currentNode == null && step > 0 && Turns.Count == 1)
            {
                moveToAdd.Add(new GoMove(Turns[0].Move.Color, Turns[0].Move.Point, false));
                m_currentNode = Turns[0];
                return;
            }


            // going forward
            if (step > 0 && m_currentNode != null)
            {
                for (int i = 0; i < step; ++i)
                {
                    // take 1st variation as default
                    if (m_currentNode.NextTurns.Count > 0)
                    {
                        m_currentNode = m_currentNode.NextTurns[0];
                        if (!m_currentNode.Move.IsPass)
                        {
                            // wanna add this move so if it was asked to be remove, cancel it
                            pointsToRemove.Remove(m_currentNode.Move.Point);
                            moveToAdd.Add(new GoMove(m_currentNode.Move.Color, m_currentNode.Move.Point, false));

                            if (m_currentNode != null && m_currentNode.Killed != null)
                            {
                                foreach (GoPoint point in m_currentNode.Killed)
                                {
                                    // want to remove it? so if wanted to add it, cancel it
                                    List <int> indexToRemove = new List <int>();
                                    for (int j = 0; j < moveToAdd.Count; ++j)
                                    {
                                        if (moveToAdd[j].Point == point)
                                        {
                                            indexToRemove.Add(j);
                                        }
                                    }
                                    foreach (int j in indexToRemove)
                                    {
                                        moveToAdd.RemoveAt(j);
                                    }
                                    pointsToRemove.Add(point);
                                }
                            }
                        }
                    }
                }
            }
            // going backward
            else if (step < 0 && m_currentNode != null)
            {
                for (int i = step; i < 0; ++i)
                {
                    if (m_currentNode.PreviousTurn != null)
                    {
                        if (!m_currentNode.Move.IsPass)
                        {
                            // want to remove it? so if wanted to add it, cancel it
                            List <int> indexToRemove = new List <int>();
                            for (int j = 0; j < moveToAdd.Count; ++j)
                            {
                                if (moveToAdd[j].Point == m_currentNode.Move.Point)
                                {
                                    indexToRemove.Add(j);
                                }
                            }
                            foreach (int j in indexToRemove)
                            {
                                moveToAdd.RemoveAt(j);
                            }

                            pointsToRemove.Add(m_currentNode.Move.Point);
                            if (m_currentNode != null && m_currentNode.Killed != null)
                            {
                                foreach (GoPoint point in m_currentNode.Killed)
                                {
                                    pointsToRemove.Remove(point);
                                    moveToAdd.Add(new GoMove(Helper.GetOppositeColor(m_currentNode.Move.Color), point, false));
                                }
                            }
                        }
                        m_currentNode = m_currentNode.PreviousTurn;
                    }
                }
            }
        }
예제 #5
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
예제 #6
0
파일: GoBoard.cs 프로젝트: nyoshi/strasgo
 public void Execute(GoTurn turn)
 {
     if (!turn.Move.IsPass)
     {
         // add played stone
         Stones.Add(turn.Move.Point, turn.Move.Color);
         // remove captured
         if (turn.Killed != null)
         {
             foreach (GoPoint point in turn.Killed)
             {
                 Stones.Remove(point);
             }
         }
     }
 }
예제 #7
0
파일: GoGame.cs 프로젝트: nyoshi/strasgo
        // step can be negative
        public void GetBoardModifications( ref List<GoPoint> pointsToRemove, ref List<GoMove> moveToAdd, int step )
        {
            pointsToRemove.Clear();
            moveToAdd.Clear();

            // special case when m_currentNode is null but a move has been played
            if (m_currentNode == null && step > 0 && Turns.Count == 1)
            {
                moveToAdd.Add(new GoMove(Turns[0].Move.Color, Turns[0].Move.Point, false) );
                m_currentNode = Turns[0];
                return;
            }

            // going forward
            if (step > 0 && m_currentNode != null)
            {
                for (int i = 0; i < step; ++i)
                {
                    // take 1st variation as default
                    if (m_currentNode.NextTurns.Count > 0)
                    {
                        m_currentNode = m_currentNode.NextTurns[0];
                        if (!m_currentNode.Move.IsPass)
                        {
                            // wanna add this move so if it was asked to be remove, cancel it
                            pointsToRemove.Remove(m_currentNode.Move.Point);
                            moveToAdd.Add(new GoMove(m_currentNode.Move.Color, m_currentNode.Move.Point, false));

                            if (m_currentNode != null && m_currentNode.Killed != null)
                            {
                                foreach (GoPoint point in m_currentNode.Killed)
                                {
                                    // want to remove it? so if wanted to add it, cancel it
                                    List<int> indexToRemove = new List<int>();
                                    for (int j = 0; j < moveToAdd.Count; ++j)
                                    {
                                        if (moveToAdd[j].Point == point)
                                        {
                                            indexToRemove.Add(j);
                                        }
                                    }
                                    foreach (int j in indexToRemove)
                                    {
                                        moveToAdd.RemoveAt(j);
                                    }
                                    pointsToRemove.Add(point);
                                }
                            }
                        }
                    }
                }
            }
            // going backward
            else if (step < 0 && m_currentNode != null)
            {
                for (int i = step; i < 0; ++i)
                {
                    if (m_currentNode.PreviousTurn != null)
                    {
                        if (!m_currentNode.Move.IsPass)
                        {
                            // want to remove it? so if wanted to add it, cancel it
                            List<int> indexToRemove = new List<int>();
                            for (int j = 0; j < moveToAdd.Count; ++j)
                            {
                                if (moveToAdd[j].Point == m_currentNode.Move.Point)
                                {
                                    indexToRemove.Add(j);
                                }
                            }
                            foreach (int j in indexToRemove)
                            {
                                moveToAdd.RemoveAt(j);
                            }

                            pointsToRemove.Add(m_currentNode.Move.Point);
                            if (m_currentNode != null && m_currentNode.Killed != null)
                            {
                                foreach (GoPoint point in m_currentNode.Killed)
                                {
                                    pointsToRemove.Remove(point);
                                    moveToAdd.Add(new GoMove(Helper.GetOppositeColor(m_currentNode.Move.Color), point, false));
                                }
                            }
                        }
                        m_currentNode = m_currentNode.PreviousTurn;
                    }
                }
            }
        }
예제 #8
0
파일: GoGame.cs 프로젝트: nyoshi/strasgo
        // 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;
        }