473,786 Members | 2,368 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Objects with value semantics - enums vs classes

The problem comes up in all sorts of contexts. But here is an example:

We want to model the basics of chess, maybe for making a chess program,
or maybe just to make an interactive board or ...

We have to have the notions of colors, squares and pieces represented.
Ideally, we want to be able to do things like initializing the board:

void initial()
{
const Piece backLine[] =
{rook,knight,bi shop,queen,king ,bishop,knight, rook};

toMove = white;
int i = 0;
for (square s = a1; s <= h1; ++s)
{
board[s].piece = backLine[i++];
board[s].color = white;
}
for (square s = a2; s <= h2; ++s)
{
board[s].piece = pawn;
board[s].color = white;
}
for (square s = a3; s <= h6; ++s)
board[s].piece = none;
for (square s = a7; s <= h7; ++s)
{
board[s].piece = pawn;
board[s].color = black;
}
i = 0;
for (Square s = a8; s <= h8; ++s)
{
board[s].piece = backLine[i++];
board[s].color = black;
}
}

This is a simple function that has to be present in a program involving
chess, and it shows a little bit about what is needed.

The simplest way to do this, is by making enums for piece, color, and
square, like:

enum Color {white,black};
enum Piece {none,pawn,knig ht,bishop,queen ,king}
enum Square {a1,a2,...,h8};

But already here, we are having trouble. We have to define several
functions to get Square to work as indicated above.

We could do it even simpler and less typesafe by just using ints. Then
we would have our value semantics; assignment, comparison,
incrementation etc.

And we could make everything a class. But how?
Then one would have to go through the tedious process of defining all
the operators necesary for value semantics.

In SML, one would just do

datatype Piece = none | pawn | ... | king;

(or something like that... My SML is rusty).

In Ada, one can do something similarly.

This sort of thing, defining a collection of values of the same kind,
being able to assign them, and iterate through them etc., but as typed
_values_, not as ints, is pretty essential as I see it.

I don't really know what my question is :)
Maybe this:

What is the _intended_ C++ way of solving this _kind_ or _class_ or
_type_ of problem?
What is the kosher OOP way to do it?

I know that one can make a hierachy like

class Color
{};

class White : public Color
{}

class Black : public Color
{}

or whatever...

But then, how will the above function look? I can't do

toMove = white;

then.

In short:

What would be a nice flexible and (type)safe design of such things?
Please give an example of how to define Color, Piece and Square, and an
outline of what the initial() function will look like.

I think this kind of problem occurs all the time.

/David

Jul 22 '05 #1
4 2276
"David Rasmussen" <da************ *@gmx.net> wrote:
This sort of thing, defining a collection of values of the same kind,
being able to assign them, and iterate through them etc., but as typed
_values_, not as ints, is pretty essential as I see it.

What is the _intended_ C++ way of solving this _kind_ or _class_ or
_type_ of problem?
What is the kosher OOP way to do it?


There is an article on various things you can do with enums called "Stupid
Enumeration Tricks" (don't be put off by the title) in:

http://www.edm2.com/0405/enumeration.html

Hope this is helpful,

David F
Jul 22 '05 #2
David Rasmussen wrote:
The problem comes up in all sorts of contexts. But here is an example:

We want to model the basics of chess, maybe for making a chess program,
or maybe just to make an interactive board or ...

We have to have the notions of colors, squares and pieces represented.
Ideally, we want to be able to do things like initializing the board:

void initial()
{
const Piece backLine[] =
{rook,knight,bi shop,queen,king ,bishop,knight, rook};

toMove = white;
int i = 0;
for (square s = a1; s <= h1; ++s)
{
board[s].piece = backLine[i++];
board[s].color = white;
}
for (square s = a2; s <= h2; ++s)
{
board[s].piece = pawn;
board[s].color = white;
}
for (square s = a3; s <= h6; ++s)
board[s].piece = none;
for (square s = a7; s <= h7; ++s)
{
board[s].piece = pawn;
board[s].color = black;
}
i = 0;
for (Square s = a8; s <= h8; ++s)
{
board[s].piece = backLine[i++];
board[s].color = black;
}
}

This is a simple function that has to be present in a program involving
chess, and it shows a little bit about what is needed.

The simplest way to do this, is by making enums for piece, color, and
square, like:

enum Color {white,black};
enum Piece {none,pawn,knig ht,bishop,queen ,king}
enum Square {a1,a2,...,h8};

#include <string>

class Color;
extern Color white;
extern Color black;

class Piece;
extern Piece pawn,knight,bis hop,queen,king, rook;

class Square;
// I have no idea why you would want to enumerate these.

std::string Name( const Color & );
std::string Name( const Piece & );

inline bool operator==( const Color & b, const Color & a )
{
return &b == &a;
}

inline bool operator==( const Piece & b, const Piece & a )
{
return &b == &a;
}

inline bool operator<( const Color & b, const Color & a )
{
return &b < &a;
}

inline bool operator<( const Piece & b, const Piece & a )
{
return &b < &a;
}
In short:

What would be a nice flexible and (type)safe design of such things?
Please give an example of how to define Color, Piece and Square, and an
outline of what the initial() function will look like.
I would probably design it differently to what you have above.

I's add

