#include <iostream>
#include <ctime>
#include<conio.h>
using namespace std;
class data
{
public:
data(int ix, int iy) :x(ix), y(iy){ fl = 0; conut = 0; }
virtual ~data(){}
virtual int GetX()const { return x; }
virtual int GetY()const { return y; }
virtual void SetX(int i){ x = i; }
virtual void SetY(int i){ y = i; }
virtual data&operator++()
{
++conut;
return *this;
}
virtual void Setfl(int i) { fl = i; }
virtual int Getfl()const { return fl; }
virtual void SetConut(int i) { conut = i; }
virtual int GetConut()const { return conut; }
private:
int x;
int y;
int conut;
int fl;
};
class wanjia:public data
{
public:
wanjia(int x, int y) :data(x, y){ }
};
class diannan :public data
{
public:
diannan(int x, int y) :data(x, y){ }
};
class qipan
{
public:
qipan() :map(0), p1(0), p2(0){ quit = 0; Temp = '0'; conut = 5; }
~qipan()
{
if (map)
{
for (int i = 0; i < max; i++)
{
delete[]map[i];
map[i] = NULL;
}
delete[]map;
map = NULL;
}
if (p1)
delete p1;
if (p2)
delete p2;
}
void init();
void initp1();
bool lanjie();
void read_map();
bool mova_map(const int i);
void initp2();
bool lujing(int x, int y, int newX, int newY, int con);
void Refresh_map();
bool gemaover();
void Setfl(const unsigned int i);
void show_map();
void Run();
bool lanjiejiance(int x, int y, int newX, int newY, int con);
bool jiance();
void movep2();
void movep1();
void input();
private:
enum{max=20};
wanjia *p1;
diannan *p2;
int quit;
int conut;
char **map;
char Temp;
};
void qipan::init()
{
map = new char*[max];
for (int i = 0; i < max; i++)
{
map[i] = new char[max];
memset(map[i], '3', sizeof(char)*max);
}
map[max / 2][max / 2] = '1';
}
void qipan::Setfl(const unsigned int i)
{
i == 1 ? p1->Setfl(i), p2->Setfl(i + 1) : p2->Setfl(i), p1->Setfl(i+1);
if (i != 1)
{
quit = true;
}
}
void qipan::initp1()
{
p1 = new wanjia(4,4);
}
void qipan::initp2()
{
p2 = new diannan(16, 16);
}
void qipan::show_map()
{
system("cls");
cout << "\n";
cout << "\t\t\t五子棋大战\n";
cout << "\t 0 1 2 3 4 5 6 7 8 9 10111213141516171819\n";
for (int i = 0; i <max; i++)
{
cout << "\t";
i < 10 ? cout << i : cout << "\b" << i;
for (int j = 0; j < max; j++)
{
switch (map[i][j])
{
case '3':
cout << "□";//●□○
break;
case '1':
cout << "●";
break;
case '2':
cout << "◎";
}
}
switch (i)
{
case 4:
cout << " 玩家起手坐标X:" << p1->GetX() << " Y坐标:" << p1->GetY();
break;
case 6:
cout << " 电脑起手坐标X:" << p2->GetX() << " Y坐标:" << p2->GetY();
break;
case 8:
p1->Getfl() == 1 ? cout << "\t先手棋:●" : cout << "\t先手棋:○";
break;
case 10:
p1->Getfl() == 1 ? cout << "\t后手棋:○" : cout << "\t先手棋:●";
break;
case 14:
if (quit)
{
cout << "\t机器人增在思考....";
}
else
{
cout << "\t该玩家走了.....";
}
break;
case 15:
cout << "\t按回车确定";
break;
case 18:
cout << "操作为方向键(上 下 左 右)控制";
break;
case 19:
cout << "\t退出请按ESC";
}
cout << endl;
}
}
bool qipan::lujing(int x,int y,int newX,int newY,int con)
{
if (map[x][y] == '3')
return 0;
if (con == this->conut - 1)
return 1;
int tempX = x + newX;
int tempY = y + newY;
if (tempX < 0 || tempX >= max || tempY < 0 || tempY >= max)
{
return 0;
}
if (map[tempX][tempY] == map[x][y])
return lujing(tempX, tempY, newX, newY, con + 1);
return 0;
}
bool qipan::jiance()
{
for (int i = 0; i < max; i++)
{
for (int j = 0; j < max; j++)
{
if (lujing(i, j, -1, 1, 0) || lujing(i, j, 1, 0, 0) || lujing(i, j, 0, 1, 0) || lujing(i, j, 1, 1, 0))
return 1;
}
}
return 0;
}
bool qipan::gemaover()
{
if (conut == max*max - 1)
{
return 1;
}
if (jiance())
{
show_map();
quit == 1 ? cout << "玩家赢了\n" : cout << "电脑赢了\n";
return 1;
}
return false;
}
bool qipan::lanjiejiance(int x, int y, int newX, int newY, int con)
{
if ( map[x][y]=='3'||map[x][y] == '2')
return 0;
if (con >= 0)
{
int tempX = x + newX;
int tempY = y + newY;
if (tempX < 0 || tempX >= max || tempY < 0 || tempY >= max)
{
return 0;
}
if (map[tempX][tempY] == map[x][y])
return lanjiejiance(tempX, tempY, newX, newY, con + 1);
if (tempX >= 0 && tempY >= 0 && tempX< max&& tempY < max)
{
if (con>0 && map[tempX][tempY] == '3')
{
map[tempX][tempY] = '2';
return true;
}
}
else
return 0;
}
return 0;
}
bool qipan::lanjie()
{
for (int i = 0; i < max; i++)
{
for (int j = 0; j < max; j++)
{
if (lanjiejiance(i, j, -1, 0, 0) || lanjiejiance(i, j, 1, 0, 0) || lanjiejiance(i, j, 0, -1, 0) || lanjiejiance(i, j, 0, 1, 0) || lanjiejiance(i, j, -1, -1, 0) || lanjiejiance(i, j, -1, 1, 0) || lanjiejiance(i, j, 1, -1, 0) || lanjiejiance(i, j, 1, 1, 0))
return 1;
}
}
return 0;
}
void qipan::movep2()
{
srand(time(0));
if (lanjie())
{
quit = false;
return;
}
while (1)
{
int val = 0;
int conut = 0;
//if ()
int x = 0;
int y = 0;
while(p2->GetConut() > 0)
{
conut++;
if (conut >= p2->GetConut())
{
p2->SetConut(0);
break;
}
x = (rand() % p2->GetConut())+1;
y = (rand() % p2->GetConut())+1;
while (x < max&&y < max&&x>=0&&y>=0)
{
while (p2->GetX() - x < 0 || p2->GetY() - y < 0 || p2->GetX() + x>max - 1 || p2->GetY() + y>max - 1)
{
x = (rand() % p2->GetConut()) + 1;
y = (rand() % p2->GetConut()) + 1;
}
if (map[p2->GetX() + x][p2->GetY() + y] == '3')
{
val = 0;
break;
}
if (map[p2->GetX() - x][p2->GetY() - y] == '3')
{
val = 1;
break;;
}
}
}
while (!p2->GetConut())
{
x = rand() % max;
y = rand() % max;
if (map[x][y] != '3')
continue;
p2->SetX(x);
p2->SetY(y);
++(*p2);
map[p2->GetX()][p2->GetY()] = '2';
quit = false;
return;
break;
}
if (!val)
{
p2->SetX(p2->GetX() + x);
p2->SetY(p2->GetY() + y);
++(*p2);
map[p2->GetX()][p2->GetY()] = '2';
quit = false;
break;
}
else
{
p2->SetX(p2->GetX() - x);
p2->SetY(p2->GetY() - y);
++(*p2);
map[p2->GetX()][p2->GetY()] = '2';
quit = false;
break;
}
}
}
bool qipan::mova_map(const int i)
{
switch (i)
{
case 1:
if (p1->GetX() - 1 >= 0 && p1->GetX() - 1 <= max - 1 && p1->GetY() <= max - 1 && p1->GetY() >=0)
{
p1->SetX(p1->GetX() - 1);
Temp = map[p1->GetX()][p1->GetY()];
map[p1->GetX()][p1->GetY()] = '1';
return true;
}
return false;;
break;
case 2:
if (p1->GetX() + 1 >= 0 && p1->GetX() + 1 <= max - 1 && p1->GetY() <= max - 1 && p1->GetY() >= 0)
{
p1->SetX(p1->GetX() + 1);
Temp = map[p1->GetX()][p1->GetY()];
map[p1->GetX()][p1->GetY()] = '1';
return true;
}
return false;;
break;
case 3:
if (p1->GetX() >= 0 && p1->GetX() <= max - 1 && p1->GetY()-1 <= max - 1 && p1->GetY()-1 >= 0)
{
p1->SetY(p1->GetY() - 1);
Temp = map[p1->GetX()][p1->GetY()];
map[p1->GetX()][p1->GetY()] = '1';
return true;
}
return false;;
case 4:
if (p1->GetX() >= 0 && p1->GetX() <= max - 1 && p1->GetY() +1<= max - 1 && p1->GetY()+1 >= 0)
{
p1->SetY(p1->GetY() +1);
Temp = map[p1->GetX()][p1->GetY()];
map[p1->GetX()][p1->GetY()] = '1';
return true;
}
return false;;
}
}
void qipan::read_map()
{
show_map();
map[p1->GetX()][p1->GetY()] = Temp;
}
void qipan::movep1()
{
if (!p1->GetConut())
{
if (map[p1->GetX()][p1->GetY()] != '3')
Temp = map[p1->GetX()][p1->GetY()];
Temp = map[p1->GetX()][p1->GetY()];
map[p1->GetX()][p1->GetY()] = '1';
show_map();
map[p1->GetX()][p1->GetY()] = Temp;
Temp = '0';
}
unsigned char ch;
while (1)
{
if (_kbhit())
{
ch = _getch();
fflush(stdin);
switch (ch)
{
case 'H':
if (mova_map(1))
{
read_map();
}
break;
case 'P':
if (mova_map(2))
read_map();
break;
case 'K':
if (mova_map(3))
read_map();
break;
case 'M':
if (mova_map(4))
read_map();
break;
}
if (ch == '\r')
{
this->quit = 1;
if (map[p1->GetX()][p1->GetY()] != '3')
continue;
else
{
map[p1->GetX()][p1->GetY()] = '1';
Temp = '1';
break;
}
}
}
}
}
void qipan::input()
{
if (this->quit==1)
{
movep2();
}
else
movep1();
}
void qipan::Refresh_map()
{
map[max / 2][max / 2] = '3';
}
void qipan::Run()
{
init();
initp1();
initp2();
cout << "\n\n\n\n";
cout << "\t\t请问是先手还是后手:";
cout << "【1先手】【2后手】";
unsigned int CID;
cin >> CID;
while (CID > 2 || CID < 1)
{
cout << "\n\t\t\t请重新选择:";
cin >> CID;
}
Setfl(CID);
show_map();
Refresh_map();
while (!gemaover())
{
input();
show_map();
}
}
void main()
{
system("color 03");
qipan *q = new qipan;
q->Run();
delete q;
system("pause");
}