Beispiel #1
0
        /// <summary>
        /// Deep-copy constructor.
        /// </summary>
        /// <param name="board"></param>
        public Board(Board board)
        {
            this.board = new int[2][];
            this.board[0] = new int[24];
            this.board[1] = new int[24];

            this.captured = new int[2];
            this.finished = new int[2];

            this.captured[0] = board.captured[0];
            this.captured[1] = board.captured[1];
            this.finished[0] = board.finished[0];
            this.finished[1] = board.finished[1];

            for (int p = 0; p < 24; p++)
            {
                this.board[0][p] = board.board[0][p];
                this.board[1][p] = board.board[1][p];
            }
        }
Beispiel #2
0
        public GameState(GameType game_type)
        {
            dice = new int[2];
            SetDice(0, 0);
            board = new Board();

            player_on_roll = -1;
            player_on_turn = -1;
            cube.Value = 1;
            cube.Owner = -1;
            offer = OfferType.None;
            resign_offer_value = ResignValue.None;
            score = new int[] { 0, 0 };
            match_to = 1;
            crawford = false;
            stake = 0;
            limit = 0;
            names = new string[] { "", "" };

            this.game_type = game_type;
        }
Beispiel #3
0
        public static string ToPositionID(Board board, int player_on_roll)
        {
            StringBuilder bit_string = new StringBuilder();

            for (int p = 0; p < 24; p++)
            {
                for (int c = 0; c < board.PointCount(player_on_roll, p); c++)
                    bit_string.Append("1");
                bit_string.Append("0");
            }

            for (int c = 0; c < board.CapturedCount(player_on_roll); c++)
                bit_string.Append("1");
            bit_string.Append("0");

            for (int p = 0; p < 24; p++)
            {
                for (int c = 0; c < board.PointCount(1 - player_on_roll, p); c++)
                    bit_string.Append("1");
                bit_string.Append("0");
            }

            for (int c = 0; c < board.CapturedCount(1 - player_on_roll); c++)
                bit_string.Append("1");
            bit_string.Append("0");

            while (bit_string.Length < 80)
                bit_string.Append("0");
            Console.WriteLine(bit_string.ToString().Length);

            return bit_string.ToString();
        }
Beispiel #4
0
        public static Board BoardFromPositionID(string position_id, ref string error)
        {
            Board board = new Board();

            error = "";
            if (position_id.Length != 14)
            {
                if (position_id.Length < 12)
                    error = "Position ID length too short.";
                else
                    error = "Position ID length too long.";
                return null;
            }

            List<bool> bits2 = new List<bool>();
            List<bool> bits = new List<bool>();
            foreach (char c in position_id)
            {
                if (!base64.Contains(c))
                {
                    error = "Position ID contains an invalid character.";
                    return null;
                }

                int dec = base64.IndexOf(c);
                for (int i = 5; i >= 0; i--)
                {
                    bits.Add((powers2[i] & dec) == powers2[i]);
                    //bool bit = (powers2[i] & dec) == powers2[i];
                    //Console.Write(bit?1:0);

                    if (bits.Count == 8)
                    {
                        bits.Reverse();
                        bits2.AddRange(bits);
                        bits.Clear();
                    }
                }
            }

            int total_chequers = 0;
            int slot = 0;
            int player = 0;
            foreach (bool bit in bits2)
            {
                if (bit)
                {
                    if (slot == 24)
                        board.IncreaseCaptured(player);
                    else
                        board.AddToPoint(player, slot, 1);

                    total_chequers++;
                }
                else
                {
                    slot++;
                }

                if (slot == 25)
                {
                    board.SetFinished(player, 15 - total_chequers);

                    player = 1 - player;
                    total_chequers = 0;
                    slot = 0;
                }
            }
            //Console.WriteLine(board.ToString(0));

            return board;
        }
