-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy path10111.cpp
104 lines (86 loc) · 2.78 KB
/
10111.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
math > game theory > minimax
difficulty: medium
date: 12/Apr/2020
problem: given a state of a tic tac toe board, check if X will win independent of the O movement
hint: minimax + memo + backtracking
by: @brpapa
*/
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef array<array<char,4>,4> Tboard;
const int INF = 1 << 30;
const int pX = -1, pY = 1;
/*
-1, se pX vence
1, se pY vence
0, se empata
INF, se ainda tem jogo
*/
int checkWinner(Tboard board) {
vector<array<pii,4>> possibilities = {
{ pii(0, 0), pii(0, 1), pii(0, 2), pii(0, 3) },
{ pii(1, 0), pii(1, 1), pii(1, 2), pii(1, 3) },
{ pii(2, 0), pii(2, 1), pii(2, 2), pii(2, 3) },
{ pii(3, 0), pii(3, 1), pii(3, 2), pii(3, 3) },
{ pii(0, 0), pii(1, 0), pii(2, 0), pii(3, 0) },
{ pii(0, 1), pii(1, 1), pii(2, 1), pii(3, 1) },
{ pii(0, 2), pii(1, 2), pii(2, 2), pii(3, 2) },
{ pii(0, 3), pii(1, 3), pii(2, 3), pii(3, 3) },
{ pii(0, 0), pii(1, 1), pii(2, 2), pii(3, 3) },
{ pii(0, 3), pii(1, 2), pii(2, 1), pii(3, 0) },
};
for (auto pos : possibilities) {
char p = board[pos[0].first][pos[0].second];
if (p != '.'
&& p == board[pos[1].first][pos[1].second]
&& p == board[pos[2].first][pos[2].second]
&& p == board[pos[3].first][pos[3].second])
return p == 'x'? pX : pY;
}
for (int r = 0; r < 4; r++)
for (int c = 0; c < 4; c++)
if (board[r][c] == '.') return INF;
return 0;
}
map<Tboard, int> memo;
// retorna o player vencedor
int minimax(int p, Tboard board) {
// jogador atual p, estado atual do jogo board
if (memo.count(board)) return memo[board];
int &ans = memo[board];
ans = checkWinner(board);
if (ans != INF) return ans;
ans *= p * (-1);
for (int r = 0; r < 4; r++)
for (int c = 0; c < 4; c++)
if (board[r][c] == '.') {
board[r][c] = (p == pX)? 'x' : 'o';
int maybe = minimax(p * (-1), board);
board[r][c] = '.';
if (p == pX) ans = min(ans, maybe);
else ans = max(ans, maybe);
}
return ans;
}
int main() {
char c;
while (cin >> c && c != '$') {
Tboard board;
for (int r = 0; r < 4; r++)
for (int c = 0; c < 4; c++)
cin >> board[r][c]; // 'x', 'o' ou '.'
pii sol = {-1, -1};
for (int r = 0; r < 4; r++)
for (int c = 0; c < 4; c++)
if (board[r][c] == '.') {
board[r][c] = 'x';
if (minimax(pY, board) == pX && sol == pii(-1, -1)) sol = {r, c};
board[r][c] = '.';
}
if (sol == pii(-1, -1)) cout << "#####" << endl;
else cout << "(" << sol.first << "," << sol.second << ")" << endl;
}
return 0;
}