/// <summary> /// Determining whether a move from the current coordinate in a specific direction is possible. /// </summary> /// <param name="coordinates">Current coordinates to check.</param> /// <param name="direction">Current direction from coordinates to check.</param> /// <returns>Whether the marker position is a possible move.</returns> private bool PossibleMove(Coordinates coordinates, ReversiPlayer player, Direction direction) { bool valid = false; int x = coordinates.X; int y = coordinates.Y; switch (direction) { case Direction.Up: y--; while (y > 0 && !valid) { if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; } y--; if (_markers[x, y] == _currentPlayer) { valid = true; } } break; case Direction.Down: y++; while (y < _markers.GetUpperBound(1) && !valid) { if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; } y++; if (_markers[x, y] == _currentPlayer) { valid = true; } } break; case Direction.Left: x--; while (x > 0 && !valid) { if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; } x--; if (_markers[x, y] == _currentPlayer) { valid = true; } } break; case Direction.Right: x++; while (x < _markers.GetUpperBound(0) && !valid) { if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; } x++; if (_markers[x, y] == _currentPlayer) { valid = true; } } break; case Direction.DiagonalRightUp: x++; y--; while ((x < _markers.GetUpperBound(0) && y > 0) && !valid) { if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; } x++; y--; if (_markers[x, y] == _currentPlayer) { valid = true; } } break; case Direction.DiagonalRightDown: x++; y++; while ((x < _markers.GetUpperBound(0) && y < _markers.GetUpperBound(1)) && !valid) { if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; } x++; y++; if (_markers[x, y] == _currentPlayer) { valid = true; } } break; case Direction.DiagonalLeftUp: x--; y--; while ((x > 0 && y > 0) && !valid) { if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; } x--; y--; if (_markers[x, y] == _currentPlayer) { valid = true; } } break; case Direction.DiagonalLeftDown: x--; y++; while ((x > 0 && y < _markers.GetUpperBound(1) && y > 0) && !valid) { if (_markers[x, y] == ReversiPlayer.None) { goto FoundEmpty; } x--; y++; if (_markers[x, y] == _currentPlayer) { valid = true; } } break; } if (valid) { _targetCoordinates = new Coordinates(x, y); } FoundEmpty: return valid; }
/// <summary> /// Checks if current tile is a valid move for the current player. /// </summary> /// <param name="coordinates">Coordinates that indicate the current tile.</param> /// <returns>Valid move or not.</returns> private bool IsValidLocation(Coordinates coordinates) { if ((coordinates.X >= 0 && coordinates.X <= _markers.GetUpperBound(0)) && (coordinates.Y >= 0 && coordinates.Y <= _markers.GetUpperBound(1))) { // Check if marker already exists if (_markers[coordinates.X, coordinates.Y] != ReversiPlayer.None) { return false; } bool validLocation = false; ReversiPlayer opponent = _currentPlayer ^ (ReversiPlayer)3; // Check 3 spots to the right of tile if (coordinates.X < _markers.GetUpperBound(0)) { if (coordinates.Y > 0 && _markers[coordinates.X + 1, coordinates.Y - 1] == opponent) { if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalRightUp)) { validLocation = true; } } if (coordinates.Y < _markers.GetUpperBound(1) && _markers[coordinates.X + 1, coordinates.Y + 1] == opponent) { if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalRightDown)) { validLocation = true; } } if (_markers[coordinates.X + 1, coordinates.Y] == opponent) { if (PossibleMove(coordinates, _currentPlayer, Direction.Right)) { validLocation = true; } } if (validLocation) { goto FoundValidMove; } } // Check 3 spots to the left of tile if (coordinates.X > 0) { if (coordinates.Y > 0 && _markers[coordinates.X - 1, coordinates.Y - 1] == opponent) { if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalLeftUp)) { validLocation = true; } } if (coordinates.Y < _markers.GetUpperBound(1) && _markers[coordinates.X - 1, coordinates.Y + 1] == opponent) { if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalLeftDown)) { validLocation = true; } } if (_markers[coordinates.X - 1, coordinates.Y] == opponent) { if (PossibleMove(coordinates, _currentPlayer, Direction.Left)) { validLocation = true; } } if (validLocation) { goto FoundValidMove; } } // Check 1 spot below the tile if (coordinates.Y < _markers.GetUpperBound(1)) { if (_markers[coordinates.X, coordinates.Y + 1] == opponent) { if (PossibleMove(coordinates, _currentPlayer, Direction.Down)) { validLocation = true; } } if (validLocation) { goto FoundValidMove; } } // Check 1 spot above the tile if (coordinates.Y > 0) { if (_markers[coordinates.X, coordinates.Y - 1] == opponent) { if (PossibleMove(coordinates, _currentPlayer, Direction.Up)) { validLocation = true; } } } FoundValidMove: return validLocation; } return false; }
/// <summary> /// Flip opponent markers from current move at specified coordinates. /// </summary> /// <param name="coordinates">Coordinates of the newly placed marker.</param> private void FlipOpponentMarkers(Coordinates coordinates) { if (PossibleMove(coordinates, _currentPlayer, Direction.Up)) { for (int i = coordinates.Y; i > _targetCoordinates.Y; i--) { _markers[coordinates.X, i] = _currentPlayer; } } if (PossibleMove(coordinates, _currentPlayer, Direction.Down)) { for (int i = coordinates.Y; i < _targetCoordinates.Y; i++) { _markers[coordinates.X, i] = _currentPlayer; } } if (PossibleMove(coordinates, _currentPlayer, Direction.Left)) { for (int i = coordinates.X; i > _targetCoordinates.X; i--) { _markers[i, coordinates.Y] = _currentPlayer; } } if (PossibleMove(coordinates, _currentPlayer, Direction.Right)) { for (int i = coordinates.X; i < _targetCoordinates.X; i++) { _markers[i, coordinates.Y] = _currentPlayer; } } if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalRightUp)) { int j = coordinates.Y; for (int i = coordinates.X; i < _targetCoordinates.X; i++, j--) { _markers[i, j] = _currentPlayer; } } if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalRightDown)) { int j = coordinates.Y; for (int i = coordinates.X; i < _targetCoordinates.X; i++, j++) { _markers[i, j] = _currentPlayer; } } if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalLeftUp)) { int j = coordinates.Y; for (int i = coordinates.X; i > _targetCoordinates.X; i--, j--) { _markers[i, j] = _currentPlayer; } } if (PossibleMove(coordinates, _currentPlayer, Direction.DiagonalLeftDown)) { int j = coordinates.Y; for (int i = coordinates.X; i > _targetCoordinates.X; i--, j++) { _markers[i, j] = _currentPlayer; } } _currentPlayer ^= (ReversiPlayer)3; this.Invalidate(); }
/// <summary> /// For clicking on the game board and adding a marker to a location on the grid. /// </summary> /// <param name="e">MouseEventArgs.</param> protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); // Check release boundaries Coordinates coordinates = new Coordinates(e.X / _tileSize, e.Y / _tileSize); if (IsValidLocation(coordinates)) { _markers[coordinates.X, coordinates.Y] = _currentPlayer; FlipOpponentMarkers(coordinates); _faintCollection.Clear(); UpdateMarkerCount(); if (GameFinished) { GameOver(); } } }
/// <summary> /// Calculates move validity and shows faint marker indicator for valid tiles /// to place markers on. /// </summary> /// <param name="e">MouseEventArgs.</param> protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (e.Button == MouseButtons.None) { Coordinates coordinates = new Coordinates(e.X / _tileSize, e.Y / _tileSize); if (!_lastCoordinates.Equals(coordinates)) { if (IsValidLocation(coordinates)) { _faintCollection.Add(new Marker(_currentPlayer, coordinates)); if (_faintCollection.Count > 1) { _faintCollection.RemoveAt(0); } } _lastCoordinates = coordinates; } } }
// Constructor public Marker(ReversiPlayer player, Coordinates location) { this.Player = player; this.TileCoordinates = location; }