|
|
以下是使用EasyX图形库实现的五子棋人机对战示例代码。该示例包含一个简单的AI算法,基于评分表选择落子位置,适合初学者理解。代码已去除外部链接,并遵循Discuz! BBCode格式要求。
- #include <graphics.h>
- #include <conio.h>
- #include <time.h>
- #define GRID_SIZE 40 // 格子大小
- #define BOARD_SIZE 15 // 棋盘大小
- int board[BOARD_SIZE][BOARD_SIZE] = {0}; // 0:空, 1:玩家, 2:AI
- bool isPlayerTurn = true; // 玩家先手
- // 绘制棋盘
- void drawBoard() {
- setbkcolor(RGB(255, 205, 150)); // 设置背景色为浅橙色
- cleardevice();
- setlinecolor(BLACK);
- for (int i = 0; i < BOARD_SIZE; i++) {
- // 画横线
- line(GRID_SIZE, GRID_SIZE + i * GRID_SIZE, GRID_SIZE * BOARD_SIZE, GRID_SIZE + i * GRID_SIZE);
- // 画竖线
- line(GRID_SIZE + i * GRID_SIZE, GRID_SIZE, GRID_SIZE + i * GRID_SIZE, GRID_SIZE * BOARD_SIZE);
- }
- // 画棋盘上的五个小黑点(天元和四星)
- int dots[5][2] = {{3, 3}, {3, 11}, {7, 7}, {11, 3}, {11, 11}};
- setfillcolor(BLACK);
- for (int i = 0; i < 5; i++) {
- int x = GRID_SIZE + dots[i][0] * GRID_SIZE;
- int y = GRID_SIZE + dots[i][1] * GRID_SIZE;
- solidcircle(x, y, 5);
- }
- }
- // 绘制棋子
- void drawPiece(int x, int y, int player) {
- if (player == 1) {
- setfillcolor(BLACK);
- } else if (player == 2) {
- setfillcolor(WHITE);
- } else {
- return;
- }
- int centerX = GRID_SIZE + x * GRID_SIZE;
- int centerY = GRID_SIZE + y * GRID_SIZE;
- solidcircle(centerX, centerY, GRID_SIZE / 2 - 2);
- }
- // 判断胜负
- int checkWin(int x, int y) {
- int directions[4][2] = {{1, 0}, {0, 1}, {1, 1}, {1, -1}};
- for (int i = 0; i < 4; i++) {
- int count = 1;
- int dx = directions[i][0];
- int dy = directions[i][1];
- // 正向检查
- for (int step = 1; step <= 4; step++) {
- int nx = x + dx * step;
- int ny = y + dy * step;
- if (nx < 0 || nx >= BOARD_SIZE || ny < 0 || ny >= BOARD_SIZE || board[nx][ny] != board[x][y]) {
- break;
- }
- count++;
- }
- // 反向检查
- for (int step = 1; step <= 4; step++) {
- int nx = x - dx * step;
- int ny = y - dy * step;
- if (nx < 0 || nx >= BOARD_SIZE || ny < 0 || ny >= BOARD_SIZE || board[nx][ny] != board[x][y]) {
- break;
- }
- count++;
- }
- if (count >= 5) {
- return board[x][y];
- }
- }
- return 0;
- }
- // 简单AI:基于评分表选择位置
- void aiMove() {
- int bestScore = -1;
- int bestX = -1, bestY = -1;
- for (int x = 0; x < BOARD_SIZE; x++) {
- for (int y = 0; y < BOARD_SIZE; y++) {
- if (board[x][y] == 0) {
- // 简单评分:优先选择靠近中心的位置
- int score = 0;
- int center = BOARD_SIZE / 2;
- score -= abs(x - center) + abs(y - center); // 距离中心越近,分数越高(负值越小)
- // 如果该位置周围有棋子,增加分数
- for (int dx = -1; dx <= 1; dx++) {
- for (int dy = -1; dy <= 1; dy++) {
- int nx = x + dx;
- int ny = y + dy;
- if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE) {
- if (board[nx][ny] == 2) {
- score += 10; // AI自己的棋子
- } else if (board[nx][ny] == 1) {
- score += 5; // 玩家的棋子
- }
- }
- }
- }
- if (score > bestScore) {
- bestScore = score;
- bestX = x;
- bestY = y;
- }
- }
- }
- }
- if (bestX != -1 && bestY != -1) {
- board[bestX][bestY] = 2;
- drawPiece(bestX, bestY, 2);
- }
- }
- int main() {
- initgraph(GRID_SIZE * (BOARD_SIZE + 1), GRID_SIZE * (BOARD_SIZE + 1));
- drawBoard();
- settextstyle(20, 0, _T("宋体"));
- settextcolor(BLACK);
- outtextxy(10, 10, _T("玩家执黑先手,AI执白后手"));
- while (true) {
- if (isPlayerTurn) {
- MOUSEMSG msg = GetMouseMsg();
- if (msg.uMsg == WM_LBUTTONDOWN) {
- int x = (msg.x - GRID_SIZE / 2) / GRID_SIZE;
- int y = (msg.y - GRID_SIZE / 2) / GRID_SIZE;
- if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE && board[x][y] == 0) {
- board[x][y] = 1;
- drawPiece(x, y, 1);
- if (checkWin(x, y) == 1) {
- MessageBox(GetHWnd(), _T("玩家获胜!"), _T("游戏结束"), MB_OK);
- break;
- }
- isPlayerTurn = false;
- }
- }
- } else {
- // AI下棋
- aiMove();
- // 检查AI是否获胜
- for (int x = 0; x < BOARD_SIZE; x++) {
- for (int y = 0; y < BOARD_SIZE; y++) {
- if (board[x][y] == 2 && checkWin(x, y) == 2) {
- drawBoard(); // 重绘棋盘以显示所有棋子
- for (int i = 0; i < BOARD_SIZE; i++) {
- for (int j = 0; j < BOARD_SIZE; j++) {
- if (board[i][j] != 0) {
- drawPiece(i, j, board[i][j]);
- }
- }
- }
- MessageBox(GetHWnd(), _T("AI获胜!"), _T("游戏结束"), MB_OK);
- closegraph();
- return 0;
- }
- }
- }
- isPlayerTurn = true;
- }
- // 检查平局(棋盘已满)
- bool isFull = true;
- for (int x = 0; x < BOARD_SIZE; x++) {
- for (int y = 0; y < BOARD_SIZE; y++) {
- if (board[x][y] == 0) {
- isFull = false;
- break;
- }
- }
- if (!isFull) break;
- }
- if (isFull) {
- MessageBox(GetHWnd(), _T("平局!"), _T("游戏结束"), MB_OK);
- break;
- }
- }
- closegraph();
- return 0;
- }
复制代码
使用说明:
1. 确保已安装 EasyX 图形库(建议使用Visual Studio开发环境)。
2. 创建一个Win32控制台应用程序项目,将上述代码复制到主文件中。
3. 编译运行即可。
注意事项:
- 该AI算法较为简单,仅基于距离中心和相邻棋子进行评分,因此棋力有限。
- 如需改进AI,可考虑实现 Minimax 算法配合 Alpha-Beta剪枝,或使用模式评分表(如冲四、活三等棋形评分)。
- 代码中已去除所有外部链接,确保符合要求。
希望这个示例能帮助你理解五子棋人机对战的基本实现。如果需要进一步优化AI,建议学习博弈树搜索相关算法。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |
|