public async Task MoveIntoWind()
        {
            var game         = new Game();
            var communicator = new DirectCommunicator();
            var gameProxy    = new Library.Level3.Game(communicator);
            var decoder      = new Messaging.Level3.Actions.ActionDecoder();

            game.Seed = 0;
            game.Initialize();
            game.State.PlayerPosition = (1, 2);

            var responseTask  = gameProxy.MoveAsync(Direction.North);
            var decodedAction = decoder.Decode(await communicator.ReceiveFromContestantAsync());
            var sentResponse  = game.Execute(decodedAction);

            sentResponse.As <Result>().GameState.PlayerPosition.Should().Be((1, 1));
            responseTask.IsCompleted.Should().BeFalse();
            communicator.SendToContestant(sentResponse);
            var decodedResponse = await responseTask;

            decodedResponse.Perceptions.Should().BeEquivalentTo(Perception.Wind);
            decodedResponse.GameState.MovesLeft.Should().Be(99);
            decodedResponse.GameState.HasArrow.Should().BeTrue();
            game.GameState.Should().Be(GameState.Running);
        }
        private static async Task <Library.Level3.Types.Result> ExecuteRequestedAction(
            Messaging.Level3.Actions.ActionDecoder decoder,
            DirectCommunicator communicator,
            IGame game,
            Task <Library.Level3.Types.Result> responseTask)
        {
            var decodedAction = decoder.Decode(await communicator.ReceiveFromContestantAsync());
            var sentResponse  = game.Execute(decodedAction);

            responseTask.IsCompleted.Should().BeFalse();
            communicator.SendToContestant(sentResponse);
            var decodedResponse = await responseTask;

            return(decodedResponse);
        }
        public async Task PickupNothing()
        {
            var game         = new Game();
            var communicator = new DirectCommunicator();
            var gameProxy    = new Library.Level3.Game(communicator);
            var decoder      = new Messaging.Level3.Actions.ActionDecoder();

            game.Seed = 0;
            game.Initialize();

            var responseTask    = gameProxy.PickupAsync();
            var decodedResponse = await ExecuteRequestedAction(decoder, communicator, game, responseTask);

            decodedResponse.Perceptions.Should().BeEmpty();
            decodedResponse.GameState.MovesLeft.Should().Be(99);
            decodedResponse.GameState.HasArrow.Should().BeTrue();
            game.GameState.Should().Be(GameState.Running);
        }
        public async Task ShootWhamps()
        {
            var game         = new Game();
            var communicator = new DirectCommunicator();
            var gameProxy    = new Library.Level3.Game(communicator);
            var decoder      = new Messaging.Level3.Actions.ActionDecoder();

            game.Seed = 0;
            game.Initialize();
            game.State.PlayerPosition = (0, 2);

            var responseTask    = gameProxy.ShootAsync(Direction.North);
            var decodedResponse = await ExecuteRequestedAction(decoder, communicator, game, responseTask);

            decodedResponse.Perceptions.Should().Contain(Library.Level3.Enums.Perception.Scream);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Twang);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Win);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Death);
            decodedResponse.GameState.MovesLeft.Should().Be(99);
            decodedResponse.GameState.HasArrow.Should().BeFalse();

            responseTask    = gameProxy.ShootAsync(Direction.North);
            decodedResponse = await ExecuteRequestedAction(decoder, communicator, game, responseTask);

            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Scream);
            decodedResponse.Perceptions.Should().Contain(Library.Level3.Enums.Perception.Twang);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Win);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Death);
            decodedResponse.GameState.MovesLeft.Should().Be(98);
            decodedResponse.GameState.HasArrow.Should().BeFalse();

            game.State.PlayerPosition = (0, 1);
            responseTask    = gameProxy.MoveAsync(Direction.North);
            decodedResponse = await ExecuteRequestedAction(decoder, communicator, game, responseTask);

            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Scream);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Twang);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Win);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Death);
            decodedResponse.GameState.MovesLeft.Should().Be(97);
            decodedResponse.GameState.HasArrow.Should().BeFalse();

            game.GameState.Should().Be(GameState.Running);
        }
        public async Task MoveOnTrap()
        {
            var game         = new Game();
            var communicator = new DirectCommunicator();
            var gameProxy    = new Library.Level3.Game(communicator);
            var decoder      = new Messaging.Level3.Actions.ActionDecoder();

            game.Seed = 0;
            game.Initialize();
            game.State.PlayerPosition = (0, 0);

            var responseTask    = gameProxy.MoveAsync(Direction.South);
            var decodedResponse = await ExecuteRequestedAction(decoder, communicator, game, responseTask);

            decodedResponse.Perceptions.Should().Contain(Library.Level3.Enums.Perception.Death);
            decodedResponse.Perceptions.Should().NotContain(Library.Level3.Enums.Perception.Win);
            decodedResponse.GameState.MovesLeft.Should().Be(99);
            decodedResponse.GameState.HasArrow.Should().BeTrue();
            game.GameState.Should().Be(GameState.Lose);
        }