void Start()
    {
        playerMove = GetComponent <PlayMove>();
        animation  = GetComponentInChildren <Animation>();

//		animation["KK_Idle"].wrapMode = WrapMode.Loop;
//		animation["KK_Run_No"].wrapMode = WrapMode.Loop;
        //animation["KK_Attack"].wrapMode = WrapMode.Once;

//		animation["KK_Run_No"].speed = 1.1f;

        //animation["KK_Attack"].layer=1;
        //Transform mt = transform.Find("Koko@KK_Idle/Koko_Bip001/Koko_Bip001 Pelvis");
        //animation["KK_Attack"].AddMixingTransform(mt);
    }
Beispiel #2
0
        private Move DetermineMove(GameState state)
        {
            var myPieces = state.Pieces.Where(p => p.Owner == state.CurrentlyPlaying);

            Move bestMove     = null;
            int  bestDistance = 0;

            foreach (var piece in myPieces)
            {
                foreach (var card in state.MyHand)
                {
                    foreach (var target in card.Targets)
                    {
                        var targetPosition = piece.PositionOnBoard + target;

                        if (!IsValidMove(state, targetPosition))
                        {
                            continue;
                        }

                        var move = new PlayMove(
                            usedCard: card.Type,
                            from: piece.PositionOnBoard,
                            to: targetPosition
                            );

                        if (IsWinningMove(state, move))
                        {
                            _botProxy.Log("Wow, we found a winning move!?");
                            return(move);
                        }

                        var position = GetPositionAfterMove(state, move);

                        var distance = CalculateSummedManhattanDistance(position);

                        if (distance > bestDistance)
                        {
                            bestMove     = move;
                            bestDistance = distance;
                        }
                    }
                }
            }

            return(bestMove ?? new PassMove(state.MyHand.First().Type));
        }
Beispiel #3
0
        private static bool IsWinningMove(GameState state, PlayMove move)
        {
            var targetPiece = state.Pieces.FirstOrDefault(p => p.PositionOnBoard == move.To);

            if (targetPiece != null &&
                targetPiece.Owner != state.CurrentlyPlaying &&
                targetPiece.IsMaster)
            {
                return(true);
            }

            var targetBase = state.CurrentlyPlaying == PlayerIdentity.Player1
                ? Position.Player2Home
                : Position.Player1Home;

            if (move.To == targetBase)
            {
                return(true);
            }

            return(false);
        }
Beispiel #4
0
        private static BoardPosition GetPositionAfterMove(BoardPosition boardPosition, PlayMove move)
        {
            var clone = BoardPosition.Clone(boardPosition);

            var piece = clone.Pieces.Single(p => p.PositionOnBoard == move.From);

            piece.PositionOnBoard = move.To;

            return(clone);
        }
Beispiel #5
0
        public async Task <PlayResult> Pass(string gameId, string username)
        {
            Game game = gameCache.ActiveGames.SingleOrDefault(g => g.Id == gameId) as Game;

            if (game == null)
            {
                string message = $"Invalid game: {gameId}";
                await logger.WarningAsync(message, context : $"{username}:{gameId}");

                return(new PlayResult {
                    MoveResult = message
                });
            }

            //  Play must be done by current player
            var player = game.GetPlayer(username);

            if (player.UserName != game.CurrentPlayer)
            {
                string message = $"Game Play received not from current player. (Game:{gameId} Current Player:{game.CurrentPlayer}) ";
                await logger.WarningAsync(message, context : $"{gameId}:{username}");

                return(new PlayResult {
                    MoveResult = message
                });
            }


            // Create move entity
            var playFinish = new DateTime(DateTime.UtcNow.Ticks, DateTimeKind.Utc);
            var move       = new PlayMove
            {
                Letters    = new IPlayLetter[0],
                Player     = player.UserName,
                PlayStart  = new DateTime(game.CurrentStart.Ticks, DateTimeKind.Utc),
                PlayFinish = playFinish,
                Words      = new IPlayWord[0],
                Score      = 0
            };

            // Update game time, and current player
            var opponent = game.Player01.UserName == player.UserName ? game.Player02 : game.Player01;

            game.CurrentStart  = playFinish;
            game.CurrentPlayer = opponent.UserName;
            game.ConsecutivePasses++;

            // Update game moves
            var moves = game.PlayMoves.ToList();

            moves.Add(move);
            game.PlayMoves = moves;

            await logger.InfoAsync($"PASS! = Duration:[{Math.Round((move.PlayFinish.Value - move.PlayStart).TotalMinutes, 2)}]", context : $"{gameId}:{username}");


            await gameRepository.Update(game.ToDataModel());

            await gameRepository.AddMoves(game.Id, new GameMoveDataModel[] { move.ToDataModel() });

            if (game.ConsecutivePasses >= 4)
            {
                return(new PlayResult
                {
                    MoveResult = "GameOver",
                    PlayMove = move,
                    GameOverResult = await FinishGame(game.Id, FinishReason.ConsecutivePass)
                });
            }
            else
            {
                return(new PlayResult
                {
                    MoveResult = "OK",
                    PlayMove = move,
                    GameOverResult = null
                });
            }
        }