class PlayingPiece;
extern PlayingPiece white_pawn;
extern PlayingPiece black_pawn;
extern PlayingPiece white_rook;
extern PlayingPiece black_rook;
.... etc

Then I would set up a static array:

struct BoardPositions
{
PlayingPiece * board_array[8][8];
};

BoardPositions initial_positio ns =
{
{
{ & black_rook, &black_knigh t, &black_bisho p, ... etc
( & black_pawn, & black_pawn, & black_pawn, & black_pawn, ...
{ },
{ },
{ },
{ },
{ & white_pawn, & white_pawn, & white_pawn, & white_pawn, ...
{ & white_rook, & white_night, .... etc
}
};

struct Board
{
BoardPositions m_board_positio ns

Board()
m_board_positio ns( initial_positio ns )
{
}
}


I think this kind of problem occurs all the time.


I'd almost never use enums. Usually you're better off statically
creating an object that represents the concept.

.... I hope this helps.

Jul 22 '05 #3
David Fisher wrote:

There is an article on various things you can do with enums called "Stupid
Enumeration Tricks" (don't be put off by the title) in:

http://www.edm2.com/0405/enumeration.html

Hope this is helpful,


Thanks, it is!

And it also highlights some very basic problems that C++ has.

Let's take the simple example mentioned on that page: the days of the week.

Who would make a class for that, and make "monday", "tuesday" etc. be
instances of this class? Sometimes, you want to enumerate something, and
you know you'll never need to expand it or reuse it etc. In my opinion,
such "native" but smart enums, should be in the language for exactly the
same reason that ints and doubles should: they are very basic.
They should be typesafe (no implicit to-int conversion), have value
semantics, and they should support native iteration (for, while etc.) like:

for (weekday w = monday; w != sunday; ++w)
...;

Ada and a lot of other languages have this already. Bjarne Stroustrup's
view on this seems to be that we wouldn't like "too good" enums, because
then people would use them too much when an OOP approach would be better.

/David

Jul 22 '05 #4
David Rasmussen wrote:
David Fisher wrote:

There is an article on various things you can do with enums called
"Stupid
Enumeration Tricks" (don't be put off by the title) in:

http://www.edm2.com/0405/enumeration.html


The really funny thing is, that this article is 8 years old. And it
still touches upon some important core topics of C++.

/David

Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
3939
by: Matteo Settenvini | last post by:
Ok, I'm quite a newbie, so this question may appear silly. I'm using g++ 3.3.x. I had been taught that an array isn't a lot different from a pointer (in fact you can use the pointer arithmetics to "browse" it). So I expected that when I run this program, I get both c1.A and c2.A pointing to the same address, and changing c1.A means that also c2.A changes too. ----- BEGIN example CODE -----------
10
1489
by: cody | last post by:
Why can't we use switches with singleton objects? I know that the compiler cannot optimize them like constant values but the same is true for strings and they are allowed in switches. The reason is that I often use singleton classes as replacement for enum's because enums does'nt provide me a (localizeable) names or descriptions when I for example fill comboboxes with them. Additionally I don't like that I can't put any code in the...
26
7096
by: Brett | last post by:
I have created a structure with five fields. I then create an array of this type of structure and place the structure into an array element. Say index one. I want to assign a value to field3 of the structure inside the array. When I try this, an error about late assignment appears. Is it possible to assign a value to a structure field that is in an array? I'm currently getting around the problem by creating a new structure, assign...
9
1393
by: cody | last post by:
Why can't switch used for objects, at least for static readonly fields it wold be nice. The Jit could certainly optimize this case because the addresses of static readonly variables are known at jit time. The thing is that is often used my own enum classes because I usually want to assign a userfriendly (and localizable) name to an enum member which is automatically displayed if I add a enum member to a combobox for example....
0
1030
by: NeoGeo | last post by:
Hi I'm using the PropertyGrid control, and implemented a popup menu to Reset properties, like the IDE The problem I have is that I'm unable to specify DefaultValues for enums and objects For example, given the following enum (inside a __gc class) __value enum Fo One = 1 Two = 2
3
1358
by: The Petar | last post by:
I am really unhappy that C# accessors are not powerful enough to mimic as if you were accessing an class field. In particular, let S be: public struct S { public int v; public void change () { v = 99; } }
3
1686
by: Ramon F Herrera | last post by:
Newbie alert: I come from C programming, so I still have that frame of mind, but I am trying to "Think in C++". In C this problem would be solved using unions. Hello: Please consider the snippet below. I have some objects which are derived (subclassed?, subtyped?) from simpler ones, in increasing size. There is a linear hierarchy. I need to keep them all in some sort of linked list (perhaps std::vector). I could have several
41
1610
by: process | last post by:
I have heard some criticism about Python, that it is not fully object- oriented. What is not an object in Python? Why isn't len implemented as a str.len and list.len method instead of a len(list) function?
55
3994
by: tonytech08 | last post by:
How valuable is it that class objects behave like built-in types? I appears that the whole "constructor doesn't return a value because they are called by the compiler" thing is to enable built-in-like behavior for objects of class type. That leads to the "necessity" for the exception machinery so that errors from constructors can be handled. Is all that complexity worth it just to get built-in-like behavior from class objects? Maybe a...
0
9647
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9491
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10163
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10104
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9959
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6744
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5397
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5532
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3668
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.