#include <iostream>
#include <iomanip>
using namespace std;

//玩家的父类-抽象类
class Cplayer
{
public:
    virtual int go() = 0;
};

class Cjudger
{
private:
    unsigned char mBoard[20][20];   // 微信用户名
    Cplayer* mA;
    Cplayer* mB;

public:
    Cjudger(){}
    void match();
    void setPlayer(Cplayer* a, Cplayer* b) { mA = a; mB = b; }
    unsigned char* getQiPan() { return (unsigned char*)mBoard; }
    void showQiPan()
    {
        for (int i = 0; i < 20; ++i){
            cout << setw(3) << (i * 20);//mBoard[i][0];
            for (int k = 1; k < 20; ++k){
                cout << setw(4) << (i * 20 + k);//mBoard[i][k];
            }
            cout << endl;
        }
    }
    //3.判断输赢
    bool check_win(int y, int x, unsigned char t)
    {
        int i, j;
        //横向
        for (i = y - 4, j = x; i <= y; i++) {
            if (i >= 0 && i < 16 && t == mBoard[i][j] && t == mBoard[i + 1][j] && t == mBoard[i + 2][j] && t == mBoard[i + 3][j] && t == mBoard[i + 4][j]) {
                return true;
            }
        }

        //纵向
        for (i = y, j = x - 4; j <= x; j++) {
            if (j >= 0 && j < 16 && t == mBoard[i][j] && t == mBoard[i][j + 1] && t == mBoard[i][j + 2] && t == mBoard[i][j + 3] && t == mBoard[i][j + 4]) {
                return true;
            }
        }

        //右下
        for (i = y - 4, j = x - 4; i <= y, j <= x; i++, j++) {
            if (i >= 0 && i < 16 && j >= 0 && j < 16 && t == mBoard[i][j] && t == mBoard[i + 1][j + 1] && t == mBoard[i + 2][j + 2] && t == mBoard[i + 3][j + 3] && t == mBoard[i + 4][j + 4]) {
                return true;
            }
        }

        //左下
        for (i = y - 4, j = x + 4; i <= y, j >= x; i++, j--) {
            if (i >= 0 && i < 16 && j >= 0 && j < 16 && t == mBoard[i][j] && t == mBoard[i + 1][j - 1] && t == mBoard[i + 2][j - 2] && t == mBoard[i + 3][j - 3] && t == mBoard[i + 4][j - 4]) {
                return true;
            }
        }
        return false;
    }
    bool dropOne(int pos, int color)
    {
        mBoard[pos/20][pos%20] = color;
        return check_win(pos / 20, pos % 20, color);
    }
};

//子类
class humanPlayer : public Cplayer
{
protected:
    Cjudger    *mJudger;
    const char *mName;
public:
    humanPlayer(const char* name, Cjudger *j):mName(name) { mJudger = j; };
    virtual int go()
    {
        //从Judger哪里获取棋局
        unsigned char* game = mJudger->getQiPan();
        //cout << mName << " 输入: ";
        int pos; cin >> pos;
        //some ai 算法计算落子位置。
        return pos;
    }
};

void Cjudger::match()
{
    for (int i = 0; i < 20; ++i){
        for (int k = 0; k < 20; ++k){
            mBoard[i][k] = 0;
        }
    }

    showQiPan();
    while (1){
        //showQiPan();
        if (dropOne(mA->go(), 1)){ cout << "A" << endl; break; }
        //showQiPan();
        if (dropOne(mB->go(), 2)){ cout << "B" << endl; break; }
    }
}

int main(int argc, char** argv)
{
    Cjudger judger;                     //裁判
    humanPlayer pa("白方", &judger);    //棋手
    humanPlayer pb("黑方", &judger);    //棋手

    judger.setPlayer(&pa, &pb);
    //开始比赛,A和B轮流下一棋子,有一方赢时裁判宣告赢家,并结束比赛。
    judger.match();
    return 0;
}