#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#include <cstdio>
#include <windows.h> 
#define clear() cout << "\033c" << flush
using namespace std;
int Queen[100][100]; 
// 值为0表示不在攻击范围内,可以放置新皇后;
// 1表示在攻击范围内,不可放置
// 9和-9表示皇后
// const int SIZE =  9;
// 游戏规则展示
void intro()
{
    cout << "===============================================" << endl;
    cout << "***欢迎运行皇后游戏!***" << endl;
    cout << "【游戏规则如下:】" << endl;
    cout << "在这个游戏里会有一个 n*n 的国际象棋棋盘,我们可以在在国际象棋的棋盘上放置皇后," << endl;
    cout << "使其不能相互攻击,即任意两个皇后不能处于棋盘的同一行、同一列和同一条对角线上。" << endl;
    cout << "1. 如果一方放置皇后时位于其他皇后的攻击范围内,该方失败,游戏结束!" << endl;
    cout << "2. 若您不能进行任何放置,游戏结束!" << endl; 
    cout << "================================================" << endl << endl;
}

// 打印当前棋盘
void drawBoard(int SIZE)
{
    // 输出行号
    cout << " ";
    for (int i = 1; i <= SIZE; i++){
		cout << "  ";
		if(i <= 9)cout<<" ";
		cout<< i;
    }
    cout << "\n";
    // 输出上边框
    cout << "  ╔";
    for (int i = 1; i <= SIZE-1; i++) cout << "═══╤";
    cout << "═══╗\n";
    // 输出中间部分
    for (int i = 1; i <= SIZE; i++) // 行
    {
        if(i<=9)cout << i << " ║";
        else cout<< i << "║";
        for (int j = 1; j <= SIZE; j++) // 列
        {
            if (Queen[i][j] == 9) // 玩家
            {
            	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);
                cout << " Q ";
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
            }
            if (Queen[i][j] == -9) // 电脑
            {
            	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
                cout << " Q " ;
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
            }
            if (Queen[i][j] == 0 ) // 空格或不可放置
            {
                cout << " " << " " << " ";
            }
            if(Queen[i][j] == 1)
            {
            	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
            	cout << " X ";
            	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
            }
            if (j != SIZE)
                cout << "│";
            else
                cout << "║";
        }
        cout << " \n";
        // 输出下边框
        if (i != SIZE)
        {
            cout << "  ╟";
            for (int i = 1; i <= SIZE-1; i++) cout << "───┼";
            cout << "───╢\n";
        }
        else
        {
            cout << "  ╚";
            for (int i = 1; i <= SIZE-1; i++) cout << "═══╧";
            cout << "═══╝\n";
        }
    }
}

// 判断一次放置皇后是否有效
bool isValid(int hang, int lie, int SIZE) 
{
    if (Queen[hang][lie] != 0 || hang > SIZE || hang < 1 || lie > SIZE || lie < 1  )
        return false;
    return true;
}

// 放置皇后、标记皇后的攻击范围
void mark(int who, int hang, int lie, int SIZE) // who为9表示玩家,-9表示电脑
{
    // 划定攻击范围
    for (int i = 1; i <= SIZE; i++)
    {
        for (int j = 1; j <= SIZE; j++)
        {
            // 跳过已经不能放置的位置
            if (Queen[i][j] != 0) continue;
            // 判断是否在皇后所管辖的 行
            if (hang - i == 0 && lie - j != 0)
            {
                Queen[i][j] = 1;
            }
            // 判断是否在皇后所管辖的 列
            if (hang - i != 0 && lie - j == 0)
            {
                Queen[i][j] = 1;
            }
            // 判断是否在皇后所管辖的 左右斜线
            if (abs(hang - i) == abs(lie - j))
            {
                Queen[i][j] = 1;
            }
        }
    }
    // 放置皇后
    if (who == 9) Queen[hang][lie] = 9;
    else Queen[hang][lie] = -9;
}

// 开始游戏
void game(int SIZE) 
{
    cout << "【玩家先开始!】" << endl << endl; 
    while (true)
    {
        // (1)玩家策略
        cout << "请玩家输入行列数字(例:行列数字:1 2)" << endl;
        int hang1, lie1;
        cin >> hang1 >> lie1;
        if (isValid(hang1, lie1, SIZE) == false) // 该位置不可放置
        {
            cout << "胜败乃兵家常事!大侠请重新来过!" << endl;
            exit(0);
        }
        else
        {
            // 放置后标记皇后的攻击范围
            mark(9, hang1, lie1, SIZE);
            // 打印放置结果
            drawBoard(SIZE);
        }
        
        // (2)电脑策略
        srand(time(0));
        int hang2, lie2;
        for (int i = 1; i <= 1000000; i++)
        {
            hang2 = rand() % SIZE + 1;
            lie2 = rand() % SIZE + 1;
            if (isValid(hang2, lie2, SIZE) == false) continue;
            else break;
        }
        if (isValid(hang2, lie2, SIZE) == false)
        {
            cout << "计算机不能进行任何位置放置,恭喜玩家胜利!游戏结束" << endl;
            exit(0);
        }
        else
        {
            // 放置后标记皇后的攻击范围
            mark(-9, hang2, lie2, SIZE);
            cout << "电脑在 (" << hang2 << ", " << lie2 << ") 处放置皇后" << endl;
        
            cout << "按下回车,查看电脑回合……" << endl;
            getchar();
            getchar();
            // 打印放置结果
            bool x;
        	for (int i = 1; i <= SIZE; i++)
	        {
	          for (int j = 1; j <= SIZE; j++)
	        	{
	            	if (isValid(i, j, SIZE) == 1) // 该位置可放置
	        		{
	            		x = 1;
	        		}
	        	}  
	        }
	        if(x == 0)
	        {
		        cout << "胜败乃兵家常事!大侠请重新来过!" << endl;
		        exit(0);
	        }
            drawBoard(SIZE);
            
        }
    }
}

int main()
{

    intro(); // 游戏规则展示
    cout << "请输入n(不大于9):";
    int SIZE;
	cin >> SIZE;
    drawBoard(SIZE); // 打印棋盘
    game(SIZE); // 开始游戏
    
    return 0;
}