Пример #1
0
        // total_hints = the number of parseble move hints in the gnubg string, ie. 6/off contains one, bar/23 6/3 contains two
        private Move ParseMoveHint(string move_string, out int count, int total_hints, int[] dice, GameState gamestate)
        {
            // from/to
            // from/to(count)
            // 'bar'/to
            // 'bar'/to(count)
            // from/'off'
            // from/'off'(count)
            // from/to*/to*
            // from/to*/to*/to*
            // from/'off'

            // get count and remove it from the string
            count = 1;
            int count_start_index = move_string.IndexOf('(');
            if (count_start_index > 0)
            {
                int count_end_index = move_string.IndexOf(')');
                count = int.Parse(move_string.Substring(count_start_index + 1, count_end_index - count_start_index - 1));
                move_string = move_string.Substring(0, count_start_index);
            }

            string[] point_strings = move_string.Split(new char[] { '/' });

            List<int> points = new List<int>();
            HashSet<int> hitpoints = new HashSet<int>();
            bool is_number;
            foreach (string point_string in point_strings)
            {
                bool hit = point_string.Contains("*");
                string clean_point_string = point_string;
                if (hit)
                    clean_point_string = clean_point_string.Replace("*", "");

                is_number = true;
                foreach (char c in clean_point_string)
                    if (!char.IsDigit(c))
                    {
                        is_number = false;
                        break;
                    }
                if (is_number)
                {
                    int point = int.Parse(clean_point_string) - 1;
                    points.Add(point);
                    if (hit)
                        hitpoints.Add(point);
                }
            }

            if (point_strings[0][0] == 'b')
                points.Insert(0, 24);

            if (point_strings[point_strings.Length - 1][0] == 'o')
                points.Insert(points.Count, -1);
            // points should be sorted from highest to lowest at this point

            // calculate the missing way points
            if (dice[0] != dice[1])
            {
                if (count == 1 && points.Count == 2)
                {
                    int distance = points[0] - points[1];
                    int bigger_die = Math.Max(dice[0], dice[1]);
                    int smaller_die = Math.Min(dice[0], dice[1]);
                    if (distance > bigger_die)//(points[0] - points[1]) == (dice[0] + dice[1]))
                    {
                        if (distance == (dice[0] + dice[1]))
                        {
                            // Must not contain hits, because gnubg tells about the hit points seperately.
                            if (gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - bigger_die) >= 0)
                                points.Insert(0, (points[0] - bigger_die));
                            else
                                points.Insert(0, (points[0] - smaller_die));
                        }
                        else if (points[0] - bigger_die < smaller_die) // bearoff from 6 with 52, need first to do the smaller one.
                        {
                            if (gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - smaller_die) >= 0) // Was broken without this condition on _ _ 8x 2o 2o 2o with dice 43
                                points.Insert(0, (points[0] - smaller_die));
                            else if (gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - smaller_die) == -1)
                                points.Insert(0, (points[0] - bigger_die));
                            else
                            {
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("Cannot handle this. Help!");
                        }
                        /*if (gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - bigger_die) > -2)
                            points.Insert(0, (points[0] - bigger_die));
                        else
                            points.Insert(0, (points[0] - smaller_die));*/
                    } // This is for lonely bearoffs like |_ _ x _ x x| with 41, gnubg gives one of the hints as '4/off'.
                        // We want atleast 2 chequers on the field because otherwise adding a waypoint is unnecessary inbetween.
                    else if (total_hints == 1 && gamestate.Board.FinishedCount(gamestate.PlayerOnRoll) <= 13 && points[1] == -1 && (points[0] - smaller_die >= 0) && gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - smaller_die) >= 0 && gamestate.Board.LastChequer(gamestate.PlayerOnRoll) <= points[0])
                    {
                        points.Insert(0, (points[0] - smaller_die));
                    }
                    else
                    {

                    }
                }
            }
            else
            {
                for (int i = 0; i < points.Count - 1; i++)
                {
                    // This was broken with bearoffs without this condition (ie. 6/off with 44, the below else condition should handle this situation)
                    /*if (points[i + 1] > -1)
                    {*/
                        int gaps = (points[i] - points[i + 1]) / dice[0];
                        int mod = (points[i] - points[i + 1]) % dice[0];
                        if (mod > 0)
                            gaps++;

                        if (gaps > 1)
                        {
                            for (int c = 1; c < gaps; c++)
                            {
                                points.Insert(i + 1, points[i] - dice[0]);
                                i++;
                            }
                        }
                    /*}
                    else
                    {
                        int gaps = (points[i] - points[i + 1]) / dice[0];
                        int mod = (points[i] - points[i + 1]) % dice[0];
                        if (mod > 0)
                        {
                            for (int c = 0; c < gaps; c++)
                            {
                                points.Insert(i + 1, points[i] - dice[0]);
                                i++;
                            }
                        }
                    }*/
                }
            }

            Move move = new Move();
            foreach (int point in points)
            {
                if (hitpoints.Contains(point))
                    move.AddHitPoint(point);
                else
                    move.AddPoint(point);
            }

            return move;
        }