Beispiel #5
0
        // A recursion which finds all possible move sequences, including permutations.
        /*private static void Recursion(int player, List<int> free_dice, Board board, List<Move> moves_made, ref List<MoveHint> move_hints)
        {
            if (free_dice.Count == 0 || board.FinishedCount(player) == 15)
            {
                move_hints.Add(new MoveHint(new List<Move>(moves_made)));
                return;
            }

            if (board.CapturedCount(player) > 0)
            {
                for (int i = 0; i < free_dice.Count; i++)
                {
                    int free_die = free_dice[i];
                    int to = 24 - free_die;
                    Move move = Move.CreateBarMove(to);

                    if (board.IsLegalMove(player, move))
                    {
                        if (board.SlotCount(player, to) == -1)
                            move.AddHitPoint(to);

                        free_dice.RemoveAt(i);

                        moves_made.Add(move);

                        board.Makemove(player, move);

                        Recursion(player, free_dice, board, moves_made, ref move_hints);

                        board.UndoMove(player, move);

                        moves_made.RemoveAt(moves_made.Count - 1);

                        free_dice.Insert(i, free_die);
                    }
                }

                return;
            }

            for (int slot = 23; slot >= 0; slot--)
            {
                if (board.SlotCount(player, slot) > 0)
                {
                    for (int i = 0; i < free_dice.Count; i++)
                    {
                        int free_die = free_dice[i];
                        int to = slot - free_die;
                        Move move = (to >= 0) ? new Move(slot, to) : Move.CreateBearoffMove(slot);

                        if (board.IsLegalMove(player, move))
                        {
                            if (board.SlotCount(player, to) == -1)
                                move.AddHitPoint(to);

                            free_dice.RemoveAt(i);

                            moves_made.Add(move);

                            board.Makemove(player, move);

                            Recursion(player, free_dice, board, moves_made, ref move_hints);

                            board.UndoMove(player, move);

                            moves_made.RemoveAt(moves_made.Count - 1);

                            free_dice.Insert(i, free_die);
                        }
                    }
                }
            }

        }*/
        // A recursion which finds all legal moves, but only adds only one move per different end board position.
        // This doesn't always find all bearoff moves, like with D31 on |_ _ _ O _ _|, it'll find 3/off but not 3/2/off. This is because the hash already contains the end position after 3/off.
        private static void Recursion(
            int player, 
            List<int> free_dice, 
            Board board, 
            List<Move> moves_made, 
            ref List<Play> plays,
            ref List<Play> partial_plays,
            ref HashSet<string> board_hash)
        {
            string hash = board.HashString();
            if (board_hash.Contains(hash))
                return;

            board_hash.Add(hash);

            if (free_dice.Count == 0)
            {
                plays.Add(new Play(moves_made));
                return;
            }

            bool further_moves = false;
            if (board.CapturedCount(player) > 0)
            {

                for (int i = 0; i < free_dice.Count; i++)
                {
                    int free_die = free_dice[i];
                    int to = 24 - free_die;
                    Move move = Move.CreateBarMove(to);

                    if (board.IsLegalMove(player, move, free_die))
                    {
                        further_moves = true;

                        if (board.PointCount(player, to) == -1)
                            move.AddHitPoint(to);

                        free_dice.RemoveAt(i);

                        moves_made.Add(move);

                        board.MakeMove(player, move);

                        Recursion(player, free_dice, board, moves_made, ref plays, ref partial_plays, ref board_hash);

                        board.UndoMove(player, move);

                        moves_made.RemoveAt(moves_made.Count - 1);

                        free_dice.Insert(i, free_die);
                    }
                }

                // No need to check for further moves here because bar moves are forced and if there aren't any, we can't move at all

                if (!further_moves && plays.Count == 0 && moves_made.Count > 0)
                {
                    partial_plays.Add(new Play(moves_made));
                }

                return;
            }

            further_moves = false;
            for (int slot = 23; slot >= 0; slot--)
            {
                if (board.PointCount(player, slot) > 0)
                {
                    for (int i = 0; i < free_dice.Count; i++)
                    {
                        int free_die = free_dice[i];
                        int to = slot - free_die;
                        Move move = (to >= 0) ? new Move(slot, to) : Move.CreateBearoffMove(slot);

                        if (board.IsLegalMove(player, move, free_die))
                        {
                            further_moves = true;

                            if (!move.IsBearOff && board.PointCount(player, to) == -1)
                                move.AddHitPoint(to);

                            free_dice.RemoveAt(i);

                            moves_made.Add(move);

                            board.MakeMove(player, move);

                            Recursion(player, free_dice, board, moves_made, ref plays, ref partial_plays, ref board_hash);

                            board.UndoMove(player, move);

                            moves_made.RemoveAt(moves_made.Count - 1);

                            free_dice.Insert(i, free_die);
                        }
                    }
                }
            }

            if (!further_moves && plays.Count == 0 && moves_made.Count > 0)
            {
                partial_plays.Add(new Play(moves_made));
            }
        }
Beispiel #6
0
        public static Board Deserialize(string s)
        {
            string[] ss = s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            int i = 0;

            Board board = new Board();
            board.captured[0] = int.Parse(ss[i]);
            i++;

            board.finished[0] = int.Parse(ss[i]);
            i++;

            while (i < 26)
            {
                board.board[0][i - 2] = int.Parse(ss[i]);
                i++;
            }

            board.captured[1] = int.Parse(ss[i]);
            i++;

            board.finished[1] = int.Parse(ss[i]);
            i++;

            while (i < 52)
            {
                board.board[1][i - 28] = int.Parse(ss[i]);
                i++;
            }

            return board;
        }
Beispiel #7
0
        public bool IsStartingPosition(BackgammonVariation variation)
        {
            Board board = new Board();
            board.InitializeBoard(variation);

            return this.Equals(board);
        }
Beispiel #8
0
        public bool Equals(Board board)
        {
            if (this.captured[0] != board.captured[0] ||
                this.captured[1] != board.captured[1] ||
                this.finished[0] != board.finished[0] ||
                this.finished[1] != board.finished[1])
                return false;

            for (int i = 0; i < 24; i++)
            {
                if (this.board[0][i] != board.board[0][i] ||
                    this.board[1][i] != board.board[1][i])
                    return false;
            }

            return true;
        }
Beispiel #9
0
        public static string Serialize(Board board)
        {
            StringBuilder sb = new StringBuilder();

            // Player1 #captured# #finished# #slot0# ... #slot23#
            // Player2 #captured# #finished# #slot0# ... #slot23#
            sb.Append(board.captured[0] + " " + board.finished[0]);
            for (int p = 0; p < 24; p++)
                sb.Append(" " + board.board[0][p]);

            sb.Append(" " + board.captured[1] + " " + board.finished[1]);
            for (int p = 0; p < 24; p++)
                sb.Append(" " + board.board[1][p]);

            return sb.ToString();
        }
Beispiel #10
0
        private static Board SwapSides(Board b)
        {
            Board sb = b.Clone();

            int n;
            for (int s = 0; s < 24; s++)
            {
                n = b.PointCount(0, s);
                sb.SetPoint(0, s, b.PointCount(1, s));
                sb.SetPoint(1, s, n);
            }

            sb.SetFinished(1, b.FinishedCount(0));
            sb.SetFinished(0, b.FinishedCount(1));

            sb.SetCaptured(1, b.CapturedCount(0));
            sb.SetCaptured(0, b.CapturedCount(1));

            return sb;
        }