演示
演示
h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <stdio.h>
#define BOARD_SIZE 20
#define CELL_SIZE 18
// 初始化游戏界面
void initGame() {
initgraph(500, 360, SHOWCONSOLE);
IMAGE img;
loadimage(&img, "bk.jpg");
putimage(0, 0, &img);
setlinecolor(BLACK);
for (int i = 0; i <= BOARD_SIZE; i++) {
line(0, i * CELL_SIZE, 360, i * CELL_SIZE);
line(i * CELL_SIZE, 0, i * CELL_SIZE, 360);
}
setbkmode(TRANSPARENT);
settextcolor(WHITE);
outtextxy(380, 50, "玩家:黑棋");
outtextxy(380, 80, "AI :白棋");
}
// 判断胜利函数
int judge(int row, int col) {
int color = ChessMap[row][col];
if (color == 0) return 0;
// 横向检查
int count = 1;
for (int i = col + 1; i < BOARD_SIZE && ChessMap[row][i] == color; i++) {
count++;
}
for (int i = col - 1; i >= 0 && ChessMap[row][i] == color; i--) {
count++;
}
if (count >= 5) return color;
// 纵向检查
count = 1;
for (int i = row + 1; i < BOARD_SIZE && ChessMap[i][col] == color; i++) {
count++;
}
for (int i = row - 1; i >= 0 && ChessMap[i][col] == color; i--) {
count++;
}
if (count >= 5) return color;
// 左上 - 右下斜向检查
count = 1;
for (int i = 1; row + i < BOARD_SIZE && col + i < BOARD_SIZE && ChessMap[row +
i][col + i] == color; i++) {
count++;
}
for (int i = 1; row - i >= 0 && col - i >= 0 && ChessMap[row - i][col - i] ==
color; i++) {
count++;
}
if (count >= 5) return color;
// 右上 - 左下斜向检查
count = 1;
for (int i = 1; row - i >= 0 && col + i < BOARD_SIZE && ChessMap[row - i][col +
i] == color; i++) {
count++;
}
for (int i = 1; row + i < BOARD_SIZE && col - i >= 0 && ChessMap[row + i][col -
i] == color; i++) {
count++;
}
if (count >= 5) return color;
return 0;
}
// 评估某个位置的得分
int evaluate(int row, int col, int color) {
int score = 0;
int directions[4][2] = { {1, 0}, {0, 1}, {1, 1}, {1, -1} };
// 正向检查
for (int i = 1; row + i * dy < BOARD_SIZE && col + i * dx < BOARD_SIZE &&
col + i * dx >= 0; i++) {
if (ChessMap[row + i * dy][col + i * dx] == color) {
count++;
}
else if (ChessMap[row + i * dy][col + i * dx] == 0) {
emptyCountRight++;
break;
}
else {
break;
}
}
// 反向检查
for (int i = 1; row - i * dy >= 0 && col - i * dx < BOARD_SIZE && col - i *
dx >= 0; i++) {
if (ChessMap[row - i * dy][col - i * dx] == color) {
count++;
}
else if (ChessMap[row - i * dy][col - i * dx] == 0) {
emptyCountLeft++;
break;
}
else {
break;
}
}
// 根据连子数量和空位情况计算得分
if (count >= 5) {
score += 10000;
}
else if (count == 4) {
if (emptyCountLeft + emptyCountRight >= 1) {
score += 1000;
}
}
else if (count == 3) {
if (emptyCountLeft + emptyCountRight >= 2) {
score += 100;
}
}
else if (count == 2) {
if (emptyCountLeft + emptyCountRight >= 3) {
score += 10;
}
}
}
return score;
}
// AI 落子函数
void AI_Move(int difficulty, int* lastX, int* lastY) {
int x = 0, y = 0;
switch (difficulty) {
case 0: // 简单模式:随机落子
do {
x = rand() % BOARD_SIZE;
y = rand() % BOARD_SIZE;
} while (ChessMap[x][y] != 0);
break;
case 1: { // 中等模式:优先靠近现有棋子
int move_found = 0;
for (int dx = -1; dx <= 1 && !move_found; dx++) {
for (int dy = -1; dy <= 1 && !move_found; dy++) {
if (dx == 0 && dy == 0) continue;
for (int i = 1; i < 5; i++) {
int cx = 9 + dx * i;
int cy = 9 + dy * i;
if (cx < 0 || cx >= BOARD_SIZE || cy < 0 || cy >= BOARD_SIZE)
continue;
if (ChessMap[cx][cy] == 0) {
for (int ddx = -1; ddx <= 1; ddx++) {
for (int ddy = -1; ddy <= 1; ddy++) {
if (ddx == 0 && ddy == 0) continue;
int nx = cx + ddx;
int ny = cy + ddy;
if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny <
BOARD_SIZE && ChessMap[nx][ny] == 2) {
x = cx;
y = cy;
move_found = 1;
break;
}
}
if (move_found) break;
}
}
}
}
}
if (!move_found) {
do {
x = rand() % BOARD_SIZE;
y = rand() % BOARD_SIZE;
} while (ChessMap[x][y] != 0);
}
break;
}
case 2: { // 困难模式:优先堵截玩家连子或创造自己连子,考虑潜在连子
int best_score = -1;
int best_move_x = -1, best_move_y = -1;
// 评估阻止玩家落子的得分
ChessMap[i][j] = 1;
int score_opponent = evaluate(i, j, 1);
ChessMap[i][j] = 0;
x = best_move_x;
y = best_move_y;
break;
}
case 3: { // 地狱模式:考虑更长远的局势,更注重创造自己的连子和阻止玩家的连子
int best_score = -1;
int best_move_x = -1, best_move_y = -1;
// 评估阻止玩家落子的得分
ChessMap[i][j] = 1;
int score_opponent = evaluate(i, j, 1);
ChessMap[i][j] = 0;
// 考虑更长远的局势,增加对自己连子的权重
int total_score = score_self * 3 + score_opponent * 2;
x = best_move_x;
y = best_move_y;
break;
}
}
ChessMap[x][y] = 2;
setfillcolor(WHITE);
// 绘制棋子到格子中心
solidcircle(y * CELL_SIZE + CELL_SIZE / 2, x * CELL_SIZE + CELL_SIZE / 2, 7);
// 记录当前落子位置
*lastX = x;
*lastY = y;
// 保存数据到文件
FILE* fp = fopen("data.txt", "a");
if (fp != NULL) {
fprintf(fp, "AI Move: Row %d, Col %d\n", x, y);
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
fprintf(fp, "%d ", ChessMap[i][j]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
}
// 优化鼠标点击处理,确保落在格子中心附近
void handleMouseClick(MOUSEMSG msg) {
if (msg.uMsg == WM_LBUTTONDOWN) {
// 检查点击位置是否在棋盘范围内
if (msg.x >= 0 && msg.x < 360 && msg.y >= 0 && msg.y < 360) {
int centerX = (msg.x / CELL_SIZE) * CELL_SIZE + CELL_SIZE / 2;
int centerY = (msg.y / CELL_SIZE) * CELL_SIZE + CELL_SIZE / 2;
int dx = msg.x - centerX;
int dy = msg.y - centerY;
// 判断是否点击在格子中心附近
if (dx * dx + dy * dy <= (CELL_SIZE / 2) * (CELL_SIZE / 2)) {
int col = msg.x / CELL_SIZE;
int row = msg.y / CELL_SIZE;
if (col < 0 || col >= BOARD_SIZE || row < 0 || row >= BOARD_SIZE ||
ChessMap[row][col] != 0) return;
ChessMap[row][col] = 1;
setfillcolor(BLACK);
// 绘制棋子到格子中心
solidcircle(col * CELL_SIZE + CELL_SIZE / 2, row * CELL_SIZE +
CELL_SIZE / 2, 7);
// 保存数据到文件
FILE* fp = fopen("data.txt", "a");
if (fp != NULL) {
fprintf(fp, "Player Move: Row %d, Col %d\n", row, col);
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
fprintf(fp, "%d ", ChessMap[i][j]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
// 只判断当前落子位置是否获胜
if (judge(row, col) == 1) {
HWND hwnd = GetHWnd();
MessageBox(hwnd, "玩家胜利!", "游戏结束", MB_OK);
closegraph();
exit(0);
}
flag++;
}
}
}
}
int main() {
srand((unsigned)time(NULL));
initGame();
// 提示选择好难度
printf("你已经选择好相应难度!\n");
// 保存初始难度信息到文件
FILE* fp = fopen("data.txt", "w");
if (fp != NULL) {
fprintf(fp, "AI Difficulty: %d\n", difficulty);
fclose(fp);
}
// 只判断当前 AI 落子位置是否获胜
if (lastX != -1 && lastY != -1) {
int win = judge(lastX, lastY);
if (win == 2) {
MessageBox(hwnd, "AI 胜利!", "游戏结束", MB_OK);
closegraph();
return 0;
}
}
}
// 检查平局
int is_full = 1;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (ChessMap[i][j] == 0) {
is_full = 0;
break;
}
}
if (!is_full) break;
}
if (is_full) {
MessageBox(hwnd, "平局!", "游戏结束", MB_OK);
closegraph();
return 0;
}
}
closegraph();
return 0;
}