Пример #2
0
        void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            if (currentGameState.PlayerOnTurn == 0 && !currentGameState.HasOffer && currentGameState.DiceRolled && legalPlays.Count > 0 && madeMoves.Count < legalPlays[0].Count)
            {
                BoundingChequer chequer = ClickTest(e.Location);
                if (chequer == null)
                {
                    return;
                }

                int[] dice = currentGameState.Dice;

                int from = chequer.Slot;

                if (dice[0] != dice[1])
                {
                    int die = -1;
                    if (unusedDice.Count == 2)
                    {
                        if (e.Button == MouseButtons.Left)
                        {
                            die = Math.Max(unusedDice[0], unusedDice[1]);
                        }
                        else if (e.Button == MouseButtons.Right)
                        {
                            die = Math.Min(unusedDice[0], unusedDice[1]);
                        }
                        else
                        {
                            return;
                        }
                    }
                    else
                    {
                        die = unusedDice[0];
                    }

                    int to = chequer.Slot - die;
                    if (to < -1)
                    {
                        to = -1;
                    }

                    Move move = new Move(from, to);

                    if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, die))
                    {
                        if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1)
                        {
                            move.AddHitPoint(to);
                        }

                        watch.Stop();

                        /*Stack<Move> s = new Stack<Move>();
                         * foreach (Move m in madeMoves.Reverse())
                         *      s.Push(m.Clone());*/

                        List <TimedMove> h = new List <TimedMove>();
                        foreach (TimedMove m in moveHistory)
                        {
                            h.Add(new TimedMove(m));
                        }

                        TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0);

                        moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h));

                        currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move);
                        madeMoves.Push(move);
                        moveHistory.Add(tmove);

                        unusedDice.Remove(die);
                        usedDice.Push(die);

                        UpdateControls();
                    }
                    else
                    {
                        if (unusedDice.Count == 2)
                        {
                            die = (dice[0] == die) ? dice[1] : dice[0];

                            to = chequer.Slot - die;
                            if (to < -1)
                            {
                                to = -1;
                            }

                            move = new Move(from, to);

                            if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, die))
                            {
                                if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1)
                                {
                                    move.AddHitPoint(to);
                                }

                                watch.Stop();

                                /*Stack<Move> s = new Stack<Move>();
                                 * foreach (Move m in madeMoves.Reverse())
                                 *      s.Push(m.Clone());*/

                                //moves.Add(new GameStateMoveAction(currentGameState.Clone(), watch.ElapsedMilliseconds, move.Clone(), s));

                                List <TimedMove> h = new List <TimedMove>();
                                foreach (TimedMove m in moveHistory)
                                {
                                    h.Add(new TimedMove(m));
                                }

                                TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0);

                                moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h));

                                currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move);
                                madeMoves.Push(move);
                                moveHistory.Add(tmove);

                                unusedDice.Remove(die);
                                usedDice.Push(die);

                                UpdateControls();
                            }
                        }
                        //else
                        //Console.WriteLine("Illegal move " + from + "/" + to);
                    }
                }
                else
                {
                    int to = chequer.Slot - dice[0];
                    if (to < -1)
                    {
                        to = -1;
                    }
                    Move move = new Move(from, to);

                    if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, dice[0]))
                    {
                        if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1)
                        {
                            move.AddHitPoint(to);
                        }

                        watch.Stop();

                        /*Stack<Move> s = new Stack<Move>();
                         * foreach (Move m in madeMoves.Reverse())
                         *      s.Push(m.Clone());
                         *
                         * moves.Add(new GameStateMoveAction(currentGameState.Clone(), watch.ElapsedMilliseconds, move.Clone(), s));*/

                        List <TimedMove> h = new List <TimedMove>();
                        foreach (TimedMove m in moveHistory)
                        {
                            h.Add(new TimedMove(m));
                        }

                        TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0);

                        moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h));

                        currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move);
                        madeMoves.Push(move);
                        moveHistory.Add(tmove);

                        unusedDice.Remove(dice[0]);
                        usedDice.Push(dice[0]);

                        UpdateControls();
                    }
                }
                // Fix problem when making an illegal move the watch resets itsefl
            }
        }
