Accepted date: 2014-07-06
Ranking (as of 2014-07-08): 467 out of 503
Re-judged and accepted date: 2016-02-07
Run Time: 0.000
Ranking (as of 2016-02-07): 392 out of 586
Language: C++
/*
UVa 220 - Othello
To build using Visual Studio 2012:
cl -EHsc -O2 UVa_220_Othello.cpp
*/
#include <cstdio>
const int nr_squares = 8;
char board[nr_squares][nr_squares + 1];
bool is_other_disk(char disk, int r, int c)
{
if (r < 0 || r >= nr_squares || c < 0 || c >= nr_squares)
return false;
return board[r][c] != '-' && disk != board[r][c];
}
bool is_leagal_move(char disk, int r, int c)
{
if (is_other_disk(disk, r - 1, c)) // above squares
for (int i = r - 2; i >= 0; i--) {
if (board[i][c] == disk)
return true;
else if (board[i][c] == '-')
break;
}
if (is_other_disk(disk, r + 1, c)) // below squares
for (int i = r + 2; i < nr_squares; i++) {
if (board[i][c] == disk)
return true;
else if (board[i][c] == '-')
break;
}
if (is_other_disk(disk, r, c - 1)) // left squares
for (int j = c - 2; j >= 0; j--) {
if (board[r][j] == disk)
return true;
else if (board[r][j] == '-')
break;
}
if (is_other_disk(disk, r, c + 1)) // rigtht squares
for (int j = c + 2; j < nr_squares; j++) {
if (board[r][j] == disk)
return true;
else if (board[r][j] == '-')
break;
}
if (is_other_disk(disk, r - 1, c - 1)) // diagonally upper left squares
for (int i = r - 2, j = c - 2; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == disk)
return true;
else if (board[i][j] == '-')
break;
}
if (is_other_disk(disk, r + 1, c - 1)) // diagonally lower left squares
for (int i = r + 2, j = c - 2; i < nr_squares && j >= 0; i++, j--) {
if (board[i][j] == disk)
return true;
else if (board[i][j] == '-')
break;
}
if (is_other_disk(disk, r - 1, c + 1)) // diagonally upper rigtht squares
for (int i = r - 2, j = c + 2; i >= 0 && j < nr_squares; i--, j++) {
if (board[i][j] == disk)
return true;
else if (board[i][j] == '-')
break;
}
if (is_other_disk(disk, r + 1, c + 1)) // diagonally lower right squares
for (int i = r + 2, j = c + 2; i < nr_squares && j < nr_squares; i++, j++) {
if (board[i][j] == disk)
return true;
else if (board[i][j] == '-')
break;
}
return false;
}
bool print_leagal_moves(char disk)
{
bool leagal = false;
for (int r = 0; r < nr_squares; r++)
for (int c = 0; c < nr_squares; c++)
if (board[r][c] == '-' && is_leagal_move(disk, r, c)) {
if (leagal)
putchar(' ');
leagal = true;
printf("(%d,%d)", r + 1, c + 1);
}
if (leagal)
putchar('\n');
else
puts("No legal move.");
return leagal;
}
void move(char disk, int r, int c, int& nr_white, int& nr_black)
{
board[r][c] = disk;
int nr_changed = 0;
if (is_other_disk(disk, r - 1, c)) // above squares
for (int i = r - 2; i >= 0; i--) {
if (board[i][c] == disk) {
for (i++; i < r; i++, nr_changed++)
board[i][c] = disk;
break;
}
else if (board[i][c] == '-')
break;
}
if (is_other_disk(disk, r + 1, c)) // below squares
for (int i = r + 2; i < nr_squares; i++) {
if (board[i][c] == disk) {
for (i--; i > r; i--, nr_changed++)
board[i][c] = disk;
break;
}
else if (board[i][c] == '-')
break;
}
if (is_other_disk(disk, r, c - 1)) // left squares
for (int j = c - 2; j >= 0; j--) {
if (board[r][j] == disk) {
for (j++; j < c; j++, nr_changed++)
board[r][j] = disk;
break;
}
else if (board[r][j] == '-')
break;
}
if (is_other_disk(disk, r, c + 1)) // rigtht squares
for (int j = c + 2; j < nr_squares; j++) {
if (board[r][j] == disk) {
for (j--; j > c; j--, nr_changed++)
board[r][j] = disk;
break;
}
else if (board[r][j] == '-')
break;
}
if (is_other_disk(disk, r - 1, c - 1)) // diagonally upper left squares
for (int i = r - 2, j = c - 2; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == disk) {
for (i++, j++; i < r && j < c; i++, j++, nr_changed++)
board[i][j] = disk;
break;
}
else if (board[i][j] == '-')
break;
}
if (is_other_disk(disk, r + 1, c - 1)) // diagonally lower left squares
for (int i = r + 2, j = c - 2; i < nr_squares && j >= 0; i++, j--) {
if (board[i][j] == disk) {
for (i--, j++; i > r && j < c; i--, j++, nr_changed++)
board[i][j] = disk;
break;
}
else if (board[i][j] == '-')
break;
}
if (is_other_disk(disk, r - 1, c + 1)) // diagonally upper rigtht squares
for (int i = r - 2, j = c + 2; i >= 0 && j < nr_squares; i--, j++) {
if (board[i][j] == disk) {
for (i++, j--; i < r && j > c; i++, j--, nr_changed++)
board[i][j] = disk;
break;
}
else if (board[i][j] == '-')
break;
}
if (is_other_disk(disk, r + 1, c + 1)) // diagonally lower right squares
for (int i = r + 2, j = c + 2; i < nr_squares && j < nr_squares; i++, j++) {
if (board[i][j] == disk) {
for (i--, j--; i > r && j > c; i--, j--, nr_changed++)
board[i][j] = disk;
break;
}
else if (board[i][j] == '-')
break;
}
if (disk == 'W') {
nr_white += nr_changed + 1; nr_black -= nr_changed;
}
else {
nr_white -= nr_changed; nr_black += nr_changed + 1;
}
}
int main()
{
int nr_games;
scanf("%d", &nr_games);
while (nr_games--) {
for (int i = 0; i < nr_squares; i++)
scanf("%s", board[i]);
int nr_white = 0, nr_black = 0;
for (int r = 0; r < nr_squares; r++)
for (int c = 0; c < nr_squares; c++) {
if (board[r][c] == 'W')
nr_white++;
else if (board[r][c] == 'B')
nr_black++;
}
char command[4];
scanf("%s", command);
char disk = command[0];
bool quit = false;
while (!quit) {
scanf("%s", command);
switch (command[0]) {
case 'L':
if (!print_leagal_moves(disk))
disk = (disk == 'W') ? 'B' : 'W';
break;
case 'M':
move(disk, command[1] - '1', command[2] - '1', nr_white, nr_black);
printf("Black - %2d White - %2d\n", nr_black, nr_white);
disk = (disk == 'W') ? 'B' : 'W';
break;
default:
quit = true;
for (int i = 0; i < nr_squares; i++)
puts(board[i]);
break;
}
}
if (nr_games)
putchar('\n');
}
return 0;
}