直接看代码:
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#include <cstdio>
#define clear() cout << "\033c" << flush
using namespace std;
const int WIDTH = 8, HEIGHT = 8;
int board[HEIGHT + 5][WIDTH + 5];
int boardCopy[HEIGHT + 5][WIDTH + 5];
int bscore = 0, wscore = 0;
struct Point
{
int x, y;
} tilesToFlip[100];
int flipSiz = 0;
// 打印当前游戏棋盘
void drawBoard(int board[HEIGHT + 5][WIDTH + 5])
{
cout << " 1 2 3 4 5 6 7 8\n";
cout << " ┌───┬───┬───┬───┬───┬───┬───┬───┐\n";
for (int i = 1; i <= HEIGHT; i++)
{
cout << i << " │";
for (int j = 1; j <= WIDTH; j++)
{
if (board[i][j] == 1)
{
cout << " ● │";
}
if (board[i][j] == -1)
{
cout << " ○ │";
}
if (board[i][j] == 0)
{
cout << " │";
}
if (board[i][j] == 2)
{
cout << " . │";
}
}
cout << " " << i << "\n";
if (i != HEIGHT)
cout << " ├───┼───┼───┼───┼───┼───┼───┼───┤\n";
else
cout << " └───┴───┴───┴───┴───┴───┴───┴───┘\n";
}
cout << " 1 2 3 4 5 6 7 8\n" << endl;
}
// 创建空白游戏棋盘
void getNewBoard()
{
memset(board, 0, sizeof(board));
board[HEIGHT / 2][WIDTH / 2] = board[HEIGHT / 2 + 1][WIDTH / 2 + 1] = 1;
board[HEIGHT / 2][WIDTH / 2 + 1] = board[HEIGHT / 2 + 1][WIDTH / 2] = -1;
}
// 判断x, y是否越界
bool isOnBoard(int x, int y)
{
return 1 <= x && x <= HEIGHT && 1 <= y && y <= WIDTH;
}
// 判断一次落子是否有效
bool isValidMove(int tile, int xstart, int ystart)
{
if (board[xstart][ystart] != 0 || !isOnBoard(xstart, ystart))
return false;
int otherTile = -tile;
// 枚举8个方向
int dir[8][2] = {{0, 1}, {1, 1}, {1, 0}, {1, -1},
{0, -1}, {-1, -1}, {-1, 0}, {-1, 1}};
flipSiz = 0;
for (int i = 0; i < 8; i++)
{
// cout << "st:" << xstart << "," << ystart << " dir:" << i << endl;
int x = xstart;
int y = ystart;
x += dir[i][0];
y += dir[i][1];
while (isOnBoard(x, y) && board[x][y] == otherTile)
{
x += dir[i][0];
y += dir[i][1];
// cout << x << "," << y << endl;
if (isOnBoard(x, y) && board[x][y] == tile)
{
while (true)
{
x -= dir[i][0];
y -= dir[i][1];
// cout << x << ", " << y << endl;
if (x == xstart && y == ystart)
break;
tilesToFlip[++flipSiz].x = x;
tilesToFlip[flipSiz].y = y;
}
}
// getchar();
}
}
if (flipSiz == 0)
return false;
return true;
}
void getBoardCopy()
{
// memset(boardCopy, 0, sizeof(boardCopy));
for (int i = 1; i <= HEIGHT; i++)
{
for (int j = 1; j <= WIDTH; j++)
{
boardCopy[i][j] = board[i][j];
}
}
}
void getBoardWithValidMoves(int board[HEIGHT + 5][WIDTH + 5], int boardCopy[HEIGHT + 5][WIDTH + 5], int tile)
{
getBoardCopy();
for (int i = 1; i <= HEIGHT; i++)
{
for (int j = 1; j <= WIDTH; j++)
{
if (isValidMove(tile, i, j))
boardCopy[i][j] = 2;
}
}
}
int getScoreOfBoard(int board[HEIGHT + 5][WIDTH + 5], int tile)
{
bscore = 0;
wscore = 0;
for (int i = 1; i <= HEIGHT; i++)
{
for (int j = 1; j <= WIDTH; j++)
{
if (board[i][j] == 1) // 黑
bscore += 1;
if (board[i][j] == -1) // 白
wscore += 1;
}
}
if (tile == 1)
return bscore;
else
return wscore;
}
int enterPlayerTile()
{
int tile = 0;
while (tile != 1 && tile != -1)
{
cout << "你想要 黑棋● 还是 白棋○ ?\n";
cout << "黑棋●: 1 白棋○: -1" << endl;
cin >> tile;
}
return tile;
}
string whoGoesFirst()
{
srand(time(NULL));
int r = rand() % 2; // 0 电脑先 1 玩家先
string turn;
if (r == 0)
turn = "电脑";
else
turn = "玩家";
return turn;
}
bool makeMove(int board[HEIGHT + 5][WIDTH + 5], int tile, int xstart, int ystart)
{
bool tf = isValidMove(tile, xstart, ystart);
if (tf == false)
return false;
board[xstart][ystart] = tile;
for (int i = 1; i <= flipSiz; i++)
{
int x = tilesToFlip[i].x;
int y = tilesToFlip[i].y;
board[x][y] = tile;
}
return true;
}
bool isOnCorner(int x, int y)
{
return x == 1 || x == HEIGHT || y == 1 || y == WIDTH;
}
string getPlayerMove(int playerTile)
{
string move;
while (true)
{
cout << "请输入行列数字或字母(例:行列数字:1 2 q: 退出游戏 h: 切换提示)" << endl;
getline(cin, move);
while (move.size() == 0)
getline(cin, move);
if (move == "q" || move == "h")
return move;
if (move.size() == 3 && move[0] >= '1' && move[0] <= '8' && move[2] >= '1' && move[2] <= '8')
{
int x = move[0] - '0';
int y = move[2] - '0';
if (isValidMove(playerTile, x, y) == false)
{
cout << "下棋失败!请重新输入" << endl;
continue;
}
else
break;
}
}
return move;
}
Point getComputerMove(int computerTile)
{
Point possibleMoves[100];
int pmsiz = 0;
for (int i = 1; i <= HEIGHT; i++)
{
for (int j = 1; j <= WIDTH; j++)
{
if (isValidMove(computerTile, i, j))
{
possibleMoves[++pmsiz].x = i;
possibleMoves[pmsiz].y = j;
}
}
}
srand(time(NULL));
random_shuffle(possibleMoves + 1, possibleMoves + pmsiz + 1);
for (int i = 1; i <= pmsiz; i++)
{
int x = possibleMoves[i].x;
int y = possibleMoves[i].y;
if (isOnCorner(x, y))
{
return possibleMoves[i];
}
}
int bestScore = -1;
Point bestMove;
for (int i = 1; i <= pmsiz; i++)
{
int x = possibleMoves[i].x;
int y = possibleMoves[i].y;
getBoardCopy();
makeMove(boardCopy, computerTile, x, y);
int score = getScoreOfBoard(boardCopy, computerTile);
if (score > bestScore)
{
bestMove = possibleMoves[i];
}
}
return bestMove;
}
void printScore(int board[HEIGHT + 5][WIDTH + 5], int playerTile, int computerTile)
{
int playerScore = getScoreOfBoard(board, playerTile);
int computerScore = getScoreOfBoard(board, computerTile);
cout << "你的分数: " << playerScore << ". 电脑分数: " << computerScore << "." << endl;
}
void playGame(int playerTile, int computerTile)
{
bool showHints = false;
string turn = whoGoesFirst();
cout << turn << " 先开始。" << endl;
getNewBoard();
while (true)
{
Point playerValidMoves[100];
int pmsiz = 0;
for (int i = 1; i <= HEIGHT; i++)
{
for (int j = 1; j <= WIDTH; j++)
{
if (isValidMove(playerTile, i, j))
{
playerValidMoves[++pmsiz].x = i;
playerValidMoves[pmsiz].y = j;
}
}
}
// cout << "CHECK" << endl;
Point computerValidMoves[100];
int cmsiz = 0;
for (int i = 1; i <= HEIGHT; i++)
{
for (int j = 1; j <= WIDTH; j++)
{
if (isValidMove(computerTile, i, j))
{
computerValidMoves[++cmsiz].x = i;
computerValidMoves[cmsiz].y = j;
}
}
}
if (pmsiz == 0 && cmsiz == 0)
{
return;
}
if (turn == "玩家")
{
if (pmsiz != 0)
{
if (showHints)
{
getBoardWithValidMoves(board, boardCopy, playerTile);
drawBoard(boardCopy);
}
else
{
drawBoard(board);
}
printScore(board, playerTile, computerTile);
}
string move = getPlayerMove(playerTile);
if (move == "q")
{
cout << "游戏结束!" << endl;
exit(0);
}
else if (move == "h")
{
showHints = !showHints;
continue;
}
else
{
makeMove(board, playerTile, move[0]-'0', move[2]-'0');
}
turn = "电脑";
}
else if (turn == "电脑")
{
if (cmsiz != 0)
{
drawBoard(board);
printScore(board, playerTile, computerTile);
cout << "按下回车,查看电脑回合……" << endl;
getchar();
Point move = getComputerMove(computerTile);
makeMove(board, computerTile, move.x, move.y);
}
turn = "玩家";
}
}
}
void startGame()
{
cout << "欢迎运行黑白棋游戏!" << endl;
int playerTile = enterPlayerTile();
int computerTile = -playerTile;
while (true)
{
playGame(playerTile, computerTile);
drawBoard(board);
int playerScore = getScoreOfBoard(board, playerTile);
int computerScore = getScoreOfBoard(board, computerTile);
printScore(board, playerTile, computerTile);
if (playerScore > computerScore)
{
cout << "恭喜你!笑傲江湖!" << endl;
}
else if (playerScore < computerScore)
{
cout << "胜败乃兵家常事!大侠请重新来过!" << endl;
}
else
{
cout << "缘分呐!平局了!" << endl;
}
cout << "你要再来一局吗?(yes or no)" << endl;
string again;
cin >> again;
if (again[0] == 'n' || again[0] == 'N')
{
break;
}
}
}
int main()
{
startGame();
return 0;
}