Beispiel #6
0
        public async Task <PlayResult> Play(string gameId, string username, PlayLetter[] letters)
        {
            var game = gameCache.ActiveGames.SingleOrDefault(g => g.Id == gameId) as Game;

            if (game == null)
            {
                string message = $"Invalid game: {gameId}";
                await logger.WarningAsync(message, context : $"{gameId}:{username}");

                return(new PlayResult {
                    MoveResult = message
                });
            }

            //  Play must be done by current player
            var player = game.GetPlayer(username);

            if (player.UserName != game.CurrentPlayer)
            {
                string message = $"Game Play received not from current player. (Game:{gameId} Current Player:{game.CurrentPlayer}) ";
                await logger.WarningAsync(message, context : $"{gameId}:{username}");

                return(new PlayResult {
                    MoveResult = message
                });
            }

            // Played letters must be int player rack
            var rack = player.Rack.Select(r => r.Char).ToList();

            foreach (var letter in letters)
            {
                if (letter.Letter.Letter.IsBlank)
                {
                    var blankInRack = rack.Contains(' ');
                    if (!blankInRack)
                    {
                        string message = "Player rack doesn't contain blank tiles";
                        await logger.InfoAsync(message, context : $"{gameId}:{username}");

                        return(new PlayResult {
                            MoveResult = message
                        });
                    }
                }
                else
                {
                    var letterInRack = rack.Contains(letter.Letter.Letter.Char);
                    if (!letterInRack)
                    {
                        string message = $"Player rack doesn't contain {letter.Letter.Letter.Char}";
                        await logger.InfoAsync(message, context : $"{gameId}:{username}");

                        return(new PlayResult {
                            MoveResult = message
                        });
                    }
                }
            }

            // Validate Move
            var validationResult = await game.ValidateMove(letters, lexiconService);

            if (validationResult.Result != "OK")
            {
                string message = $"Invalid move: {validationResult.Result} ";
                //await logger.InfoAsync(message, context: username);
                return(new PlayResult {
                    MoveResult = message
                });
            }

            // Score the words
            var scoreWords = game.ScoreMove(validationResult.Words, letters);


            // Create move entity
            var playFinish = new DateTime(DateTime.UtcNow.Ticks, DateTimeKind.Utc);
            var move       = new PlayMove
            {
                Letters    = letters,
                Player     = player.UserName,
                PlayStart  = new DateTime(game.CurrentStart.Ticks, DateTimeKind.Utc),
                PlayFinish = playFinish,
                Words      = scoreWords.ToArray(),
                Score      = scoreWords.Sum(w => w.Score)
            };

            // Update game time, and current player and reset ConsecutivePasses
            var opponent = game.Player01.UserName == player.UserName ? game.Player02 : game.Player01;

            game.CurrentStart      = playFinish;
            game.CurrentPlayer     = opponent.UserName;
            game.ConsecutivePasses = 0;

            // Update game moves
            var moves = game.PlayMoves.ToList();

            moves.Add(move);
            game.PlayMoves = moves;

            // TODO: update player rack
            var ePlayer         = player as GamePlayer;
            var eRack           = player.Rack.ToList();
            var lettersToRemove = letters.Select(l => l.Letter).ToList();

            foreach (var letter in lettersToRemove)
            {
                var rLetter = letter.Letter.IsBlank
                    ? eRack.First(l => l.IsBlank)
                    : eRack.First(l => l.Char == letter.Letter.Char);
                eRack.Remove(rLetter);
            }
            var lettersNeeded = 7 - eRack.Count();
            var newLetters    = game.LetterBag.TakeLetters(lettersNeeded);

            ePlayer.Rack  = eRack.Concat(newLetters);
            ePlayer.Score = moves.Where(m => m.Player == ePlayer.UserName).Sum(m => m.Score);



            // Save game state to DB
            await gameRepository.Update(game.ToDataModel());

            await gameRepository.AddMoves(game.Id, new GameMoveDataModel[] { move.ToDataModel() });

            //logger.Info($"Game move letter:[{letters.GetString()}] Words:[{string.Join(",", move.Words.Select(w => w.GetString() + "=" + w.Score))}]",context: player.UserName);
            await logger.InfoAsync($"PLAY! = Duration:[{Math.Round((move.PlayFinish.Value - move.PlayStart).TotalMinutes,2)}] Letters:[{letters.GetString()}] Words:[{string.Join(",", move.Words.Select(w => w.GetString() + "=" + w.Score))}]", context : $"{gameId}:{username}");

            return(new PlayResult
            {
                MoveResult = "OK",
                PlayMove = move
            });
        }