#include <iomanip>
#include <iostream>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
//#include "main.h"
using namespace std;
class chess_board;
class check_not_numeric
{
public:
bool operator()(const char ch)
{
if (ch > '9' || ch < '0')
{
for (int i=0; i<_include.size(); i++)
{
if (ch == _include[i])
{
return false;
}
}
return true;
}
return false;
}
static void set_include(string& str)
{
_include = str;
}
protected:
private:
static string _include;
};
string check_not_numeric::_include = "";
class chess_board
{
typedef vector<char> line;
typedef pair<int, int> point;
public:
enum symbol {none=0, black, white};
chess_board(int size=15) : _size(size) {
for (int i=0; i<_size; i++)
{
line _line(_size);
vector<char>::iterator ite;
for (ite=_line.begin(); ite!=_line.end(); ite++)
{
*ite = static_cast<int>(_symbol[none]);
}
_content.push_back(_line);
}
}
void show()
{
cout << "five chess" << endl;
cout << "1: black=#, white=*, black first!" << endl;
cout << setw(_formats) << " ";
for (int ii=0; ii<_size; ii++)
{
cout << setw(_formats) << ii+1 << "|";
}
cout << endl;
for (int i=0; i<_size; i++)
{
cout << setw(_formats) << i+1 << "|";
for (int j=0; j<_size; j++)
{
cout << setw(_formats) << _content[i][j] << " ";
}
cout << endl;
}
}
void set(int x, int y, symbol sbl)
{
_content[x-1][y-1] = _symbol[sbl];
show();
}
void clear()
{
for (int i=0; i<_size; i++)
{
for (int j=0; j<_size; j++)
{
_content[i][j] = _symbol[none];
}
}
show();
}
int size() {return _size;}
char get_symbol(symbol sbl) {return _symbol[sbl];}
bool can_set(int x, int y, symbol sbl)
{
return (_content[x-1][y-1]==_symbol[none]);
}
bool is_win(bool isblack)
{
bool ret = true;
int i, j, cnt(0);
// x direction scan
for (i=0; i<_size; i++)
{
cnt = 0;
for (j=0; j<_size; j++)
{
if (isblack)
{
if (_content[i][j] == _symbol[black])
{
cnt ++;
}else
{
cnt = 0;
}
}else
{
if (_content[i][j] == _symbol[white])
{
cnt ++;
}else
{
cnt = 0;
}
}
if (cnt >= 5)
{
return true;
}
}
}
// y direction
for (i=0; i<_size; i++)
{
cnt = 0;
for (j=0; j<_size; j++)
{
if (isblack)
{
if (_content[j][i] == _symbol[black])
{
cnt ++;
}else
{
cnt = 0;
}
}else
{
if (_content[j][i] == _symbol[white])
{
cnt ++;
}else
{
cnt = 0;
}
}
if (cnt >= 5)
{
return true;
}
}
}
// / direction scan
int down_cnt(0), up_cnt(0);
for (i=0; i<_size; i++)
{
down_cnt = 0;
up_cnt = 0;
for (j=0; j<_size; j++)
{
if (isblack)
{
// / down
if ((j-i>=0) && _content[j][j-i] == _symbol[black])
{
down_cnt ++;
}else
{
down_cnt = 0;
}
// / up
if ((j-i>=0) && _content[j-i][j] == _symbol[black])
{
up_cnt ++;
}else
{
up_cnt = 0;
}
}else
{
// / down
if ((j-i>=0) && _content[j][j-i] == _symbol[white])
{
down_cnt ++;
}else
{
down_cnt = 0;
}
// / up
if ((j-i>=0) && _content[j-i][j] == _symbol[white])
{
up_cnt ++;
}else
{
up_cnt = 0;
}
}
if (down_cnt >= 5 || up_cnt >= 5)
{
return true;
}
}
}
// / direction scan
for (i=0; i<_size; i++)
{
down_cnt = 0;
up_cnt = 0;
for (j=0; j<_size; j++)
{
if (isblack)
{
// / down
if ((j-i>=0) && (_size-j-1>=0) && _content[j-i][_size-j-1] == _symbol[black])
{
down_cnt ++;
}else
{
down_cnt = 0;
}
// / up
if ((j-i>=0) && (_size-j-1>=0) && _content[_size-j-1][j-i] == _symbol[black])
{
down_cnt ++;
}else
{
down_cnt = 0;
}
}else
{
// / down
if ((j-i>=0) && (_size-j-1>=0) && _content[j-i][_size-j-1] == _symbol[white])
{
down_cnt ++;
}else
{
down_cnt = 0;
}
// / up
if ((j-i>=0) && (_size-j-1>=0) && _content[_size-j-1][j-i] == _symbol[white])
{
down_cnt ++;
}else
{
down_cnt = 0;
}
}
if (down_cnt >= 5 || up_cnt >= 5)
{
return true;
}
}
}
return false;
}
bool is_numeric(string& cin)
{
vector<char> vin(&cin[0], &cin[0]+cin.size());
vector<char>::iterator vite;
vite = find_if(vin.begin(), vin.end(), check_not_numeric());
if (vite != vin.end())
{
cout << "has invalid character: " << cin << endl;
return false;
}
return true;
}
protected:
private:
int _size;
vector<line> _content;
static const char _symbol[3];
static const int _formats;
};
const char chess_board::_symbol[3] = {'-', '#', '*'};
const int chess_board::_formats = 2;
void main()
{
// create chess board
chess_board board;
board.show();
// input's split character set
string key(",./"), in;
check_not_numeric::set_include(key);
// switch flag
bool isblack = true;
// read input
while (cout << (isblack ? "black" : "white")
<< " input x,y coordinate(split_char=',./' restart=r, exit=q):" << endl
&& cin >> in)
{
// exit
if (in == "q")
{
break;
}
// restart
if (in == "r")
{
system("cls");
board.clear();
isblack = true;
continue;
}
// check numeric input
if (!board.is_numeric(in))
{
system("pause");
continue;
}
// input coordinate
string sx, sy;
string::size_type pos = 0;
if ((pos = in.find_first_of(key, pos)) != string::npos)
{
sx = in.substr(0, pos);
sy = in.substr(++pos, in.size());
}else
{
sx = in;
while (cout << "please input y coordinate:" << endl
&& cin >> in)
{
// check numeric input
if (board.is_numeric(in))
{
break;
}
}
//cout << "please input y coordinate:" << endl;
//cin >> in;
sy = in;
}
// convert into x,y coordinate
int x,y;
x = ::atoi(sx.c_str());
y = ::atoi(sy.c_str());
// range check
if (x<=0 || y<=0 || x>board.size() || y>board.size())
{
cout << "out of range!" << endl;
system("pause");
continue;
}
// input same position check
if (!board.can_set(x, y, isblack?board.black:board.white))
{
cout << "the position has chess!" << endl;
system("pause");
continue;
}
// clear screen
system("cls");
// chess set
if (isblack)
{
board.set(x, y, board.black);
}else
{
board.set(x, y, board.white);
}
// judge winner
if (board.is_win(isblack))
{
cout << (isblack ? "black" : "white") << " win!" << endl;
system("pause");
system("cls");
board.clear();
isblack = true;
}else
{
isblack = !isblack;
}
}
}