コード例 #1
0
ファイル: GameController.cs プロジェクト: stanroze/orleans
 public async Task<ActionResult> MakeMove(Guid id, int x, int y)
 {
     var guid = GetGuid();
     var game = GameGrainFactory.GetGrain(id);
     var move = new GameMove { PlayerId = guid, X = x, Y = y };
     var state = await game.MakeMove(move);
     return Json(state, JsonRequestBehavior.AllowGet);
 }
コード例 #2
0
ファイル: GameGrain.cs プロジェクト: stanroze/orleans
        // make a move during the game
        public async Task<GameState> MakeMove(GameMove move)
        {
            // check if its a legal move to make
            if (this.GameState != GameState.InPlay) throw new ApplicationException("This game is not in play");

            if (ListOfPlayers.IndexOf(move.PlayerId) < 0) throw new ArgumentException("No such playerid for this game", "move");
            if (move.PlayerId != ListOfPlayers[indexNextPlayerToMove]) throw new ArgumentException("The wrong player tried to make a move", "move");

            if (move.X < 0 || move.X > 2 || move.Y < 0 || move.Y > 2) throw new ArgumentException("Bad co-ordinates for a move", "move");
            if (theBoard[move.X, move.Y] != -1) throw new ArgumentException("That square is not empty", "move");

            // record move
            this.ListOfMoves.Add(move);
            this.theBoard[move.X, move.Y] = indexNextPlayerToMove;

            // check for a winning move
            var win = false;
            if (!win)
                for (int i = 0; i < 3 && !win; i++)
                    win = isWinningLine(theBoard[i, 0], theBoard[i, 1], theBoard[i, 2]);
            if (!win)
                for (int i = 0; i < 3 && !win; i++)
                    win = isWinningLine(theBoard[0, i], theBoard[1, i], theBoard[2, i]);
            if (!win)
                win = isWinningLine(theBoard[0, 0], theBoard[1, 1], theBoard[2, 2]);
            if (!win)
                win = isWinningLine(theBoard[0, 2], theBoard[1, 1], theBoard[2, 0]);

            // check for draw

            var draw = false;
            if (this.ListOfMoves.Count() == 9)
                draw = true;  // we could try to look for stalemate earlier, if we wanted 

            // handle end of game
            if (win || draw)
            {
                // game over
                this.GameState = GameState.Finished;
                if (win)
                {
                    WinnerId = ListOfPlayers[indexNextPlayerToMove];
                    LoserId = ListOfPlayers[(indexNextPlayerToMove + 1) % 2];
                }

                // collect tasks up, so we await both notifications at the same time
                var promises = new List<Task>();
                // inform this player of outcome
                var playerGrain = PlayerGrainFactory.GetGrain(ListOfPlayers[indexNextPlayerToMove]);
                promises.Add(playerGrain.LeaveGame(this.GetPrimaryKey(), win ? GameOutcome.Win : GameOutcome.Draw));

                // inform other player of outcome
                playerGrain = PlayerGrainFactory.GetGrain(ListOfPlayers[(indexNextPlayerToMove + 1) % 2]);
                promises.Add(playerGrain.LeaveGame(this.GetPrimaryKey(), win ? GameOutcome.Lose : GameOutcome.Draw));
                await Task.WhenAll(promises);
                return this.GameState;
            }

            // if game hasnt ended, prepare for next players move
            indexNextPlayerToMove = (indexNextPlayerToMove + 1) % 2;
            return this.GameState;
        }