Modeling an individual field space as an object can be quite useful.
I get good OOP mileage there.
However, a minefield object would be (in my model) a simple owner and manager of a 2D array of mineField objects.
There would be just 1 minefield in the program, so Singleton? This is an "anti-pattern" property.
It may be useful to enapsulate the fieldSpace array in a minefield class, but I just wrote global createField(), displayField(), destroyField(), etc.. functions.
I suppose that in a mineField class these would be mineField(), display() and ~mineField() respectively.
I made a debatable design choice for fieldSpace objects. I allow the exclusive nature of some properties to be reflected in a single char data member.
For example, a fieldSpace (FS) is either a mine OR it has a count. Not both.
Hence 1 variable to reflect this
char cnt;// = 'M' or '0'-'9'
Member functions may be then:
1 2 3 4 5 6 7
|
bool fieldSpace::isMine()const { return cnt == 'M'; }
int fieldSpace::getCount()const
{
if( cnt == 'M' ) return -1;// I rest my case
return (int)(cnt-'0');
}
|
Are you treating a space as only revealed or not revealed?
Are there no other states like marked with a '?' or flag?
If so a bool revealed data member will do.
Otherwise, I went with a 2nd char data member to record which of 4 states a fieldSpace could be in.
char st;// state = 'r'(revealed) or covered: '-', '?', 'f'
Two of those states are clearable: '-' (unmarked) and '?'.
The other 2 are unclearable: 'f'(locked) and 'r' = already cleared
Hence:
bool fieldSpace::isClearable()const { return (st == '-' || st == '?'); }
Otherwise just:
bool fieldSpace::isClearable()const { return !revealed; }
Constructor?
fieldSpace::fieldSpace( bool mined, char Count='0' ): st('-'), cnt(mined ? 'M' : Count) {}
Drawing?
1 2 3 4 5
|
void fieldSpace::show()const
{
if( st == 'r' ) cout << cnt;
else cout << st;
}
|
Hope this gives you some useful ideas.
edit: corrections