/// <summary> /// Plays the game. /// </summary> public void PlayGame() { NextTetromino = GenerateNewRandomTetromino(); do { ActiveTetromino = NextTetromino; NextTetromino = GenerateNewRandomTetromino(); GameController.RefreshUserInterface(); GameController.DisplayNexTetromino(); if (Fieldgrid.IsLegalPosition(ActiveTetromino)) { Thread tetrominoDownMover = new Thread(MoveTetrominoDown); tetrominoDownMover.IsBackground = true; //makes sure the thread gets killed on application exit tetrominoDownMover.Start(); while (!ActiveTetromino.IsLockedInPlace) { //wait until active tetromino is locked in place } int rowsRemoved = Fieldgrid.RemoveFullRows(); CalculateScore(rowsRemoved); RowsRemovedAtCurrentLevel += rowsRemoved; RowsRemovedInTotal += rowsRemoved; GameController.UpdateLineCount(); ManageLevel(); } else { GameIsOver = true; ActiveTetromino = null; } } while (!GameIsOver); GameController.GameOver(); }
/// <summary> /// Moves the tetromino down. /// </summary> /// <remarks> /// This method is used by a thread. It needs its own copy of the reference to the /// tetromino, because the only time this thread stops is when the /// tetromino cant move any further. If the tetromino is dropped all /// the way at once (space bar), it will generate a new active tetromino. /// This will get its own thread, and now two threads are working on the /// same tetromino. /// </remarks> private void MoveTetrominoDown() { Tetromino tet = ActiveTetromino; Thread.Sleep((int)(500 * Math.Pow(0.75, Level - 1))); MovingTetrominoMutex.WaitOne(); while (tet != null && !Fieldgrid.IsCollisionBelow(tet)) { tet.MoveDownIfPossible(Fieldgrid); MovingTetrominoMutex.ReleaseMutex(); GameController.RefreshUserInterface(); Thread.Sleep((int)(500 * Math.Pow(0.75, Level - 1))); MovingTetrominoMutex.WaitOne(); } if (tet != null && !tet.IsLockedInPlace) { Fieldgrid.PlaceOnGrid(tet); } MovingTetrominoMutex.ReleaseMutex(); GameController.RefreshUserInterface(); }