Esempio n. 1
0
        /// <summary>
        /// Scores the passed word in the passed boggle board. It assumes the word has not been played before.
        ///
        /// Case insensitive.
        /// </summary>
        private int ScoreWord(string boardString, string word)
        {
            //If the word is too small
            if (word.Length < 3)
            {
                return(0);
            }
            //Valid word scoring
            else if (StaticBoard.CanBeFormed(boardString, word) && Dict.Contains(word.ToLower()))
            {
                int leng = word.Length;

                if (leng == 3 || leng == 4)
                {
                    return(1);
                }
                else if (leng == 5 || leng == 6)
                {
                    return(leng - 3);
                }
                else if (leng == 7)
                {
                    return(5);
                }
                else
                {
                    return(11);
                }
            }
            //Invalid word that is longer is length 3
            else
            {
                return(-1);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Attempts to join a game with user userToken and timeLimit
        ///
        /// If UserToken is invalid, TimeLimit is less than 5, or TimeLimit is over 120, responds
        /// with status 403 (Forbidden).
        ///
        /// Otherwise, if UserToken is already a player in the pending game, responds with status
        /// 409 (Conflict).
        ///
        /// Otherwise, if there is already one player in the pending game, adds UserToken as the
        /// second player. The pending game becomes active. The active game's time limit is the integer
        /// average of the time limits requested by the two players. Returns the new active game's
        /// GameID (which should be the same as the old pending game's GameID). Responds with
        /// status 201 (Created).
        ///
        /// Otherwise, adds UserToken as the first player of a new pending game, and the TimeLimit as
        /// the pending game's requested time limit. Returns the pending game's GameID. Responds with
        /// status 202 (Accepted).
        /// </summary>
        public GameIDResponse JoinGame(JoinRequest request, out HttpStatusCode status)
        {
            int timeLimit = request.TimeLimit;

            // make sure TimeLimit is within the expected bounds
            if (!(timeLimit >= 5 && timeLimit <= 120))
            {
                status = Forbidden;
                return(null);
            }

            //null checks
            if (request is null || request.UserToken is null)
            {
                status = Forbidden;
                return(null);
            }

            // the UserID that'll be used throughout this method
            string userID = request.UserToken.Trim();

            // make sure UserToken is within the expected bounds
            if (userID == null || userID.Length == 0 || userID.Length > 36)
            {
                status = Forbidden;
                return(null);
            }

            // open connection to database
            using (SqlConnection connection = new SqlConnection(BoggleDB))
            {
                connection.Open();

                // execute all commands within a single transaction
                using (SqlTransaction transaction = connection.BeginTransaction())
                {
                    // todo: make sure GameID starts at 1, not 0
                    // (otherwise, this should be changed, because this might actually end up as 0 when creating a game)
                    int gameID = -1;

                    // find out whether there's a pending game
                    using (SqlCommand command = new SqlCommand("select GameID, Player1, TimeLimit from Games where Player2 is null",
                                                               connection, transaction))
                    {
                        // the reader that will determine whether there's a pending game, and if so, what its gameID is
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                gameID = (int)reader["GameID"];
                                string player1 = (string)reader["Player1"];

                                // averages the time between player1's requested time and this user's requested time
                                int player1RequestedTime = (int)reader["TimeLimit"];
                                timeLimit = (timeLimit + player1RequestedTime) / 2;

                                // player is already searching for a game
                                if (player1 == userID)
                                {
                                    status = Conflict;
                                    reader.Close();
                                    transaction.Commit();
                                    return(null);
                                }
                            }
                        }
                    }

                    if (gameID == -1)
                    {
                        using (SqlCommand command = new SqlCommand("insert into Games (Player1, TimeLimit) output inserted.GameID values(@Player1, @TimeLimit)", connection, transaction))
                        {
                            command.Parameters.AddWithValue("@Player1", userID);
                            command.Parameters.AddWithValue("@TimeLimit", timeLimit);

                            SqlParameter outputparam = new SqlParameter("@GameID", SqlDbType.Int)
                            {
                                Direction = ParameterDirection.Output
                            };

                            command.Parameters.Add(outputparam);

                            // execute command, and get back the primary key (GameID)
                            try
                            {
                                gameID = (int)command.ExecuteScalar();
                            }
                            //If an exception was thrown, a foreign key pair was violated
                            catch (SqlException)
                            {
                                status = Forbidden;
                                transaction.Commit();
                                return(null);
                            }
                            status = Accepted;
                        }
                    }
                    else
                    {
                        using (SqlCommand command = new SqlCommand("update Games set Player2 = @Player2, Board = @Board, TimeLimit = @TimeLimit, StartTime = @StartTime where GameID = @GameID", connection, transaction))
                        {
                            command.Parameters.AddWithValue("@Player2", userID);
                            command.Parameters.AddWithValue("@Board", StaticBoard.GenerateBoggleBoard());
                            command.Parameters.AddWithValue("@TimeLimit", timeLimit);
                            command.Parameters.AddWithValue("@StartTime", DateTime.UtcNow);
                            command.Parameters.AddWithValue("@GameID", gameID);

                            try
                            {
                                if (command.ExecuteNonQuery() != 1)
                                {
                                    throw new Exception("SQL query failed");
                                }
                            }
                            //If Player2 is not a registered user
                            catch (SqlException)
                            {
                                status = Forbidden;
                                transaction.Commit();
                                return(null);
                            }

                            status = Created;
                        }
                    }

                    transaction.Commit();
                    return(new GameIDResponse {
                        GameID = gameID
                    });
                }
            }
        }