/// <summary> /// Constructs a new turn with the board /// </summary> public BoardState() { Playstones = new PlaystoneState[7, 7]; ModelHelpFunctions.InitializePlaystoneStates(Playstones); ActivePlayer = PlaystoneState.Neutral; PlaystonesPlayer1 = 0; PlaystonesPlayer2 = 0; BeforeLastTurnWasMill = false; }
/// <summary> /// Copies a board /// </summary> /// <param name="playstones">Board to copy</param> /// <returns>Copied board</returns> public static PlaystoneState[,] CopyPlaystoneStates(PlaystoneState[,] playstones) { PlaystoneState[,] stones = new PlaystoneState[7, 7]; for (int i = 0; i <= 6; i++) { for (int j = 0; j <= 6; j++) { stones[i, j] = playstones[i, j]; } } return stones; }
/// <summary> /// Counts the amount of playstones /// </summary> /// <param name="state">State to search for</param> /// <param name="playstones">Board</param> /// <returns>Amount of found states</returns> public static int CountPlaystoneStates(PlaystoneState state, PlaystoneState[,] playstones) { int tmpInt = 0; for (int i = 0; i <= 6; i++) { for (int j = 0; j <= 6; j++) { if (playstones[i, j] == state) tmpInt++; } } return tmpInt; }
/// <summary> /// Makes a random turn /// </summary> /// <param name="state">Playstone for the turn</param> /// <param name="playstones">Actual board</param> /// <param name="index1">Return value for chosen playstone</param> /// <param name="index2">Return value for chosen playstone</param> /// <param name="rnd">Random number generator</param> public static void ChoseRandomPlaystone(PlaystoneState state, PlaystoneState[,] playstones, ref int index1, ref int index2, Random rnd) { while (true) { int i = rnd.Next(7), j = rnd.Next(7); if (playstones[i, j] == state) { index1 = i; index2 = j; break; } } }
/// <summary> /// Sets the whole board to a single state /// </summary> /// <param name="state">State to set</param> /// <param name="playstones">Board</param> public static void SetPlaystoneStates(PlaystoneState state, PlaystoneState[,] playstones) { for (int i = 0; i <= 6; i++) { for (int j = 0; j <= 6; j++) { playstones[i, j] = state; } } }
/// <summary> /// Replaces playstones /// </summary> /// <param name="stateOld">State to search for</param> /// <param name="stateNew">State to replace with</param> /// <param name="playstones">Board</param> public static void ReplacePlaystoneStates(PlaystoneState stateOld, PlaystoneState stateNew, PlaystoneState[,] playstones) { for (int i = 0; i <= 6; i++) { for (int j = 0; j <= 6; j++) { if (playstones[i, j] == stateOld) playstones[i, j] = stateNew; } } }
/// <summary> /// Merges a board /// </summary> /// <param name="actualBoard">Board</param> /// <param name="index1">Chosen Playstone</param> /// <param name="index2">Chosen playstone</param> /// <param name="newState">State to set</param> /// <returns>Merged board</returns> public static PlaystoneState[,] MergePlaystones(PlaystoneState[,] actualBoard, int index1, int index2, PlaystoneState newState) { PlaystoneState[,] playstones = (PlaystoneState[,])actualBoard.Clone(); playstones[index1, index2] = newState; return playstones; }
/// <summary> /// Checks if there are playstones not in mills /// </summary> /// <param name="player">Player to check</param> /// <param name="playstones">Current board</param> /// <returns>True if there are playstones available which are not in a mill, false if not</returns> public static bool ArePlaystonesNotInMills(PlaystoneState player, PlaystoneState[,] playstones) { for (int i = 0; i <= 6; i++) { for (int j = 0; j <= 6; j++) { if (playstones[i, j] == player) { if (!IsMill(i, j, player, playstones)) return true; } } } return false; }
/// <summary> /// Generates an ellipse /// </summary> /// <param name="left">x coordinate</param> /// <param name="top">y coordinate</param> /// <param name="playstoneState">State of the palystone</param> /// <param name="clickEvent">Event to assign to the ellipse</param> /// <returns></returns> private Ellipse GenerateEllipse(double left, double top, PlaystoneState playstoneState, OnClickEvent clickEvent) { double radiusToUse = 0; Ellipse ellipse = new Ellipse { VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left }; #region get radius for ellipse switch (playstoneState) { case PlaystoneState.Neutral: radiusToUse = nonselectablePlaystoneRadius; break; case PlaystoneState.Player1: case PlaystoneState.Player2: case PlaystoneState.Selectable: radiusToUse = selectablePlaystoneRadius; break; default: radiusToUse = 0; break; } ellipse.Width = radiusToUse; ellipse.Height = radiusToUse; #endregion #region set color switch (playstoneState) { case PlaystoneState.Player1: ellipse.Fill = Brushes.Crimson; break; case PlaystoneState.Player2: ellipse.Fill = Brushes.DarkCyan; break; case PlaystoneState.Selectable: ellipse.Fill = Brushes.Gray; break; default: ellipse.Fill = Brushes.Black; break; } #endregion #region assign event switch (playstoneState) { case PlaystoneState.Player1: case PlaystoneState.Player2: case PlaystoneState.Selectable: ellipse.MouseDown += new MouseButtonEventHandler(clickEvent); break; default: break; } #endregion #region set coordinates Thickness margin = new Thickness() { Left = (left + radiusToUse / 2) - radiusToUse, Top = (top + radiusToUse / 2) - radiusToUse }; ellipse.Margin = margin; #endregion return ellipse; }
/// <summary> /// Help function for IsMill /// </summary> /// <param name="column">Column to check</param> /// <param name="playerToCheck">Active player</param> /// <param name="playstones">Actual board</param> /// <param name="checkPartial">If true, the method checks if there is a mill after this turn</param> /// <param name="from">From this row</param> /// <param name="to">To this row</param> /// <returns>True if mill, false if no mill</returns> private static bool CheckVerticalForMill(int column, PlaystoneState playerToCheck, PlaystoneState[,] playstones, bool checkPartial = false, int from = 0, int to = 6) { int tmpInt = 0; for (int i = from; i <= to; i++) { if (playstones[i, column] == playerToCheck) tmpInt++; } if (tmpInt == 2 && checkPartial) return true; else if (tmpInt == 3) return true; else return false; }
/// <summary> /// Help function for PossibleMoves /// </summary> /// <param name="playstones">Actual board</param> /// <param name="square">Board square</param> /// <param name="pos">Position inside the square</param> private static void CheckPositionForMove(PlaystoneState[,] playstones, BoardSquare square, SquarePosition pos) { int i = 0, j = 0; ModelHelpFunctions.GetIndexes(square, pos, ref i, ref j); if (playstones[i, j] == PlaystoneState.Neutral) playstones[i, j] = PlaystoneState.Selectable; }
/// <summary> /// Help function for PossibleMoves /// </summary> /// <param name="index1">Chosen Playstone</param> /// <param name="index2">Chosen playstone</param> /// <param name="playstones">Actual board</param> /// <param name="pos1">Position in the corner</param> /// <param name="pos2">Position in the corner</param> private static void CheckMiddleForMove(int index1, int index2, PlaystoneState[,] playstones, SquarePosition pos1, SquarePosition pos2) { BoardSquare square = ModelHelpFunctions.GetSquare(index1, index2); // Check fields next to this one CheckPositionForMove(playstones, square, pos1); CheckPositionForMove(playstones, square, pos2); // Check fields in the middle switch (square) { case BoardSquare.OutterSquare: case BoardSquare.InnerSquare: CheckPositionForMove(playstones, BoardSquare.MiddleSquare, ModelHelpFunctions.GetPosition(index1, index2)); break; case BoardSquare.MiddleSquare: CheckPositionForMove(playstones, BoardSquare.OutterSquare, ModelHelpFunctions.GetPosition(index1, index2)); CheckPositionForMove(playstones, BoardSquare.InnerSquare, ModelHelpFunctions.GetPosition(index1, index2)); break; } }
/// <summary> /// Help function for PossibleMoves /// </summary> /// <param name="index1">Chosen Playstone</param> /// <param name="index2">Chosen playstone</param> /// <param name="playstones">Actual board</param> /// <param name="pos1">Position next to the corner</param> /// <param name="pos2">Position next to the corner</param> private static void CheckCornerForMove(int index1, int index2, PlaystoneState[,] playstones, SquarePosition pos1, SquarePosition pos2) { BoardSquare square = ModelHelpFunctions.GetSquare(index1, index2); // Check fields next to this one CheckPositionForMove(playstones, square, pos1); CheckPositionForMove(playstones, square, pos2); }
/// <summary> /// Sets the possible moves on the board /// </summary> /// <param name="index1">Chosen Playstone</param> /// <param name="index2">Chosen playstone</param> /// <param name="activePlayer">Active Player</param> /// <param name="playstones">Actual board</param> /// <param name="freeJumps">If true, the player can jump on every field</param> public static void PossibleMoves(int index1, int index2, PlaystoneState activePlayer, PlaystoneState[,] playstones, bool freeJumps = false) { if (freeJumps) { ModelHelpFunctions.ReplacePlaystoneStates(PlaystoneState.Neutral, PlaystoneState.Selectable, playstones); return; } switch (ModelHelpFunctions.GetPosition(index1, index2)) { case SquarePosition.TopLeft: CheckCornerForMove(index1, index2, playstones, SquarePosition.Left, SquarePosition.TopMiddle); break; case SquarePosition.TopMiddle: CheckMiddleForMove(index1, index2, playstones, SquarePosition.TopLeft, SquarePosition.TopRight); break; case SquarePosition.TopRight: CheckCornerForMove(index1, index2, playstones, SquarePosition.TopMiddle, SquarePosition.Right); break; case SquarePosition.Right: CheckMiddleForMove(index1, index2, playstones, SquarePosition.TopRight, SquarePosition.BottomRight); break; case SquarePosition.BottomRight: CheckCornerForMove(index1, index2, playstones, SquarePosition.Right, SquarePosition.BottomMiddle); break; case SquarePosition.BottomMiddle: CheckMiddleForMove(index1, index2, playstones, SquarePosition.BottomRight, SquarePosition.BottomLeft); break; case SquarePosition.BottomLeft: CheckCornerForMove(index1, index2, playstones, SquarePosition.BottomMiddle, SquarePosition.Left); break; case SquarePosition.Left: CheckMiddleForMove(index1, index2, playstones, SquarePosition.BottomLeft, SquarePosition.TopLeft); break; default: return; } }
/// <summary> /// Checks if there is a mill /// </summary> /// <param name="index1">Chosen Playstone</param> /// <param name="index2">Chosen playstone</param> /// <param name="playerToCheck">Active player</param> /// <param name="playstones">Actual board</param> /// <param name="checkPartial">If true, the method checks if there is a mill after this turn</param> /// <returns>True if mill, false if no mill</returns> public static bool IsMill(int index1, int index2, PlaystoneState playerToCheck, PlaystoneState[,] playstones, bool checkPartial = false) { bool isMill = false; // Check middle fields first if (index1 == 3) { if (index2 <= 2) isMill = CheckHorizontalForMill(3, playerToCheck, playstones, checkPartial, 0, 2); else if (index2 >= 4) isMill = CheckHorizontalForMill(3, playerToCheck, playstones, checkPartial, 4, 6); if (isMill) return true; if (CheckVerticalForMill(index2, playerToCheck, playstones, checkPartial)) return true; else return false; } else if (index2 == 3) { if (index1 <= 2) isMill = CheckVerticalForMill(3, playerToCheck, playstones, checkPartial, 0, 2); else if (index1 >= 4) isMill = CheckVerticalForMill(3, playerToCheck, playstones, checkPartial, 4, 6); if (isMill) return true; if (CheckHorizontalForMill(index1, playerToCheck, playstones, checkPartial)) return true; else return false; } // Check corner fields if (CheckHorizontalForMill(index1, playerToCheck, playstones, checkPartial)) return true; if (CheckVerticalForMill(index2, playerToCheck, playstones, checkPartial)) return true; return false; }
/// <summary> /// Draws playstones on the board /// </summary> /// <param name="playstones">Board</param> public void DrawPlaystones(PlaystoneState[,] playstones) { for (int i = 0; i < 7; i++) { for (int j = 0; j < 7; j++) { _workGrid.Children.Add(GenerateEllipse(CoordinatesX[i, j], CoordinatesY[i, j], playstones[i, j], _ellipsEvent)); } } }
/// <summary> /// /// </summary> /// <param name="index1">Chosen Playstone</param> /// <param name="index2">Chosen playstone</param> /// <param name="state">New state of the chosen playstone</param> private void NextStep(int index1, int index2, PlaystoneState state) { BoardState actualState = _boardStates[_boardStates.Count - 1]; _boardStates.Add(new BoardState()); CurrentPlaystones = ModelHelpFunctions.MergePlaystones(actualState.Playstones, index1, index2, state); if (actualState.ActivePlayer == PlaystoneState.Player1) CurrentPlayer = PlaystoneState.Player2; else CurrentPlayer = PlaystoneState.Player1; _boardStates[_boardStates.Count - 1].PlaystonesPlayer1 = actualState.PlaystonesPlayer1; _boardStates[_boardStates.Count - 1].PlaystonesPlayer2 = actualState.PlaystonesPlayer2; }
/// <summary> /// Constructor for a new game. /// </summary> /// <param name="gameType">Type of the game</param> public GameData(GameType gameType) { GameType = gameType; PlayerName1 = ""; PlayerName2 = ""; MoveIsActive = false; InactiveMoveIndex1 = -1; InactiveMoveIndex2 = -1; BoardStates = new List<BoardState>(); StartTime = new DateTime(); EndTime = new DateTime(); GameIsOver = false; Winner = PlaystoneState.NotAvailable; Description = ""; }
/// <summary> /// Get string for game event /// </summary> /// <param name="player">Active player</param> /// <returns>Player event</returns> private string GetGameEvent(PlaystoneState player) { GameEvent gameEvent; if (player == PlaystoneState.Player1) gameEvent = _modelControl.GameEventPlayer1; else gameEvent = _modelControl.GameEventPlayer2; switch (gameEvent) { case GameEvent.PlayerHasMill: return "Mühle! Sie können einen Stein entfernen."; case GameEvent.WrongPlaystoneAfterMill: return "Sie können nur Steine Ihres Gegners auswählen!"; case GameEvent.CannotBreakMill: return "Sie können nicht Steine aus einer Mühle entfernen!"; case GameEvent.InvalidPlaystone: return "Sie können diesen Stein nicht auswählen!"; case GameEvent.NoPlaystonesRemovable: return "Es können keine Steine entfernt werden!"; case GameEvent.GameOverNoMovesPossible: return "Spieler hat verloren (alle Steine eingeschlossen)!"; case GameEvent.GameOverNoPlaystonesLeft: return "Spieler hat verloren (weniger als drei Steine)!"; case GameEvent.FinishTurn: return "Beenden Sie Ihren Spielzug!"; case GameEvent.CannotUndoMill: return "Eine Mühle kann nicht rückgängig gemacht werden!"; default: return ""; } }
/// <summary> /// Initializes a new board /// </summary> /// <param name="playstones">Board</param> /// <param name="defaultValue">Default value of possible positions</param> public static void InitializePlaystoneStates(PlaystoneState[,] playstones, PlaystoneState defaultValue = DefaultAvailablePlaystoneState) { SetPlaystoneStates(DefaultNotAvailablePlaystoneState, playstones); #region first square playstones[0, 0] = defaultValue; playstones[0, 3] = defaultValue; playstones[0, 6] = defaultValue; playstones[3, 6] = defaultValue; playstones[6, 6] = defaultValue; playstones[6, 3] = defaultValue; playstones[6, 0] = defaultValue; playstones[3, 0] = defaultValue; #endregion #region second square playstones[1, 1] = defaultValue; playstones[1, 3] = defaultValue; playstones[1, 5] = defaultValue; playstones[3, 5] = defaultValue; playstones[5, 5] = defaultValue; playstones[5, 3] = defaultValue; playstones[5, 1] = defaultValue; playstones[3, 1] = defaultValue; #endregion #region third square playstones[2, 2] = defaultValue; playstones[2, 3] = defaultValue; playstones[2, 4] = defaultValue; playstones[3, 4] = defaultValue; playstones[4, 4] = defaultValue; playstones[4, 3] = defaultValue; playstones[4, 2] = defaultValue; playstones[3, 2] = defaultValue; #endregion }
/// <summary> /// Checks if the actual player can make moves /// </summary> /// <param name="activePlayer">Active Player</param> /// <param name="playstones">Current board</param> /// <returns>True if the player can make moves, false if not</returns> public static bool AreMovesPossible(PlaystoneState activePlayer, PlaystoneState[,] playstones) { for (int i = 0; i <= 6; i++) { for (int j = 0; j <= 6; j++) { if (playstones[i, j] == activePlayer) { PlaystoneState[,] stones = ModelHelpFunctions.CopyPlaystoneStates(playstones); PossibleMoves(i, j, activePlayer, stones); if (ModelHelpFunctions.CountPlaystoneStates(PlaystoneState.Selectable, stones) > 0) return true; } } } return false; }