Othello, ACM/ICPC World Finals 1992
阿新 • • 發佈:2018-12-15
- 模擬
- 思路:
- 依次模擬3種指令
- 注意:
- Make a move指令輸出的格式是‘Black - xx White - yy’1
- 統計棋子的個數時,要不重不漏。當然,也可以每次遍歷棋盤,統計個數,這種方法可以減少錯誤
- 函式可以替代重複程式碼
#include <iostream>
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
char board[9][9];
typedef pair<int, int> Pint;
set< Pint> pm;
int piece[2];
bool inBoard(int r, int c)
{
return 1 <= r && r <= 8 && 1 <= c && c <= 8;
}
bool isPossibleLine(int r, int c, int dr, int dc, const char &cur, const char &curPlayer)
{
r += dr;
c += dc;
while (inBoard(r, c) && board[r][c] == cur)
{
r += dr;
c += dc;
if (inBoard(r, c) && board[r][c] == curPlayer)
{
return true;
}
}
return false;
}
bool isPossibleMove(const int &r0, const int &c0, const bool &isB)
{
if (board[r0][c0] != '-' )
return false;
char cur = 'B';
char curPlayer = 'W';
if (isB)
{
cur = 'W';
curPlayer = 'B';
}
for (int dr = -1; dr <= 1; ++dr)
for (int dc = -1; dc <= 1; ++dc)
{
if (dr == 0 && dc == 0)
continue;
if (isPossibleLine(r0, c0, dr, dc, cur, curPlayer))
return true;
}
return false;
}
bool makeAMove(const int &r0, const int &c0, bool isB)
{
char cur = 'B', curPlayer = 'W';
if (isB)
{
cur = 'W';
curPlayer = 'B';
}
bool okCurPlayer = false;
for (int dr = -1; dr <= 1; ++dr)
for (int dc = -1; dc <= 1; ++dc)
{
if (dr == 0 && dc == 0)
continue;
// bool okLine = false;
if (isPossibleLine(r0, c0, dr, dc, cur, curPlayer))
{
okCurPlayer = true;
board[r0][c0] = curPlayer;
int r = r0 + dr, c = c0 + dc;
while (board[r][c] == cur)
{
piece[isB]++;
piece[!isB]--;
board[r][c] = curPlayer;
r += dr;
c += dc;
}
}
}
if (okCurPlayer)
{
piece[isB]++;
}
else
{
char temp = cur;
cur = curPlayer;
curPlayer = temp;
isB = !isB;
piece[isB]++;
for (int dr = -1; dr <= 1; ++dr)
for (int dc = -1; dc <= 1; ++dc)
{
if (dr == 0 && dc == 0)
continue;
// bool okLine = false;
if (isPossibleLine(r0, c0, dr, dc, cur, curPlayer))
{
board[r0][c0] = curPlayer;
int r = r0 + dr, c = c0 + dc;
while (board[r][c] == cur)
{
piece[isB]++;
piece[!isB]--;
board[r][c] = curPlayer;
r += dr;
c += dc;
}
}
}
}
return !isB;
}
int main()
{
int T;
bool first = true;
cin >> T;
while (T--)
{
if (first)
first = false;
else
cout << endl;
pm.clear();
memset(piece, 0, sizeof(piece));
for (int r = 1; r <= 8; ++r)
for (int c = 1; c <= 8; ++c)
{
cin >> board[r][c];
if (board[r][c] == 'W')
piece[0]++;
else if (board[r][c] == 'B')
piece[1]++;
}
char curPlayer;
bool isB = false;
cin >> curPlayer;
if (curPlayer == 'B')
isB = true;
char p[4];
while (cin >> p)
{
// cout << p << endl;
if (p[0] == 'L')
{
// int cnt = 0;
pm.clear();
for (int r = 1; r <= 8; ++r)
for (int c = 1; c <= 8; ++c)
{
if (board[r][c] != '-')
continue;
// cout << "here!" << endl;
if (isPossibleMove(r, c, isB))
pm.insert(Pint(r, c));
}
for (auto it = pm.begin(); it != pm.end(); ++it)
{
if (it != pm.begin())
cout << " ";
cout << '(' << it->first << ',' << it->second << ")";
}
if (pm.size() == 0)
cout << "No legal move.";
cout << endl;
}
if (p[0] == 'M')
{
int r = p[1] - '0', c = p[2] - '0';
isB = makeAMove(r, c, isB);
printf("Black - %2d White - %2d\n", piece[1], piece[0]);
// printf("%d %d\n", piece[1], piece[0]);
// cout << "Black - " << piece[1] << " White - " << piece[0] << endl;
}
if (p[0] == 'Q')
{
for (int r = 1; r <= 8; r++)
{
for (int c = 1; c <= 8; ++c)
cout << board[r][c];
cout << endl;
}
break;
}
}
}
return 0;
}
如果棋盤上某顏色棋子的個數是個位數,則要在十位處空出一格。 ↩︎