/// <summary> /// /// </summary> /// <param name="cmd"></param> /// <returns></returns> public BoardPosition ParseString(string cmd) { BoardPosition pos = new BoardPosition(); if (cmd == "exit") return null; if (cmd.Substring(0, 3) == ";B[") pos.Contains = BoardPositionEntry.BLACK; else if (cmd.Substring(0, 3) == ";W[") pos.Contains = BoardPositionEntry.WHITE; else return null; char sx = cmd[3]; char sy = cmd[4]; int x = 0; int y = 0; for (int i = 0; i < 26; i++) { if (letters[i] == sx) x = i; if (letters[i] == sy) y = i; } pos.x = x; pos.y = y; return pos; }
static void Main(string[] args) { Board board = new Board(19); Parser parser = new Parser(); BoardPosition pos; /* System.IO.TextReader sr = System.IO.File.OpenText("game.sgf"); string zeile; while(sr.Peek() != -1) { zeile = sr.ReadLine(); BoardPosition p = parser.ParseString(zeile); if (p != null) { Console.WriteLine("Setting stone at " + p.x + "x" + p.y); board.SetStone(p); } }*/ board.PrintToConsole(); while ((pos = parser.ParseString(Console.ReadLine())) != null) { board.SetStone(pos); System.Console.Clear(); board.PrintToConsole(); Random rand = new Random(); int x = rand.Next(20); int y = rand.Next(20); BoardPosition comp = new BoardPosition(x, y, BoardPositionEntry.WHITE); board.SetStone(comp); } }
/// <summary> /// /// </summary> /// <param name="pos"></param> /// <returns></returns> public bool ConnectsWithGroup(Board board, BoardPosition pos) { foreach(BoardPosition stone in Stones) { if (board.DirectNeighbors(pos, stone) && pos.Contains == stone.Contains) { if(pos.Group != this) return true; } } return false; }
/// <summary> /// Checks if the group is still alive /// </summary> /// <param name="pos"> /// A stone belonging to that group /// </param> /// <returns> /// Returns true if the group is still alive. Otherwise, false /// </returns> public bool CheckForFreeLiberties(BoardPosition pos) { if (pos != null && pos.Group != null) { if (pos.Group.GetFreeLiberties(this) == 0) { return false; } } return true; }
/// <summary> /// Checks if the new placed stone /// connects 2 groups or itself is connected /// to a group. /// Otherwise, the stone creates a new group. /// In the opening, many groups will be created, /// but later they'll all converge into /// few big groups. /// </summary> public void ConnectToGroups(BoardPosition pos) { bool flag = false; BoardPosition west = West(pos); BoardPosition east = East(pos); BoardPosition north = North(pos); BoardPosition south = South(pos); ConnectToGroupsHelper(ref pos, ref west, ref east, ref north, ref south, ref flag); ConnectToGroupsHelper(ref pos, ref east, ref west, ref north, ref south, ref flag); ConnectToGroupsHelper(ref pos, ref north, ref west, ref east, ref south, ref flag); ConnectToGroupsHelper(ref pos, ref south, ref west, ref east, ref north, ref flag); if (!flag) { pos.Group = new Group(); pos.Group.AddToGroup(pos); Groups.Add(pos.Group); } }
/// <summary> /// Checks if the given point /// and the surrounding one's /// connect to a new bigger group. /// </summary> /// <param name="pos"> /// The position to check from /// </param> /// <param name="p1"> /// /// </param> /// <param name="p2"> /// /// </param> /// <param name="p3"> /// /// </param> /// <param name="p4"> /// /// </param> /// <param name="flag"> /// This flag is set to true if the stone connects /// to a new group. Otherwise, the stone itself /// creates a new group. /// </param> protected void ConnectToGroupsHelper(ref BoardPosition pos, ref BoardPosition p1, ref BoardPosition p2, ref BoardPosition p3, ref BoardPosition p4, ref bool flag) { if (p1 != null) { if (p1.Contains == pos.Contains) { p1.Group.AddToGroup(pos); if (p2 != null) { if (p2.Contains == pos.Contains && p2.Group != pos.Group) { p1.Group.JoinWithGroup(this, p2.Group); } } if (p3 != null) { if (p3.Contains == pos.Contains && p3.Group != pos.Group) { p1.Group.JoinWithGroup(this, p3.Group); } } if (p4 != null) { if (p4.Contains == pos.Contains && p4.Group != pos.Group) { p1.Group.JoinWithGroup(this, p4.Group); } } flag = true; } } }
/// <summary> /// Constructor /// </summary> /// <param name="s"> /// The board's size /// </param> public Board(int s) { Size = s; board = new BoardPosition[size, size]; for (int x = 0; x < Size; x++) { for (int y = 0; y < Size; y++) { board[x, y] = new BoardPosition(x, y, BoardPositionEntry.EMTPY); } } }
/// <summary> /// Checks if the two given stones are /// diagonal neighbors /// </summary> /// <param name="pos1"> /// The first stone to check /// </param> /// <param name="pos2"> /// The second stone to check /// </param> /// <returns> /// True if they are diagonal neighbours /// </returns> public bool DiagonalNeighbors(BoardPosition pos1, BoardPosition pos2) { return (pos1 == SouthWest(pos2)) || (pos1 == SouthEast(pos2)) || (pos1 == NorthWest(pos2)) || (pos1 == NorthEast(pos2)); }
/// <summary> /// /// </summary> /// <param name="pos"></param> public void SetStone(BoardPosition pos) { SetStone(pos.x, pos.y, pos.Contains); }
/// <summary> /// Returns the stone south-west of the given position /// </summary> /// <param name="pos"> /// The stone to go from /// </param> /// <returns> /// The stone south-west of the given position /// </returns> public BoardPosition SouthWest(BoardPosition pos) { try { return GetStone(pos.x - 1, pos.y + 1); } catch (System.Exception e) { throw e; } }
/// <summary> /// Returns the stone east of the given position /// </summary> /// <param name="pos"> /// The stone to go from /// </param> /// <returns> /// The stone east of the given position /// </returns> public BoardPosition East(BoardPosition pos) { try { return GetStone(pos.x + 1, pos.y); } catch (System.Exception e) { return null; } }
/// <summary> /// Returns the stone north of the given position /// </summary> /// <param name="pos"> /// The stone to go from /// </param> /// <returns> /// The stone north of the given position /// </returns> public BoardPosition North(BoardPosition pos) { try { return GetStone(pos.x, pos.y - 1); } catch (System.Exception e) { return null; } }
/// <summary> /// /// </summary> /// <param name="pos"></param> public void AddToGroup(BoardPosition pos) { Stones.AddLast(pos); pos.Group = this; }
/// <summary> /// /// </summary> /// <param name="pos"></param> /// <returns></returns> public bool BelongsToGroup(BoardPosition pos) { return pos.Group == this; }
/// <summary> /// A little helper method to check if a group is dead. /// The free liberties are checked and if they are = 0, /// then the group is removed and the captured stones /// counter increases /// </summary> /// <param name="pos"> /// A stone of the group to check for death /// </param> protected void CheckSurroundingGroupsForDeathHelper(ref BoardPosition pos) { if (pos == null) return; BoardPositionEntry entry = pos.Contains; int size = 0; if (pos != null) { if (!CheckForFreeLiberties(pos)) size = pos.Group.RemoveGroup(this); } if (entry == BoardPositionEntry.BLACK) CapturedBlackStones += size; else if (entry == BoardPositionEntry.WHITE) CapturedWhiteStones += size; }
/// <summary> /// Checks if the new placed stone kills any /// surrounding groups /// </summary> /// <param name="pos"> /// The new placed stones /// </param> public void CheckSurroundingGroupsForDeath(BoardPosition pos) { BoardPosition west = West(pos); BoardPosition east = East(pos); BoardPosition north = North(pos); BoardPosition south = South(pos); CheckSurroundingGroupsForDeathHelper(ref west); CheckSurroundingGroupsForDeathHelper(ref east); CheckSurroundingGroupsForDeathHelper(ref north); CheckSurroundingGroupsForDeathHelper(ref south); }
/// <summary> /// Returns the stone north-east of the given position /// </summary> /// <param name="pos"> /// The stone to go from /// </param> /// <returns> /// The stone north-east of the given position /// </returns> public BoardPosition NorthEast(BoardPosition pos) { try { return GetStone(pos.x + 1, pos.y - 1); } catch (System.Exception e) { throw e; } }
/// <summary> /// Removes the stone at the given position /// </summary> /// <param name="pos"> /// The stone to remove /// </param> public void RemoveStone(BoardPosition pos) { board[pos.x, pos.y].Contains = BoardPositionEntry.EMTPY; board[pos.x, pos.y].Group = null; }
/// <summary> /// Checks if the two given stones are /// direct neighbors /// </summary> /// <param name="pos1"> /// The first stone to check /// </param> /// <param name="pos2"> /// The second stone to check /// </param> /// <returns> /// True if they are neighbours /// </returns> public bool DirectNeighbors(BoardPosition pos1, BoardPosition pos2) { return (pos1 == South(pos2)) || (pos1 == West(pos2)) || (pos1 == North(pos2)) || (pos1 == East(pos2)); }