Spelling and typing test with text to speech

Spelling and typing test with text to speech

Game description:

The game is played for 2 minutes at a time and the player’s aim is to spell as many words as possible in the time allotted. The words are all taken from a supplied text file (see attached) which will form the basis for the game’s data. As it is a spelling game – it has to play the required word using audio so that the user knows what to spell without seeing the word. Due to the fact that this will be done through computer speech, each word must be associated with a short sentence to disambiguate similar sounding words such as week and wick or Hill and ill. The speech part of this assignment will be implemented using the Text-To-Speech library built into Visual Studio’s SpeechSynthesizer Class located in – System.Speech.Synthesis (this will also be provided) The game will contain 3 separate dictionaries (text files), one for each Key Stage at school (e.g. KS1, KS2 and KS3). A player will start from the first dictionary and gradually progress to the most difficult. These dictionaries should not be confused with the 4 levels of game difficulties (detailed later on in this document). Each dictionary (text file) will consist of groups of words which will be denoted using the ‘[ ]’ signs. This means that before each group of words you will see the ‘[ ]’ sign in a line on its own. Each word will also appear in a line on its own together with the sentence it is associated with.

The two will be separate using the ‘-‘ (hyphen) symbol. You can make the following assumptions: (i) There is no space between the square brackets []. (ii) Each word and its associated sentence will appear in a line on their own. So for example, a typical text file will look like this…

KS1.txt

“[]

Bowl – A bowl of cereal

Ball –kick the ball

Rock – Granite is a hard rock

[]

Role – My role in the company

Roll – Rolling down the hill

[]

Beach –sand castles on the beach.

Batch – A consignment of goods.”

The simple rules of the game are:

  1. Before a word has to be typed in, it must first be played to the player (audible sound) along with its associated sentence. This is so that the player could listen to the word before having to type it in. 2. If a word has been typed incorrectly (even with one mistake, no points will be awarded), an error message will be shown and no points will be awarded. The word will then be played again. If the user wishes to pass (skip) to the next word they need to type ‘0’ (the number zero).
  2. If the level’s maximum time for spelling has lapsed (for the specific level) the game will show an appropriate message followed by the next word.
  3. Letters are captured from the keyboard and are treated sequentially. For example, if the game is showing ‘T_w_l’ (for towel) the first letter inputted into the keyboard will show here ‘T1w_l’ and the second letter will show here ‘T1w2l’.
  4. If a word was spelt correctly, the player is awarded points and the next word will be heard/shown.

The game will contain 4 levels of difficulty, each of which will have a different set of time limits for word completion and the number of letters obfuscated. The latter should be achieved at random (words within a group will be randomised).

Difficulty Level 1 – In this level, up to a third of the word’s characters are hidden and the maximum time to complete a word is 15 seconds. For example, the word ‘Door’ will show as ‘D_or’ and the word ‘Cat’ will show as ‘C_t’. If the number of characters is not divisible by 3, round down.

Difficulty Level 2 – up to half of the word’s characters are hidden and the maximum time to complete a word is 13 seconds. As in level 1, if the number of characters is not divisible by 2, round down.

Difficulty Level 3 – up to two thirds of the word’s characters are hidden and the maximum time to complete a word is 11 seconds.

Difficulty Level 4 – All characters are hidden and the maximum time to complete a word is 9 seconds. In addition to…

  1. Upon launch, the program will load all 3 dictionaries and store the information in scalable data structure. It is up to you to decide on the type of structure. This refers to both the words and their associated sentences.
  2. Each word’s characters will be obfuscated based on the game levels described above, starting at the lowest level of difficulty.
  3. Words are worth the number of consonants they contain (e.g. Cat-2 and Gerbil – 4).
  4. There will be a time limit for inputting the missing characters. Again, this will be based on the game levels described above.
  5. The program will randomise the order in which words are played/displayed within a group, irrespective of the number of words in a group (i.e. the randomisation has to work for groups with 5 words and 9 words).
  6. A simple player’s record will be kept for the duration of the 2 minutes game. It will record and display on the screen the following data:
  7. The current level;
  8. The game time;
  9. Time left to input the spelling;
  10. Total number of correct words;
  11. Total number of incorrect words;
  12. Total score; 

Solution

using System;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Threading.Tasks;

usingSystem.Threading;

usingSystem.Speech.Synthesis;

using System.IO;

usingSystem.Diagnostics;

namespaceSpelling_Game

