# What is the best way to store temporary selected characters and their insertion order?

I'm developing word game, similar to "Word Mole". I'm having a hard time determining how to store temporarily selected characters, which in turn, will changed into a word.

For example, say, I have the following characters:

0  1  2  3
0 O  B O S
1 S  F  R  H
2 T  N  E  Z
3 R  B  D  I

I store all this information in a character array named playCharacter, and I also created a character array named markedCharacter, with the default value of ' ' for each element. Every time I select each cell, say cell[1,0], I set markedCharacter[1,0] = 'b' an so on, until I'm done with current word. How do I store the step information? For example, if I choose to play bored, I'll be marking:

markedCharacter[1,0] = 'b'
markedCharacter[2,0] = 'o'
markedCharacter[2,1] = 'r'
markedCharacter[2,2] = 'e'
markedCharacter[2,3] = 'd'


Do I need another array? if so, what data should I store in it?

In turn, I'll want to use this markedCharacter as a way to check

• if certain moves are valid (eg, are they marked within an already marked neighbor cell?)
• if stored words are valid or not (this part is already covered)
• I don't need to do undo operation
• I think your question lacks information about what you intend to do with the data. Do you need to keep track of all the selected indices (eg. for validation, undo functionality or similar)? How do you validate a sequence (if it's a real word and if the sequence is possible/allowed)? – bummzack Dec 19 '11 at 18:04

TL;DR

A simple List<int> is enough to store all the information you need. Read on for the details.

Context

I'll drop in a little trick here then. Are you aware that when working with 2D matrices there's a way to index them with a single number, instead of having to provide a (x,y) pair?

For instance, where is the letter d in the following matrix?

  | 0 1 2
--|-------
0 | a b c
1 | d e f


Using the usual (x,y) notation the answer would be (0,1) - the letter d can be found on the first column of the second row (remember, zero based indexes).

But you could also index your matrix like this:

a b c    =>    0 1 2
d e f          3 4 5


In which case the answer would simply be (3) - the letter d is the fourth element in the matrix starting from the top and to the right (once again, zero based).

Conversion

You can convert from a (X,Y) pair to a simple (index) by doing:

int index = x  + y * width


And you can convert an (index) back to a (X,Y) pair by doing:

int x = index % width;
int y = index / width; // Note: Integer division (truncate)


Where width is simply the width of the matrix.

Here's two simple methods to do this:

int encode(int x, int y, int width)
{
return x + y * width;
}

void decode(int index, int width, out int x, out in y)
{
x = index % width;
y = index / width;
}


And how to use them:

int width = 3;

// Encode (1,2)
int index = encode(1, 2, width);

// Decode
int x, y;
decode(index, width, out x, out y);


On to your question. Using this little encoding you can store a sequence as simply as:

List<int> sequence = new List<int>();

• The order in which you store elements in the list becomes the order in which the letters were selected.
• It's easy to check for duplicates or collisions. Just do a List.Contains or List.Find.
• Undoing is simply a matter of removing the last index from the list.
• Starting a new sequence is as simple as calling List.Clear.
• You can check which letter corresponds to any element in the sequence by doing board.GetLetterAt(index % board.Width, index / board.Width).
• Just repeat the previous line for each element in the sequence to reconstruct the word.

And to answer your specific example, if you chose to play bored, that would be stored as:

sequence.Clear();
sequence.Add(new []{encode(1,0), encode(2,0), encode(2,1), encode(2,2), encode(2,3)});

• this, by far is the best answer for my situation and several other who develop similar game (say, sudoku, or other word game). I'll wait for 2-3 days before finally choose one answer. – ariefbayu Dec 20 '11 at 1:40
• This is more intuitive and straight to the point than my approach, I'd go with this! – Zolomon Dec 20 '11 at 10:27

Why not create a Sequence object that is a list of marked words in the order they were chosen?

Something like this..

class Sequence {
List<Letter> letters;
int index = 0;

public void addLetter(char letter, Point position) {
}

public boolean checkIfThereIsAMatchInThisLevel(List<string> words) {
return words.contains(letters);
}

/* OTHER COOL AND USEFUL METHODS HERE */
}

class Letter
char letter;
Point position; // Just a struct/class with x,y values stored.
int index;

//Constructor omitted
}


Then you can just create a new object or reset it, or whatever floats your boat, when a new sequence is created/finished etc.

I hope I understood your question correctly!

• interesting, I think I can use this one. Lemme test it first. – ariefbayu Dec 19 '11 at 23:05
• @silent Get back to me if you're having problems and I'll try to help you out! – Zolomon Dec 20 '11 at 10:24