/// <summary> /// Helper method finds valid words, given a game board /// </summary> /// <param name="board"></param> /// <returns></returns> public Dictionary <int, LinkedList <string> > GetValidWords(BoggleBoard board, int desiredNumWords) { Dictionary <int, LinkedList <string> > validWords = new Dictionary <int, LinkedList <string> >(); int timesChecked = 0; using (StreamReader reader = new StreamReader("dictionary.txt")) { string line; while ((line = reader.ReadLine()) != null && timesChecked < desiredNumWords) { if (board.CanBeFormed(line)) { if (!validWords.ContainsKey(line.Length)) { validWords.Add(line.Length, new LinkedList <string>()); } validWords[line.Length].AddLast(line); desiredNumWords++; } } } return(validWords); }
/// <summary> /// Helper to check score for a given word /// </summary> private int CheckScore(string word, BoggleBoard board) { if (word.Length < 3) { return(0); } // Illegal word if (!validwords.Contains(word) || !board.CanBeFormed(word)) { return(-1); } else if (word.Length > 7) { return(11); } else if (word.Length == 7) { return(5); } else if (word.Length == 6) { return(3); } else if (word.Length == 5) { return(2); } // word length 3 or 4 else { return(1); } }
/// Play a word in a game. /// If Word is null or empty or longer than 30 characters when trimmed, or if GameID or UserToken is invalid, or if UserToken is not a player in the /// game identified by GameID, responds with response code 403 (Forbidden). /// Otherwise, if the game state is anything other than "active", responds with response code 409 (Conflict). /// Otherwise, records the trimmed Word as being played by UserToken in the game identified by GameID. Returns the score for Word in the context of the /// game (e.g. if Word has been played before the score is zero). Responds with status 200 (OK). Note: The word is not case sensitive. public WordScore PlayWord(WordToPlay w, string gameID) { lock (sync) { if (w.Word == null || w.Word.Trim().Length > 30 || w.UserToken == null || !players.ContainsKey(w.UserToken) || gameID == null || !(games.TryGetValue(gameID, out GameStatus temp) || (temp.Player1.UserToken != w.UserToken || temp.Player2.UserToken != w.UserToken))) { SetStatus(Forbidden); return(null); } else { games.TryGetValue(gameID, out GameStatus g); if (!g.GameState.Equals("active")) { SetStatus(Conflict); return(null); } else { updateTime(gameID); Words wordPlay = new Words(); wordPlay.Word = w.Word; // Generate boggle board board = new BoggleBoard(g.Board); players.TryGetValue(w.UserToken, out Player p); // Score 0 if the word is less than 3 characters or -1 if it doesn't exist in dic. wordPlay.Score = board.CanBeFormed(wordPlay.Word) ? GetScore(wordPlay.Word) : -1; if (wordPlay.Word.Length < 3) { wordPlay.Score = 0; } else { foreach (Words word in p.WordsPlayed) { if (word.Word.ToUpper().Equals(wordPlay.Word.ToUpper())) { wordPlay.Score = 0; } } } // Set the appropriate score for each word WordScore scoreWord = new WordScore(); scoreWord.Score = wordPlay.Score; // Update the players' scores p.Score += wordPlay.Score; p.WordsPlayed.Add(wordPlay); SetStatus(OK); return(scoreWord); } } } }
public int PlayWord(string userToken, string word) { if (userToken == null || word == null) { throw new ArgumentNullException(); } else if (userToken != Player1 && userToken != Player2) { throw new ArgumentOutOfRangeException(); } List<WordAndScore> words; if (userToken == Player1) { words = Words1; } else { words = Words2; } int score; if (word.Length < 3) { score = 0; } else if (words.Find(p => p.Word == word) != null) { score = 0; } else if (!dictionary.Contains(word.ToUpper())) { score = -1; } else if (board.CanBeFormed(word)) { if (word.Length <= 4) score = 1; else if (word.Length == 5) score = 2; else if (word.Length == 6) score = 3; else if (word.Length == 7) score = 5; else score = 11; } else { score = -1; } words.Add(new WordAndScore() { Word = word, Score = score }); return score; }
/// Play a word in a game. /// If Word is null or empty or longer than 30 characters when trimmed, or if GameID or UserToken is invalid, or if UserToken is not a player in the /// game identified by GameID, responds with response code 403 (Forbidden). /// Otherwise, if the game state is anything other than "active", responds with response code 409 (Conflict). /// Otherwise, records the trimmed Word as being played by UserToken in the game identified by GameID. Returns the score for Word in the context of the /// game (e.g. if Word has been played before the score is zero). Responds with status 200 (OK). Note: The word is not case sensitive. public WordScore PlayWord(WordToPlay w, string gameID) { int timeLeft; if (w.Word == null || w.Word.Equals("") || w.Word.Trim().Length > 30 || w.UserToken == null || !tryGetPlayer(w.UserToken, out Player p) || gameID == null || !int.TryParse(gameID, out int GameID) || !((timeLeft = getTimeLeft(GameID)) is int) || !tryGetGame(GameID, out GameStatus g) || (!w.UserToken.Equals(g.Player1.UserToken) && !w.UserToken.Equals(g.Player2.UserToken))) { SetStatus(Forbidden); return(null); } else { if (!g.GameState.Equals("active")) { SetStatus(Conflict); return(null); } else { Words wordPlay = new Words(); wordPlay.Word = w.Word; // Generate boggle board BoggleBoard board = new BoggleBoard(g.Board); // Score 0 if the word is less than 3 characters or -1 if it doesn't exist in dic. wordPlay.Score = board.CanBeFormed(wordPlay.Word) ? GetScore(wordPlay.Word) : -1; if (wordPlay.Word.Length < 3) { wordPlay.Score = 0; } else { foreach (Words word in getWordsPlayed(w.UserToken, GameID)) { if (word.Word.ToUpper().Equals(wordPlay.Word.ToUpper())) { wordPlay.Score = 0; } } } // Set the appropriate score for each word WordScore scoreWord = new WordScore(); scoreWord.Score = wordPlay.Score; // Update the players' played words addWordToList(w, GameID, scoreWord.Score); SetStatus(OK); return(scoreWord); } } }
/// <summary> /// Given a board configuration, returns all the valid words. /// </summary> private static List <string> AllValidWords(string board) { BoggleBoard bb = new BoggleBoard(board); List <string> validWords = new List <string>(); foreach (string word in dictionary) { if (word.Length > 2 && bb.CanBeFormed(word)) { validWords.Add(word); } } return(validWords); }
public static int WordValue(string word, string board, ISet <string> dictionary) { if (word == null) { return(-2); } else if (word.Length < 3) { return(0); } else if (!dictionary.Contains(word.ToUpper())) { return(-1); } else if (BoggleBoard.CanBeFormed(word, board)) { if (word.Length <= 4) { return(1); } else if (word.Length == 5) { return(2); } else if (word.Length == 6) { return(3); } else if (word.Length == 7) { return(5); } else { return(11); } } else { return(-1); } }
private int calculateScore(BoggleBoard boggleBoard, string word) { if (word == null || boggleBoard == null) { return(-2); } //here you need to add the word to the database, //if the word is already there set the score to zero. return((boggleBoard.CanBeFormed(word) && bigDict.Contains(word)) ? word.Length < 3 ? 0 : word.Length < 5 ? 1 : word.Length < 6 ? 2 : word.Length < 7 ? 3 : word.Length < 8 ? 5 : 11 : -1); }
public void PlayWord13() { Dictionary <string, string> gameInfo = simulateGame(30); string[] words = File.ReadAllLines("dictionary.txt"); Response gameRequest = client.DoGetAsync("games/{0}?Brief={1}", gameInfo["gameId"], "asdf").Result; dynamic game = gameRequest.Data; BoggleBoard board = new BoggleBoard(game.Board.ToString()); string word = ""; foreach (string s in words) { if (s.Length == 5 && board.CanBeFormed(s)) { // Found a valid word word = s; break; } } // Repeat the test with new boards until a word with 5 letters can be formed. if (word != "") { dynamic play = new ExpandoObject(); play.UserToken = gameInfo["userToken"]; play.Word = word; Response r = client.DoPutAsync(play, "games/" + gameInfo["gameId"]).Result; Assert.AreEqual(OK, r.Status); dynamic result = r.Data; int score; Assert.IsTrue(Int32.TryParse(result.Score.ToString(), out score)); Assert.AreEqual(2, score); } else { PlayWord13(); } }
private int calculateScore(string word, List <Words> words, BoggleBoard board) { if (word.Length < 3) { return(0); } if (words != null && words.Count > 0) { foreach (Words wordThing in words) { if (wordThing.Word.Equals(word)) { return(0); } } } if (!board.CanBeFormed(word)) { return(-1); } switch (word.Length) { case 3: case 4: return(1); case 5: return(2); case 6: return(3); case 7: return(5); default: return(11); } }
/// <summary> /// This private helper evaluate player's word input and returns a valid score. /// </summary> /// <param name="trimmed"></param> /// <param name="board"></param> /// <returns></returns> private int ComputeScore(string trimmed, BoggleBoard board, List <WordsPlayed> words) { int wordCount = trimmed.Length; WordsPlayed PlayedWord = new WordsPlayed(); PlayedWord.Word = trimmed; // If word is less than 3 words, no point. Same goes for duplicated inputs. if (wordCount < 3 || words.Contains(PlayedWord)) { return(0); } // If word is not present in the dictionary.txt if (!board.CanBeFormed(trimmed) || !dictionary.Contains(trimmed)) { return(-1); } // Assign score based on the length of word input if (wordCount == 3 || wordCount == 4) { return(1); } else if (wordCount == 5) { return(2); } else if (wordCount == 6) { return(3); } else if (wordCount == 7) { return(5); } // word inputs > 7 gets 11 points return(11); }
public WordPlayed PlayWord(UserInfo user, string GameID, out HttpStatusCode status) { lock (sync) { string trimmedWord = user.Word.Trim().ToUpper(); int scoreOfWord = 0; string boardString = ""; if (!(Int32.TryParse(GameID, out int result))) { status = Forbidden; return(null); } if (user.UserToken == null || user.UserToken.Length == 0 || user.Word == null || user.Word.Length == 0 || user.Word.Trim().Length > 30) { status = Forbidden; return(null); } using (SqlConnection conn = new SqlConnection(BoggleDB)) { conn.Open(); using (SqlTransaction trans = conn.BeginTransaction()) { // determine whether GameID is valid (exists in Games table) using (SqlCommand command = new SqlCommand("select GameID, Player1, Player2, Board from Games where Games.GameID = @GameID", conn, trans)) { command.Parameters.AddWithValue("@GameID", GameID); using (SqlDataReader reader = command.ExecuteReader()) { // if GameID does not exist in games if (!reader.HasRows) { status = Forbidden; reader.Close(); trans.Commit(); return(null); } // determine whether user has valid userToken (Player1 or Player2 has user.UserToken) while (reader.Read()) { string player1Token = reader["Player1"].ToString(); string player2Token = reader["Player2"].ToString(); boardString = reader["Board"].ToString(); // if neither player1 nor player2 has user.UserToken if ((player1Token != user.UserToken) && (player2Token != user.UserToken)) { status = Forbidden; reader.Close(); trans.Commit(); return(null); } } reader.Close(); // determine whether game state is not active string gameState = ""; HttpStatusCode a = OK; GameStatus("asd", GameID, out a); using (SqlCommand cmd = new SqlCommand("select GameState from Games where Games.GameID = @GameID2", conn, trans)) { cmd.Parameters.AddWithValue("@GameID2", GameID); using (SqlDataReader reader2 = cmd.ExecuteReader()) { while (reader2.Read()) { gameState = reader2["GameState"].ToString(); } reader2.Close(); } } if (gameState != "active") { status = Conflict; trans.Commit(); return(null); } if (trimmedWord.Length < 3) { scoreOfWord = 0; } else { BoggleBoard board = new BoggleBoard(boardString); if (board.CanBeFormed(trimmedWord) && IsInDictionary(trimmedWord)) { if (trimmedWord.Length < 5) { scoreOfWord = 1; } else if (trimmedWord.Length == 5) { scoreOfWord = 2; } else if (trimmedWord.Length == 6) { scoreOfWord = 3; } else if (trimmedWord.Length == 7) { scoreOfWord = 5; } else { scoreOfWord = 11; } } else { scoreOfWord = -1; } } } } // check if this word has already been played by this player in this game using (SqlCommand command = new SqlCommand("select Word from Words where Words.GameID = @GameID and Words.Word = @Word and Words.Player = @Player", conn, trans)) { command.Parameters.AddWithValue("@Word", trimmedWord); command.Parameters.AddWithValue("@GameID", GameID); command.Parameters.AddWithValue("@Player", user.UserToken); using (SqlDataReader reader = command.ExecuteReader()) { // if this word has already been played by this player in this game if (reader.HasRows) { scoreOfWord = 0; } reader.Close(); } } //update Word table using (SqlCommand command = new SqlCommand("insert into Words(Word, GameID, Player, Score) values(@Word, @GameID, @Player, @Score)", conn, trans)) { command.Parameters.AddWithValue("@GameID", GameID); command.Parameters.AddWithValue("@Word", trimmedWord); command.Parameters.AddWithValue("@Player", user.UserToken); command.Parameters.AddWithValue("@Score", scoreOfWord); command.ExecuteNonQuery(); status = OK; trans.Commit(); WordPlayed word = new WordPlayed(); word.Score = scoreOfWord; return(word); } } } } }
public string PlayWord(string gameIDString, WordPlayed wordPlayed) { lock (sync) { int gameID = int.Parse(gameIDString); string UserToken = wordPlayed.UserToken; string Word = wordPlayed.Word.ToUpper(); // If Word is null or empty when trimmed, or if GameID or UserToken is missing or invalid, // or if UserToken is not a player in the game identified by GameID, responds with response code 403 (Forbidden). if (Word == null || Word.Trim() == string.Empty || !users.ContainsKey(UserToken) || (games[gameID].Player1Token != UserToken && games[gameID].Player2Token != UserToken)) { SetStatus(Forbidden); return(null); } // Otherwise, if the game state is anything other than "active", responds with response code 409(Conflict). else if (games[gameID].GameState != "active") { SetStatus(Conflict); return(null); } else { // Otherwise, records the trimmed Word as being played by UserToken in the game identified by GameID. // Returns the score for Word in the context of the game(e.g. if Word has been played before the score is zero). // Responds with status 200(OK).Note: The word is not case sensitive. BoggleBoard board = new BoggleBoard(games[gameID].GameBoard); int score = 0; // TODO Check if word exists in the dictionary if (board.CanBeFormed(Word)) { if (Word.Length > 2) { score++; } if (Word.Length > 4) { score++; } if (Word.Length > 5) { score++; } if (Word.Length > 6) { score += 2; } if (Word.Length > 7) { score += 6; } if (games[gameID].Player1Token == UserToken) { if (games[gameID].Player2WordScores.ContainsKey(Word)) { games[gameID].Player2Score -= games[gameID].Player2WordScores[Word]; games[gameID].Player2WordScores[Word] = score = 0; } if (games[gameID].Player1WordScores.ContainsKey(Word)) { score = 0; } else { games[gameID].Player1WordScores.Add(Word, score); } } else if (games[gameID].Player2Token == UserToken) { if (games[gameID].Player1WordScores.ContainsKey(Word)) { games[gameID].Player1Score -= games[gameID].Player1WordScores[Word]; games[gameID].Player1WordScores[Word] = score = 0; } if (games[gameID].Player2WordScores.ContainsKey(Word)) { score = 0; } else { games[gameID].Player2WordScores.Add(Word, score); } } } SetStatus(OK); return(score.ToString()); } } }
/// <summary> /// Play a word in a game. /// /// (1) If Word is null or empty when trimmed, or if GameID or UserToken is /// missing or invalid, or if UserToken is not a player in the game /// identified by GameID, responds with response code 403 (Forbidden). /// (2) Otherwise, if the game state is anything other than "active", responds /// with response code 409 (Conflict). /// (3) Otherwise, records the trimmed Word as being played by UserToken in the /// game identified by GameID. Returns the score for Word in the context of /// the game (e.g. if Word has been played before the score is zero). Responds /// with status 200 (OK). Note: The word is not case sensitive. /// </summary> /// <param name="wordPlayed">Contains the body of the request</param> /// <param name="GameID">ID of the game</param> /// <returns>The score of the played word</returns> public PlayWordReturnInfo PlayWord(string GameID, WordInfo wordPlayed) { // Check the validity GameInfo currentGameInfo = GetGameInfo(GameID); bool isInvalidObject = (wordPlayed.Word == null || wordPlayed.UserToken == null || GameID == null || currentGameInfo == null); // If the passed object contains non-null elements, begin processing it if (!isInvalidObject) { string word = wordPlayed.Word.Trim().ToUpper(); // If Word is null or empty when trimmed, or if GameID or UserToken is // missing or invalid, or if UserToken is not a player in the game identified // by GameID, responds with response code 403 (Forbidden). if (String.IsNullOrEmpty(word) || String.IsNullOrWhiteSpace(word) || currentGameInfo == null || String.IsNullOrEmpty(GameID) || (currentGameInfo.Player1Token != wordPlayed.UserToken && currentGameInfo.Player2Token != wordPlayed.UserToken)) { SetStatus(Forbidden); return(null); } // Otherwise, if the game state is anything other than "active", responds // with response code 409 (Conflict). else if (currentGameInfo.GameState != "active") { SetStatus(Conflict); return(null); } // Otherwise, records the trimmed Word as being played by this player in this // game identified by the GameID. else { // Form a new board from the game's board and retrieve the player's info BoggleBoard board = new BoggleBoard(currentGameInfo.Board); // If the word was already played, add it as an attempt and // return the score is 0 (since duplicate word). if (WasWordPlayed(wordPlayed.UserToken, GameID, wordPlayed.Word)) { SetStatus(OK); AddWordToDB(wordPlayed.Word, wordPlayed.UserToken, GameID, 0); PlayWordReturnInfo info = new PlayWordReturnInfo(); info.Score = "0"; return(info); } // Now, if the word was never played before, first ensure that the // word is valid on the board. If so, add the word to DB and return // this play's score. else if (board.CanBeFormed(wordPlayed.Word)) { // Compute the score and add it to the Words DB as the player's play // in this game identified the passed GameID int score = scoreWord(wordPlayed.Word, GameID, wordPlayed.UserToken); AddWordToDB(wordPlayed.Word, wordPlayed.UserToken, GameID, score); SetStatus(OK); PlayWordReturnInfo info = new PlayWordReturnInfo(); info.Score = score + ""; return(info); } // Otherwise, this never-before-played word cannot be formed on this // game's board. As such, add this word to DB and return this play's // score which will be -1. else { AddWordToDB(wordPlayed.Word, wordPlayed.UserToken, GameID, -1); SetStatus(OK); PlayWordReturnInfo info = new PlayWordReturnInfo(); info.Score = "-1"; return(info); } } } // The dynamic object sent with the PUT request contained a null object else { SetStatus(Forbidden); return(null); } }
public ScoreReturn PlayWord(WordInfo InputObject, string GameID) { lock (sync) { Game CurrentGame; ScoreReturn Score = new ScoreReturn(); Score.Score = 0; int internalscore = 0; //All the failure cases for bad input. if (InputObject.Word == null || InputObject.Word.Trim().Length == 0) { SetStatus(Forbidden); return(Score); } // Playing a word in a pending game. if ((GameList.Keys.Count + 1).ToString() == GameID) { SetStatus(Conflict); return(Score); } // Invalid GameID if (!GameList.TryGetValue(Int32.Parse(GameID), out CurrentGame) || !UserIDs.ContainsKey(InputObject.UserToken)) { SetStatus(Forbidden); return(Score); } else if (CurrentGame.Player1Token != InputObject.UserToken && CurrentGame.Player2Token != InputObject.UserToken) { SetStatus(Forbidden); return(Score); } else if (CurrentGame.GameState != "active") { SetStatus(Conflict); return(Score); } else { CurrentGame = new Game(); GameList.TryGetValue(Int32.Parse(GameID), out CurrentGame); string word = InputObject.Word.Trim(); BoggleBoard Board = new BoggleBoard(CurrentGame.Board); // If its player 1 playing the word. if (CurrentGame.Player1Token == InputObject.UserToken) { if (word.Length < 3) { internalscore = 0; // repeated code across branches, can be cleaned up later. this is to fix branching issues, will need to be done with player 2 as well WordScore CurrentPair = new WordScore(); CurrentPair.Score = internalscore; CurrentPair.Word = word; CurrentGame.Player1.WordsPlayed.Add(CurrentPair); } else if (Board.CanBeFormed(word)) { foreach (WordScore obj in CurrentGame.Player1.WordsPlayed) { if (obj.Word == word) { internalscore = 0; break; } } if (word.Length == 3 || word.Length == 4) { internalscore = 1; } else if (word.Length == 5) { internalscore = 2; } else if (word.Length == 6) { internalscore = 3; } else if (word.Length == 7) { internalscore = 5; } else if (word.Length > 7) { internalscore = 11; } WordScore CurrentPair = new WordScore(); CurrentPair.Score = internalscore; CurrentPair.Word = word; CurrentGame.Player1.WordsPlayed.Add(CurrentPair); CurrentGame.Player1.Score += internalscore; } else { internalscore = -1; WordScore CurrentPair = new WordScore(); CurrentPair.Score = internalscore; CurrentPair.Word = word; CurrentGame.Player1.WordsPlayed.Add(CurrentPair); CurrentGame.Player1.Score += internalscore; } GameList[Int32.Parse(GameID)] = CurrentGame; } //If its player 2 playing the word. if (CurrentGame.Player2Token == InputObject.UserToken) { if (word.Length < 3) { internalscore = 0; // repeated code across branches, can be cleaned up later. this is to fix branching issues, will need to be done with player 2 as well WordScore CurrentPair = new WordScore(); CurrentPair.Score = internalscore; CurrentPair.Word = word; CurrentGame.Player2.WordsPlayed.Add(CurrentPair); } else if (Board.CanBeFormed(word)) { foreach (WordScore obj in CurrentGame.Player1.WordsPlayed) { if (obj.Word == word) { internalscore = 0; break; } } if (word.Length == 3 || word.Length == 4) { internalscore = 1; } else if (word.Length == 5) { internalscore = 2; } else if (word.Length == 6) { internalscore = 3; } else if (word.Length == 7) { internalscore = 5; } else if (word.Length > 7) { internalscore = 11; } WordScore CurrentPair = new WordScore(); CurrentPair.Score = internalscore; CurrentPair.Word = word; CurrentGame.Player2.WordsPlayed.Add(CurrentPair); CurrentGame.Player2.Score += internalscore; } else { internalscore = -1; WordScore CurrentPair = new WordScore(); CurrentPair.Score = internalscore; CurrentPair.Word = word; CurrentGame.Player2.WordsPlayed.Add(CurrentPair); CurrentGame.Player2.Score += internalscore; } GameList[Int32.Parse(GameID)] = CurrentGame; } } // Records the word as being played. SetStatus(OK); Score.Score = internalscore; return(Score); } }
/// <summary> /// method for play word /// </summary> /// <param name="user">the UserToek and the word that this player typied. </param> /// <param name="GameID">the GameID of this player in . </param> /// <returnsplayWordsReturn>return the score of the word that the user type. </returns> public playWordsReturn PlayWords(playGameInfo user, String GameID) { //get gameID int number; bool result = Int32.TryParse(GameID, out number); //check user info if (user == null || user.Word == null || user.Word.Trim().Length == 0 || GameID == null || user.UserToken == null || !result) { SetStatus(Forbidden); return(null); } //check game status statudReturn4 check = gameStatus(GameID, ""); if (check.GameState != "active") { SetStatus(Conflict); return(null); } // if (checkmatching(GameID, user.UserToken) == false) { SetStatus(Forbidden); return(null); } using (SqlConnection conn = new SqlConnection(BoggleDB)) { conn.Open(); using (SqlTransaction trans = conn.BeginTransaction()) { BoggleBoard NewGame = new BoggleBoard(check.Board); int scoreResult = 0; if (user.Word.Length < 3) { scoreResult = 0; } else if (NewGame.CanBeFormed(user.Word) && File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory.ToString() + "dictionary.txt").Contains(user.Word)) { scoreResult = CalculateScore(user.Word); } else { scoreResult--; } if (checkWordPlay(GameID, user.UserToken, user.Word) == false) { using (SqlCommand cmd = new SqlCommand(getPath("updatePlayWords"), conn, trans)) { cmd.Parameters.AddWithValue("@Word", user.Word); cmd.Parameters.AddWithValue("@Score", scoreResult); cmd.Parameters.AddWithValue("@GameID", GameID); cmd.Parameters.AddWithValue("@Player", user.UserToken); cmd.ExecuteNonQuery(); trans.Commit(); } } else { scoreResult = 0; } playWordsReturn info = new playWordsReturn(); info.Score = scoreResult; SetStatus(OK); return(info); } } }
/// <summary> /// Play a word in a game /// /// If Word is null or empty when trimmed, or if GameID or /// UserToken is missing or invalid, or if UserToken is not a /// player in the game identified by GameID, responds with response /// code 403 (Forbidden). /// /// Otherwise, if the game state is anything other than "active", /// responds with response code 409 (Conflict). /// /// Otherwise, records the trimmed Word as being played by UserToken /// in the game identified by GameID. Returns the score for Word in the /// context of the game (e.g. if Word has been played before the score is zero). /// Responds with status 200 (OK). Note: The word is not case sensitive. /// </summary> /// <param name="gameID"></param> /// <param name="UserToken"></param> /// <param name="Word"></param> /// <returns></returns> public WordScore PlayWord(string gameID, WordCheck info) { try { string word = info.Word.Trim(); string userToken = info.UserToken; BoggleBoard PlayBoard; string status1; int score = 0; bool canPlay; DateTime time; int TimeLimit; if (word.Length == 0 || userToken == null || gameID == null) { SetStatus(Forbidden); return(null); } if (!(new Regex(@"\d+").IsMatch(gameID))) { SetStatus(Forbidden); return(null); } //Creates a sql connection using (SqlConnection conn = new SqlConnection(BoggleDB)) { //open connection conn.Open(); using (SqlTransaction trans = conn.BeginTransaction()) { using (SqlCommand command = new SqlCommand("select GameStatus, StartTime, TimeLimit from Games where GameID = @GameID", conn, trans)) { command.Parameters.AddWithValue("@GameID", gameID); using (SqlDataReader reader = command.ExecuteReader()) { //added check to make sure game was in table if (!reader.HasRows) { SetStatus(Forbidden); return(null); } reader.Read(); status1 = reader.GetString(0); // else we get the time the game started and the calculated time limit from the 2 players. time = reader.GetDateTime(1); TimeLimit = (int)reader.GetValue(2); double elapsedTime = Math.Round((DateTime.Now.TimeOfDay.TotalSeconds - time.TimeOfDay.TotalSeconds), 0); // If the elapsed time is greater than or equal to the time limit, the game is marked as completed so no // Actions can be made to the game. if (elapsedTime >= (double)TimeLimit) { SetStatus(Conflict); status1 = "completed"; } } } } using (SqlTransaction trans = conn.BeginTransaction()) { // Gets thge players and board based on the given GameID. using (SqlCommand command = new SqlCommand("select Player1, Player2, Board, GameStatus from Games where GameID = @GameID", conn, trans)) { string P1; string P2; string status; command.Parameters.AddWithValue("@GameID", gameID); using (SqlDataReader reader = command.ExecuteReader()) { if (!reader.HasRows) { SetStatus(Forbidden); return(null); } reader.Read(); P1 = reader.GetString(0); P2 = reader.GetString(1); status = reader.GetString(3); if (!P1.Equals(userToken) && !P2.Equals(userToken)) { SetStatus(Forbidden); return(null); } if (status1 != "active") { SetStatus(Conflict); return(null); } PlayBoard = new BoggleBoard(reader.GetString(2)); // Checks to make sure P1 and P2 are in the game. if (P1 == null || P2 == null) { SetStatus(Forbidden); return(null); } // If game status is Active, sets a bool that allows up to play a word. If it is anything but Active, // we can't play a word. if (status == "active") { canPlay = true; } else { canPlay = false; SetStatus(Conflict); } } } // If we can play a word, we go in to the if statement. If not, we set the status to 409 - Conflict and return null if (canPlay) { // Checks to make sure the word can be formed on the game board. if (PlayBoard.CanBeFormed(word)) { string scoreString; // Sets the score initially to the word score from the dictionary. Can be changed below if the word has already been played by // the player. if (dictionary.TryGetValue(word.ToUpper(), out scoreString)) { int.TryParse(scoreString, out score); // Gets all the words played by a player in a game. using (SqlCommand command2 = new SqlCommand("select Word from Words where GameID = @GameID and Player = @Player", conn, trans)) { command2.Parameters.AddWithValue("@GameID", gameID); command2.Parameters.AddWithValue("@Player", userToken); using (SqlDataReader reader1 = command2.ExecuteReader()) { // Reads each row/word that a player has played for a game. while (reader1.Read()) { // If the word has been played, score is updated to 0. if (reader1.GetString(0) == word) { score = 0; break; } } } } } } // If the word can't be formed on the board or is an invalid word, score is set to -1. else { score = -1; } // Inserts the word into the Words table. The word is accociated with a GameID, Player, and score. using (SqlCommand command3 = new SqlCommand("Insert into Words (Word, GameID, Player, Score) values (@Word, @GameID, @Player, @Score)", conn, trans)) { command3.Parameters.AddWithValue("@Word", word); command3.Parameters.AddWithValue("@GameID", gameID); command3.Parameters.AddWithValue("@Player", userToken); command3.Parameters.AddWithValue("@Score", score); if (command3.ExecuteNonQuery() != 1) { SetStatus(BadRequest); return(null); } } SetStatus(OK); //comit transaction and return the usertoken trans.Commit(); // Returns a WordScore object that reflect the score of the word a player just played. return(new WordScore { Score = score.ToString() }); } // Only gets done when the game status is anything other than Active. { SetStatus(Conflict); return(null); } } } } catch (Exception) { SetStatus(Conflict); return(null); } }
public void TestMethod4() { IISAgent.Start(@"/site:""BoggleService"" /apppool:""Clr4IntegratedAppPool"" /config:""..\..\..\.vs\config\applicationhost.config"""); dynamic p3 = new ExpandoObject(); dynamic p4 = new ExpandoObject(); dynamic game2 = new ExpandoObject(); p3.Nickname = "John"; p4.Nickname = "June"; Response r3 = client.DoPostAsync("/users", p3).Result; Response r4 = client.DoPostAsync("/users", p4).Result; p3.UserToken = r3.Data.UserToken; p4.UserToken = r4.Data.UserToken; p3.TimeLimit = "10"; p4.TimeLimit = "10"; r3 = client.DoPostAsync("/games", p3).Result; r4 = client.DoPostAsync("/games", p4).Result; Assert.AreEqual(Accepted, r3.Status); Assert.AreEqual(Created, r4.Status); p3.GameID = r3.Data.GameID; p4.GameID = r4.Data.GameID; game2 = client.DoGetAsync("/games/" + p3.GameID).Result; BoggleBoard board2 = new BoggleBoard(game2.Data.Board.ToString()); ///////////////////////////////////////////////////////////////////////////////////////////// dynamic p5 = new ExpandoObject(); dynamic p6 = new ExpandoObject(); dynamic game3 = new ExpandoObject(); p5.Nickname = "Jack"; p6.Nickname = "Jill"; Response r5 = client.DoPostAsync("/users", p5).Result; Response r6 = client.DoPostAsync("/users", p6).Result; p5.UserToken = r5.Data.UserToken; p6.UserToken = r6.Data.UserToken; p5.TimeLimit = "8"; p6.TimeLimit = "8"; r5 = client.DoPostAsync("/games", p5).Result; r6 = client.DoPostAsync("/games", p6).Result; Assert.AreEqual(Accepted, r5.Status); Assert.AreEqual(Created, r6.Status); p5.GameID = r5.Data.GameID; p6.GameID = r6.Data.GameID; game3 = client.DoGetAsync("/games/" + p5.GameID).Result; HashSet <string> testDictionary = new HashSet <string>(); List <string> potentialWords = new List <string>(); foreach (string i in File.ReadAllLines(AppDomain.CurrentDomain.BaseDirectory + "../../../\\dictionary.txt")) { testDictionary.Add(i); if (board2.CanBeFormed(i)) { potentialWords.Add(i); } } Random rand = new Random(); dynamic p3words = new ExpandoObject(); dynamic p4words = new ExpandoObject(); dynamic p5words = new ExpandoObject(); dynamic p6words = new ExpandoObject(); p3words.UserToken = p3.UserToken; p4words.UserToken = p4.UserToken; p5words.UserToken = p5.UserToken; p6words.UserToken = p6.UserToken; for (int i = 0; i < potentialWords.Count + 4; i++) { p3.Word = potentialWords[rand.Next(0, potentialWords.Count)]; p4.Word = potentialWords[rand.Next(0, potentialWords.Count)]; p5.Word = potentialWords[rand.Next(0, potentialWords.Count)]; p6.Word = potentialWords[rand.Next(0, potentialWords.Count)]; p3words.Word = p3.Word; p4words.Word = p4.Word; p5words.Word = p5.Word; p6words.Word = p6.Word; r3 = client.DoPutAsync(p3words, "games/" + p3.GameID).Result; r4 = client.DoPutAsync(p4words, "games/" + p4.GameID).Result; r5 = client.DoPutAsync(p5words, "games/" + p5.GameID).Result; r6 = client.DoPutAsync(p6words, "games/" + p6.GameID).Result; Assert.AreEqual(OK, r3.Status); Assert.AreEqual(OK, r4.Status); Assert.AreEqual(OK, r5.Status); Assert.AreEqual(OK, r6.Status); } ///////////////////////////////////////////// dynamic gameBrief2 = new ExpandoObject(); gameBrief2 = client.DoGetAsync("/games/" + p3.GameID + "?Brief=yes").Result; Assert.AreEqual(OK, gameBrief2.Status); Thread.Sleep(11000); gameBrief2 = client.DoGetAsync("/games/" + p3.GameID).Result; Assert.AreEqual("completed", (string)gameBrief2.Data.GameState); //////////////////////////////////////////////// dynamic gameBrief3 = new ExpandoObject(); gameBrief3 = client.DoGetAsync("/games/" + p5.GameID + "?Brief=yes").Result; Assert.AreEqual(OK, gameBrief3.Status); gameBrief3 = client.DoGetAsync("/games/" + p5.GameID).Result; Assert.AreEqual("completed", (string)gameBrief3.Data.GameState); }
public void TestMethod3() { dynamic p1 = new ExpandoObject(); dynamic p2 = new ExpandoObject(); dynamic game = new ExpandoObject(); p1.Nickname = "Mark"; p2.Nickname = "Bob"; Response r1 = client.DoPostAsync("/users", p1).Result; Response r2 = client.DoPostAsync("/users", p2).Result; p1.UserToken = r1.Data.UserToken; p2.UserToken = r2.Data.UserToken; p1.TimeLimit = "10"; p2.TimeLimit = "10"; r1 = client.DoPostAsync("/games", p1).Result; r2 = client.DoPostAsync("/games", p2).Result; Assert.AreEqual(Accepted, r1.Status); Assert.AreEqual(Created, r2.Status); p1.GameID = r1.Data.GameID; p2.GameID = r2.Data.GameID; game = client.DoGetAsync("/games/" + p1.GameID).Result; BoggleBoard board = new BoggleBoard(game.Data.Board.ToString()); HashSet <string> testDictionary = new HashSet <string>(); List <string> potentialWords = new List <string>(); foreach (string i in File.ReadAllLines(AppDomain.CurrentDomain.BaseDirectory + "../../../\\dictionary.txt")) { testDictionary.Add(i); if (board.CanBeFormed(i)) { potentialWords.Add(i); } } Random rand = new Random(); dynamic p1words = new ExpandoObject(); dynamic p2words = new ExpandoObject(); p1words.UserToken = p1.UserToken; p2words.UserToken = p2.UserToken; p1words.Word = " "; r1 = client.DoPutAsync(p1words, "games/" + p1.GameID).Result; p1words.Word = null; r1 = client.DoPutAsync(p1words, "games/" + p1.GameID).Result; p1words.Word = "kkkkkkkkkkkkk"; r1 = client.DoPutAsync(p1words, "games/" + p1.GameID).Result; p1words.Word = "kkkkkkkkkkkkk"; r1 = client.DoPutAsync(p1words, "games/" + p1.GameID).Result; for (int i = 0; i < potentialWords.Count + 4; i++) { p1.Word = potentialWords[rand.Next(0, potentialWords.Count)]; p2.Word = potentialWords[rand.Next(0, potentialWords.Count)]; p1words.Word = p1.Word; p2words.Word = p2.Word; r1 = client.DoPutAsync(p1words, "games/" + p1.GameID).Result; r2 = client.DoPutAsync(p2words, "games/" + p2.GameID).Result; Assert.AreEqual(OK, r1.Status); Assert.AreEqual(OK, r2.Status); } dynamic gameBrief = new ExpandoObject(); gameBrief = client.DoGetAsync("/games/" + p1.GameID + "?Brief=yes").Result; Assert.AreEqual(OK, gameBrief.Status); Thread.Sleep(11000); dynamic endResult = new ExpandoObject(); gameBrief = client.DoGetAsync("/games/" + p1.GameID).Result; Assert.AreEqual("completed", (string)gameBrief.Data.GameState); }
public score Play(PlayWord Word, string GameID) { if (Word.Word == null || Word.Word.Trim() == "" || Word.Word.Trim().Length > 30) { SetStatus(Forbidden); return(null); } using (SqlConnection conn = new SqlConnection(BoggleDB)) { conn.Open(); using (SqlTransaction trans = conn.BeginTransaction()) { //Checking if UserToken exists in Users table. using (SqlCommand command = new SqlCommand("select UserID from Users where UserID = @UserID", conn, trans)) { command.Parameters.AddWithValue("@UserID", Word.UserToken); using (SqlDataReader reader = command.ExecuteReader()) { if (!reader.HasRows) { SetStatus(Forbidden); trans.Commit(); return(null); } } } //Checking if GameID exists in Games table and that user is in the game. using (SqlCommand command = new SqlCommand("select GameID from Games where GameID = @GameID and (Player1 = @UserID or Player2 = @UserID2)", conn, trans)) { command.Parameters.AddWithValue("@GameID", GameID); command.Parameters.AddWithValue("@UserID", Word.UserToken); command.Parameters.AddWithValue("@UserID2", Word.UserToken); using (SqlDataReader reader = command.ExecuteReader()) { if (!reader.HasRows) { SetStatus(Forbidden); trans.Commit(); return(null); } } } // Check if game is active or not using (SqlCommand command = new SqlCommand("select * from Games where GameID = @GameID and Player2 is not null", conn, trans)) { command.Parameters.AddWithValue("@GameID", GameID); using (SqlDataReader reader = command.ExecuteReader()) { if (!reader.HasRows) { SetStatus(Conflict); trans.Commit(); return(null); } while (reader.Read()) { DateTime temp = (DateTime)reader["StartTime"]; int TimeLeft = (int)reader["TimeLimit"] + (int)(temp.Subtract(DateTime.Now).TotalSeconds); if (TimeLeft <= 0) { SetStatus(Conflict); trans.Commit(); return(null); } } } } // Checks if word has been played bool played = false; string word = Word.Word.ToUpper(); using (SqlCommand command = new SqlCommand("select * from Words where GameID = @GameID and Player = @Player and Word = @Word", conn, trans)) { command.Parameters.AddWithValue("@GameID", GameID); command.Parameters.AddWithValue("@Player", Word.UserToken); command.Parameters.AddWithValue("@Word", word); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.HasRows) { played = true; } } } // Calculates score int score = 0; using (SqlCommand command = new SqlCommand("select * from Games where GameID = @GameID", conn, trans)) { command.Parameters.AddWithValue("@GameID", GameID); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { BoggleBoard board = new BoggleBoard((string)reader["Board"]); if (word.Length < 3) { score = 0; } else if (played) { score = 0; } else if (board.CanBeFormed(word) && Legal(word)) { if (word.Length < 5) { score = 1; } else if (word.Length == 5) { score = 2; } else if (word.Length == 6) { score = 3; } else if (word.Length == 7) { score = 5; } else { score = 11; } } else { score = -1; } } } } score Score = new score { Score = score }; using (SqlCommand command = new SqlCommand("insert into Words (Word, GameID, Player, Score) values(@Word, @GameID, @Player, @Score)", conn, trans)) { command.Parameters.AddWithValue("@Word", word); command.Parameters.AddWithValue("@GameID", GameID); command.Parameters.AddWithValue("@Player", Word.UserToken); command.Parameters.AddWithValue("@Score", score); command.ExecuteNonQuery(); SetStatus(OK); trans.Commit(); return(Score); } } } }