/// <summary> /// Performs a valid move on the board /// </summary> /// <param name="selected">marbles that are selected</param> /// <param name="direction">direction of push movement</param> /// <returns></returns> public bool DoMove(List <Marble> selected, Direction direction) { if (Rules.MoveIsValid(this, selected, direction)) { MoveType mt = Rules.DetermineMoveType(selected, direction); if (mt == MoveType.Line) { Marble current = selected[0]; while (current != null) { Marble next = null; //get marble at the destination location of current marble ICoordinates nc = Rules.NextCoordinates(current.Coordinates, direction); next = GetMarble(nc, false); //move the current marble afterwards, to prevent two marbles at same location current.Move(direction); if (current.IsOut) { //marble was thrown out, get the direction of r direction = Rules.ConvertDirection(current.Coordinates as OuterRingCoordinates, direction); } //repeat until there is no marble left in the line current = next; } return(true); } else if (mt == MoveType.Broad) { //simply move all selected marbles in the desired direction foreach (Marble m in selected) { m.Move(direction); } return(true); } } return(false); }
/// <summary> /// Determines if a turn of a player may be valid /// </summary> /// <param name="selected"></param> /// <param name="direction"></param> /// <returns></returns> public static bool MoveIsValid(Board board, List <Marble> selected, Direction direction) { if (direction == Direction.None) { return(false); } MoveType mt = DetermineMoveType(selected, direction); if (mt == MoveType.Line) { MarbleColor currentPlayer = selected[0].Color; List <MarbleColor> moveline = new List <MarbleColor>(); foreach (Marble m in selected) { moveline.Add(m.Color); } Marble next = selected[selected.Count - 1]; while (next != null) { next = board.GetMarble(NextCoordinates(next.Coordinates, direction), true); if (next != null) { moveline.Add(next.Color); } } int i = 0, mcol = 0, hcol = 0, ncol = 0; while (i < moveline.Count && moveline[i] == currentPlayer) { mcol++; i++; } while (i < moveline.Count && moveline[i] != currentPlayer) { hcol++; i++; } while (i < moveline.Count && moveline[i] == currentPlayer) { ncol++; i++; } // move max. three own marbles; push fewer amount of enemy marbles than own // and have no other own marbles behind them return(mcol <= 3 && mcol > hcol && ncol == 0); } else if (mt == MoveType.Broad) { // move max. three marbles; all destination slots must be free bool free = selected.Count < 4; if (free) { foreach (Marble m in selected) { ICoordinates dest = NextCoordinates(m.Coordinates, direction); free = free && board.GetMarble(dest, true) == null; } } return(free); } return(false); }