{

class Program

{

static string masked;

staticintcorrect_words, incorrect_words;

static Stopwatch st;

public static void Main(string[] args)

{

//initiate the speaker and set its rate so it doesn’t go too fast

SpeechSynthesizer speaker = new SpeechSynthesizer();

speaker.Rate = -2;

st = new Stopwatch();

Random s = new Random();

#region reading_files

StreamReadersr = new StreamReader(@”ks1_word_dictionary.txt”);

List<string> ks1_word = new List<string>();

List<string> ks1_sentence = new List<string>();

while (!sr.EndOfStream)

{

string line = sr.ReadLine();

if (line == “[]”) continue;

string[] temp = line.Split(new string[] { ” – ” }, StringSplitOptions.None);

ks1_word.Add(temp[0]);

ks1_sentence.Add(temp[1]);

}

sr = new StreamReader(@”ks2_word_dictionary.txt”);

List<string> ks2_word = new List<string>();

List<string> ks2_sentence = new List<string>();

while (!sr.EndOfStream)

{

string line = sr.ReadLine();

if (line == “[]”) continue;

string[] temp = line.Split(new string[] { ” – ” }, StringSplitOptions.None);

ks2_word.Add(temp[0]);

ks2_sentence.Add(temp[1]);

}

sr = new StreamReader(@”ks3_word_dictionary.txt”);

List<string> ks3_word = new List<string>();

List<string> ks3_sentence = new List<string>();

while (!sr.EndOfStream)

{

string line = sr.ReadLine();

if (line == “[]”) continue;

string[] temp = line.Split(new string[] { ” – ” }, StringSplitOptions.None);

ks3_word.Add(temp[0]);

ks3_sentence.Add(temp[1]);

}

sr.Close();

#endregion

correct_words = 0; incorrect_words = 0;

List<string>allWords = ks1_word.Concat(ks2_word).Concat(ks3_word).ToList();

List<string>allSentences = ks1_sentence.Concat(ks2_sentence).Concat(ks3_sentence).ToList();

int points = 0;

Stopwatch game = new Stopwatch();

game.Start();

int iteration = 1, difficulty = 1;

float time = 15;

floatgametime = 120;

while (game.ElapsedMilliseconds<= 120000) // 2 minutes

{

if (iteration % 5 == 0 && iteration < 16)

{

difficulty += 1;

time -= 2;

}

int k = s.Next(0, allWords.Count());

masked = maskWord(allWords[k], difficulty);

string original = allWords[k];

stringorsen = allSentences[k];

appendConsole(correct_words, incorrect_words, time – st.ElapsedMilliseconds / 1000, masked, points, difficulty, gametime – game.ElapsedMilliseconds / 1000);

 

varasyncTask = Task.Run(() =>

{

speaker.Speak(original + “; as in: ” + orsen);

});

allWords.RemoveAt(k);

allSentences.RemoveAt(k);

st.Reset();

st.Start();

while ((masked.Contains(“_”) &&st.ElapsedMilliseconds<= time * 1000) || asyncTask.IsCompleted == false)

{

if (st.ElapsedMilliseconds % 1000 < 10)

appendConsole(correct_words, incorrect_words, time – st.ElapsedMilliseconds / 1000, masked, points, difficulty, gametime – game.ElapsedMilliseconds / 1000);

char c = ‘ ‘;

ConsoleKeyInfocki;

if (Console.KeyAvailable)

{

cki = Console.ReadKey(false);

if (Char.IsLetter(cki.KeyChar))

{

c = Convert.ToChar(cki.KeyChar);

intind = masked.IndexOf(“_”);

masked = masked.Remove(ind, 1);

masked = masked.Insert(ind, c.ToString());

appendConsole(correct_words, incorrect_words, time – st.ElapsedMilliseconds / 1000, masked, points, difficulty, gametime – game.ElapsedMilliseconds / 1000);

}

else if (Char.IsDigit(cki.KeyChar))

{

int input = Convert.ToChar(cki.KeyChar) – ‘0’;

if (input == 0)

{

appendConsole(correct_words, incorrect_words, time – st.ElapsedMilliseconds / 1000, original, points, difficulty, gametime – game.ElapsedMilliseconds / 1000);

incorrect_words–;

break;

}

}

else

appendConsole(correct_words, incorrect_words, time – st.ElapsedMilliseconds / 1000, masked, points, difficulty, gametime – game.ElapsedMilliseconds / 1000);

}

}

long temp = st.ElapsedMilliseconds;

st.Stop();

if (temp >= time * 1000)

Console.WriteLine(“The time is out.”);

else

{

if (original == masked)

{

correct_words++;

points += numberOfConsonants(masked);

}

elseincorrect_words++;

}

Thread.Sleep(1000);

iteration++;

}

game.Stop();

Console.Clear();

Console.WriteLine(“Your final score is ” + points + ” points. Thank you for playing!”);

Thread.Sleep(2000);

}

private static void appendConsole(intcorr, intincorr, float len, string fin, int score, int difficulty, float gamelen)

{

Console.Clear();

Console.Write(“Total # correct words: ” + corr);

Console.CursorLeft = Console.BufferWidth – (“Total # incorrect words: ” + incorr).Length;

Console.WriteLine(“Total # incorrect words: ” + incorr);

Console.Write(“Game Time: ” + gamelen + “s”);

Console.CursorLeft = Console.BufferWidth – (“Word time: ” + len + “s”).Length;

Console.WriteLine(“Word time: ” + len + “s”);

Console.Write(“Score: ” + score + ” points”);

Console.CursorLeft = Console.BufferWidth – (“Level ” + difficulty).Length;

Console.WriteLine(“Level ” + difficulty);

Console.CursorLeft = Console.BufferWidth / 2 – fin.Length / 2;

Console.WriteLine(fin);

}

private static intnumberOfConsonants(string s)

{

int count = 0;

string consonants = “bcdfghjklmnpqrstvwxyz”;

foreach (char letter in s)

{

if (consonants.Contains(letter)) count++;

}

return count;

}

private static string maskWord(string word, int difficulty)

{

int l = word.Length;

switch (difficulty)

{

case 1: l /= 3; break;

case 2: l /= 2; break;

case 3: l = l * 2 / 3; break;

default: l = -1; break;

}

string masked = “”;

if (l == -1)

{

for (int i = 0; i <word.Length; i++)

{

masked += “_”;

}

return masked;

}

if (l == 0) l = 1;

string temp = word;

Random s = new Random();

for (int i = 0; i < l; i++)

{

int k = s.Next(0, temp.Length);

if (temp[k] == ‘_’)

{

i–; continue;

}

temp = temp.Remove(k, 1);

temp = temp.Insert(k, “_”);

}

return temp;

}

}

}