/// <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]; } }
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; }
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(); }
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; }
// 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)); } }
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; }
public bool IsStartingPosition(BackgammonVariation variation) { Board board = new Board(); board.InitializeBoard(variation); return this.Equals(board); }
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; }
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(); }
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; }