public void PlayAGame(int sleepInterval) { while (!IsOver) { // Let current user make a move MakeAMove(); Thread.Sleep(sleepInterval); // Update printout MovePerformed?.Invoke(this, EventArgs.Empty); } }
void Update() { if (Input.GetMouseButtonDown(0)) { _inputPos = Input.mousePosition; PressPerformed?.Invoke(_inputPos); } if (Input.GetMouseButton(0) && (_inputPos != Input.mousePosition)) { _inputPos = Input.mousePosition; MovePerformed?.Invoke(_inputPos); } if (Input.GetMouseButtonUp(0)) { PressCancelled?.Invoke(Input.mousePosition); } }
/// Current thinker makes its move private Winner Play() { // Get a reference to the current thinker IThinker thinker = matchData.CurrentThinker; // Determine the color of the current thinker PColor color = board.Turn; // Match result so far Winner winner = Winner.None; // Thinking start time DateTime startTime = DateTime.Now; // Real think time in milliseconds int thinkTimeMillis; // Apparent thinking time left int timeLeftMillis; // Task to execute the thinker in a separate thread Task <FutureMove> thinkTask; // Notify listeners that next turn is about to start NextTurn?.Invoke(color, thinker.ToString()); // Ask thinker to think about its next move thinkTask = Task.Run( () => thinker.Think(board.Copy(), ts.Token)); // The thinking process might throw an exception, so we wrap // task waiting in a try/catch block try { // Wait for thinker to think... until the allowed time limit if (thinkTask.Wait(timeLimitMillis)) { // Thinker successfully made a move within the time limit // Get the move selected by the thinker FutureMove move = thinkTask.Result; // Was the thinker able to chose a move? if (move.IsNoMove) { // Thinker was not able to chose a move // Raise an invalid play event and set the other // thinker as the winner of the match winner = OnInvalidPlay( color, thinker, "Thinker unable to perform move"); } else { // Thinker was able to chose a move // Perform move in game board, get column where move // was performed int row = board.DoMove(move.shape, move.column); // If the column had space for the move... if (row >= 0) { // Obtain thinking end time thinkTimeMillis = (int)(DateTime.Now - startTime) .TotalMilliseconds; // How much time left for the minimum apparent move // time? timeLeftMillis = minMoveTimeMillis - thinkTimeMillis; // Was the minimum apparent move time reached if (timeLeftMillis > 0) { // If not, wait until it is reached Thread.Sleep(timeLeftMillis); } // Notify listeners of the move performed MovePerformed?.Invoke( color, thinker.ToString(), move, thinkTimeMillis); // Get possible winner and solution winner = board.CheckWinner(solution); } else { // If we get here, column didn't have space for the // move, which means that thinker made an invalid // move and should lose the game // Raise an invalid play event and set the other // thinker as the winner of the match winner = OnInvalidPlay( color, thinker, "Tried to place piece in column " + $"{move.column}, which is full"); } } } else // Did the time limit expired? { // Notify thinker to voluntarily stop thinking ts.Cancel(); // Raise an invalid play event and set the other thinker // as the winner of the match winner = OnInvalidPlay( color, thinker, "Time limit expired"); } } catch (Exception e) { // Is this an inner exception? if (e.InnerException != null) { // If so, use it for error message purposes e = e.InnerException; } // Raise an invalid play event and set the other thinker as // the winner of the match winner = OnInvalidPlay( color, thinker, $"Thinker exception: '{e.Message}'"); } // Notify listeners that the board was updated BoardUpdate?.Invoke(board); // Return winner return(winner); }