magicSquarePostIn a previous post, i covered how to implement a magic square in C#, that supports only odd dimensions, i.e 3,5,7..
However, this time i will try to make it more generic, with the help of the cool features of C++ language!

First, we define the interface of the program; Means, to determine which fields should be in the ‘private’ section and whom will be the ‘public’, moreover, what functions/methods there gonna be.

/*
* Magic Square.cpp : a programe that fills numbers in a given range into
* a square so that square becomes a magic square.
* created on: 9/2/2015 - Mon.
* by: Bassam Yassin
* thunderwiring.wordpress.com
*/
#include "stdafx.h"
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
/*****************************************************************/
/*exception classes:*/
class invalidDimntions {};
class indexOutOfrange {};
/*****************************************************************/
/*DEFINES and typedefs:*/
const int EMPTY = 0;
const int OFFSET = 0;
const int LOW_BOUND = 0;
typedef int* Data;
/*****************************************************************/
/*
 * The object of the class holds the data in a grid implemented by
 * 2D array of integers
 */
class Square {
private:
	int dim, bottomRange, topRange, initialValue;
	Data data;
	const bool checkRowsAndColumns() const;
	const bool checkDiagnals() const;
public:
	Square(int dim, int bottom = 0, int top = 0) :
	  dim(dim), bottomRange(bottom), topRange(top) {
		if(dim <= 0) {
			throw invalidDimntions();
		}
		data = new int[dim*dim];
		initialValue = bottomRange - OFFSET;
		for(int i = 0; i < (dim*dim); ++i) {
			data[i] = initialValue;
		}
	}
	~Square() {
		delete data;
	  }
	/*****class functions declaration:*****/
	const Data getData() const;
	const int initValue() const;
	const int size() const;
	int const dimention() const;
	bool checkValid() const;
	void print() const;
	void solve() const;
	/*****class operators overloading:*****/
	const int operator()(int row, int column) const;
	int operator()(int row, int column);
}; /*end class Square*/

As seen above, the functionality of the class is divided between 3 major groups:

  1. Private Methods: those are serving inside the class and inaccessible from the outside(i.e function  main()). Basically, I used methods to check if the column/rows/diagonals are valid(all have the same sum of elements.)
  2. [public] Functions: those are the interface between the class Square and the outside environment. Between the functions there are the ‘getters’ who give us feedback regarding the private fields.
  3. Operators: those are functions(means public as well)  whom been overridden and customized to afford extra services than their normal behavior.

Here is some of the implementations of the methods/functions stated above:

/*****************************************************************/
/* Implementation of calss 'Square' private methods:*/
/*****************************************************************/
const bool Square::checkRowsAndColumns() const {
	int sumRow(EMPTY), sumCol(EMPTY);
	int refRow(initialValue), refCol(initialValue);
	for(int column = 0; column < dim; ++column) {
		for(int row = 0; row < dim; ++row) {
			sumRow += data[column + row * dim];
			sumCol += data[row + column * dim];
		}
		if((refRow == initialValue) &&
					(refCol == initialValue)) {
			refRow = sumRow;
			refCol = sumCol;
		} else if((sumRow != refRow) || (sumCol != refCol)) {
			return false;
		}
		sumRow = EMPTY;
		sumCol = EMPTY;
	}
	return true;
}
const bool Square::checkDiagnals() const {
	int sumMainDiag(EMPTY), sumSecondryDiag(EMPTY);
	int refMainDiag(initialValue),
		refSecondryDiag(initialValue);
	for(int i = 0; i < dim; ++i) {
		sumMainDiag += data[i + i * dim];
		sumSecondryDiag += data[(dim-i) + (i * dim)];
	}
}
/*****************************************************************/
/* Implementation of calss 'Square' operators overloading:*/
/*****************************************************************/
const int Square::operator()(int row, int column) const {
	if((row <= LOW_BOUND) || (row >= dim) ||(column <= LOW_BOUND) ||
		(column >= dim)) {
			throw indexOutOfrange();
	}
	return data[(row * dim) + column];
}
int Square::operator()(int row, int column) {
	if((row <= LOW_BOUND) || (row >= dim) ||(column <= LOW_BOUND) ||
		(column >= dim)) {
			throw indexOutOfrange();
	}
	return data[(row * dim) + column];
}
/*****************************************************************/
/* Implementation of calss 'Square' functions:*/
/*****************************************************************/
const Data Square::getData() const {
	return this->data;
}
const int Square::initValue() const {
	return this->initialValue;
}
const int Square::size() const {
	return (this->dim) * (this->dim);
}
int const Square::dimention() const {
	return this->dim;
}
bool Square::checkValid() const {
	int sum(EMPTY);
	for(int i = 0; i < this->dimention(); ++i) {
		for(int i = 0; i < this->dimention(); ++i) {
			sum += data[(i * dim) + j];
		}
	}
}
/*****************************************************************/

In part 2, I will discuss more about how to actually solve the square.
please add your comments bellow or send me your feed back at my email in the about page.
stay tuned for more cool stuff!!

Advertisements