Пример #3
0
        void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            if (currentGameState.PlayerOnTurn == 0 && !currentGameState.HasOffer && currentGameState.DiceRolled && legalPlays.Count > 0 && madeMoves.Count < legalPlays[0].Count)
            {
                BoundingChequer chequer = ClickTest(e.Location);
                if (chequer == null)
                    return;

                int[] dice = currentGameState.Dice;

                int from = chequer.Slot;

                if (dice[0] != dice[1])
                {
                    int die = -1;
                    if (unusedDice.Count == 2)
                    {
                        if (e.Button == MouseButtons.Left)
                            die = Math.Max(unusedDice[0], unusedDice[1]);
                        else if (e.Button == MouseButtons.Right)
                            die = Math.Min(unusedDice[0], unusedDice[1]);
                        else
                            return;
                    }
                    else
                        die = unusedDice[0];

                    int to = chequer.Slot - die;
                    if (to < -1)
                        to = -1;

                    Move move = new Move(from, to);

                    if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, die))
                    {
                        if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1)
                            move.AddHitPoint(to);

                        watch.Stop();

                        /*Stack<Move> s = new Stack<Move>();
                        foreach (Move m in madeMoves.Reverse())
                            s.Push(m.Clone());*/

                        List<TimedMove> h = new List<TimedMove>();
                        foreach (TimedMove m in moveHistory)
                            h.Add(new TimedMove(m));

                        TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0);

                        moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h));

                        currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move);
                        madeMoves.Push(move);
                        moveHistory.Add(tmove);

                        unusedDice.Remove(die);
                        usedDice.Push(die);

                        UpdateControls();
                    }
                    else
                    {
                        if (unusedDice.Count == 2)
                        {
                            die = (dice[0] == die) ? dice[1] : dice[0];

                            to = chequer.Slot - die;
                            if (to < -1)
                                to = -1;

                            move = new Move(from, to);

                            if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, die))
                            {
                                if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1)
                                    move.AddHitPoint(to);

                                watch.Stop();
                                /*Stack<Move> s = new Stack<Move>();
                                foreach (Move m in madeMoves.Reverse())
                                    s.Push(m.Clone());*/

                                //moves.Add(new GameStateMoveAction(currentGameState.Clone(), watch.ElapsedMilliseconds, move.Clone(), s));

                                List<TimedMove> h = new List<TimedMove>();
                                foreach (TimedMove m in moveHistory)
                                    h.Add(new TimedMove(m));

                                TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0);

                                moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h));

                                currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move);
                                madeMoves.Push(move);
                                moveHistory.Add(tmove);

                                unusedDice.Remove(die);
                                usedDice.Push(die);

                                UpdateControls();
                            }
                        }
                        //else
                        //Console.WriteLine("Illegal move " + from + "/" + to);
                    }
                }
                else
                {
                    int to = chequer.Slot - dice[0];
                    if (to < -1)
                        to = -1;
                    Move move = new Move(from, to);

                    if (currentGameState.Board.IsLegalMove(currentGameState.PlayerOnRoll, move, dice[0]))
                    {
                        if (to >= 0 && currentGameState.Board.PointCount(currentGameState.PlayerOnRoll, to) == -1)
                            move.AddHitPoint(to);

                        watch.Stop();

                        /*Stack<Move> s = new Stack<Move>();
                        foreach (Move m in madeMoves.Reverse())
                            s.Push(m.Clone());

                        moves.Add(new GameStateMoveAction(currentGameState.Clone(), watch.ElapsedMilliseconds, move.Clone(), s));*/

                        List<TimedMove> h = new List<TimedMove>();
                        foreach (TimedMove m in moveHistory)
                            h.Add(new TimedMove(m));

                        TimedMove tmove = new TimedMove(move, (int)watch.ElapsedMilliseconds, 0);

                        moves.Add(new GameStateMoveAction(currentGameState.Clone(), originalGameState, watch.ElapsedMilliseconds, tmove, h));

                        currentGameState.Board.MakeMove(currentGameState.PlayerOnRoll, move);
                        madeMoves.Push(move);
                        moveHistory.Add(tmove);

                        unusedDice.Remove(dice[0]);
                        usedDice.Push(dice[0]);

                        UpdateControls();
                    }
                }
                // Fix problem when making an illegal move the watch resets itsefl
            }
        }
