/// <summary> /// Reverts the <see cref="Game"/> back to the <see cref="LastMove"/>'s state. /// </summary> public void Undo() { if (!CanUndo) { return; } Tile removedTile = _history.Pop(); BoardChanging?.Invoke( this, new BoardChangingEventArgs( new Tile[0], new Tile[] { removedTile })); removedTile.Piece = new Piece(Pieces.None); Manager.Turn.MoveBack(); if (IsOver) { IsOver = false; Manager.Turn.ShiftStartBackwards(); } BoardChanged?.Invoke( this, new BoardChangedEventArgs( new Tile[0], new Tile[] { removedTile })); }
/// <summary> /// Resets the <see cref="Game"/> to its original state. /// </summary> public void Restart() { Tile[] history = _history.ToArray(); BoardChanging?.Invoke( this, new BoardChangingEventArgs( new Tile[0], history)); foreach (Tile tile in _history) { tile.Piece = new Piece(Pieces.None); } Manager.Turn.Reset(); _history.Clear(); IsOver = false; BoardChanged?.Invoke( this, new BoardChangedEventArgs( new Tile[0], history)); }
/// <summary> /// Puts a <see cref="Tile"/> corresponding to <see cref="CurrentPlayer"/> /// and advances the <see cref="Game"/> to the next state. at position /// <paramref name="x"/>, <paramref name="y"/>. /// </summary> /// <param name="x">x-axis position</param> /// <param name="y">y-axis position</param> /// <exception cref="ArgumentException"></exception> public void Play(int x, int y) { if (x < 0 || x > Board.Width) { throw new ArgumentException("Value is out of range", nameof(x)); } if (y < 0 || y > Board.Height) { throw new ArgumentException("Value is out of range", nameof(y)); } // Check if game is over if (IsOver) { return; } Tile tile = Board[x, y]; // Check for already placed tile if (tile.Piece.Type != Pieces.None) { return; } Player oldPlayer = Manager.CurrentPlayer; tile.Piece = oldPlayer.Piece; Tile previousTile = LastMove; _history.Push(tile); BoardChanging?.Invoke( this, new BoardChangingEventArgs( new Tile[] { tile }, new Tile[0])); // Check for game over if (CheckGameOver(x, y, out IList <Tile> winningLine)) { IsOver = true; if (ShiftPlayersOnGameOver) { Manager.Turn.ShiftStartForwards(); } } // Increment turn Manager.Turn.MoveNext(); BoardChanged?.Invoke( this, new BoardChangedEventArgs( new Tile[] { tile }, new Tile[0])); if (IsOver) { GameOver?.Invoke( this, new GameOverEventArgs( Manager.Turn.Current, oldPlayer, winningLine)); } }