#include<iostream>
#include<stdbool.h>
#include<vector>
#include<deque>
#include<set>
#include <string.h>
#include <ctime>
#include <cstdlib>
#include<limits.h>
#include<memory>
using namespace std;
char board[15][15];
typedef struct cell {
int cx;
int cy;
struct cell* father;
char input[15][15];
int x[15][15];//标记横向是否访问过
int y[15][15];//标记纵向
int z[15][15];//标记主对角线
int h[15][15];//标记次对角线
int depth;
int value;
struct cell*child[225];
}cell;
cell* root, * nextnode;
int ex =1;
int maxdepth =2;
cell*pos_insert[300];//构建环状队列
int top=0,tail=0,coun=0;
string black_form[31] = {
"10000", "01000", "00100", "00010", "00001",
"11000", "01100", "00110", "00011", "10100", "01010", "00101", "10010", "01001", "10001"
"11100", "01110", "00111", "11010", "01101", "10110", "01011", "11001", "10011", "10101",
"11110", "11101", "11011", "10111", "01111",
};
string white_form[31] = {
"w0000", "0w000", "00w00", "000w0", "0000w",
"ww000", "0ww00", "00ww0", "000ww", "w0w00", "0w0w0", "00w0w", "w00w0", "0w00w", "w000w"
"www00", "0www0", "00www", "ww0w0", "0ww0w", "w0ww0", "0w0ww", "ww00w", "w00ww", "w0w0w",
"wwww0", "www0w", "ww0ww", "w0www", "0wwww",
};
int score_white[31] = {
35,35,35,35,35,
800,800,800,800,800,800,800,800,800,800,
15000,15000,15000,15000,15000,15000,15000,15000,15000,15000,
30000,30000,30000,30000,30000
};
int score_black[31] = {
15,15,15,15,15,
400,400,400,400,400,400,400,400,400,400,
14000,14000,14000,14000,14000,14000,14000,14000,14000,14000,
40000,40000,40000,40000,40000
};
int evaluate(cell* a);//估值函数
bool ismax(cell* a);//判断是否为max节点
void f();//对root和nextnode初始化
cell* creat(cell* a, int x, int y);//生成孩子节点
vector<pair<int, int>>cunchu(cell* a);//把固定下棋区域的节点放入一个容器中
int expand_pos(cell* a);//配合creat生成博弈树
int af_bt(cell* a, int val);//af_bt剪枝(递归)
char qizi(char& s);//判断棋盘上某个节点黑白子或无落子情况
pair<int, int>game();//控制整个游戏
int black(string& s);//某个五元组黑棋的评分
int white(string& s);//某个五元组白棋的评分
void f(){
root = NULL;
root = (cell*)malloc(sizeof(cell));
memcpy(root->input, board, sizeof(board));
root->father = NULL;
memset(root->child,NULL,sizeof(225));
memset(pos_insert,NULL,sizeof(pos_insert));
root->depth = 0;
nextnode = NULL;
root->cx=0;
root->cy=0;
memset(root->x,0,sizeof(root->x));
memset(root->y,0,sizeof(root->y));
memset(root->z,0,sizeof(root->z));
memset(root->h,0,sizeof(root->h));
}
cell* creat(cell*b,cell* a, int x, int y) {
b = NULL;
b=(cell*)malloc(sizeof(cell));
b->father = a;
memset(b->child, NULL, sizeof(225));
b->depth = a->depth + 1;
b->cx = x;
b->cy = y;
memset(b->x, 0, sizeof(b->x));
memset(b->y, 0, sizeof(b->y));
memset(b->z, 0, sizeof(b->z));
memset(b->h, 0, sizeof(b->h));
b->value = 0;
memcpy(b->input, a->input, sizeof(a->input));
if (ismax(b))
b->input[x][y] = 'w';
else
b->input[x][y] = '1';
return b;
}
bool ismax(cell* a){
if (a->depth % 2 != 0)
return false;
return true;
}
vector<pair<int, int>>cunchu(cell* a) {//找到待拓展的节点
int first = 0, i = 0, j = 0;int newboard[15][15], k = 0, w = 0;
memset(newboard,0,sizeof(newboard));
int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
for (i = 0;i < 15;i++)
for (j = 0;j < 15;j++)
{
if (a->input[i][j] != '0')
{
first = 1;
x1 = max(0, i - ex);
y1 = max(0, j - ex);
x2 = min(14, i + ex);
y2 = min(14, j + ex);
for (w = x1;w <= x2;w++)
for (k = y1;k <= y2;k++) {
if (a->input[w][k] == '0') {
newboard[w][k] = 1;
}
}
}
}
vector<pair<int, int>>example;
if (first == 0) {
example.emplace_back(7, 7);
return example;
}
for (i = 0;i < 15;i++)
for (j = 0;j < 15;j++) {
if (newboard[i][j] == 1)
example.emplace_back(i, j);
}
return example;
}
int expand_pos(cell* a) {//生成子树
vector<pair<int, int>>example = cunchu(a);
int i=0;
for (auto n : example) {
a->child[i]=creat(a->child[i],a, n.first, n.second);
pos_insert[tail]=a->child[i];
tail=(tail+1)%300;
coun++;
i++;
}
return example.size();
}
char qizi(char& s) {
if (s == '0')
return '0';
if (s == '1')
return '1';
return 'w';
}
int evaluate(cell* a) {//对局势进行评估
int i = 0, j = 0, k = 0;
for (i = 0;i < 15;i++)
for (j = 0;j < 15;j++) {
if (j + 4 < 15) {
if (a->x[i][j] == 1 )//横向该棋子被访问则不在访问
continue;
string s;
for (k = 0;k < 5;k++)
{
s += qizi(a->input[i][j + k]);
a->x[i][j + k] = 1;
}
(a->value) += black(s) - white(s);
}
if (i + 4 < 15) {
if (a->y[i][j] == 1 )
continue;
string s;
for (k = 0;k < 5;k++)
{
s += qizi(a->input[i + k][j]);
a->y[i + k][j] = 1;
}
(a->value) += black(s) - white(s);
}
if (i + 4 < 15 && j + 4 < 15) {
if (a->z[i][j] == 1 )
continue;
string s;
for (k = 0;k < 5;k++)
{
s += qizi(a->input[i + k][j + k]);
a->z[i + k][j + k] = 1;
}
(a->value) += black(s) - white(s);
}
if (i + 4 < 15 && j - 4 >= 0) {
if (a->h[i][j] == 1 )
continue;
string s;
for (k = 0;k < 5;k++)
{
s += qizi(a->input[i + k][j - k]);
a->h[i + k][j - k] = 1;
}
(a->value) += black(s) - white(s);
}
}
return a->value;
}
int black(string& s) {
int i = 0;
for (i = 0;i < 31;i++)
if (s == black_form[i])
return score_black[i];
return 0;
}
int white(string& s) {
int i = 0;
for (i = 0;i < 31;i++)
if (s == white_form[i])
return score_white[i];
return 0;
}
//---------------------------------//
int af_bt(cell* a, int val) {
int af = INT_MIN;
int bt = INT_MAX;
if (a->depth == maxdepth)
return evaluate(a);
if (ismax(a)) {
for (int i=0;a->child[i]!=NULL;i++) {
a->value = af_bt(a->child[i], af);
if (a->value > af)
af =a->value;
if (af > bt)
return af;
}
return af;
}
if (!ismax(a)) {
for (int i=0;a->child[i]!=NULL;i++) {
a->value = af_bt(a->child[i], bt);
if (a->value < bt)
bt = a->value;
if (af > bt)
return bt;
}
return bt;
}
}
pair<int, int>game() {
f();//生成当前的对局
pos_insert[tail]=root;//根节点入队
tail=(tail+1)%300;
coun++;
while (coun!=0) {
cell* n = pos_insert[top];//取队头元素
top=(top+1)%300;
coun--;//队头出队
if (n->depth < maxdepth)
int a = expand_pos(n);//进行拓展
}
int i=0;
root->value=af_bt(root,root->value);
int ma=0;
for(i=0;root->child[i]!=NULL;++i)
{if(root->child[i]->value>root->child[ma]->value)
ma=i;}
return pair<int, int>(root->child[ma]->cx,root->child[ma]->cy);
}
int main() {
memset(board, '0', sizeof(board));
int x, y, n;
cin >> n;
for (int i = 0; i < n - 1; i++) {
cin >> x >> y; if (x != -1) board[x][y] = 'w'; //对方
cin >> x >> y; if (x != -1) board[x][y] = '1'; //我方
}
cin >> x >> y;
if (n == 1 && x == -1)
{
cout << 7 << " " << 7 << endl;
return 0;
}
board[x][y] = 'w';
pair<int, int>aa = game();
cout<<aa.first<<' '<<aa.second<<endl;
return 0;
}