Пример #4
0
        // total_hints = the number of parseble move hints in the gnubg string, ie. 6/off contains one, bar/23 6/3 contains two
        private Move ParseMoveHint(string move_string, out int count, int total_hints, int[] dice, GameState gamestate)
        {
            // from/to
            // from/to(count)
            // 'bar'/to
            // 'bar'/to(count)
            // from/'off'
            // from/'off'(count)
            // from/to*/to*
            // from/to*/to*/to*
            // from/'off'

            // get count and remove it from the string
            count = 1;
            int count_start_index = move_string.IndexOf('(');

            if (count_start_index > 0)
            {
                int count_end_index = move_string.IndexOf(')');
                count       = int.Parse(move_string.Substring(count_start_index + 1, count_end_index - count_start_index - 1));
                move_string = move_string.Substring(0, count_start_index);
            }

            string[] point_strings = move_string.Split(new char[] { '/' });

            List <int>    points    = new List <int>();
            HashSet <int> hitpoints = new HashSet <int>();
            bool          is_number;

            foreach (string point_string in point_strings)
            {
                bool   hit = point_string.Contains("*");
                string clean_point_string = point_string;
                if (hit)
                {
                    clean_point_string = clean_point_string.Replace("*", "");
                }

                is_number = true;
                foreach (char c in clean_point_string)
                {
                    if (!char.IsDigit(c))
                    {
                        is_number = false;
                        break;
                    }
                }
                if (is_number)
                {
                    int point = int.Parse(clean_point_string) - 1;
                    points.Add(point);
                    if (hit)
                    {
                        hitpoints.Add(point);
                    }
                }
            }

            if (point_strings[0][0] == 'b')
            {
                points.Insert(0, 24);
            }

            if (point_strings[point_strings.Length - 1][0] == 'o')
            {
                points.Insert(points.Count, -1);
            }
            // points should be sorted from highest to lowest at this point


            // calculate the missing way points
            if (dice[0] != dice[1])
            {
                if (count == 1 && points.Count == 2)
                {
                    int distance    = points[0] - points[1];
                    int bigger_die  = Math.Max(dice[0], dice[1]);
                    int smaller_die = Math.Min(dice[0], dice[1]);
                    if (distance > bigger_die)                    //(points[0] - points[1]) == (dice[0] + dice[1]))
                    {
                        if (distance == (dice[0] + dice[1]))
                        {
                            // Must not contain hits, because gnubg tells about the hit points seperately.
                            if (gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - bigger_die) >= 0)
                            {
                                points.Insert(0, (points[0] - bigger_die));
                            }
                            else
                            {
                                points.Insert(0, (points[0] - smaller_die));
                            }
                        }
                        else if (points[0] - bigger_die < smaller_die)                                            // bearoff from 6 with 52, need first to do the smaller one.
                        {
                            if (gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - smaller_die) >= 0) // Was broken without this condition on _ _ 8x 2o 2o 2o with dice 43
                            {
                                points.Insert(0, (points[0] - smaller_die));
                            }
                            else if (gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - smaller_die) == -1)
                            {
                                points.Insert(0, (points[0] - bigger_die));
                            }
                            else
                            {
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("Cannot handle this. Help!");
                        }

                        /*if (gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - bigger_die) > -2)
                         *  points.Insert(0, (points[0] - bigger_die));
                         * else
                         *  points.Insert(0, (points[0] - smaller_die));*/
                    }                     // This is for lonely bearoffs like |_ _ x _ x x| with 41, gnubg gives one of the hints as '4/off'.
                    // We want atleast 2 chequers on the field because otherwise adding a waypoint is unnecessary inbetween.
                    else if (total_hints == 1 && gamestate.Board.FinishedCount(gamestate.PlayerOnRoll) <= 13 && points[1] == -1 && (points[0] - smaller_die >= 0) && gamestate.Board.PointCount(gamestate.PlayerOnRoll, points[0] - smaller_die) >= 0 && gamestate.Board.LastChequer(gamestate.PlayerOnRoll) <= points[0])
                    {
                        points.Insert(0, (points[0] - smaller_die));
                    }
                    else
                    {
                    }
                }
            }
            else
            {
                for (int i = 0; i < points.Count - 1; i++)
                {
                    // This was broken with bearoffs without this condition (ie. 6/off with 44, the below else condition should handle this situation)

                    /*if (points[i + 1] > -1)
                     * {*/
                    int gaps = (points[i] - points[i + 1]) / dice[0];
                    int mod  = (points[i] - points[i + 1]) % dice[0];
                    if (mod > 0)
                    {
                        gaps++;
                    }

                    if (gaps > 1)
                    {
                        for (int c = 1; c < gaps; c++)
                        {
                            points.Insert(i + 1, points[i] - dice[0]);
                            i++;
                        }
                    }

                    /*}
                     * else
                     * {
                     *  int gaps = (points[i] - points[i + 1]) / dice[0];
                     *  int mod = (points[i] - points[i + 1]) % dice[0];
                     *  if (mod > 0)
                     *  {
                     *      for (int c = 0; c < gaps; c++)
                     *      {
                     *          points.Insert(i + 1, points[i] - dice[0]);
                     *          i++;
                     *      }
                     *  }
                     * }*/
                }
            }

            Move move = new Move();

            foreach (int point in points)
            {
                if (hitpoints.Contains(point))
                {
                    move.AddHitPoint(point);
                }
                else
                {
                    move.AddPoint(point);
                }
            }



            return(move);
        }